SMetric3 max_edge_curvature_metric(const GVertex *gv) { SMetric3 val (1.e-12); std::list<GEdge*> l_edges = gv->edges(); for (std::list<GEdge*>::const_iterator ite = l_edges.begin(); ite != l_edges.end(); ++ite){ GEdge *_myGEdge = *ite; Range<double> range = _myGEdge->parBounds(0); SMetric3 cc; if (gv == _myGEdge->getBeginVertex()) { SVector3 t = _myGEdge->firstDer(range.low()); t.normalize(); double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.low())) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; cc = buildMetricTangentToCurve(t,l_t,l_n); } else { SVector3 t = _myGEdge->firstDer(range.high()); t.normalize(); double l_t = ((2 * M_PI) /( fabs(_myGEdge->curvature(range.high())) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; cc = buildMetricTangentToCurve(t,l_t,l_n); } val = intersection(val,cc); } return val; }
SMetric3 buildMetricTangentToSurface(SVector3 &t1, SVector3 &t2, double l_t1, double l_t2, double l_n) { t1.normalize(); t2.normalize(); SVector3 n = crossprod (t1,t2); n.normalize(); l_t1 = std::max(l_t1, CTX::instance()->mesh.lcMin); l_t2 = std::max(l_t2, CTX::instance()->mesh.lcMin); l_t1 = std::min(l_t1, CTX::instance()->mesh.lcMax); l_t2 = std::min(l_t2, CTX::instance()->mesh.lcMax); SMetric3 Metric (1./(l_t1*l_t1),1./(l_t2*l_t2),1./(l_n*l_n),t1,t2,n); return Metric; }
SMetric3 metric_based_on_surface_curvature(const GFace *gf, double u, double v, bool surface_isotropic, double d_normal , double d_tangent_max) { if (gf->geomType() == GEntity::Plane)return SMetric3(1.e-12); double cmax, cmin; SVector3 dirMax,dirMin; cmax = gf->curvatures(SPoint2(u, v),&dirMax, &dirMin, &cmax,&cmin); if (cmin == 0)cmin =1.e-12; if (cmax == 0)cmax =1.e-12; double lambda1 = ((2 * M_PI) /( fabs(cmin) * CTX::instance()->mesh.minCircPoints ) ); double lambda2 = ((2 * M_PI) /( fabs(cmax) * CTX::instance()->mesh.minCircPoints ) ); SVector3 Z = crossprod(dirMax,dirMin); if (surface_isotropic) lambda2 = lambda1 = std::min(lambda2,lambda1); dirMin.normalize(); dirMax.normalize(); Z.normalize(); lambda1 = std::max(lambda1, CTX::instance()->mesh.lcMin); lambda2 = std::max(lambda2, CTX::instance()->mesh.lcMin); lambda1 = std::min(lambda1, CTX::instance()->mesh.lcMax); lambda2 = std::min(lambda2, CTX::instance()->mesh.lcMax); double lambda3 = std::min(d_normal, CTX::instance()->mesh.lcMax); lambda3 = std::max(lambda3, CTX::instance()->mesh.lcMin); lambda1 = std::min(lambda1, d_tangent_max); lambda2 = std::min(lambda2, d_tangent_max); SMetric3 curvMetric (1./(lambda1*lambda1),1./(lambda2*lambda2), 1./(lambda3*lambda3), dirMin, dirMax, Z ); return curvMetric; }
// returns the cross field as a pair of othogonal vectors (NOT in parametric coordinates, but real 3D coordinates) Pair<SVector3, SVector3> frameFieldBackgroundMesh2D::compute_crossfield_directions(double u, double v, double angle_current) { // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return Pair<SVector3,SVector3>(SVector3(), SVector3()); } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); return Pair<SVector3,SVector3>(SVector3(t1[0],t1[1],t1[2]), SVector3(t2[0],t2[1],t2[2])); }
SMetric3 max_edge_curvature_metric(const GEdge *ge, double u) { SVector3 t = ge->firstDer(u); t.normalize(); double l_t = ((2 * M_PI) /( fabs(ge->curvature(u)) * CTX::instance()->mesh.minCircPoints )); double l_n = 1.e12; return buildMetricTangentToCurve(t,l_t,l_n); }
static void _relocateVertexOfPyramid(MVertex *ver, const std::vector<MElement *> <, double relax) { if(ver->onWhat()->dim() != 3) return; double x = 0.0, y = 0.0, z = 0.0; int N = 0; MElement *pyramid = NULL; for(std::size_t i = 0; i < lt.size(); i++) { double XCG = 0.0, YCG = 0.0, ZCG = 0.0; if(lt[i]->getNumVertices() == 5) pyramid = lt[i]; else { for(std::size_t j = 0; j < lt[i]->getNumVertices(); j++) { XCG += lt[i]->getVertex(j)->x(); YCG += lt[i]->getVertex(j)->y(); ZCG += lt[i]->getVertex(j)->z(); } x += XCG; y += YCG; z += ZCG; N += lt[i]->getNumVertices(); } } x /= N; y /= N; z /= N; if(pyramid) { MFace q = pyramid->getFace(4); double A = q.approximateArea(); SVector3 n = q.normal(); n.normalize(); SPoint3 c = q.barycenter(); SVector3 d(x - c.x(), y - c.y(), z - c.z()); if(dot(n, d) < 0) n = n * (-1.0); double H = .5 * sqrt(fabs(A)); double XOPT = c.x() + relax * H * n.x(); double YOPT = c.y() + relax * H * n.y(); double ZOPT = c.z() + relax * H * n.z(); double FULL_MOVE_OBJ = objective_function(1.0, ver, XOPT, YOPT, ZOPT, lt, true); // printf("relax %g obj %g\n",relax,FULL_MOVE_OBJ); if(FULL_MOVE_OBJ > 0.1) { ver->x() = XOPT; ver->y() = YOPT; ver->z() = ZOPT; return; } } }
SMetric3 buildMetricTangentToCurve(SVector3 &t, double l_t, double l_n) { if (l_t == 0.0) return SMetric3(1.e-22); SVector3 a; if (fabs(t(0)) <= fabs(t(1)) && fabs(t(0)) <= fabs(t(2))){ a = SVector3(1,0,0); } else if (fabs(t(1)) <= fabs(t(0)) && fabs(t(1)) <= fabs(t(2))){ a = SVector3(0,1,0); } else{ a = SVector3(0,0,1); } SVector3 b = crossprod (t,a); SVector3 c = crossprod (b,t); b.normalize(); c.normalize(); t.normalize(); SMetric3 Metric (1./(l_t*l_t),1./(l_n*l_n),1./(l_n*l_n),t,b,c); // printf("bmttc %g %g %g %g %g\n",l_t,l_n,Metric(0,0),Metric(0,1),Metric(1,1)); return Metric; }
int edge_normal (const MVertex *const vertex, const int zoneIndex, const GEdge *const gEdge, const CCon::FaceVector<MZoneBoundary<2>::GlobalVertexData<MEdge>::FaceDataB> &faces, SVector3 &boNormal, const int onlyFace = -1) { double par=0.0; // Note: const_cast used to match MVertex.cpp interface if(!reparamMeshVertexOnEdge(const_cast<MVertex*>(vertex), gEdge, par)) return 1; const SVector3 tangent(gEdge->firstDer(par)); // Tangent to the boundary face SPoint3 interior(0., 0., 0.); // An interior point SVector3 meshPlaneNormal(0.); // This normal is perpendicular to the // plane of the mesh // The interior point and mesh plane normal are computed from all elements in // the zone. int cFace = 0; int iFace = 0; int nFace = faces.size(); if ( onlyFace >= 0 ) { iFace = onlyFace; nFace = onlyFace + 1; } for(; iFace != nFace; ++iFace) { if(faces[iFace].zoneIndex == zoneIndex) { ++cFace; interior += faces[iFace].parentElement->barycenter(); // Make sure all the planes go in the same direction //**Required? SVector3 mpnt = faces[iFace].parentElement->getFace(0).normal(); if(dot(mpnt, meshPlaneNormal) < 0.) mpnt.negate(); meshPlaneNormal += mpnt; } } interior /= cFace; // Normal to the boundary edge (but unknown direction) boNormal = crossprod(tangent, meshPlaneNormal); boNormal.normalize(); // Direction vector from vertex to interior (inwards). The normal should // point in the same direction. if(dot(boNormal, SVector3(vertex->point(), interior)) < 0.) boNormal.negate(); return 0; }
void CActorEntity::update( float timeAlpha ) { bool alive = mGameEntity->isAlive(); if( alive ) { // fade out the outline float dt = CSystemTimer::getInstance().getDeltaTimeS(); mOutlineTTL -= dt; if( mOutlineTTL < 0.0f ) mOutlineTTL = 0.0f; SMatrix4x4& m = mWorldMat; SVector3 pos = samplePos( timeAlpha ); SVector3 dir = samplePos( timeAlpha + 0.1f ) - pos; if( dir.lengthSq() < 1.0e-3f ) dir = m.getAxisZ(); else dir.normalize(); if( mGameEntity->getType() == ENTITY_BLOCKER ) { double tt = CSystemTimer::getInstance().getTimeS(); D3DXMatrixRotationY( &m, tt * 0.2f ); m.getOrigin() = pos; m.getOrigin().y += sinf( tt * 0.6f ) * 0.2f; } else { m.getOrigin() = pos; m.getAxisZ() = dir; m.getAxisZ().y *= 0.2f; m.getAxisZ().normalize(); m.getAxisY().set( 0, 1, 0 ); m.getAxisX() = m.getAxisY().cross( m.getAxisZ() ); m.getAxisX().normalize(); m.getAxisY() = m.getAxisZ().cross( m.getAxisX() ); } } else { mOutlineTTL = 0.0f; } }
void CCollisionRay::setDirection( const SVector3& direction ) { SVector3 d = direction; d.normalize(); mRay.mDir = convert( d ); }
/** * Main loop code. */ void CDemo::perform() { char buf[100]; time_value tmv = CSystemTimer::getInstance().getTime(); double t = tmv.tosec(); float dt = CSystemTimer::getInstance().getDeltaTimeS(); gTimeParam = float(t); CDynamicVBManager::getInstance().discard(); CD3DDevice& dx = CD3DDevice::getInstance(); gScreenFixUVs.set( 0.5f/dx.getBackBufferWidth(), 0.5f/dx.getBackBufferHeight(), 0.0f, 0.0f ); CGameInfo& gi = CGameInfo::getInstance(); const CGameDesc& desc = gi.getGameDesc(); CGameState& state = gi.getState(); const CGameMap& gmap = desc.getMap(); // // should we still perform some initialization steps? if( !gInitGuiDone ) { // perform multi-step initialization... const char* initStepName = NULL; if( !gInitMainStarted ) { BEGIN_T(); initStepName = gi.initBegin(); gInitMainStarted = true; } else if( !gInitMainDone ) { initStepName = gi.initStep(); if( !initStepName ) { initStepName = "Initializing GUI..."; gInitMainDone = true; } } else { gInitiallyPlaceViewer(); gSetupGUI(); gInitGuiDone = true; END_T( "initialization" ); return; } // check for init errors... if( !gErrorMsg.empty() ) { CONS << "Fatal error: " << gErrorMsg << endl; gFinished = true; return; } if( initStepName ) { CONS << "Init step: " << initStepName << endl; } // render progress assert( initStepName ); dx.clearTargets( true, true, true, 0xFF000000, 1.0f, 0L ); dx.sceneBegin(); G_RENDERCTX->applyGlobalEffect(); gUIDlg->renderBegin(); gUIDrawLogo(); gUIDrawProgress( initStepName ); gUIDlg->renderEnd(); dx.sceneEnd(); return; } // // fatal error if( gCheckFatalError() ) return; // // check if settings dialog just was closed if( gSettingsDlgWasActive && gUISettingsDlg->getState() != CDemoSettingsDialog::STATE_ACTIVE ) { gSettingsDlgWasActive = false; gUIDlg->getCheckBox( GID_CHK_OPTIONS )->setChecked( false ); if( gUISettingsDlg->getState() == CDemoSettingsDialog::STATE_OK ) { // apply settings, return if( gAppSettings.gfxDetail != gUISettingsDlg->getAppSettings().gfxDetail ) { gi.getLevelMesh().updateDetailLevel( gUISettingsDlg->getAppSettings().gfxDetail ); } gAppSettings = gUISettingsDlg->getAppSettings(); CD3DSettings d3dset; gUISettingsDlg->getFinalSettings( d3dset ); // don't apply d3d settings if they didn't change if( d3dset != gAppContext->getD3DSettings() ) gAppContext->applyD3DSettings( d3dset ); return; } } else if( gSettingsDlgWasActive ) { // if the dialog is active, but the d3d settings just changed (eg. alt-tab), // hide it and re-show it if( gSettingsAtDlgStart != gAppContext->getD3DSettings() ) { gUISettingsDlg->hideDialog(); gSettingsAtDlgStart = gAppContext->getD3DSettings(); gUISettingsDlg->showDialog( gSettingsAtDlgStart ); } } // // check if help dialog just was closed if( gHelpDlgWasActive && !gUIHelpDlg->isActive() ) { gHelpDlgWasActive = false; gUIDlg->getCheckBox( GID_CHK_HELP )->setChecked( false ); } bool gameSetupActive = (gUIGameSetupDlg->getState() == CGameSetupDialog::STATE_ACTIVE); bool insideView = gAppSettings.followMode && !gameSetupActive; // // perform input G_INPUTCTX->perform(); // // update game if it's started if( gameSetupActive ) { gUILabelTime->setVisible( false ); } else { // if server state is starting, update it if( state.getServerState().state == GST_STARTING ) { gUILabelTime->setVisible( false ); state.updateServerState( false, false ); } else { gUILabelTime->setVisible( true ); // update game state if( tmv - gLastGameUpdateTime >= time_value::fromsec(desc.getTurnDT()*0.5f) ) { // TBD: commands to dll net::updateGame( 0, 0, 0, state ); gLastGameUpdateTime = tmv; } } } // // control time // TBD /* float gameTime = gi.getTime(); float oldGameTime = gameTime; if( gUIBtnTimeRew->isPressed() ) gameTime -= TURNS_PER_SEC * TIME_SPD_FAST * dt; if( gUIBtnTimeFfwd->isPressed() ) gameTime += TURNS_PER_SEC * TIME_SPD_FAST * dt; if( gameTime != oldGameTime ) gSetPlayMode( false ); if( gPlayMode ) gameTime += TURNS_PER_SEC * TIME_SPD_NORMAL * dt; if( gameTime < 0 ) gameTime = 0; if( gameTime > replay.getGameTurnCount()-1 ) { gameTime = replay.getGameTurnCount()-1; gSetPlayMode( false ); } gUIDlg->enableNonUserEvents( false ); gUISliderTime->setValue( gameTime ); gUIDlg->enableNonUserEvents( true ); gi.setTime( gameTime ); */ // // camera int selEntityID = gi.getEntities().getSelectedEntityID(); const CActorEntity* selEntity = gi.getEntities().getActorEntityByID( selEntityID ); bool hasSelected = (selEntity != NULL); if( hasSelected ) { SVector3 selPos = selEntity->mWorldMat.getOrigin(); if( !gAppSettings.followMode ) { selPos.y = VIEWER_Y; SVector3 newPos = smoothCD( gViewer.getOrigin(), selPos, gViewerVel, 0.25f, dt ); gTryPositionViewer( newPos, selPos ); } else { //SVector3 selPrevPos = selEntity.samplePos( gi.getTime() - 10.0f ); // TBD SVector3 selPrevPos = selPos; selPrevPos.y = (selPrevPos.y + VIEWER_Y)*0.5f; selPos.y = selPrevPos.y; SVector3 dirZ = selPos - selPrevPos; dirZ.y = 0.0f; const float MIN_DIST = 2.0f; if( dirZ.lengthSq() < MIN_DIST*MIN_DIST ) { dirZ = gViewer.getAxisZ(); selPrevPos = selPrevPos - dirZ * MIN_DIST; } const float PREF_DIST = 5.0f; if( dirZ.lengthSq() < PREF_DIST*PREF_DIST ) { dirZ.normalize(); selPrevPos = selPos - dirZ * PREF_DIST; } else { dirZ.normalize(); } const float SMOOTHT = 0.5f; SVector3 newPos = smoothCD( gViewer.getOrigin(), selPrevPos, gViewerVel, SMOOTHT, dt ); gTryPositionViewer( newPos, selPrevPos ); dirZ = smoothCD( gViewer.getAxisZ(), dirZ, gViewerZVel, SMOOTHT, dt ); if( dirZ.lengthSq() < 0.5f ) { dirZ = gViewer.getAxisZ(); } else { gViewer.getAxisZ() = dirZ.getNormalized(); } gViewer.getAxisY().set(0,1,0); gViewer.getAxisX() = gViewer.getAxisY().cross( gViewer.getAxisZ() ); } } else { gViewerVel.set(0,0,0); gViewerZVel.set(0,0,0); } // // check if current viewer's position is valid { SVector3 testViewerPos = gViewer.getOrigin(); int cx = testViewerPos.x; int cy = -testViewerPos.z; if( cx >= 0 && cy >= 0 && cx < gmap.getCellsX() && cy < gmap.getCellsY() && gmap.isBlood( gmap.getCell(cx,cy).type ) ) { gi.getLevelMesh().fitSphere( testViewerPos, VIEWER_R*2.0f ); const float SMALL_FIT = 0.2f; if( SVector3(testViewerPos - gViewer.getOrigin()).lengthSq() < SMALL_FIT * SMALL_FIT ) { gLastViewerValidPos = testViewerPos; } } } SMatrix4x4& mm = gCamera.mWorldMat; mm = gViewer; float camnear, camfar, camfov, fognear, fogfar; if( !insideView ) { float tilt = gAppSettings.megaTilt; float zoom = gAppSettings.megaZoom; if( gameSetupActive ) { gUIGameSetupDlg->updateViewer( gViewer, tilt, zoom ); } SMatrix4x4 mr; D3DXMatrixRotationX( &mr, D3DXToRadian( tilt ) ); mm = mr * mm; mm.getOrigin() -= mm.getAxisZ() * zoom; camnear = (zoom - 15.0f) * 0.25f; camfar = (zoom + 10.0f) * 2.5f; camfov = D3DX_PI/3; fognear = (zoom + 10.0f) * 2.0f; fogfar = (zoom + 10.0f) * 2.3f; gFogColorParam.set( 0, 0, 0, 1 ); } else { camnear = 0.3f; camfar = 60.0f; camfov = D3DX_PI/4; fognear = 20.0f; fogfar = camfar-1; gFogColorParam.set( 0.25f, 0, 0, 1 ); } if( camnear < 0.1f ) camnear = 0.1f; gCamera.setProjectionParams( camfov, dx.getBackBufferAspect(), camnear, camfar ); gCamera.setOntoRenderContext(); // // update entities and stats UI gMouseRay = gCamera.getWorldRay( gMouseX, gMouseY ); const SVector3& eyePos = gCamera.mWorldMat.getOrigin(); SLine3 mouseRay; mouseRay.pos = eyePos; mouseRay.vec = gMouseRay; float timeAlpha = (tmv - gi.getState().getTurnReceivedTime()).tosec() / desc.getTurnDT(); if( timeAlpha >= 1.0f ) timeAlpha = 1.0f; gi.getEntities().update( mouseRay, timeAlpha ); // stats UI int nplayers = desc.getPlayerCount(); for( int p = 0; p < nplayers; ++p ) { const CGameState::SPlayer& pl = state.getPlayer(p); SUIPlayerStats& plui = gUIPlayerStats[p]; if( plui.score ) { itoa( pl.score, buf, 10 ); plui.score->setText( buf ); } if( plui.botCount ) { itoa( pl.botCount, buf, 10 ); plui.botCount->setText( buf ); } } // entity stats UI gUpdateSelEntityStats(); gUpdateMissionStats(); // time UI sprintf( buf, "%i", state.getTurn() ); gUILabelTime->setText( buf ); sprintf( buf, "fps: %.1f", dx.getStats().getFPS() ); gUILabelFPS->setText( buf ); gFogParam.set( fognear, fogfar, 1.0f/(fogfar-fognear), 0 ); dx.clearTargets( true, true, true, insideView ? 0xFF400000 : 0xFF000000, 1.0f, insideView ? 1L : 0L ); dx.sceneBegin(); G_RENDERCTX->applyGlobalEffect(); gi.getLevelMesh().render( RM_NORMAL, insideView ? (CLevelMesh::FULL) : (CLevelMesh::NOTOP) ); gi.getPointsMesh().render( RM_NORMAL ); gi.getEntities().render( RM_NORMAL, !insideView, insideView, timeAlpha ); G_RENDERCTX->perform(); // render GUI if( !gameSetupActive ) { gUIDlg->onRender( dt ); } // render minimap if( gAppSettings.showMinimap && !gameSetupActive ) gRenderMinimap(); // render GUI #2 if( gUISettingsDlg->getState() == CDemoSettingsDialog::STATE_ACTIVE ) { gUISettingsDlg->getDialog().onRender( dt ); } if( gUIHelpDlg->isActive() ) { gUIHelpDlg->getDialog().onRender( dt ); } if( gUIGameSetupDlg->getState() == CGameSetupDialog::STATE_ACTIVE ) { gUIGameSetupDlg->getDialog().onRender( dt ); } dx.sceneEnd(); }
bool frameFieldBackgroundMesh2D::compute_RK_infos(double u,double v, double x, double y, double z, RK_form &infos) { // check if point is in domain if (!inDomain(u,v)) return false; // get stored angle double angle_current = angle(u,v); // compute t1,t2: cross field directions // get the unit normal at that point GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return false; } Pair<SVector3, SVector3> der = face->firstDer(SPoint2(u,v)); SVector3 s1 = der.first(); SVector3 s2 = der.second(); SVector3 n = crossprod(s1,s2); n.normalize(); SVector3 basis_u = s1; basis_u.normalize(); SVector3 basis_v = crossprod(n,basis_u); // normalize vector t1 that is tangent to gf at uv SVector3 t1 = basis_u * cos(angle_current) + basis_v * sin(angle_current) ; t1.normalize(); // compute the second direction t2 and normalize (t1,t2,n) is the tangent frame SVector3 t2 = crossprod(n,t1); t2.normalize(); // get metric double L = size(u,v); infos.metricField = SMetric3(1./(L*L)); FieldManager *fields = gf->model()->getFields(); if(fields->getBackgroundField() > 0) { Field *f = fields->get(fields->getBackgroundField()); if (!f->isotropic()) { (*f)(x,y,z, infos.metricField,gf); } else { L = (*f)(x,y,z,gf); infos.metricField = SMetric3(1./(L*L)); } } double M = dot(s1,s1); double N = dot(s2,s2); double E = dot(s1,s2); // compute the first fundamental form i.e. the metric tensor at the point // M_{ij} = s_i \cdot s_j double metric[2][2] = {{M,E},{E,N}}; // get sizes double size_1 = sqrt(1. / dot(t1,infos.metricField,t1)); double size_2 = sqrt(1. / dot(t2,infos.metricField,t2)); // compute covariant coordinates of t1 and t2 - cross field directions in parametric domain double covar1[2],covar2[2]; // t1 = a s1 + b s2 --> // t1 . s1 = a M + b E // t1 . s2 = a E + b N --> solve the 2 x 2 system // and get covariant coordinates a and b double rhs1[2] = {dot(t1,s1),dot(t1,s2)}; bool singular = false; if (!sys2x2(metric,rhs1,covar1)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g -- %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z(),size_1,size_2); covar1[1] = 1.0; covar1[0] = 0.0; singular = true; } double rhs2[2] = {dot(t2,s1),dot(t2,s2)}; if (!sys2x2(metric,rhs2,covar2)) { Msg::Info("Argh surface %d %g %g %g -- %g %g %g",gf->tag(),s1.x(),s1.y(),s1.z(),s2.x(),s2.y(),s2.z()); covar2[0] = 1.0; covar2[1] = 0.0; singular = true; } // transform the sizes with respect to the metric // consider a vector v of size 1 in the parameter plane // its length is sqrt (v^T M v) --> if I want a real size // of size1 in direction v, it should be sqrt(v^T M v) * size1 double l1 = sqrt(covar1[0]*covar1[0]+covar1[1]*covar1[1]); double l2 = sqrt(covar2[0]*covar2[0]+covar2[1]*covar2[1]); covar1[0] /= l1; covar1[1] /= l1; covar2[0] /= l2; covar2[1] /= l2; double size_param_1 = size_1 / sqrt ( M*covar1[0]*covar1[0]+ 2*E*covar1[1]*covar1[0]+ N*covar1[1]*covar1[1]); double size_param_2 = size_2 / sqrt ( M*covar2[0]*covar2[0]+ 2*E*covar2[1]*covar2[0]+ N*covar2[1]*covar2[1]); if (singular) { size_param_1 = size_param_2 = std::min (size_param_1,size_param_2); } // filling form... infos.t1 = t1; infos.h.first = size_1; infos.h.second = size_2; infos.paramh.first = size_param_1; infos.paramh.second = size_param_2; infos.paramt1 = SPoint2(covar1[0],covar1[1]); infos.paramt2 = SPoint2(covar2[0],covar2[1]); infos.angle = angle_current; infos.localsize = L; infos.normal = n; return true; }
void frameFieldBackgroundMesh2D::computeCrossField(simpleFunction<double> &eval_diffusivity) { angles.clear(); DoubleStorageType _cosines4,_sines4; list<GEdge*> e; GFace *face = dynamic_cast<GFace*>(gf); if(!face) { Msg::Error("Entity is not a face in background mesh"); return; } replaceMeshCompound(face, e); list<GEdge*>::const_iterator it = e.begin(); for( ; it != e.end(); ++it ) { if (!(*it)->isSeam(face)) { for(unsigned int i = 0; i < (*it)->lines.size(); i++ ) { MVertex *v[2]; v[0] = (*it)->lines[i]->getVertex(0); v[1] = (*it)->lines[i]->getVertex(1); SPoint2 p1,p2; reparamMeshEdgeOnFace(v[0],v[1],face,p1,p2); Pair<SVector3, SVector3> der = face->firstDer((p1+p2)*.5); SVector3 t1 = der.first(); SVector3 t2 = der.second(); SVector3 n = crossprod(t1,t2); n.normalize(); SVector3 d1(v[1]->x()-v[0]->x(),v[1]->y()-v[0]->y(),v[1]->z()-v[0]->z()); t1.normalize(); d1.normalize(); double _angle = myAngle (t1,d1,n); normalizeAngle (_angle); for (int i=0; i<2; i++) { DoubleStorageType::iterator itc = _cosines4.find(v[i]); DoubleStorageType::iterator its = _sines4.find(v[i]); if (itc != _cosines4.end()) { itc->second = 0.5*(itc->second + cos(4*_angle)); its->second = 0.5*(its->second + sin(4*_angle)); } else { _cosines4[v[i]] = cos(4*_angle); _sines4[v[i]] = sin(4*_angle); } } } } } propagateValues(_cosines4,eval_diffusivity,false); propagateValues(_sines4,eval_diffusivity,false); std::map<MVertex*,MVertex*>::iterator itv2 = _2Dto3D.begin(); for ( ; itv2 != _2Dto3D.end(); ++itv2) { MVertex *v_2D = itv2->first; MVertex *v_3D = itv2->second; double angle = atan2(_sines4[v_3D],_cosines4[v_3D]) / 4.0; normalizeAngle (angle); angles[v_2D] = angle; } }