X-Git-Url: http://git.salome-platform.org/gitweb/?p=modules%2Fsmesh.git;a=blobdiff_plain;f=src%2FStdMeshers%2FStdMeshers_Import_1D2D.cxx;h=cd2874d4f404213663e9b8516755a20376a6ef53;hp=8cc97b6e017243dd4296e504c46d93fdd823b610;hb=499f29d24922cec66e41b41a0039a954993bc6df;hpb=4a591503f83eb00e13ddff5946e8a5ec51ccdbd5 diff --git a/src/StdMeshers/StdMeshers_Import_1D2D.cxx b/src/StdMeshers/StdMeshers_Import_1D2D.cxx index 8cc97b6e0..cd2874d4f 100644 --- a/src/StdMeshers/StdMeshers_Import_1D2D.cxx +++ b/src/StdMeshers/StdMeshers_Import_1D2D.cxx @@ -1,4 +1,4 @@ -// Copyright (C) 2007-2016 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,7 +20,7 @@ // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com // -// SMESH SMESH : implementaion of SMESH idl descriptions +// SMESH SMESH : implementation of SMESH idl descriptions // File : StdMeshers_Import_1D2D.cxx // Module : SMESH // @@ -40,6 +40,7 @@ #include "SMESH_Mesh.hxx" #include "SMESH_MesherHelper.hxx" #include "SMESH_OctreeNode.hxx" +#include "SMESH_MeshEditor.hxx" #include "SMESH_subMesh.hxx" #include "Utils_SALOME_Exception.hxx" @@ -48,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -96,8 +98,8 @@ namespace */ //============================================================================= -StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, int studyId, SMESH_Gen * gen) - :SMESH_2D_Algo(hypId, studyId, gen), _sourceHyp(0) +StdMeshers_Import_1D2D::StdMeshers_Import_1D2D(int hypId, SMESH_Gen * gen) + :SMESH_2D_Algo(hypId, gen), _sourceHyp(0) { _name = "Import_1D2D"; _shapeType = (1 << TopAbs_FACE); @@ -199,7 +201,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & gp_Pnt p; gp_Vec du, dv; // BRepClass_FaceClassifier is most time consuming, so minimize its usage - BRepClass_FaceClassifier classifier; + const double clsfTol = 1e2 * BRep_Tool::MaxTolerance( geomFace, TopAbs_VERTEX ); + BRepTopAdaptor_FClass2d classifier( geomFace, clsfTol ); //Brimless_FaceClassifier classifier; Bnd_B2d bndBox2d; Bnd_Box bndBox3d; { @@ -271,7 +274,6 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & double minGroupTol = Precision::Infinite(); SMESH::Controls::ElementsOnShape onEdgeClassifier; - if ( helper.HasSeam() ) { TopoDS_Compound edgesCompound; BRep_Builder builder; @@ -306,21 +308,23 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & const double groupTol = 0.5 * sqrt( getMinElemSize2( srcGroup )); minGroupTol = std::min( groupTol, minGroupTol ); + // clsfTol is 2D tolerance of a probe line //GeomAdaptor_Surface S( surface ); // const double clsfTol = Min( S.UResolution( 0.1 * groupTol ), -- issue 0023092 // S.VResolution( 0.1 * groupTol )); - const double clsfTol = BRep_Tool::Tolerance( geomFace ); + // another idea: try to use max tol of all edges + //const double clsfTol = 10 * BRep_Tool::Tolerance( geomFace ); // 0.1 * groupTol; + + onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() ); + onEdgeClassifier.SetTolerance( groupTol / 10 ); - if ( helper.HasSeam() ) - onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() ); SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements(); while ( srcElems->more() ) // loop on group contents { const SMDS_MeshElement* face = srcElems->next(); - SMDS_MeshElement::iterator node = face->begin_nodes(); - if ( bndBox3d.IsOut( SMESH_TNodeXYZ( *node ))) + if ( bndBox3d.IsOut( SMESH_NodeXYZ( face->GetNode(0) ))) continue; // find or create nodes of a new face @@ -329,13 +333,14 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & newNodes.back() = 0; int nbCreatedNodes = 0; bool isOut = false, isIn = false; // if at least one node isIn - do not classify other nodes - for ( size_t i = 0; i < newNodes.size(); ++i, ++node ) + for ( size_t i = 0; i < newNodes.size(); ++i ) { - SMESH_TNodeXYZ nXYZ = *node; + const SMDS_MeshNode* node = face->GetNode( i ); + SMESH_NodeXYZ nXYZ = node; nodeState[ i ] = TopAbs_UNKNOWN; newNodes [ i ] = 0; - it_isnew = n2n->insert( make_pair( *node, (SMDS_MeshNode*)0 )); + it_isnew = n2n->insert( make_pair( node, nullptr )); n2nIt = it_isnew.first; const SMDS_MeshNode* & newNode = n2nIt->second; @@ -349,7 +354,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & if ( newNode->GetID() < (int) isNodeIn.size() && isNodeIn[ newNode->GetID() ]) isIn = true; - if ( !isIn && bndNodes.count( *node )) + if ( !isIn && bndNodes.count( node )) nodeState[ i ] = TopAbs_ON; } else @@ -368,15 +373,18 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & { // find out if node lies on the surface of theShape gp_XY uv( Precision::Infinite(), 0 ); - isOut = ( !helper.CheckNodeUV( geomFace, *node, uv, groupTol, /*force=*/true ) || - bndBox2d.IsOut( uv )); + bool isOutBox = true; + isOut = (! helper.CheckNodeUV( geomFace, node, uv, groupTol, /*force=*/true ) || + ( isOutBox = bndBox2d.IsOut( uv ))); //int iCoo; if ( !isOut && !isIn ) // classify { - classifier.Perform( geomFace, uv, clsfTol ); - nodeState[i] = classifier.State(); + nodeState[i] = classifier.Perform( uv ); //classifier.Perform( geomFace, uv, clsfTol ); + //nodeState[i] = classifier.State(); isOut = ( nodeState[i] == TopAbs_OUT ); - if ( isOut && helper.IsOnSeam( uv ) && onEdgeClassifier.IsSatisfy( (*node)->GetID() )) + if (( isOut ) && + ( !isOutBox || helper.IsOnSeam( uv )) && + onEdgeClassifier.IsSatisfy( node )) { // uv.SetCoord( iCoo, helper.GetOtherParam( uv.Coord( iCoo ))); // classifier.Perform( geomFace, uv, clsfTol ); @@ -391,13 +399,13 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & newNode = tgtMesh->AddNode( nXYZ.X(), nXYZ.Y(), nXYZ.Z()); tgtMesh->SetNodeOnFace( newNode, shapeID, uv.X(), uv.Y() ); nbCreatedNodes++; - if ( newNode->GetID() >= (int) isNodeIn.size() ) + if ( newNode->GetID() >= (smIdType) isNodeIn.size() ) { isNodeIn.push_back( false ); // allow allocate more than newNode->GetID() isNodeIn.resize( newNode->GetID() + 1, false ); } if ( nodeState[i] == TopAbs_ON ) - bndNodes.insert( *node ); + bndNodes.insert( node ); else if ( nodeState[i] != TopAbs_UNKNOWN ) isNodeIn[ newNode->GetID() ] = isIn = true; } @@ -417,8 +425,8 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & { if ( nodeState[i] != TopAbs_UNKNOWN ) continue; gp_XY uv = helper.GetNodeUV( geomFace, newNodes[i] ); - classifier.Perform( geomFace, uv, clsfTol ); - nodeState[i] = classifier.State(); + nodeState[i] = classifier.Perform( uv ); //geomFace, uv, clsfTol ); + //nodeState[i] = classifier.State(); isIn = ( nodeState[i] == TopAbs_IN ); } if ( !isIn ) // classify face center @@ -439,8 +447,9 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & Standard_Real U,V; proj.LowerDistanceParameters(U,V); gp_XY uv( U,V ); - classifier.Perform( geomFace, uv, clsfTol ); - if ( classifier.State() != TopAbs_IN ) + //classifier.Perform( geomFace, uv, clsfTol ); + TopAbs_State state = classifier.Perform( uv ); + if ( state != TopAbs_IN ) continue; } } @@ -559,7 +568,6 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & // the imported mesh is valid if all external links (encountered once) // lie on geom edges subShapeIDs.erase( shapeID ); // to contain edges and vertices only - double u, f, l; for ( link2Nb = linkCount.begin(); link2Nb != linkCount.end(); ++link2Nb) { const TLink& link = (*link2Nb).first; @@ -574,17 +582,14 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & const SMDS_MeshNode* n = is1stN ? link.node1() : link.node2(); if ( !subShapeIDs.count( n->getshapeId() )) // n is assigned to FACE { - for ( size_t iE = 0; iE < edges.size(); ++iE ) - if ( helper.CheckNodeU( edges[iE], n, u=0, projTol, /*force=*/true )) - { - BRep_Tool::Range(edges[iE],f,l); - if ( Abs(u-f) < 2 * faceTol || Abs(u-l) < 2 * faceTol ) - // duplicated node on vertex - return error("Source elements overlap one another"); - tgtFaceSM->RemoveNode( n, /*isNodeDeleted=*/false ); - tgtMesh->SetNodeOnEdge( n, edges[iE], u ); - break; - } + TopoDS_Shape edge; + if ( onEdgeClassifier.IsSatisfy( n, &edge )) + { + tgtFaceSM->RemoveNode( n ); + double u, v; + onEdgeClassifier.GetParams( u, v ); + tgtMesh->SetNodeOnEdge( n, TopoDS::Edge(edge), u ); + } nodesOnBoundary = subShapeIDs.count( n->getshapeId()); } if ( nodesOnBoundary ) @@ -632,9 +637,10 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & { edge = tgtMesh->AddEdge( newNodes[0], newNodes[1], link._medium ); + double u; TopoDS_Edge geomEdge = TopoDS::Edge(bndShapes.back()); helper.CheckNodeU( geomEdge, link._medium, u, projTol, /*force=*/true ); - tgtFaceSM->RemoveNode( link._medium, /*isNodeDeleted=*/false ); + tgtFaceSM->RemoveNode( link._medium ); tgtMesh->SetNodeOnEdge( (SMDS_MeshNode*)link._medium, geomEdge, u ); } else @@ -704,6 +710,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & TUNodeList nodesOnSeam; double u = helper.GetNodeU( seamEdge, vertNode ); nodesOnSeam.push_back( make_pair( u, vertNode )); + size_t nbNodesOnSeam = 1; TUNodeList::iterator u2nIt = nodesOnSeam.begin(); for ( ; u2nIt != nodesOnSeam.end(); ++u2nIt ) { @@ -717,8 +724,9 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & { const SMDS_MeshNode* n = face->GetNode( i ); if ( n == startNode || !checkedNodes.insert( n ).second ) continue; - if ( helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true )) - nodesOnSeam.push_back( make_pair( u, n )); + helper.CheckNodeU( seamEdge, n, u=0, projTol, /*force=*/true ); + nodesOnSeam.push_back( make_pair( u, n )); + ++nbNodesOnSeam; } } } @@ -727,6 +735,15 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & map< double, const SMDS_MeshNode* > u2nodeMap; for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt ) u2nodeMap.insert( u2nodeMap.end(), *u2nIt ); + if ( u2nodeMap.size() != nbNodesOnSeam ) // problem with parameters on EDGE + { + // sort nodes by distance from seamVertex + gp_Pnt vertPnt = SMESH_NodeXYZ( vertNode ); + u2nodeMap.clear(); + for ( u2nIt = nodesOnSeam.begin(); u2nIt != nodesOnSeam.end(); ++u2nIt ) + u2nodeMap.insert + ({ vertPnt.SquareDistance( SMESH_NodeXYZ( u2nIt->second )), u2nIt->second }); + } // create edges { @@ -747,7 +764,7 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape & seamHelper.AddEdge( node1, node2 ); if ( node2->getshapeId() == helper.GetSubShapeID() ) { - tgtFaceSM->RemoveNode( node2, /*isNodeDeleted=*/false ); + tgtFaceSM->RemoveNode( node2 ); tgtMesh->SetNodeOnEdge( const_cast( node2 ), seamEdge, n2->first ); } } @@ -817,7 +834,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, if ( srcGroups.empty() ) return error("Invalid source groups"); - vector aVec(SMDSEntity_Last,0); + vector aVec(SMDSEntity_Last,0); bool toCopyMesh, toCopyGroups; _sourceHyp->GetCopySourceMesh(toCopyMesh, toCopyGroups); @@ -907,7 +924,7 @@ bool StdMeshers_Import_1D2D::Evaluate(SMESH_Mesh & theMesh, { TopoDS_Edge geomEdge = TopoDS::Edge( exp.Current() ); SMESH_subMesh* sm = theMesh.GetSubMesh( geomEdge ); - vector& edgeVec = aResMap[sm]; + vector& edgeVec = aResMap[sm]; if ( edgeVec.empty() ) { edgeVec.resize(SMDSEntity_Last,0);