]> SALOME platform Git repositories - modules/smesh.git/commitdiff
Salome HOME
bos #29395 EDF 25009 - import1D2D mesh fails
authoreap <eap@opencascade.com>
Tue, 22 Mar 2022 13:31:40 +0000 (16:31 +0300)
committereap <eap@opencascade.com>
Tue, 22 Mar 2022 13:31:40 +0000 (16:31 +0300)
src/Controls/SMESH_Controls.cxx
src/SMESH/SMESH_MesherHelper.cxx
src/SMESH/SMESH_MesherHelper.hxx
src/StdMeshers/StdMeshers_Import_1D2D.cxx

index 44d92ef4d8694d5d059cd0079d64d9924128a41f..a8a20c46ce1dc98ccb32e59abb7212e61b9343ec 100644 (file)
@@ -4453,9 +4453,12 @@ SMDSAbs_ElementType ElementsOnShape::GetType() const
 
 void ElementsOnShape::SetTolerance (const double theToler)
 {
-  if (myToler != theToler) {
+  if (myToler != theToler)
+  {
     myToler = theToler;
-    SetShape(myShape, myType);
+    TopoDS_Shape s = myShape;
+    myShape.Nullify();
+    SetShape( s, myType );
   }
 }
 
index 1dcc5b0643e4ab8d4ee4c92bc88166964dd5e5ca..5621cc34b9309cafeaaf7f9ad1a943221086b521 100644 (file)
@@ -51,6 +51,7 @@
 #include <Geom_RectangularTrimmedSurface.hxx>
 #include <Geom_Surface.hxx>
 #include <ShapeAnalysis.hxx>
+#include <ShapeAnalysis_Curve.hxx>
 #include <TopExp.hxx>
 #include <TopExp_Explorer.hxx>
 #include <TopTools_ListIteratorOfListOfShape.hxx>
@@ -875,6 +876,51 @@ GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face&
   return *( i_proj->second );
 }
 
+//=======================================================================
+//function : GetProjector
+//purpose  : Return projector initialized by given face, which is returned
+//=======================================================================
+
+GeomAPI_ProjectPointOnSurf& SMESH_MesherHelper::GetProjector(const TopoDS_Face& F,
+                                                             double             tol ) const
+{
+  Handle(Geom_Surface) surface = BRep_Tool::Surface( F );
+  int faceID = GetMeshDS()->ShapeToIndex( F );
+  TID2ProjectorOnSurf& i2proj = const_cast< TID2ProjectorOnSurf&>( myFace2Projector );
+  TID2ProjectorOnSurf::iterator i_proj = i2proj.find( faceID );
+  if ( i_proj == i2proj.end() )
+  {
+    if ( tol == 0 ) tol = BRep_Tool::Tolerance( F );
+    double U1, U2, V1, V2;
+    surface->Bounds(U1, U2, V1, V2);
+    GeomAPI_ProjectPointOnSurf* proj = new GeomAPI_ProjectPointOnSurf();
+    proj->Init( surface, U1, U2, V1, V2, tol );
+    i_proj = i2proj.insert( make_pair( faceID, proj )).first;
+  }
+  return *( i_proj->second );
+}
+
+//=======================================================================
+//function : GetPCProjector
+//purpose  : Return projector initialized by given EDGE
+//=======================================================================
+
+GeomAPI_ProjectPointOnCurve& SMESH_MesherHelper::GetPCProjector(const TopoDS_Edge& E ) const
+{
+  int edgeID = GetMeshDS()->ShapeToIndex( E );
+  TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
+  TID2ProjectorOnCurve::iterator i_proj = i2proj.insert( make_pair( edgeID, nullptr )).first;
+  if ( !i_proj->second  )
+  {
+    double f,l;
+    Handle(Geom_Curve) curve = BRep_Tool::Curve( E,f,l );
+    i_proj->second = new GeomAPI_ProjectPointOnCurve();
+    i_proj->second->Init( curve, f, l );
+  }
+  GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
+  return *projector;
+}
+
 //=======================================================================
 //function : GetSurface
 //purpose  : Return a cached ShapeAnalysis_Surface of a FACE
