X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_ProjectionUtils.cxx;h=a504888d0949f335ece66b0afbe5dd49d7b0fc1b;hp=a21f5d7aa26b1986e6cbccc706a138ef5df5d70c;hb=d9f4b53e489dd5857db264ede6acded7b076c9f1;hpb=a713f0b919f062a1c9839670d4b51639c8133940 diff --git a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx index a21f5d7aa..a504888d0 100644 --- a/src/StdMeshers/StdMeshers_ProjectionUtils.cxx +++ b/src/StdMeshers/StdMeshers_ProjectionUtils.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2015 CEA/DEN, EDF R&D, OPEN CASCADE +// Copyright (C) 2007-2022 CEA/DEN, EDF R&D, OPEN CASCADE // // Copyright (C) 2003-2007 OPEN CASCADE, EADS/CCR, LIP6, CEA/DEN, // CEDRAT, EDF R&D, LEG, PRINCIPIA R&D, BUREAU VERITAS @@ -20,32 +20,35 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : idl implementation based on 'SMESH' unit's calsses +// SMESH SMESH : idl implementation based on 'SMESH' unit's classes // File : StdMeshers_ProjectionUtils.cxx // Created : Fri Oct 27 10:24:28 2006 // Author : Edward AGAPOV (eap) // #include "StdMeshers_ProjectionUtils.hxx" -#include "StdMeshers_ProjectionSource1D.hxx" -#include "StdMeshers_ProjectionSource2D.hxx" -#include "StdMeshers_ProjectionSource3D.hxx" - #include "SMDS_EdgePosition.hxx" +#include "SMDS_FacePosition.hxx" +#include "SMESHDS_Mesh.hxx" #include "SMESH_Algo.hxx" #include "SMESH_Block.hxx" #include "SMESH_Gen.hxx" #include "SMESH_HypoFilter.hxx" #include "SMESH_Hypothesis.hxx" #include "SMESH_Mesh.hxx" +#include "SMESH_MeshAlgos.hxx" +#include "SMESH_MeshEditor.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_subMesh.hxx" #include "SMESH_subMeshEventListener.hxx" -#include "SMESH_MeshAlgos.hxx" +#include "StdMeshers_ProjectionSource1D.hxx" +#include "StdMeshers_ProjectionSource2D.hxx" +#include "StdMeshers_ProjectionSource3D.hxx" #include "utilities.h" #include +#include #include #include #include @@ -79,23 +82,9 @@ using namespace std; #define RETURN_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); return false; } #define CONT_BAD_RESULT(msg) { MESSAGE(")-: Error: " << msg); continue; } #define SHOW_SHAPE(v,msg) \ -// { \ -// if ( (v).IsNull() ) cout << msg << " NULL SHAPE" << endl; \ -// else if ((v).ShapeType() == TopAbs_VERTEX) {\ -// gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( (v) ));\ -// cout<::const_iterator e = l.begin();\ -// for ( int i = 0; e != l.end(); ++e, ++i ) {\ -// cout << i << "V (" << TopExp::FirstVertex( *e, true ).TShape().operator->() << ") "\ -// << i << "E (" << e->TShape().operator->() << "); "; }\ -// cout << endl;\ -// } + // { show_list((msg),(l)); } namespace HERE = StdMeshers_ProjectionUtils; @@ -108,7 +97,24 @@ namespace { return max(theMeshDS[0]->ShapeToIndex(S), theMeshDS[1]->ShapeToIndex(S) ); return long(S.TShape().operator->()); } - + void show_shape( TopoDS_Shape v, const char* msg ) // debug // todo: unused in release mode + { + if ( v.IsNull() ) cout << msg << " NULL SHAPE" << endl; + else if (v.ShapeType() == TopAbs_VERTEX) { + gp_Pnt p = BRep_Tool::Pnt( TopoDS::Vertex( v )); + cout<& l ) // debug // todo: unused in release mode + { + cout << msg << " "; + list< TopoDS_Edge >::const_iterator e = l.begin(); + for ( int i = 0; e != l.end(); ++e, ++i ) { + cout << i << "V (" << TopExp::FirstVertex( *e, true ).TShape().operator->() << ") " + << i << "E (" << e->TShape().operator->() << "); "; } + cout << endl; + } //================================================================================ /*! * \brief Write shape for debug purposes @@ -117,11 +123,19 @@ namespace { bool storeShapeForDebug(const TopoDS_Shape& shape) { + bool toShow; #ifdef _DEBUG_ const char* type[] ={"COMPOUND","COMPSOLID","SOLID","SHELL","FACE","WIRE","EDGE","VERTEX"}; BRepTools::Write( shape, SMESH_Comment("/tmp/") << type[shape.ShapeType()] << "_" << shape.TShape().operator->() << ".brep"); + toShow = !theMeshDS[0]; // no show +#else + toShow = theMeshDS[0]; // no show #endif + if ( toShow ) { + show_shape( shape, "avoid warning: show_shape() defined but not used"); + show_list( "avoid warning: show_list() defined but not used", list< TopoDS_Edge >() ); + } return false; } @@ -407,9 +421,8 @@ namespace { const gp_Pnt2d& uv, const double& tol2d ) { - TopoDS_Vertex VV[2]; - TopExp::Vertices( edge, VV[0], VV[1], true); - gp_Pnt2d v1UV = BRep_Tool::Parameters( VV[vIndex], face); + TopoDS_Vertex V = SMESH_MesherHelper::IthVertex( vIndex, edge, /*CumOri=*/true ); + gp_Pnt2d v1UV = BRep_Tool::Parameters( V, face); double dist2d = v1UV.Distance( uv ); return dist2d < tol2d; } @@ -470,6 +483,26 @@ namespace { return !allBndEdges.empty(); } + /*! + * \brief Converter used in Delaunay constructor + */ + struct SideVector2UVPtStructVec + { + std::vector< const UVPtStructVec* > _uvVecs; + + SideVector2UVPtStructVec( const TSideVector& wires ) + { + _uvVecs.resize( wires.size() ); + for ( size_t i = 0; i < wires.size(); ++i ) + _uvVecs[ i ] = & wires[i]->GetUVPtStruct(); + } + + operator const std::vector< const UVPtStructVec* > & () const + { + return _uvVecs; + } + }; + } // namespace //======================================================================= @@ -509,8 +542,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // b) find association of a couple of vertices and recall self. // +#ifdef _DEBUG_ theMeshDS[0] = theMesh1->GetMeshDS(); // debug theMeshDS[1] = theMesh2->GetMeshDS(); +#endif // ================================================================================= // 1) Is it the case of associating a group member -> another group? (PAL16202, 16203) @@ -673,7 +708,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the RETURN_BAD_RESULT("edge2 does not belong to theShape2"); } // - // Look for 2 corresponing faces: + // Look for 2 corresponding faces: // TopoDS_Shape F1, F2; @@ -736,8 +771,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the int nbE = FindFaceAssociation( face1, VV1, face2, VV2, edges1, edges2, isVCloseness ); if ( !nbE ) RETURN_BAD_RESULT("FindFaceAssociation() failed"); InsertAssociation( face1, face2, theMap ); // assoc faces - MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( face2 )); + // MESSAGE("Assoc FACE " << theMesh1->GetMeshDS()->ShapeToIndex( face1 )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( face2 )); if ( nbE == 2 && (edge1.IsSame( edges1.front())) != (edge2.IsSame( edges2.front()))) { reverseEdges( edges2, nbE ); @@ -756,6 +791,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the TopoDS_Face nextFace1 = GetNextFace( edgeToFace1, *eIt1, face1 ); TopoDS_Face nextFace2 = GetNextFace( edgeToFace2, *eIt2, face2 ); if ( !nextFace1.IsNull() && !nextFace2.IsNull() ) { + if ( SMESH_MesherHelper::GetSubShapeOri( nextFace1, *eIt1 ) == eIt1->Orientation() ) + nextFace1.Reverse(); + if ( SMESH_MesherHelper::GetSubShapeOri( nextFace2, *eIt2 ) == eIt2->Orientation() ) + nextFace2.Reverse(); FE1.push_back( make_pair( nextFace1, *eIt1 )); FE2.push_back( make_pair( nextFace2, *eIt2 )); } @@ -837,8 +876,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the } // Associate shells // - int nbFaces1 = SMESH_MesherHelper:: Count( shell1, TopAbs_FACE, 0 ); - int nbFaces2 = SMESH_MesherHelper:: Count( shell2, TopAbs_FACE, 0 ); + int nbFaces1 = SMESH_MesherHelper::Count( shell1, TopAbs_FACE, 0 ); + int nbFaces2 = SMESH_MesherHelper::Count( shell2, TopAbs_FACE, 0 ); if ( nbFaces1 != nbFaces2 ) RETURN_BAD_RESULT("Different nb of faces found for shells"); if ( nbFaces1 > 0 ) { @@ -944,14 +983,14 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the v2e[0].UnBind( V[0] ); v2e[1].UnBind( V[1] ); InsertAssociation( e0, e1, theMap ); - MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0 )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1 )); + // MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0 )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1 )); V[0] = GetNextVertex( e0, V[0] ); V[1] = GetNextVertex( e1, V[1] ); if ( !V[0].IsNull() ) { InsertAssociation( V[0], V[1], theMap ); - MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( V[0] )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( V[1] )); + // MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( V[0] )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( V[1] )); } } else if ( nbE0 == 2 ) @@ -978,12 +1017,12 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the InsertAssociation( e0b, e1b, theMap ); InsertAssociation( e0n, e1n, theMap ); InsertAssociation( v0n, v1n, theMap ); - MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0b )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1b )); - MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0n )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1n )); - MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( v0n )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( v1n )); + // MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0b )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1b )); + // MESSAGE("Assoc edge " << theMesh1->GetMeshDS()->ShapeToIndex( e0n )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( e1n )); + // MESSAGE("Assoc vertex " << theMesh1->GetMeshDS()->ShapeToIndex( v0n )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( v1n )); v2e[0].UnBind( V[0] ); v2e[1].UnBind( V[1] ); V[0] = v0n; @@ -1088,6 +1127,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the // take care of proper association of propagated edges bool same1 = edge1.IsSame( edges1.front() ); bool same2 = edge2.IsSame( edges2.front() ); + if ( !same1 && !same2 ) + { + same1 = ( edges1.back().Orientation() == edge1.Orientation() ); + same2 = ( edges2.back().Orientation() == edge2.Orientation() ); + } if ( same1 != same2 ) { reverseEdges(edges2, nbE); @@ -1100,8 +1144,8 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the for ( ; eIt1 != edges1.end(); ++eIt1, ++eIt2 ) { InsertAssociation( *eIt1, *eIt2, theMap ); - VV1[0] = TopExp::FirstVertex( *eIt1, true ); - VV2[0] = TopExp::FirstVertex( *eIt2, true ); + VV1[0] = SMESH_MesherHelper::IthVertex( 0, *eIt1, true ); + VV2[0] = SMESH_MesherHelper::IthVertex( 0, *eIt2, true ); InsertAssociation( VV1[0], VV2[0], theMap ); } InsertAssociation( theShape1, theShape2, theMap ); @@ -1170,11 +1214,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the if ( !VV1[1].IsNull() ) { InsertAssociation( VV1[0], VV2[0], theMap ); InsertAssociation( VV1[1], VV2[1], theMap ); + TShapeShapeMap::EAssocType asType = theMap._assocType; + theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) - { - theMap.SetAssocType( TShapeShapeMap::PROPAGATION ); return true; - } + theMap._assocType = asType; } } break; // try by vertex closeness @@ -1216,7 +1260,7 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the const TopoDS_Shape& v1 = vMap1(i); if ( vMap2.Contains( v1 )) { - // find an egde sharing v1 and sharing at the same time another common vertex + // find an edge sharing v1 and sharing at the same time another common vertex PShapeIteratorPtr edgeIt = SMESH_MesherHelper::GetAncestors( v1, *theMesh1, TopAbs_EDGE); bool edgeFound = false; while ( edgeIt->more() && !edgeFound ) @@ -1230,11 +1274,11 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the { InsertAssociation( VV1[0], VV1[0], theMap ); InsertAssociation( VV1[1], VV1[1], theMap ); - if (FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) - { - theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); + TShapeShapeMap::EAssocType asType = theMap._assocType; + theMap.SetAssocType( TShapeShapeMap::COMMON_VERTEX ); + if ( FindSubShapeAssociation( theShape1, theMesh1, theShape2, theMesh2, theMap )) return true; - } + theMap._assocType = asType; } } } @@ -1332,10 +1376,10 @@ bool StdMeshers_ProjectionUtils::FindSubShapeAssociation(const TopoDS_Shape& the InsertAssociation( VV1[ 0 ], VV2[ 0 ], theMap ); InsertAssociation( VV1[ 1 ], VV2[ 1 ], theMap ); - MESSAGE("Initial assoc VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 0 ] )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 0 ] )<< - "\nand VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 1 ] )<< - " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 1 ] )); + // MESSAGE("Initial assoc VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 0 ] )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 0 ] )<< + // "\nand VERT " << theMesh1->GetMeshDS()->ShapeToIndex( VV1[ 1 ] )<< + // " to " << theMesh2->GetMeshDS()->ShapeToIndex( VV2[ 1 ] )); if ( theShape1.ShapeType() == TopAbs_EDGE ) { InsertAssociation( theShape1, theShape2, theMap ); return true; @@ -1406,7 +1450,7 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, } if ( TopExp::FirstVertex( *edgeIt ).IsSame( TopExp::LastVertex( *edgeIt )) && SMESH_Algo::isDegenerated( *edgeIt )) { - --edgeIt; // skip a degenerated edge (www.salome-platform.org/forum/forum_11/173031193) + --edgeIt; // skip a degenerated edge (test 3D_mesh_Projection_00/A3) } if ( !VV1[1].IsSame( TopExp::FirstVertex( *edgeIt, true ))) { CONT_BAD_RESULT("GetOrderedEdges() failed"); @@ -1579,7 +1623,7 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, std::advance( edge2End, *nbE2 ); if ( *nbE1 == *nbE2 && iW2 >= iW1 ) { - // rotate edge2 untill coincidence with edge1 in 2D + // rotate edge2 until coincides with edge1 in 2D int i = *nbE2; bool sameUV = false; while ( !( sameUV = sameVertexUV( *edge2Beg, face2, 0, v0f1UV, vTolUV )) && --i > 0 ) @@ -1593,20 +1637,21 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, // reverse edges2 if needed if ( SMESH_MesherHelper::IsClosedEdge( *edge1Beg )) { - double f,l; - Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l ); - if ( edge1Beg->Orientation() == TopAbs_REVERSED ) - std::swap( f,l ); - gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY(); - - Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l ); - if ( edge2Beg->Orientation() == TopAbs_REVERSED ) - std::swap( f,l ); - gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); - gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); - - if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) - edge2Beg->Reverse(); + // Commented (so far?) as it's not checked if orientation must be same or reversed + // double f,l; + // Handle(Geom2d_Curve) c1 = BRep_Tool::CurveOnSurface( *edge1Beg, face1,f,l ); + // if ( edge1Beg->Orientation() == TopAbs_REVERSED ) + // std::swap( f,l ); + // gp_Pnt2d uv1 = dUV + c1->Value( f * 0.8 + l * 0.2 ).XY(); + + // Handle(Geom2d_Curve) c2 = BRep_Tool::CurveOnSurface( *edge2Beg, face2,f,l ); + // if ( edge2Beg->Orientation() == TopAbs_REVERSED ) + // std::swap( f,l ); + // gp_Pnt2d uv2 = c2->Value( f * 0.8 + l * 0.2 ); + // gp_Pnt2d uv3 = c2->Value( l * 0.8 + f * 0.2 ); + + // if ( uv1.SquareDistance( uv2 ) > uv1.SquareDistance( uv3 )) + // edge2Beg->Reverse(); } else { @@ -1627,7 +1672,7 @@ int StdMeshers_ProjectionUtils::FindFaceAssociation(const TopoDS_Face& face1, break; } } - // prepare to the next wire loop + // prepare for the next wire loop edge2Beg = edge2End; } edge1Beg = edge1End; @@ -1860,7 +1905,7 @@ StdMeshers_ProjectionUtils::GetPropagationEdge( SMESH_Mesh* aMes int prevChainSize = aChain.Extent(); if ( aChain.Add(anOppE) > prevChainSize ) { // ... anOppE is not in aChain // Add found edge to the chain oriented so that to - // have it co-directed with a forward MainEdge + // have it co-directed with a fromEdge TopAbs_Orientation ori = anE.Orientation(); if ( anOppE.Orientation() == fourEdges[found].Orientation() ) ori = TopAbs::Reverse( ori ); @@ -1923,7 +1968,7 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, helper1.SetSubShape( face1 ); helper2.SetSubShape( face2 ); - if ( helper1.HasSeam() != helper2.HasSeam() ) + if ( helper1.HasRealSeam() != helper2.HasRealSeam() ) RETURN_BAD_RESULT("Different faces' geometry"); // Data to call SMESH_MeshEditor::FindMatchingNodes(): @@ -2171,11 +2216,10 @@ FindMatchingNodesOnFaces( const TopoDS_Face& face1, SMDS_NodeIteratorPtr nIt = edgeSM->GetNodes(); while ( nIt->more() ) { const SMDS_MeshNode* node = nIt->next(); - const SMDS_EdgePosition* pos = - static_cast(node->GetPosition()); + SMDS_EdgePositionPtr pos = node->GetPosition(); pos2nodes.insert( make_pair( pos->GetUParameter(), node )); } - if ( pos2nodes.size() != edgeSM->NbNodes() ) + if ((int) pos2nodes.size() != edgeSM->NbNodes() ) RETURN_BAD_RESULT("Equal params of nodes on edge " << smDS->ShapeToIndex( edge ) << " of face " << is2 ); } @@ -2313,7 +2357,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter string algoType = algo->GetName(); if ( algoType.substr(0, 11) != "Projection_") - return gen->Compute( *mesh, shape, /*shapeOnly=*/true ); + return gen->Compute( *mesh, shape, SMESH_Gen::SHAPE_ONLY ); // try to compute source mesh @@ -2354,7 +2398,7 @@ bool StdMeshers_ProjectionUtils::MakeComputed(SMESH_subMesh * sm, const int iter srcMesh = mesh; if ( MakeComputed( srcMesh->GetSubMesh( srcShape ), iterationNb + 1 ) && - gen->Compute( *mesh, shape, /*shapeOnly=*/true )) + gen->Compute( *mesh, shape, SMESH_Gen::SHAPE_ONLY )) return sm->IsMeshComputed(); return false; @@ -2376,7 +2420,7 @@ std::string StdMeshers_ProjectionUtils::SourceNotComputedError( SMESH_subMesh * if ( !sm || sm->GetAlgoState() != SMESH_subMesh::NO_ALGO ) return usualMessage; // algo is OK, anything else is KO. - // Try to find a type of all-dimentional algorithm that would compute the + // Try to find a type of all-dimensional algorithm that would compute the // given sub-mesh if it could be launched before projection const TopoDS_Shape shape = sm->GetSubShape(); const int shapeDim = SMESH_Gen::GetShapeDim( shape ); @@ -2557,7 +2601,7 @@ namespace StdMeshers_ProjectionUtils //================================================================================ /*! - * \brief Computes transformation beween two sets of 2D points using + * \brief Computes transformation between two sets of 2D points using * a least square approximation * * See "Surface Mesh Projection For Hexahedral Mesh Generation By Sweeping" @@ -2613,13 +2657,13 @@ namespace StdMeshers_ProjectionUtils // cout << vec( 1 ) << "\t " << vec( 2 ) << endl // << vec( 3 ) << "\t " << vec( 4 ) << endl; - _trsf.SetTranslation( tgtGC ); + _trsf.SetTranslationPart( tgtGC ); _srcOrig = srcGC; - gp_Mat2d& M = const_cast< gp_Mat2d& >( _trsf.HVectorialPart()); + gp_Mat2d& M = const_cast< gp_Mat2d& >( _trsf.VectorialPart()); M( 1,1 ) = vec( 1 ); - M( 2,1 ) = vec( 2 ); - M( 1,2 ) = vec( 3 ); + M( 2,1 ) = vec( 2 ); // | 1 3 | -- is it correct ???????? + M( 1,2 ) = vec( 3 ); // | 2 4 | M( 2,2 ) = vec( 4 ); return true; @@ -2640,7 +2684,7 @@ namespace StdMeshers_ProjectionUtils //================================================================================ /*! - * \brief Computes transformation beween two sets of 3D points using + * \brief Computes transformation between two sets of 3D points using * a least square approximation * * See "Surface Mesh Projection For Hexahedral Mesh Generation By Sweeping" @@ -2710,9 +2754,9 @@ namespace StdMeshers_ProjectionUtils // << vec( 7 ) << "\t " << vec( 8 ) << "\t " << vec( 9 ) << endl; _srcOrig = srcOrig; - _trsf.SetTranslation( tgtOrig ); + _trsf.SetTranslationPart( tgtOrig ); - gp_Mat& M = const_cast< gp_Mat& >( _trsf.HVectorialPart() ); + gp_Mat& M = const_cast< gp_Mat& >( _trsf.VectorialPart() ); M.SetRows( gp_XYZ( vec( 1 ), vec( 2 ), vec( 3 )), gp_XYZ( vec( 4 ), vec( 5 ), vec( 6 )), gp_XYZ( vec( 7 ), vec( 8 ), vec( 9 ))); @@ -2740,7 +2784,7 @@ namespace StdMeshers_ProjectionUtils gp_XYZ TrsfFinder3D::TransformVec( const gp_Vec& v ) const { - return v.XYZ().Multiplied( _trsf.HVectorialPart() ); + return v.XYZ().Multiplied( _trsf.VectorialPart() ); } //================================================================================ /*! @@ -2755,7 +2799,7 @@ namespace StdMeshers_ProjectionUtils { // seems to be defined via Solve() gp_XYZ newSrcOrig = _trsf.TranslationPart(); - gp_Mat& M = const_cast< gp_Mat& >( _trsf.HVectorialPart() ); + gp_Mat& M = const_cast< gp_Mat& >( _trsf.VectorialPart() ); const double D = M.Determinant(); if ( D < 1e-3 * ( newSrcOrig - _srcOrig ).Modulus() ) { @@ -2766,7 +2810,7 @@ namespace StdMeshers_ProjectionUtils return false; } gp_Mat Minv = M.Inverted(); - _trsf.SetTranslation( _srcOrig ); + _trsf.SetTranslationPart( _srcOrig ); _srcOrig = newSrcOrig; M = Minv; } @@ -2776,4 +2820,145 @@ namespace StdMeshers_ProjectionUtils } return true; } -} + + //================================================================================ + /*! + * \brief triangulate the srcFace in 2D + * \param [in] srcWires - boundary of the src FACE + */ + //================================================================================ + + Morph::Morph(const TSideVector& srcWires): + _delaunay( srcWires, /*checkUV=*/true ) + { + _srcSubMesh = srcWires[0]->GetMesh()->GetSubMesh( srcWires[0]->Face() ); + } + + //================================================================================ + /*! + * \brief Move non-marked target nodes + * \param [in,out] tgtHelper - helper + * \param [in] tgtWires - boundary nodes of the target FACE; must be in the + * same order as the nodes in srcWires given in the constructor + * \param [in] src2tgtNodes - map of src -> tgt nodes + * \param [in] moveAll - to move all nodes; if \c false, move only non-marked nodes + * \return bool - Ok or not + */ + //================================================================================ + + bool Morph::Perform(SMESH_MesherHelper& tgtHelper, + const TSideVector& tgtWires, + Handle(ShapeAnalysis_Surface) tgtSurface, + const TNodeNodeMap& src2tgtNodes, + const bool moveAll) + { + // get tgt boundary points corresponding to src boundary nodes + size_t nbP = 0; + for ( size_t iW = 0; iW < tgtWires.size(); ++iW ) + nbP += tgtWires[iW]->NbPoints() - 1; // 1st and last points coincide + if ( nbP != _delaunay.GetBndNodes().size() ) + return false; + + std::vector< gp_XY > tgtUV( nbP ); + for ( size_t iW = 0, iP = 0; iW < tgtWires.size(); ++iW ) + { + const UVPtStructVec& tgtPnt = tgtWires[iW]->GetUVPtStruct(); + for ( int i = 0, nb = tgtPnt.size() - 1; i < nb; ++i, ++iP ) + { + tgtUV[ iP ] = tgtPnt[i].UV(); + } + } + + SMESHDS_Mesh* tgtMesh = tgtHelper.GetMeshDS(); + const SMDS_MeshNode *srcNode, *tgtNode; + + // un-mark internal src nodes in order iterate them using _delaunay + smIdType nbSrcNodes = 0; + SMDS_NodeIteratorPtr nIt = _srcSubMesh->GetSubMeshDS()->GetNodes(); + if ( !nIt || !nIt->more() ) return true; + if ( moveAll ) + { + nbSrcNodes = _srcSubMesh->GetSubMeshDS()->NbNodes(); + while ( nIt->more() ) + nIt->next()->setIsMarked( false ); + } + else + { + while ( nIt->more() ) + nbSrcNodes += int( !nIt->next()->isMarked() ); + } + + // Move tgt nodes + + double bc[3]; // barycentric coordinates + int nodeIDs[3]; // nodes of a delaunay triangle + + _delaunay.InitTraversal( nbSrcNodes ); + + while (( srcNode = _delaunay.NextNode( bc, nodeIDs ))) + { + // compute new coordinates for a corresponding tgt node + gp_XY uvNew( 0., 0. ), nodeUV; + for ( int i = 0; i < 3; ++i ) + uvNew += bc[i] * tgtUV[ nodeIDs[i]]; + gp_Pnt xyz = tgtSurface->Value( uvNew ); + + // find and move tgt node + TNodeNodeMap::const_iterator n2n = src2tgtNodes.find( srcNode ); + if ( n2n == src2tgtNodes.end() ) continue; + tgtNode = n2n->second; + tgtMesh->MoveNode( tgtNode, xyz.X(), xyz.Y(), xyz.Z() ); + + if ( SMDS_FacePositionPtr pos = tgtNode->GetPosition() ) + pos->SetParameters( uvNew.X(), uvNew.Y() ); + + --nbSrcNodes; + } + + return nbSrcNodes == 0; + + } // Morph::Perform + + //======================================================================= + //function : Delaunay + //purpose : construct from face sides + //======================================================================= + + Delaunay::Delaunay( const TSideVector& wires, bool checkUV ): + SMESH_Delaunay( SideVector2UVPtStructVec( wires ), + TopoDS::Face( wires[0]->FaceHelper()->GetSubShape() ), + wires[0]->FaceHelper()->GetSubShapeID() ) + { + _wire = wires[0]; // keep a wire to assure _helper to keep alive + _helper = _wire->FaceHelper(); + _checkUVPtr = checkUV ? & _checkUV : 0; + } + + //======================================================================= + //function : Delaunay + //purpose : construct from UVPtStructVec's + //======================================================================= + + Delaunay::Delaunay( const std::vector< const UVPtStructVec* > & boundaryNodes, + SMESH_MesherHelper& faceHelper, + bool checkUV): + SMESH_Delaunay( boundaryNodes, + TopoDS::Face( faceHelper.GetSubShape() ), + faceHelper.GetSubShapeID() ) + { + _helper = & faceHelper; + _checkUVPtr = checkUV ? & _checkUV : 0; + } + + //======================================================================= + //function : getNodeUV + //purpose : + //======================================================================= + + gp_XY Delaunay::getNodeUV( const TopoDS_Face& face, const SMDS_MeshNode* node ) const + { + return _helper->GetNodeUV( face, node, 0, _checkUVPtr ); + } + + +} // namespace StdMeshers_ProjectionUtils