From 26ca162de107306fe6937e9482172a2603136beb Mon Sep 17 00:00:00 2001 From: eap Date: Mon, 26 Dec 2016 16:25:15 +0300 Subject: [PATCH] IPAL53863: MG-CADSurf + Viscous Layers 2D on a cylindrical face ==> crash --- src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx | 103 +++++++++++++++++++---- 1 file changed, 88 insertions(+), 15 deletions(-) diff --git a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx index e59f1ca..3679c02 100644 --- a/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx +++ b/src/BLSURFPlugin/BLSURFPlugin_BLSURF.cxx @@ -61,17 +61,19 @@ extern "C"{ // OPENCASCADE includes #include #include -//#include +#include #include #include #include #include #include #include +#include #include #include #include #include +#include #include #include #include @@ -1589,32 +1591,43 @@ namespace if ( err && err->IsKO() ) throw *err.get(); // it should be caught at SMESH_subMesh + SMESH_MesherHelper helper( *origMesh ); + helper.SetSubShape( origFace ); + const bool hasSeam = helper.HasRealSeam(); + // proxy nodes and corresponding tmp VERTEXes std::vector origNodes; std::vector tmpVertex; // create a proxy FACE - TopoDS_Shape origFaceCopy = origFace.EmptyCopied(); - BRepBuilderAPI_MakeFace newFace( TopoDS::Face( origFaceCopy )); + TopoDS_Face origFaceCopy = TopoDS::Face( origFace.EmptyCopied() ); + BRepBuilderAPI_MakeFace newFace( origFaceCopy ); + bool hasPCurves = false; for ( size_t iW = 0; iW != wireVec.size(); ++iW ) { StdMeshers_FaceSidePtr& wireData = wireVec[iW]; - const UVPtStructVec& wirePoints = wireData->GetUVPtStruct(); + const UVPtStructVec& wirePoints = wireData->GetUVPtStruct(); if ( wirePoints.size() < 3 ) continue; - BRepBuilderAPI_MakePolygon wire; + BRepBuilderAPI_MakePolygon polygon; const size_t i0 = tmpVertex.size(); for ( size_t iN = 0; iN < wirePoints.size(); ++iN ) { - wire.Add( SMESH_TNodeXYZ( wirePoints[ iN ].node )); + polygon.Add( SMESH_TNodeXYZ( wirePoints[ iN ].node )); origNodes.push_back( wirePoints[ iN ].node ); - tmpVertex.push_back( wire.LastVertex() ); + tmpVertex.push_back( polygon.LastVertex() ); + + // check presence of a pcurve + checkPCurve( polygon, origFaceCopy, hasPCurves, &wirePoints[ iN-1 ] ); } - tmpVertex[ i0 ] = wire.FirstVertex(); // wire.LastVertex()==NULL for 1 vertex in wire - wire.Close(); - if ( !wire.IsDone() ) + tmpVertex[ i0 ] = polygon.FirstVertex(); // polygon.LastVertex()==NULL for 1 vertex in wire + polygon.Close(); + if ( !polygon.IsDone() ) throw SALOME_Exception("BLSURFPlugin_BLSURF: BRepBuilderAPI_MakePolygon failed"); + TopoDS_Wire wire = polygon; + if ( hasSeam ) + wire = updateSeam( wire, origNodes ); newFace.Add( wire ); } _proxyFace = newFace; @@ -1628,9 +1641,6 @@ namespace ShapeToMesh( auxCompoundToMesh ); - //TopExp_Explorer fExp( auxCompoundToMesh, TopAbs_FACE ); - //_proxyFace = TopoDS::Face( fExp.Current() ); - // Make input mesh for MG-CADSurf: segments on EDGE's of newFace @@ -1642,8 +1652,8 @@ namespace GetSubMesh( tmpVertex[i] )->ComputeStateEngine( SMESH_subMesh::COMPUTE ); if ( const SMDS_MeshNode* tmpN = SMESH_Algo::VertexNode( tmpVertex[i], tmpMeshDS )) _tmp2origNN.insert( _tmp2origNN.end(), make_pair( tmpN, origNodes[i] )); - else - throw SALOME_Exception("BLSURFPlugin_BLSURF: a proxy vertex not meshed"); + // else -- it can be a seam vertex replaced by updateSeam() + // throw SALOME_Exception("BLSURFPlugin_BLSURF: a proxy vertex not meshed"); } // make segments @@ -1662,6 +1672,69 @@ namespace return _proxyFace; } + //-------------------------------------------------------------------------------- + /*! + * \brief Add pcurve to the last edge of a wire + */ + //-------------------------------------------------------------------------------- + + void checkPCurve( BRepBuilderAPI_MakePolygon& wire, + const TopoDS_Face& face, + bool & hasPCurves, + const uvPtStruct * wirePoints ) + { + if ( hasPCurves ) + return; + TopoDS_Edge edge = wire.Edge(); + if ( edge.IsNull() ) return; + double f,l; + if ( BRep_Tool::CurveOnSurface(edge, face, f, l)) + { + hasPCurves = true; + return; + } + gp_XY p1 = wirePoints[ 0 ].UV(), p2 = wirePoints[ 1 ].UV(); + Handle(Geom2d_Line) pcurve = new Geom2d_Line( p1, gp_Dir2d( p2 - p1 )); + BRep_Builder().UpdateEdge( edge, Handle(Geom_Curve)(), Precision::Confusion() ); + BRep_Builder().UpdateEdge( edge, pcurve, face, Precision::Confusion() ); + BRep_Builder().Range( edge, 0, ( p2 - p1 ).Modulus() ); + // cout << "n1 = mesh.AddNode( " << p1.X()*10 << ", " << p1.Y() << ", 0 )" << endl + // << "n2 = mesh.AddNode( " << p2.X()*10 << ", " << p2.Y() << ", 0 )" << endl + // << "mesh.AddEdge( [ n1, n2 ] )" << endl; + } + + //-------------------------------------------------------------------------------- + /*! + * \brief Replace coincident EDGEs with reversed copies. + */ + //-------------------------------------------------------------------------------- + + TopoDS_Wire updateSeam( const TopoDS_Wire& wire, + const std::vector& nodesOfVertices ) + { + BRepBuilderAPI_MakeWire newWire; + + typedef NCollection_DataMap TSeg2EdgeMap; + TSeg2EdgeMap seg2EdgeMap; + + TopoDS_Iterator edgeIt( wire ); + for ( int iSeg = 1; edgeIt.More(); edgeIt.Next(), ++iSeg ) + { + SMESH_TLink link( nodesOfVertices[ iSeg-1 ], nodesOfVertices[ iSeg ]); + TopoDS_Edge edge( TopoDS::Edge( edgeIt.Value() )); + + TopoDS_Edge* edgeInMap = seg2EdgeMap.Bound( link, edge ); + bool isSeam = ( *edgeInMap != edge ); + if ( isSeam ) + { + edgeInMap->Reverse(); + edge = *edgeInMap; + } + newWire.Add( edge ); + } + return newWire; + } + //-------------------------------------------------------------------------------- /*! * \brief Fill in the origMesh with faces computed by MG-CADSurf in this tmp mesh -- 2.39.2