@@ -1121,27 +1167,17 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
       {
         setPosOnShapeValidity( shapeID, false );
         // u incorrect, project the node to the curve
-        int edgeID = GetMeshDS()->ShapeToIndex( E );
-        TID2ProjectorOnCurve& i2proj = const_cast< TID2ProjectorOnCurve&>( myEdge2Projector );
-        TID2ProjectorOnCurve::iterator i_proj =
-          i2proj.insert( make_pair( edgeID, (GeomAPI_ProjectPointOnCurve*) 0 )).first;
-        if ( !i_proj->second  )
-        {
-          i_proj->second = new GeomAPI_ProjectPointOnCurve();
-          i_proj->second->Init( curve, f, l );
-        }
-        GeomAPI_ProjectPointOnCurve* projector = i_proj->second;
-        projector->Perform( nodePnt );
-        if ( projector->NbPoints() < 1 )
-        {
-          MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
-          return false;
-        }
-        Standard_Real U = projector->LowerDistanceParameter();
-        u = double( U );
-        curvPnt = curve->Value( u );
-        dist = nodePnt.Distance( curvPnt );
+        //GeomAPI_ProjectPointOnCurve& projector = GetPCProjector( E ); -- bug in OCCT-7.5.3p1
+        GeomAdaptor_Curve curveAd( curve, f, l );
+        ShapeAnalysis_Curve projector;
+        dist = projector.Project( curveAd, nodePnt, tol, curvPnt, u, false );
+        // if ( projector.NbPoints() < 1 )
+        // {
+        //   MESSAGE( "SMESH_MesherHelper::CheckNodeU() failed to project" );
+        //   return false;
+        // }
         if ( distXYZ ) {
+          curvPnt = curve->Value( u );
           curvPnt.Transform( loc );
           distXYZ[0] = dist;
           distXYZ[1] = curvPnt.X(); distXYZ[2] = curvPnt.Y(); distXYZ[3]=curvPnt.Z();
@@ -1154,7 +1190,7 @@ bool SMESH_MesherHelper::CheckNodeU(const TopoDS_Edge&   E,
         // store the fixed U on the edge
         if ( myShape.IsSame(E) && shapeID == myShapeID && myFixNodeParameters )
           const_cast<SMDS_MeshNode*>(n)->SetPosition
-            ( SMDS_PositionPtr( new SMDS_EdgePosition( U )));
+            ( SMDS_PositionPtr( new SMDS_EdgePosition( u )));
       }
       else if ( fabs( u ) > numeric_limits<double>::min() )
       {
index 82d242ec2c741c424f114d0893bdfa2dfa978384..0a4bd8b0dcfa2039fcaa39c4d8bd86948904dd2e 100644 (file)
@@ -554,11 +554,20 @@ public:
   bool GetNodeUVneedInFaceNode(const TopoDS_Face& F = TopoDS_Face()) const;
 
   /*!
-   * \brief Return projector initialized by given face without location, which is returned
+   * \brief Return projector initialized by given face without location
    */
   GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
                                            TopLoc_Location&   loc,
-                                           double             tol=0 ) const; 
+                                           double             tol=0 ) const;
+  /*!
+   * \brief Return projector initialized by given face
+   */
+  GeomAPI_ProjectPointOnSurf& GetProjector(const TopoDS_Face& F,
+                                           double             tol=0 ) const;
+  /*!
+   * \brief Return projector initialized by given EDGE
+   */
+  GeomAPI_ProjectPointOnCurve& GetPCProjector(const TopoDS_Edge& E ) const;
   /*!
    * \brief Return a cached ShapeAnalysis_Surface of a FACE
    */
index f4586c979cd0537c0b45474a5dd8b558b9110c5a..890084da3177dcf75490ead4eb4aa65e9ffabfdf 100644 (file)
@@ -201,7 +201,7 @@ 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
-  const double clsfTol = 10 * BRep_Tool::Tolerance( geomFace );
+  const double clsfTol = 1e2 * BRep_Tool::MaxTolerance( geomFace, TopAbs_VERTEX );
   BRepTopAdaptor_FClass2d classifier( geomFace, clsfTol ); //Brimless_FaceClassifier classifier;
   Bnd_B2d bndBox2d;
   Bnd_Box bndBox3d;
@@ -274,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;
@@ -316,8 +315,9 @@ bool StdMeshers_Import_1D2D::Compute(SMESH_Mesh & theMesh, const TopoDS_Shape &
     // another idea: try to use max tol of all edges
     //const double clsfTol = 10 * BRep_Tool::Tolerance( geomFace ); // 0.1 * groupTol;
 
-    if ( helper.HasSeam() )
-      onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
+    onEdgeClassifier.SetMesh( srcMesh->GetMeshDS() );
+    onEdgeClassifier.SetTolerance( groupTol / 10 );
+
 
     SMDS_ElemIteratorPtr srcElems = srcGroup->GetElements();
     while ( srcElems->more() ) // loop on group contents
@@ -373,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
           {
             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->GetID() ))
             {
               // uv.SetCoord( iCoo, helper.GetOtherParam( uv.Coord( iCoo )));
               // classifier.Perform( geomFace, uv, clsfTol );
@@ -396,7 +399,7 @@ 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 );
@@ -565,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;
@@ -580,17 +582,12 @@ 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 );
-                tgtMesh->SetNodeOnEdge( n, edges[iE], u );
-                break;
-              }
+            TopoDS_Shape edge;
+            if ( onEdgeClassifier.IsSatisfy( n, &edge ))
+            {
+              tgtFaceSM->RemoveNode( n );
+              tgtMesh->SetNodeOnEdge( n, TopoDS::Edge(edge), /*u=*/0 );
+            }
             nodesOnBoundary = subShapeIDs.count( n->getshapeId());
           }
           if ( nodesOnBoundary )
@@ -638,6 +635,7 @@ 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 );
@@ -710,6 +708,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 )
       {
@@ -723,8 +722,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;
           }
         }
       }
@@ -733,6 +733,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
       {