From 8109385697ebcc3a91f8b0d0d88f5ac713af3a1f Mon Sep 17 00:00:00 2001 From: msv Date: Wed, 4 May 2016 04:12:28 +0300 Subject: [PATCH] 0027362: Meshing performance 1) BRepMesh_FastDiscretFace.cxx: - exclude planes from procedure of inserting internal points. - localize declaration of the container aNewVertices in each method where it is needed. - correct the logic of the method insertInternalVerticesOther, so that to separate the processes of removing extra points and addition of new points in different cycles, thus making the code more clear and in addition stable. - insert useful output of intermediate mesh to a file in control() method for debug purposes (with definition DEBUG_MESH). 2) Add global functions MeshTest_DrawTriangles and MeshTest_DrawLinks to draw mesh data in debug session. 3) BRepMesh_FastDiscret: - in the method Add calculations of deflections have been simplified for non-relative mode. - replace the attribute MinDist with Deflection in EdgeAttributes structure. Correct its computation so that later to store this value as deflection of the polygon. 4) Make protection against exception in the method BRepMesh_Delaun::addTriangle() when an added triangle creates a third connection of a mesh edge. 5) BRepMesh_EdgeTessellator.cxx, BRepMesh_EdgeTessellationExtractor.cxx: use Geom2dAdaptor_Curve in order to use b-spline cache while computing value on a curve. 6) In BndLib_Box2dCurve::PerformBSpline, avoid creating new b-spline in case of requested parameter range differ from natural bounds insignificantly. 7) In GeomAdaptor classes, postpone building of cache till the time of its actual usage. So, creation of an adapter to compute intervals of continuity does not lead to creation of internal cache. 8) In the methods BRepAdaptor_Curve::Bezier and BSpline do not call Transformed() if transformation is identity. 9) In the classes Geom_BSplineCurve, Geom_BSplineSurface, Geom_BezierCurve, Geom_BezierSurface, Geom2d_BSplineCurve, Geom2d_BezierCurve change the method Pole() to return the point by const reference. 10) In CPnts_AbscissaPoint.cxx, compute derivative by D1 instead of DN to make use of b-spline cache. 11) Change test cases to actual state: - Number of triangles/nodes can grow due to more accurate work with deflection of edges. Now the edge is tessellated using its own tolerance instead of maximal tolerance of all shapes in the face. - Accept new numbers of mesh errors (free links, free nodes) for really bad shapes. - Correct the test "bugs/mesh/bug25612" to produce stable result. - Disable redundant checks in test cases bug25378* (lower limit for computation time). - Speed up iso-lines computation for offset of bspline surfaces. For that use adaptor instead of original surface in evaluator of approximation. - Add output of polylines for debug of insertInternalVerticesOther(). Reference data in test case bugs\moddata_2\bug453_3 have been changed to be close to expected theoretical values. This makes the test give stable result on different platforms. --- dox/dev_guides/debug/debug.md | 11 + src/BRepAdaptor/BRepAdaptor_Curve.cxx | 6 +- src/BRepMesh/BRepMesh_Delaun.cxx | 13 +- src/BRepMesh/BRepMesh_Delaun.hxx | 6 +- .../BRepMesh_EdgeTessellationExtractor.cxx | 4 +- .../BRepMesh_EdgeTessellationExtractor.hxx | 6 +- src/BRepMesh/BRepMesh_EdgeTessellator.cxx | 41 +- src/BRepMesh/BRepMesh_EdgeTessellator.hxx | 9 +- src/BRepMesh/BRepMesh_FastDiscret.cxx | 109 ++--- src/BRepMesh/BRepMesh_FastDiscret.hxx | 19 +- src/BRepMesh/BRepMesh_FastDiscretFace.cxx | 398 +++++++++++------- src/BRepMesh/BRepMesh_FastDiscretFace.hxx | 7 +- src/BRepMesh/BRepMesh_GeomTool.cxx | 12 +- src/BRepMesh/BRepMesh_GeomTool.hxx | 6 +- src/BRepMesh/BRepMesh_ShapeTool.cxx | 4 +- src/BRepMesh/BRepMesh_ShapeTool.hxx | 5 - src/BndLib/BndLib_Add2dCurve.cxx | 4 +- src/CPnts/CPnts_AbscissaPoint.cxx | 8 +- src/Geom/Geom_BSplineCurve.hxx | 2 +- src/Geom/Geom_BSplineCurve_1.cxx | 2 +- src/Geom/Geom_BSplineSurface.hxx | 2 +- src/Geom/Geom_BSplineSurface_1.cxx | 2 +- src/Geom/Geom_BezierCurve.cxx | 2 +- src/Geom/Geom_BezierCurve.hxx | 2 +- src/Geom/Geom_BezierSurface.cxx | 2 +- src/Geom/Geom_BezierSurface.hxx | 2 +- src/Geom/Geom_OffsetSurface.cxx | 7 +- src/Geom2d/Geom2d_BSplineCurve.hxx | 2 +- src/Geom2d/Geom2d_BSplineCurve_1.cxx | 2 +- src/Geom2d/Geom2d_BezierCurve.cxx | 2 +- src/Geom2d/Geom2d_BezierCurve.hxx | 2 +- src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx | 52 +-- src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx | 2 +- src/GeomAdaptor/GeomAdaptor_Curve.cxx | 54 +-- src/GeomAdaptor/GeomAdaptor_Curve.hxx | 2 +- src/GeomAdaptor/GeomAdaptor_Surface.cxx | 59 +-- src/GeomAdaptor/GeomAdaptor_Surface.hxx | 2 +- src/MeshTest/FILES | 1 + src/MeshTest/MeshTest_Debug.cxx | 109 +++++ tests/blend/simple/G6 | 2 - tests/bugs/iges/bug306 | 2 +- tests/bugs/mesh/bug23631 | 2 +- tests/bugs/mesh/bug25378_1_1 | 7 +- tests/bugs/mesh/bug25378_1_2 | 7 +- tests/bugs/mesh/bug25378_1_3 | 7 +- tests/bugs/mesh/bug25378_3_3 | 2 +- tests/bugs/mesh/bug25519 | 2 +- tests/bugs/mesh/bug25612 | 4 +- tests/bugs/modalg_2/bug264_0 | 2 +- tests/bugs/modalg_2/bug287 | 2 +- tests/bugs/modalg_2/bug292 | 2 +- tests/bugs/moddata_1/bug22759 | 2 +- tests/bugs/moddata_2/bug453_3 | 7 +- tests/bugs/moddata_2/fra62476_2 | 2 +- tests/bugs/moddata_3/bug25737_1 | 2 +- tests/bugs/vis/bug288_5 | 2 +- tests/mesh/data/advanced/A7 | 3 +- tests/mesh/data/standard/C7 | 15 +- tests/mesh/data/standard/J8 | 5 +- tests/mesh/data/standard/L2 | 4 + tests/mesh/data/standard/L6 | 2 +- tests/mesh/data/standard/U7 | 2 +- tests/mesh/data/standard/V4 | 2 +- tests/mesh/data/standard/W4 | 4 +- tests/mesh/data/standard/X3 | 2 +- 65 files changed, 635 insertions(+), 440 deletions(-) create mode 100644 src/MeshTest/MeshTest_Debug.cxx diff --git a/dox/dev_guides/debug/debug.md b/dox/dev_guides/debug/debug.md index c0984673ea..963957c46c 100644 --- a/dox/dev_guides/debug/debug.md +++ b/dox/dev_guides/debug/debug.md @@ -114,6 +114,17 @@ Stores mesh produced in parametric space to BREP file. - *theMeshHandlePtr* -- a pointer to *Handle(BRepMesh_DataStructureOfDelaun)* variable. - *theFileNameStr* -- the name of the file where the mesh is stored. +The following functions are provided by *TKTopTest* toolkit: + +~~~~~ +const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr) +const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr) +~~~~~ + +Sets the edges or triangles from mesh data structure of type *Handle(BRepMesh_FaceAttribute)* as DRAW interpreter variables, assigning a unique name in the form "_" to each object. +- *theNameStr* -- the prefix to use in names of objects. +- *theFaceAttr* -- a pointer to *Handle(BRepMesh_FaceAttribute)* variable. + The following additional function is provided by *TKGeomBase* toolkit: ~~~~~ diff --git a/src/BRepAdaptor/BRepAdaptor_Curve.cxx b/src/BRepAdaptor/BRepAdaptor_Curve.cxx index 61fae26445..ca986abac3 100644 --- a/src/BRepAdaptor/BRepAdaptor_Curve.cxx +++ b/src/BRepAdaptor/BRepAdaptor_Curve.cxx @@ -627,7 +627,8 @@ Handle(Geom_BezierCurve) BRepAdaptor_Curve::Bezier() const else { BC = myConSurf->Bezier(); } - return Handle(Geom_BezierCurve)::DownCast(BC->Transformed(myTrsf)); + return myTrsf.Form() == gp_Identity + ? BC : Handle(Geom_BezierCurve)::DownCast(BC->Transformed(myTrsf)); } @@ -645,5 +646,6 @@ Handle(Geom_BSplineCurve) BRepAdaptor_Curve::BSpline() const else { BS = myConSurf->BSpline(); } - return Handle(Geom_BSplineCurve)::DownCast(BS->Transformed(myTrsf)); + return myTrsf.Form() == gp_Identity + ? BS : Handle(Geom_BSplineCurve)::DownCast(BS->Transformed(myTrsf)); } diff --git a/src/BRepMesh/BRepMesh_Delaun.cxx b/src/BRepMesh/BRepMesh_Delaun.cxx index 6d10ac5087..6c82eb11aa 100644 --- a/src/BRepMesh/BRepMesh_Delaun.cxx +++ b/src/BRepMesh/BRepMesh_Delaun.cxx @@ -1086,10 +1086,17 @@ Standard_Boolean BRepMesh_Delaun::checkIntersection( //function : addTriangle //purpose : Add a triangle based on the given oriented edges into mesh //======================================================================= -inline void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3], - const Standard_Boolean (&theEdgesOri)[3], - const Standard_Integer (&theNodesId)[3] ) +void BRepMesh_Delaun::addTriangle( const Standard_Integer (&theEdgesId)[3], + const Standard_Boolean (&theEdgesOri)[3], + const Standard_Integer (&theNodesId)[3]) { + for (Standard_Integer i = 0; i < 3; ++i) + { + const BRepMesh_PairOfIndex& aPair = myMeshData->ElementsConnectedTo(theEdgesId[i]); + if (aPair.Extent() == 2) + // it is forbidden to have more than two triangles connected to the same link + return; + } Standard_Integer aNewTriangleId = myMeshData->AddElement(BRepMesh_Triangle(theEdgesId, theEdgesOri, BRepMesh_Free)); diff --git a/src/BRepMesh/BRepMesh_Delaun.hxx b/src/BRepMesh/BRepMesh_Delaun.hxx index 14fa8d4d06..37db10c277 100755 --- a/src/BRepMesh/BRepMesh_Delaun.hxx +++ b/src/BRepMesh/BRepMesh_Delaun.hxx @@ -223,9 +223,9 @@ private: BRepMesh::MapOfIntegerInteger& thePoly); //! Add a triangle based on the given oriented edges into mesh - inline void addTriangle (const Standard_Integer (&theEdgesId)[3], - const Standard_Boolean (&theEdgesOri)[3], - const Standard_Integer (&theNodesId)[3]); + void addTriangle (const Standard_Integer (&theEdgesId)[3], + const Standard_Boolean (&theEdgesOri)[3], + const Standard_Integer (&theNodesId)[3]); //! Deletes the triangle with the given index and adds the free edges into the map. //! When an edge is suppressed more than one time it is destroyed. diff --git a/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx b/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx index d85d0934bd..5fbb1bba33 100644 --- a/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx +++ b/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.cxx @@ -14,7 +14,7 @@ // commercial license or contractual agreement. #include -#include +#include #include #include #include @@ -28,7 +28,7 @@ IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_EdgeTessellationExtractor,BRepMesh_IEdgeTool //======================================================================= BRepMesh_EdgeTessellationExtractor::BRepMesh_EdgeTessellationExtractor( const TopoDS_Edge& theEdge, - const Handle(Geom2d_Curve)& thePCurve, + const Handle(Geom2dAdaptor_HCurve)& thePCurve, const TopoDS_Face& theFace, const Handle(Poly_Triangulation)& theTriangulation, const Handle(Poly_PolygonOnTriangulation)& thePolygon, diff --git a/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.hxx b/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.hxx index 5b847d39dd..d7f20a6146 100644 --- a/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.hxx +++ b/src/BRepMesh/BRepMesh_EdgeTessellationExtractor.hxx @@ -28,7 +28,7 @@ class Poly_Triangulation; class Poly_PolygonOnTriangulation; class TopoDS_Edge; class TopoDS_Face; -class Geom2d_Curve; +class Geom2dAdaptor_HCurve; //! Auxiliary class implements functionality retrieving tessellated //! representation of an edge stored in polygon. @@ -40,7 +40,7 @@ public: //! Initializes extractor. BRepMesh_EdgeTessellationExtractor( const TopoDS_Edge& theEdge, - const Handle(Geom2d_Curve)& thePCurve, + const Handle(Geom2dAdaptor_HCurve)& thePCurve, const TopoDS_Face& theFace, const Handle(Poly_Triangulation)& theTriangulation, const Handle(Poly_PolygonOnTriangulation)& thePolygon, @@ -76,7 +76,7 @@ private: private: BRepMesh_EdgeParameterProvider myProvider; - const Handle(Geom2d_Curve)& myPCurve; + Handle(Geom2dAdaptor_HCurve) myPCurve; const TColgp_Array1OfPnt& myNodes; const TColStd_Array1OfInteger& myIndices; const TopLoc_Location myLoc; diff --git a/src/BRepMesh/BRepMesh_EdgeTessellator.cxx b/src/BRepMesh/BRepMesh_EdgeTessellator.cxx index d1895602c1..b35b3bccd6 100644 --- a/src/BRepMesh/BRepMesh_EdgeTessellator.cxx +++ b/src/BRepMesh/BRepMesh_EdgeTessellator.cxx @@ -17,6 +17,7 @@ #include #include #include +#include #include #include #include @@ -66,9 +67,11 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator( const GeomAbs_CurveType aCurveType = myCOnS.GetType(); Standard_Integer aMinPntNb = (aCurveType == GeomAbs_Circle) ? 4 : 2; //OCC287 - // Get range on 2d curve + // Get 2d curve and init geom tool Standard_Real aFirstParam, aLastParam; - BRep_Tool::Range(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam); + Handle(Geom2d_Curve) aCurve2d = + BRep_Tool::CurveOnSurface(theEdge, theFaceAttribute->Face(), aFirstParam, aLastParam); + myCurve2d.Load(aCurve2d, aFirstParam, aLastParam); myTool = new BRepMesh_GeomTool(myCOnS, aFirstParam, aLastParam, aPreciseLinDef, aPreciseAngDef, aMinPntNb, theMinSize); @@ -94,7 +97,9 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator( Standard_Real aParam; gp_Pnt aPoint3d; gp_Pnt2d aPoint2d; - aDetalizator.Value( aNodeIt, mySurface, aParam, aPoint3d, aPoint2d ); + aDetalizator.Value( aNodeIt, aParam, aPoint3d); + myCurve2d.D0(aParam, aPoint2d); + myTool->AddPoint( aPoint3d, aParam, Standard_False ); } } @@ -122,11 +127,10 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator( TopTools_ListIteratorOfListOfShape aFaceIt(aSharedFaces); for (; aFaceIt.More(); aFaceIt.Next()) { - TopLoc_Location aLoc; - const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value()); - Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc); + const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Value()); + BRepAdaptor_Surface aSurf(aFace, Standard_False); - if (aSurf->IsInstance(STANDARD_TYPE(Geom_Plane))) + if (aSurf.GetType() == GeomAbs_Plane) continue; Standard_Real aF, aL; @@ -136,20 +140,20 @@ BRepMesh_EdgeTessellator::BRepMesh_EdgeTessellator( { continue; } + Geom2dAdaptor_Curve aGACurve(aCurve2d, aF, aL); aNodesNb = myTool->NbPoints(); TColStd_Array1OfReal aParamArray(1, aNodesNb); for (Standard_Integer i = 1; i <= aNodesNb; ++i) { - gp_Pnt2d aTmpUV; gp_Pnt aTmpPnt; Standard_Real aParam; - myTool->Value(i, mySurface, aParam, aTmpPnt, aTmpUV); + myTool->Value(i, aParam, aTmpPnt); aParamArray.SetValue(i, aParam); } for (Standard_Integer i = 1; i < aNodesNb; ++i) - splitSegment(aSurf, aCurve2d, aParamArray(i), aParamArray(i + 1), 1); + splitSegment(aSurf, aGACurve, aParamArray(i), aParamArray(i + 1), 1); } } @@ -174,7 +178,8 @@ Standard_Boolean BRepMesh_EdgeTessellator::Value( gp_Pnt& thePoint, gp_Pnt2d& theUV) { - myTool->Value(theIndex, mySurface, theParameter, thePoint, theUV); + myTool->Value(theIndex, theParameter, thePoint); + myCurve2d.D0(theParameter, theUV); // If point coordinates are out of surface range, // it is necessary to re-project point. @@ -207,8 +212,8 @@ Standard_Boolean BRepMesh_EdgeTessellator::Value( //purpose : //======================================================================= void BRepMesh_EdgeTessellator::splitSegment( - const Handle(Geom_Surface)& theSurf, - const Handle(Geom2d_Curve)& theCurve2d, + const Adaptor3d_Surface& theSurf, + const Geom2dAdaptor_Curve& theCurve2d, const Standard_Real theFirst, const Standard_Real theLast, const Standard_Integer theNbIter) @@ -224,17 +229,17 @@ void BRepMesh_EdgeTessellator::splitSegment( if(Abs(theLast - theFirst) < 2 * Precision::PConfusion()) return; - theCurve2d->D0(theFirst, uvf); - theCurve2d->D0(theLast, uvl); + theCurve2d.D0(theFirst, uvf); + theCurve2d.D0(theLast, uvl); - P3dF = theSurf->Value(uvf.X(), uvf.Y()); - P3dL = theSurf->Value(uvl.X(), uvl.Y()); + P3dF = theSurf.Value(uvf.X(), uvf.Y()); + P3dL = theSurf.Value(uvl.X(), uvl.Y()); if(P3dF.SquareDistance(P3dL) < mySquareMinSize) return; uvm = gp_Pnt2d((uvf.XY() + uvl.XY())*0.5); - midP3dFromSurf = theSurf->Value(uvm.X(), uvm.Y()); + midP3dFromSurf = theSurf.Value(uvm.X(), uvm.Y()); gp_XYZ Vec1 = midP3dFromSurf.XYZ() - P3dF.XYZ(); if(Vec1.SquareModulus() < mySquareMinSize) diff --git a/src/BRepMesh/BRepMesh_EdgeTessellator.hxx b/src/BRepMesh/BRepMesh_EdgeTessellator.hxx index 80b184d3dd..5af1a9e432 100644 --- a/src/BRepMesh/BRepMesh_EdgeTessellator.hxx +++ b/src/BRepMesh/BRepMesh_EdgeTessellator.hxx @@ -23,10 +23,10 @@ #include #include #include +#include #include -class Geom_Surface; -class Geom2d_Curve; +class Adaptor3d_Surface; class TopoDS_Edge; class BRepAdaptor_HSurface; @@ -70,8 +70,8 @@ public: private: //! - void splitSegment(const Handle(Geom_Surface)& theSurf, - const Handle(Geom2d_Curve)& theCurve2d, + void splitSegment(const Adaptor3d_Surface& theSurf, + const Geom2dAdaptor_Curve& theCurve2d, const Standard_Real theFirst, const Standard_Real theLast, const Standard_Integer theNbIter); @@ -80,6 +80,7 @@ private: NCollection_Handle myTool; Handle(BRepAdaptor_HSurface) mySurface; BRepAdaptor_Curve myCOnS; + Geom2dAdaptor_Curve myCurve2d; Standard_Real mySquareEdgeDef; Standard_Real mySquareMinSize; Standard_Real myEdgeSqTol; diff --git a/src/BRepMesh/BRepMesh_FastDiscret.cxx b/src/BRepMesh/BRepMesh_FastDiscret.cxx index 622a3b2c04..1d453897ff 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.cxx @@ -41,6 +41,7 @@ #include #include +#include #include #include #include @@ -205,7 +206,10 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) Standard_Real defface = 0.; if (!myParameters.Relative) + { + defedge = Max(UVDEFLECTION, defedge); defface = Max(myParameters.Deflection, maxdef); + } const TopoDS_Face& aFace = myAttribute->Face(); for (TopoDS_Iterator aWireIt(aFace); aWireIt.More(); aWireIt.Next()) @@ -215,9 +219,9 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) const TopoDS_Edge& aEdge = TopoDS::Edge(aEdgeIt.Value()); if (aEdge.IsNull()) continue; - if (!myMapdefle.IsBound(aEdge)) + if (myParameters.Relative) { - if (myParameters.Relative) + if (!myMapdefle.IsBound(aEdge)) { if (myEdges.IsBound(aEdge)) { @@ -232,26 +236,26 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) myParameters.Angle = savangle * cdef; } - - defface += defedge; - defface = Max(maxdef, defface); } else { - defedge = myParameters.Deflection; + defedge = myMapdefle(aEdge); } - defedge = Max(maxdef, defedge); - defedge = Max(UVDEFLECTION, defedge); - myMapdefle.Bind(aEdge, defedge); + defface += defedge; + defface = Max(maxdef, defface); + + if (!myMapdefle.IsBound(aEdge)) + { + defedge = Max(UVDEFLECTION, defedge); + myMapdefle.Bind(aEdge, defedge); + } } else { - defedge = myMapdefle(aEdge); - if ( myParameters.Relative ) + if (!myMapdefle.IsBound(aEdge)) { - defface += defedge; - defface = Max(maxdef, defface); + myMapdefle.Bind(aEdge, defedge); } } @@ -261,8 +265,8 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) if (aCurve2d.IsNull()) continue; - - EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam }; + Handle(Geom2dAdaptor_HCurve) aPCurve = + new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam); add(aEdge, aPCurve, defedge); myParameters.Angle = savangle; @@ -418,7 +422,8 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) if (aCurve2d.IsNull()) continue; - EdgePCurve aPCurve = { aCurve2d, aFirstParam, aLastParam }; + Handle(Geom2dAdaptor_HCurve) aPCurve = + new Geom2dAdaptor_HCurve(aCurve2d, aFirstParam, aLastParam); add(anEdge, aPCurve, defedge); } } @@ -590,7 +595,7 @@ Standard_Integer BRepMesh_FastDiscret::Add(const TopoDS_Face& theFace) //======================================================================= Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes( const TopoDS_Edge& theEdge, - const BRepMesh_FastDiscret::EdgePCurve& thePCurve, + const Handle(Geom2dAdaptor_HCurve)& thePCurve, const Standard_Real theDefEdge, BRepMesh_FastDiscret::EdgeAttributes& theAttributes) const { @@ -610,35 +615,34 @@ Standard_Boolean BRepMesh_FastDiscret::getEdgeAttributes( aEAttr.IsSameUV = aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion()); - - //Control tolerance of vertices - const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); - gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y()); - gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y()); - - aEAttr.MinDist = 10. * Max(pFirst.Distance(BRep_Tool::Pnt(aEAttr.FirstVertex)), - pLast .Distance(BRep_Tool::Pnt(aEAttr.LastVertex))); - - if (aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.FirstVertex) || - aEAttr.MinDist < BRep_Tool::Tolerance(aEAttr.LastVertex)) - { - aEAttr.MinDist = theDefEdge; - } - if (aEAttr.IsSameUV) { // 1. is it really sameUV without being degenerated gp_Pnt2d uvF, uvL; - thePCurve.Curve2d->D0(thePCurve.FirstParam, uvF); - thePCurve.Curve2d->D0(thePCurve.LastParam, uvL); + thePCurve->D0(thePCurve->FirstParameter(), uvF); + thePCurve->D0(thePCurve->LastParameter(), uvL); if (!aEAttr.FirstUV.IsEqual(uvF, Precision::PConfusion())) aEAttr.FirstUV = uvF; if (!aEAttr.LastUV.IsEqual(uvL, Precision::PConfusion())) aEAttr.LastUV = uvL; + + aEAttr.IsSameUV = + aEAttr.FirstUV.IsEqual(aEAttr.LastUV, Precision::PConfusion()); } + //Control tolerance of vertices + const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); + gp_Pnt pFirst = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y()); + gp_Pnt pLast = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y()); + + Standard_Real aSqDist = pFirst.SquareDistance(BRep_Tool::Pnt(aEAttr.FirstVertex)); + aSqDist = Max(aSqDist, pLast.SquareDistance(BRep_Tool::Pnt(aEAttr.LastVertex))); + + aEAttr.Deflection = Max(theDefEdge, BRep_Tool::Tolerance(theEdge)); + aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist)); + return Standard_True; } @@ -670,21 +674,30 @@ void BRepMesh_FastDiscret::registerEdgeVertices( new TopoDSVExplorer(aEAttr.LastVertex, aEAttr.IsSameUV, aEAttr.FirstVertex); } - gp_XY aTmpUV; // Process first vertex ipf = myAttribute->GetVertexIndex(aEAttr.FirstVExtractor, Standard_True); - aTmpUV = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aEAttr.FirstVertex, - aEAttr.MinDist, myAttribute); + Standard_Real aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.FirstVertex); + gp_XY aTmpUV1 = BRepMesh_ShapeTool::FindUV(ipf, aEAttr.FirstUV, aMinDist, myAttribute); - myAttribute->AddNode(ipf, aTmpUV, BRepMesh_Frontier, ivf, isvf); + myAttribute->AddNode(ipf, aTmpUV1, BRepMesh_Frontier, ivf, isvf); // Process last vertex ipl = aEAttr.LastVertex.IsSame(aEAttr.FirstVertex) ? ipf : myAttribute->GetVertexIndex(aEAttr.LastVExtractor, Standard_True); - aTmpUV = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aEAttr.LastVertex, - aEAttr.MinDist, myAttribute); + aMinDist = 2. * BRep_Tool::Tolerance(aEAttr.LastVertex); + gp_XY aTmpUV2 = BRepMesh_ShapeTool::FindUV(ipl, aEAttr.LastUV, aMinDist, myAttribute); + + myAttribute->AddNode(ipl, aTmpUV2, BRepMesh_Frontier, ivl, isvl); - myAttribute->AddNode(ipl, aTmpUV, BRepMesh_Frontier, ivl, isvl); + // Update edge deflection + const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); + gp_Pnt aPntE1 = gFace->Value(aEAttr.FirstUV.X(), aEAttr.FirstUV.Y()); + gp_Pnt aPntFound1 = gFace->Value(aTmpUV1.X(), aTmpUV1.Y()); + Standard_Real aSqDist = aPntE1.SquareDistance(aPntFound1); + gp_Pnt aPntE2 = gFace->Value(aEAttr.LastUV.X(), aEAttr.LastUV.Y()); + gp_Pnt aPntFound2 = gFace->Value(aTmpUV2.X(), aTmpUV2.Y()); + aSqDist = Max(aSqDist, aPntE2.SquareDistance(aPntFound2)); + aEAttr.Deflection = Max(aEAttr.Deflection, sqrt(aSqDist)); } //======================================================================= @@ -693,7 +706,7 @@ void BRepMesh_FastDiscret::registerEdgeVertices( //======================================================================= void BRepMesh_FastDiscret::add( const TopoDS_Edge& theEdge, - const BRepMesh_FastDiscret::EdgePCurve& thePCurve, + const Handle(Geom2dAdaptor_HCurve)& thePCurve, const Standard_Real theDefEdge) { const TopAbs_Orientation orEdge = theEdge.Orientation(); @@ -706,7 +719,7 @@ void BRepMesh_FastDiscret::add( if (!myEdges.IsBound(theEdge)) { - update(theEdge, thePCurve.Curve2d, theDefEdge, aEAttr); + update(theEdge, thePCurve, theDefEdge, aEAttr); return; } @@ -743,7 +756,7 @@ void BRepMesh_FastDiscret::add( const gp_Pnt& aPnt = myBoundaryPoints->Find(aPointId); const Standard_Real aParam = aProvider.Parameter(i, aPnt); - gp_Pnt2d aUV = thePCurve.Curve2d->Value(aParam); + gp_Pnt2d aUV = thePCurve->Value(aParam); Standard_Integer iv2, isv; myAttribute->AddNode(aPointId, aUV.Coord(), BRepMesh_OnCurve, iv2, isv); @@ -756,7 +769,7 @@ void BRepMesh_FastDiscret::add( Handle(Poly_PolygonOnTriangulation) P1 = new Poly_PolygonOnTriangulation(aNewNodes, aNewParams); - storePolygon(theEdge, P1, theDefEdge); + storePolygon(theEdge, P1, aEAttr.Deflection); } //======================================================================= @@ -765,7 +778,7 @@ void BRepMesh_FastDiscret::add( //======================================================================= void BRepMesh_FastDiscret::update( const TopoDS_Edge& theEdge, - const Handle(Geom2d_Curve)& theC2d, + const Handle(Geom2dAdaptor_HCurve)& theC2d, const Standard_Real theDefEdge, BRepMesh_FastDiscret::EdgeAttributes& theAttributes) { @@ -885,8 +898,8 @@ void BRepMesh_FastDiscret::update( P2 = new Poly_PolygonOnTriangulation(aNewNodInStruct, aNewParams); } - storePolygon(theEdge, P1, theDefEdge); - storePolygonSharedData(theEdge, P2, theDefEdge); + storePolygon(theEdge, P1, aEAttr.Deflection); + storePolygonSharedData(theEdge, P2, aEAttr.Deflection); } //======================================================================= diff --git a/src/BRepMesh/BRepMesh_FastDiscret.hxx b/src/BRepMesh/BRepMesh_FastDiscret.hxx index be0236145a..3db6feeae2 100644 --- a/src/BRepMesh/BRepMesh_FastDiscret.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscret.hxx @@ -40,8 +40,8 @@ class Bnd_Box; class TopoDS_Shape; class TopoDS_Face; class TopoDS_Edge; +class Geom2dAdaptor_HCurve; class BRepAdaptor_HSurface; -class Geom2d_Curve; class BRepMesh_Edge; class BRepMesh_Vertex; class gp_Pnt; @@ -273,27 +273,18 @@ private: gp_Pnt2d FirstUV; gp_Pnt2d LastUV; + Standard_Real Deflection; Standard_Boolean IsSameUV; - Standard_Real MinDist; NCollection_Handle FirstVExtractor; NCollection_Handle LastVExtractor; }; - //! Structure keeps geometrical parameters of edge's PCurve. - //! Used for caching. - struct EdgePCurve - { - Handle(Geom2d_Curve) Curve2d; - Standard_Real FirstParam; - Standard_Real LastParam; - }; - //! Fills structure of by attributes of the given edge. //! @return TRUE on success, FALSE elsewhere. Standard_Boolean getEdgeAttributes( const TopoDS_Edge& theEdge, - const EdgePCurve& thePCurve, + const Handle(Geom2dAdaptor_HCurve)& thePCurve, const Standard_Real theDefEdge, EdgeAttributes& theAttributes) const; @@ -311,7 +302,7 @@ private: //! Adds tessellated representation of the given edge to //! mesh data structure of currently processed face. void add(const TopoDS_Edge& theEdge, - const EdgePCurve& theCurve2D, + const Handle(Geom2dAdaptor_HCurve)& theCurve2D, const Standard_Real theEdgeDeflection); //! Updates tessellated representation of the given edge. @@ -320,7 +311,7 @@ private: //! Computes tessellation using edge's geometry elsewhere. void update( const TopoDS_Edge& theEdge, - const Handle(Geom2d_Curve)& theCurve2D, + const Handle(Geom2dAdaptor_HCurve)& theCurve2D, const Standard_Real theEdgeDeflection, EdgeAttributes& theAttributes); diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx index 0b913ada87..2abfe722c7 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.cxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.cxx @@ -56,6 +56,11 @@ #include +//#define DEBUG_MESH "mesh.tcl" +#ifdef DEBUG_MESH +#include +#endif + IMPLEMENT_STANDARD_RTTIEXT(BRepMesh_FastDiscretFace,Standard_Transient) @@ -393,27 +398,28 @@ void BRepMesh_FastDiscretFace::add(const Handle(BRepMesh_FaceAttribute)& theAttr Standard_Real aDef = -1; if ( !isaline && myStructure->ElementsOfDomain().Extent() > 0 ) { - Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; - BRepMesh::ListOfVertex aNewVertices(anAlloc); if (!rajout) { - aDef = control(aNewVertices, trigu, Standard_True); + // compute maximal deflection + aDef = control(trigu, Standard_True); rajout = (aDef > myAttribute->GetDefFace() || aDef < 0.); } - - if (!rajout && useUVParam) + if (thetype != GeomAbs_Plane) { - rajout = (myVParam.Extent() > 2 && - (gFace->IsUClosed() || gFace->IsVClosed())); - } + if (!rajout && useUVParam) + { + rajout = (myVParam.Extent() > 2 && + (gFace->IsUClosed() || gFace->IsVClosed())); + } - if (rajout) - { - insertInternalVertices(aNewVertices, trigu); + if (rajout) + { + insertInternalVertices(trigu); - //control internal points - if (myIsControlSurfaceDeflection) - aDef = control(aNewVertices, trigu, Standard_False); + //control internal points + if (myIsControlSurfaceDeflection) + aDef = control(trigu, Standard_False); + } } } @@ -455,7 +461,7 @@ Standard_Boolean BRepMesh_FastDiscretFace::addVerticesToMesh( } //======================================================================= -//function : insertInternalVertices +//function : filterParameters //purpose : //======================================================================= static void filterParameters(const BRepMesh::IMapOfReal& theParams, @@ -516,35 +522,39 @@ static void filterParameters(const BRepMesh::IMapOfReal& theParams, theResult.Append(aParamArray(aParamLength)); } -void BRepMesh_FastDiscretFace::insertInternalVertices( - BRepMesh::ListOfVertex& theNewVertices, - BRepMesh_Delaun& theMeshBuilder) +//======================================================================= +//function : insertInternalVertices +//purpose : +//======================================================================= +void BRepMesh_FastDiscretFace::insertInternalVertices(BRepMesh_Delaun& theMeshBuilder) { + Handle(NCollection_IncAllocator) anAlloc = new NCollection_IncAllocator; + BRepMesh::ListOfVertex aNewVertices(anAlloc); const Handle(BRepAdaptor_HSurface)& gFace = myAttribute->Surface(); switch (gFace->GetType()) { case GeomAbs_Sphere: - insertInternalVerticesSphere(theNewVertices); - break; + insertInternalVerticesSphere(aNewVertices); + break; case GeomAbs_Cylinder: - insertInternalVerticesCylinder(theNewVertices); - break; + insertInternalVerticesCylinder(aNewVertices); + break; case GeomAbs_Cone: - insertInternalVerticesCone(theNewVertices); + insertInternalVerticesCone(aNewVertices); break; case GeomAbs_Torus: - insertInternalVerticesTorus(theNewVertices); + insertInternalVerticesTorus(aNewVertices); break; default: - insertInternalVerticesOther(theNewVertices); + insertInternalVerticesOther(aNewVertices); break; } - addVerticesToMesh(theNewVertices, theMeshBuilder); + addVerticesToMesh(aNewVertices, theMeshBuilder); } //======================================================================= @@ -856,162 +866,239 @@ void BRepMesh_FastDiscretFace::insertInternalVerticesOther( // check intermediate isolines Handle (Geom_Surface) aSurface = gFace->ChangeSurface ().Surface ().Surface (); - const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); BRepMesh::MapOfReal aParamsToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc), BRepMesh::MapOfReal(1, anAlloc) }; BRepMesh::MapOfReal aParamsForbiddenToRemove[2] = { BRepMesh::MapOfReal(1, anAlloc), BRepMesh::MapOfReal(1, anAlloc) }; - // precision for compare square distances - const Standard_Real aPrecision = Precision::Confusion(); + // insert additional points where it is needed to conform criteria. + // precision for normals calculation + const Standard_Real aNormPrec = Precision::Confusion(); for (Standard_Integer k = 0; k < 2; ++k) { const Standard_Integer aOtherIndex = (k + 1) % 2; BRepMesh::SequenceOfReal& aParams1 = aParams[k]; BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex]; const Standard_Boolean isU = (k == 0); - Standard_Integer aStartIndex, aEndIndex; - if (isU) - { - aStartIndex = 1; - aEndIndex = aParams1.Length(); - } - else - { - aStartIndex = 2; - aEndIndex = aParams1.Length() - 1; - } - - BRepMesh::MapOfReal& aToRemove2 = aParamsToRemove[aOtherIndex]; - BRepMesh::MapOfReal& aForbiddenToRemove1 = aParamsForbiddenToRemove[k]; - BRepMesh::MapOfReal& aForbiddenToRemove2 = aParamsForbiddenToRemove[aOtherIndex]; - for (Standard_Integer i = aStartIndex; i <= aEndIndex; ++i) + for (Standard_Integer i = 2; i < aParams1.Length(); ++i) { const Standard_Real aParam1 = aParams1(i); GeomAdaptor_Curve aIso(isU ? - aSurface->UIso (aParam1) : aSurface->VIso (aParam1)); + aSurface->UIso(aParam1) : aSurface->VIso(aParam1)); Standard_Real aPrevParam2 = aParams2(1); gp_Pnt aPrevPnt2; gp_Vec aPrevVec2; - aIso.D1 (aPrevParam2, aPrevPnt2, aPrevVec2); + aIso.D1(aPrevParam2, aPrevPnt2, aPrevVec2); for (Standard_Integer j = 2; j <= aParams2.Length();) { Standard_Real aParam2 = aParams2(j); gp_Pnt aPnt2; gp_Vec aVec2; - aIso.D1 (aParam2, aPnt2, aVec2); + aIso.D1(aParam2, aPnt2, aVec2); Standard_Real aMidParam = 0.5 * (aPrevParam2 + aParam2); gp_Pnt aMidPnt = aIso.Value(aMidParam); - Standard_Real aDist = deflectionOfSegment (aPrevPnt2, aPnt2, aMidPnt); + Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aPnt2, aMidPnt); if (aDist > aDefFace && aDist > myMinSize) { // insertion aParams2.InsertBefore(j, aMidParam); + continue; + } + //put regular grig for normals + gp_Pnt2d aStPnt1, aStPnt2; + if (isU) + { + aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2); + aStPnt2 = gp_Pnt2d(aParam1, aMidParam); } else { - //put regular grig for normals - gp_Pnt2d aStPnt1, aStPnt2; - if (isU) - { - aStPnt1 = gp_Pnt2d(aParam1, aPrevParam2); - aStPnt2 = gp_Pnt2d(aParam1, aMidParam); - } - else - { - aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1); - aStPnt2 = gp_Pnt2d(aMidParam, aParam1); - } + aStPnt1 = gp_Pnt2d(aPrevParam2, aParam1); + aStPnt2 = gp_Pnt2d(aMidParam, aParam1); + } - gp_Dir N1(0, 0, 1), N2(0, 0, 1); - Standard_Boolean aSt1 = GeomLib::NormEstim (aSurface, aStPnt1, aPrecision, N1); - Standard_Boolean aSt2 = GeomLib::NormEstim (aSurface, aStPnt2, aPrecision, N2); + gp_Dir N1(0, 0, 1), N2(0, 0, 1); + Standard_Integer aSt1 = GeomLib::NormEstim(aSurface, aStPnt1, aNormPrec, N1); + Standard_Integer aSt2 = GeomLib::NormEstim(aSurface, aStPnt2, aNormPrec, N2); - const Standard_Real aAngle = N2.Angle(N1); - if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle) - { - const Standard_Real aLen = GCPnts_AbscissaPoint::Length ( - aIso, aPrevParam2, aMidParam, aDefFace); + const Standard_Real aAngle = N2.Angle(N1); + if (aSt1 < 1 && aSt2 < 1 && aAngle > myAngle) + { + const Standard_Real aLen = GCPnts_AbscissaPoint::Length( + aIso, aPrevParam2, aMidParam, aDefFace); - if (aLen > myMinSize) - { - // insertion - aParams2.InsertBefore(j, aMidParam); - continue; - } + if (aLen > myMinSize) + { + // insertion + aParams2.InsertBefore(j, aMidParam); + continue; } + } + aPrevParam2 = aParam2; + aPrevPnt2 = aPnt2; + aPrevVec2 = aVec2; - // Here we should leave at least 3 parameters as far as - // we must have at least one parameter related to surface - // internals in order to prevent movement of triangle body - // outside the surface in case of highly curved ones, e.g. - // BSpline springs. - if (aDist < aDefFace && - aParams2.Length () > 3 && - j < aParams2.Length ()) + ++j; + } + } + } +#ifdef DEBUG_InsertInternal + // output numbers of parameters along U and V + cout << "aParams: " << aParams[0].Length() << " " << aParams[1].Length() << endl; +#endif + // try to reduce number of points evaluating of isolines sampling + for (Standard_Integer k = 0; k < 2; ++k) + { + const Standard_Integer aOtherIndex = (k + 1) % 2; + BRepMesh::SequenceOfReal& aParams1 = aParams[k]; + BRepMesh::SequenceOfReal& aParams2 = aParams[aOtherIndex]; + const Standard_Boolean isU = (k == 0); + BRepMesh::MapOfReal& aToRemove2 = aParamsToRemove[aOtherIndex]; + BRepMesh::MapOfReal& aForbiddenToRemove1 = aParamsForbiddenToRemove[k]; + BRepMesh::MapOfReal& aForbiddenToRemove2 = aParamsForbiddenToRemove[aOtherIndex]; + for (Standard_Integer i = 2; i < aParams1.Length(); ++i) + { + const Standard_Real aParam1 = aParams1(i); + GeomAdaptor_Curve aIso(isU ? + aSurface->UIso (aParam1) : aSurface->VIso (aParam1)); +#ifdef DEBUG_InsertInternal + // write polyline containing initial parameters to the file + { + ofstream ff(DEBUG_InsertInternal, std::ios_base::app); + ff << "polyline " << (k == 0 ? "u" : "v") << i << " "; + for (Standard_Integer j = 1; j <= aParams2.Length(); j++) + { + gp_Pnt aP; + aIso.D0(aParams2(j), aP); + ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " "; + } + ff << endl; + } +#endif + + Standard_Real aPrevParam2 = aParams2(1); + gp_Pnt aPrevPnt2; + gp_Vec aPrevVec2; + aIso.D1 (aPrevParam2, aPrevPnt2, aPrevVec2); + for (Standard_Integer j = 2; j <= aParams2.Length();) + { + Standard_Real aParam2 = aParams2(j); + gp_Pnt aPnt2; + gp_Vec aVec2; + aIso.D1 (aParam2, aPnt2, aVec2); + + // Here we should leave at least 3 parameters as far as + // we must have at least one parameter related to surface + // internals in order to prevent movement of triangle body + // outside the surface in case of highly curved ones, e.g. + // BSpline springs. + if (aParams2.Length() > 3 && j < aParams2.Length()) + { + // Remove too dense points + const Standard_Real aNextParam = aParams2(j + 1); + gp_Pnt aNextPnt; + gp_Vec aNextVec; + aIso.D1(aNextParam, aNextPnt, aNextVec); + + // Lets check current parameter. + // If it fits deflection, we can remove it. + Standard_Real aDist = deflectionOfSegment(aPrevPnt2, aNextPnt, aPnt2); + if (aDist < aDefFace) { - // Remove too dense points - const Standard_Real aTmpParam = aParams2 (j + 1); - gp_Pnt aTmpPnt; - gp_Vec aTmpVec; - aIso.D1 (aTmpParam, aTmpPnt, aTmpVec); - - Standard_Real aTmpMidParam = 0.5 * (aPrevParam2 + aTmpParam); - gp_Pnt aTmpMidPnt = aIso.Value (aTmpMidParam); - - // Lets check next parameter. - // If it also fits deflection, we can remove previous parameter. - aDist = deflectionOfSegment (aPrevPnt2, aTmpPnt, aTmpMidPnt); - if (aDist < aDefFace) + // Lets check parameters for angular deflection. + if (aPrevVec2.Angle(aNextVec) < myAngle) { - // Lets check parameters for angular deflection. - if (aPrevVec2.SquareMagnitude() < gp::Resolution() || - aTmpVec.SquareMagnitude() < gp::Resolution() || - aPrevVec2.Angle (aTmpVec) < myAngle) + // For current Iso line we can remove this parameter. +#ifdef DEBUG_InsertInternal + // write point of removed parameter { - // For current Iso line we can remove this parameter. - aToRemove2.Add (aParam2); - aParam2 = aTmpParam; - aPnt2 = aTmpPnt; - aVec2 = aTmpVec; - ++j; + ofstream ff(DEBUG_InsertInternal, std::ios_base::app); + ff << "point " << (k == 0 ? "u" : "v") << i << "r_" << j << " " + << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl; } - else { - // We have found a place on the surface refusing - // removement of this parameter. - aForbiddenToRemove1.Add (aParam1); - aForbiddenToRemove2.Add (aParam2); +#endif + aToRemove2.Add(aParam2); + aPrevParam2 = aNextParam; + aPrevPnt2 = aNextPnt; + aPrevVec2 = aNextVec; + j += 2; + continue; + } + else { + // We have found a place on the surface refusing + // removement of this parameter. +#ifdef DEBUG_InsertInternal + // write point of forbidden to remove parameter + { + ofstream ff(DEBUG_InsertInternal, std::ios_base::app); + ff << "vertex " << (k == 0 ? "u" : "v") << i << "f_" << j << " " + << aPnt2.X() << " " << aPnt2.Y() << " " << aPnt2.Z() << endl; } +#endif + aForbiddenToRemove1.Add(aParam1); + aForbiddenToRemove2.Add(aParam2); } } - - aPrevParam2 = aParam2; - aPrevPnt2 = aPnt2; - aPrevVec2 = aVec2; - - ++j; } + aPrevParam2 = aParam2; + aPrevPnt2 = aPnt2; + aPrevVec2 = aVec2; + ++j; + } + } + } + // remove filtered out parameters + for (Standard_Integer k = 0; k < 2; ++k) + { + BRepMesh::SequenceOfReal& aParamsk = aParams[k]; + for (Standard_Integer i = 1; i <= aParamsk.Length();) + { + const Standard_Real aParam = aParamsk.Value(i); + if (aParamsToRemove[k].Contains(aParam) && + !aParamsForbiddenToRemove[k].Contains(aParam)) + { + aParamsk.Remove(i); + } + else + i++; + } + } +#ifdef DEBUG_InsertInternal + // write polylines containing remaining parameters + { + ofstream ff(DEBUG_InsertInternal, std::ios_base::app); + for (Standard_Integer k = 0; k < 2; ++k) + { + for (Standard_Integer i = 1; i <= aParams[k].Length(); i++) + { + ff << "polyline " << (k == 0 ? "uo" : "vo") << i << " "; + for (Standard_Integer j = 1; j <= aParams[1 - k].Length(); j++) + { + gp_Pnt aP; + if (k == 0) + gFace->D0(aParams[k](i), aParams[1 - k](j), aP); + else + gFace->D0(aParams[1 - k](j), aParams[k](i), aP); + ff << aP.X() << " " << aP.Y() << " " << aP.Z() << " "; + } + ff << endl; } } } +#endif // insert nodes of the regular grid + const BRepMesh::HClassifier& aClassifier = myAttribute->ChangeClassifier(); for (Standard_Integer i = 1; i <= aParams[0].Length(); ++i) { const Standard_Real aParam1 = aParams[0].Value (i); - if (aParamsToRemove[0].Contains (aParam1) && !aParamsForbiddenToRemove[0].Contains (aParam1)) - continue; - for (Standard_Integer j = 1; j <= aParams[1].Length(); ++j) { const Standard_Real aParam2 = aParams[1].Value (j); - if (aParamsToRemove[1].Contains (aParam2) && !aParamsForbiddenToRemove[1].Contains (aParam2)) - continue; - gp_Pnt2d aPnt2d(aParam1, aParam2); // Classify intersection point @@ -1091,7 +1178,6 @@ Standard_Boolean BRepMesh_FastDiscretFace::checkDeflectionAndInsert( //purpose : //======================================================================= Standard_Real BRepMesh_FastDiscretFace::control( - BRepMesh::ListOfVertex& theNewVertices, BRepMesh_Delaun& theTrigu, const Standard_Boolean theIsFirst) { @@ -1115,7 +1201,7 @@ Standard_Real BRepMesh_FastDiscretFace::control( new NCollection_IncAllocator(BRepMesh::MEMORY_BLOCK_SIZE_HUGE); NCollection_DataMap aNorMap(1, anAlloc); BRepMesh::MapOfIntegerInteger aStatMap(1, anAlloc); - NCollection_Map aCouples(3 * aTrianglesNb, anAlloc); + NCollection_Map aCouples(3 * aTrianglesNb, anAlloc); const BRepMesh_CircleTool& aCircles = theTrigu.Circles(); // Perform refinement passes @@ -1131,7 +1217,7 @@ Standard_Real BRepMesh_FastDiscretFace::control( for (; aPass <= aPassesNb && aInsertedNb && !isAllDegenerated; ++aPass) { aTempAlloc->Reset(Standard_False); - theNewVertices.Clear(); + BRepMesh::ListOfVertex aNewVertices(aTempAlloc); // Reset stop condition aInsertedNb = 0; @@ -1206,7 +1292,7 @@ Standard_Real BRepMesh_FastDiscretFace::control( aSqDef *= aSqDef; isSkipped = !checkDeflectionAndInsert(pDef, aCenter2d, theIsFirst, - aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc); + aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc); if (isSkipped) break; @@ -1217,30 +1303,18 @@ Standard_Real BRepMesh_FastDiscretFace::control( if (m[i]) // is a boundary continue; - Standard_Integer j = (i + 1) % 3; // Check if this link was already processed - Standard_Integer aFirstVertex, aLastVertex; - if (v[i] < v[j]) - { - aFirstVertex = v[i]; - aLastVertex = v[j]; - } - else - { - aFirstVertex = v[j]; - aLastVertex = v[i]; - } - - if (aCouples.Add(BRepMesh_OrientedEdge(aFirstVertex, aLastVertex))) + if (aCouples.Add(myStructure->GetLink(e[i]))) { // Check deflection on edge 1 + Standard_Integer j = (i + 1) % 3; gp_XY mi2d = (xy[i] + xy[j]) * 0.5; gFace->D0(mi2d.X(), mi2d.Y(), pDef); gp_Lin aLin(p[i], gp_Vec(p[i], p[j])); aSqDef = aLin.SquareDistance(pDef); isSkipped = !checkDeflectionAndInsert(pDef, mi2d, theIsFirst, - aSqDef, aSqDefFace, aCircles, theNewVertices, aMaxSqDef, aTempAlloc); + aSqDef, aSqDefFace, aCircles, aNewVertices, aMaxSqDef, aTempAlloc); } } @@ -1286,7 +1360,43 @@ Standard_Real BRepMesh_FastDiscretFace::control( if (theIsFirst) continue; - if (addVerticesToMesh(theNewVertices, theTrigu)) +#ifdef DEBUG_MESH + // append to the file triangles in the form of polyline commands; + // so the file can be sourced in draw to analyze triangles on each pass of the algorithm. + // write triangles + ofstream ftt(DEBUG_MESH, std::ios_base::app); + Standard_Integer nbElem = myStructure->NbElements(); + for (Standard_Integer i = 1; i <= nbElem; i++) + { + const BRepMesh_Triangle& aTri = myStructure->GetElement(i); + if (aTri.Movability() == BRepMesh_Deleted) + continue; + Standard_Integer n[3]; + myStructure->ElementNodes(aTri, n); + const BRepMesh_Vertex& aV1 = myStructure->GetNode(n[0]); + const BRepMesh_Vertex& aV2 = myStructure->GetNode(n[1]); + const BRepMesh_Vertex& aV3 = myStructure->GetNode(n[2]); + const gp_Pnt& aP1 = myAttribute->GetPoint(aV1); + const gp_Pnt& aP2 = myAttribute->GetPoint(aV2); + const gp_Pnt& aP3 = myAttribute->GetPoint(aV3); + ftt << "polyline t" << aPass << "_" << i << " " + << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << " " + << aP2.X() << " " << aP2.Y() << " " << aP2.Z() << " " + << aP3.X() << " " << aP3.Y() << " " << aP3.Z() << " " + << aP1.X() << " " << aP1.Y() << " " << aP1.Z() << endl; + } + // write points to insert on the current pass + BRepMesh::ListOfVertex::Iterator it(aNewVertices); + for (Standard_Integer i=1; it.More(); it.Next(), i++) + { + const BRepMesh_Vertex& aVertex = it.Value(); + const gp_Pnt& aP = myAttribute->GetPoint(aVertex); + ftt << "vertex vt" << aPass << "_" << i << " " + << aP.X() << " " << aP.Y() << " " << aP.Z() << endl; + } +#endif + + if (addVerticesToMesh(aNewVertices, theTrigu)) ++aInsertedNb; } @@ -1314,7 +1424,7 @@ void BRepMesh_FastDiscretFace::add(const TopoDS_Vertex& theVertex) NCollection_Handle aFixedVExplorer = new FixedVExplorer(theVertex); Standard_Integer aIndex = myAttribute->GetVertexIndex(aFixedVExplorer); gp_XY anUV = BRepMesh_ShapeTool::FindUV(aIndex, aPnt2d, - theVertex, BRep_Tool::Tolerance(theVertex), myAttribute); + BRep_Tool::Tolerance(theVertex), myAttribute); Standard_Integer aTmpId1, aTmpId2; anUV = myAttribute->Scale(anUV, Standard_True); diff --git a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx index 01a36a7938..76b00e1914 100644 --- a/src/BRepMesh/BRepMesh_FastDiscretFace.hxx +++ b/src/BRepMesh/BRepMesh_FastDiscretFace.hxx @@ -69,8 +69,7 @@ private: void add(const Handle(BRepMesh_FaceAttribute)& theAttribute); void add(const TopoDS_Vertex& theVertex); - Standard_Real control(BRepMesh::ListOfVertex& theNewVertices, - BRepMesh_Delaun& theMeshBuilder, + Standard_Real control(BRepMesh_Delaun& theMeshBuilder, const Standard_Boolean theIsFirst); //! Registers the given nodes in mesh data structure and @@ -84,11 +83,9 @@ private: BRepMesh_Delaun& theMeshBuilder); //! Calculates nodes lying on face's surface and inserts them to a mesh. - //! @param theNewVertices list of vertices to be extended and added to mesh. //! @param theMeshBuilder initialized tool refining mesh //! in respect to inserting nodes. - void insertInternalVertices(BRepMesh::ListOfVertex& theNewVertices, - BRepMesh_Delaun& theMeshBuilder); + void insertInternalVertices(BRepMesh_Delaun& theMeshBuilder); //! Calculates nodes lying on spherical surface. //! @param theNewVertices list of vertices to be extended and added to mesh. diff --git a/src/BRepMesh/BRepMesh_GeomTool.cxx b/src/BRepMesh/BRepMesh_GeomTool.cxx index 3733f6a9ba..16c34331b2 100644 --- a/src/BRepMesh/BRepMesh_GeomTool.cxx +++ b/src/BRepMesh/BRepMesh_GeomTool.cxx @@ -76,10 +76,8 @@ BRepMesh_GeomTool::BRepMesh_GeomTool( //======================================================================= Standard_Boolean BRepMesh_GeomTool::Value( const Standard_Integer theIndex, - const Handle(BRepAdaptor_HSurface)& theSurface, Standard_Real& theParam, - gp_Pnt& thePoint, - gp_Pnt2d& theUV) const + gp_Pnt& thePoint) const { if (theIndex < 1 || theIndex > NbPoints()) return Standard_False; @@ -90,14 +88,6 @@ Standard_Boolean BRepMesh_GeomTool::Value( thePoint = myDiscretTool.Value(theIndex); theParam = myDiscretTool.Parameter(theIndex); - const TopoDS_Face& aFace = ((BRepAdaptor_Surface*)&(theSurface->Surface()))->Face(); - - Standard_Real aFirst, aLast; - Handle(Geom2d_Curve) aCurve = - BRep_Tool::CurveOnSurface(*myEdge, aFace, aFirst, aLast); - - aCurve->D0(theParam, theUV); - return Standard_True; } diff --git a/src/BRepMesh/BRepMesh_GeomTool.hxx b/src/BRepMesh/BRepMesh_GeomTool.hxx index 54fbd48014..047cb188c0 100644 --- a/src/BRepMesh/BRepMesh_GeomTool.hxx +++ b/src/BRepMesh/BRepMesh_GeomTool.hxx @@ -124,16 +124,12 @@ public: //! Gets parameters of discretization point with the given index. //! @param theIndex index of discretization point. - //! @param theSurface surface the curve is lying onto. //! @param theParam[out] parameter of the point on the curve. //! @param thePoint[out] discretization point. - //! @param theUV[out] discretization point in parametric space of the surface. //! @return TRUE on success, FALSE elsewhere. Standard_EXPORT Standard_Boolean Value(const Standard_Integer theIndex, - const Handle(BRepAdaptor_HSurface)& theSurface, Standard_Real& theParam, - gp_Pnt& thePoint, - gp_Pnt2d& theUV) const; + gp_Pnt& thePoint) const; public: //! @name static API diff --git a/src/BRepMesh/BRepMesh_ShapeTool.cxx b/src/BRepMesh/BRepMesh_ShapeTool.cxx index 9ac6957464..ebd837bd7a 100644 --- a/src/BRepMesh/BRepMesh_ShapeTool.cxx +++ b/src/BRepMesh/BRepMesh_ShapeTool.cxx @@ -130,7 +130,6 @@ Standard_Real BRepMesh_ShapeTool::RelativeEdgeDeflection( gp_XY BRepMesh_ShapeTool::FindUV( const Standard_Integer theIndexOfPnt3d, const gp_Pnt2d& thePnt2d, - const TopoDS_Vertex& theVertex, const Standard_Real theMinDistance, const Handle(BRepMesh_FaceAttribute)& theFaceAttribute) { @@ -164,8 +163,7 @@ gp_XY BRepMesh_ShapeTool::FindUV( } } - const Standard_Real aTolerance = - Min(2. * BRep_Tool::Tolerance(theVertex), theMinDistance); + const Standard_Real aTolerance = theMinDistance; // Get face limits Standard_Real aDiffU = theFaceAttribute->GetUMax() - theFaceAttribute->GetUMin(); diff --git a/src/BRepMesh/BRepMesh_ShapeTool.hxx b/src/BRepMesh/BRepMesh_ShapeTool.hxx index 35192a6fdc..e1883d7746 100644 --- a/src/BRepMesh/BRepMesh_ShapeTool.hxx +++ b/src/BRepMesh/BRepMesh_ShapeTool.hxx @@ -67,12 +67,8 @@ public: //! representation should be associated. //! @param thePnt2d 2d representation of the point with the //! given index. - //! @param theVertex vertex corresponded to 3d point with the - //! given index. Used to extract vertex tolerance in 3d space. //! @param theMinDistance minimum distance between vertices //! regarding which they could be treated as distinct ones. - //! This value is defined by mesher using parameters given by - //! user in connection with shape metrics. //! @param theFaceAttribute attributes contining data calculated //! according to face geomtry and define limits of face in parametric //! space. If defined, will be used instead of surface parameter. @@ -83,7 +79,6 @@ public: Standard_EXPORT static gp_XY FindUV( const Standard_Integer theIndexOfPnt3d, const gp_Pnt2d& thePnt2d, - const TopoDS_Vertex& theVertex, const Standard_Real theMinDistance, const Handle(BRepMesh_FaceAttribute)& theFaceAttribute); diff --git a/src/BndLib/BndLib_Add2dCurve.cxx b/src/BndLib/BndLib_Add2dCurve.cxx index 58db9703e7..13ee2b2843 100644 --- a/src/BndLib/BndLib_Add2dCurve.cxx +++ b/src/BndLib/BndLib_Add2dCurve.cxx @@ -496,7 +496,8 @@ void BndLib_Box2dCurve::PerformBSpline() } // - if (!(aT1==aTb[0] && aT2==aTb[1])) { + const Standard_Real eps = Precision::PConfusion(); + if (fabs(aT1-aTb[0]) > eps || fabs(aT2-aTb[1]) > eps) { aG=aCBS->Copy(); // aCBSs=Handle(Geom2d_BSplineCurve)::DownCast(aG); @@ -799,7 +800,6 @@ void BndLib_Box2dCurve::GetInfoBase() return; } // - aC2DB=myCurve; while(!bIsTypeBase) { iTrimmed=0; iOffset=0; diff --git a/src/CPnts/CPnts_AbscissaPoint.cxx b/src/CPnts/CPnts_AbscissaPoint.cxx index 5af6f170ee..22a9e6f966 100644 --- a/src/CPnts/CPnts_AbscissaPoint.cxx +++ b/src/CPnts/CPnts_AbscissaPoint.cxx @@ -41,13 +41,17 @@ // auxiliary functions to compute the length of the derivative static Standard_Real f3d(const Standard_Real X, const Standard_Address C) { - gp_Vec V = ((Adaptor3d_Curve*)C)->DN(X,1); + gp_Pnt P; + gp_Vec V; + ((Adaptor3d_Curve*)C)->D1(X,P,V); return V.Magnitude(); } static Standard_Real f2d(const Standard_Real X, const Standard_Address C) { - gp_Vec2d V = ((Adaptor2d_Curve2d*)C)->DN(X,1); + gp_Pnt2d P; + gp_Vec2d V; + ((Adaptor2d_Curve2d*)C)->D1(X,P,V); return V.Magnitude(); } diff --git a/src/Geom/Geom_BSplineCurve.hxx b/src/Geom/Geom_BSplineCurve.hxx index 63e612b41e..dc28c43f1b 100644 --- a/src/Geom/Geom_BSplineCurve.hxx +++ b/src/Geom/Geom_BSplineCurve.hxx @@ -729,7 +729,7 @@ public: //! Returns the pole of range Index. //! Raised if Index < 1 or Index > NbPoles. - Standard_EXPORT gp_Pnt Pole (const Standard_Integer Index) const; + Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer Index) const; //! Returns the poles of the B-spline curve; //! diff --git a/src/Geom/Geom_BSplineCurve_1.cxx b/src/Geom/Geom_BSplineCurve_1.cxx index 2cb0abe3d0..0354196746 100644 --- a/src/Geom/Geom_BSplineCurve_1.cxx +++ b/src/Geom/Geom_BSplineCurve_1.cxx @@ -665,7 +665,7 @@ Standard_Integer Geom_BSplineCurve::NbPoles () const //purpose : //======================================================================= -gp_Pnt Geom_BSplineCurve::Pole (const Standard_Integer Index) const +const gp_Pnt& Geom_BSplineCurve::Pole (const Standard_Integer Index) const { Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), "Geom_BSplineCurve::Pole"); diff --git a/src/Geom/Geom_BSplineSurface.hxx b/src/Geom/Geom_BSplineSurface.hxx index 52e25850cc..9a54bf071d 100644 --- a/src/Geom/Geom_BSplineSurface.hxx +++ b/src/Geom/Geom_BSplineSurface.hxx @@ -899,7 +899,7 @@ public: //! //! Raised if UIndex < 1 or UIndex > NbUPoles or VIndex < 1 or //! VIndex > NbVPoles. - Standard_EXPORT gp_Pnt Pole (const Standard_Integer UIndex, const Standard_Integer VIndex) const; + Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer UIndex, const Standard_Integer VIndex) const; //! Returns the poles of the B-spline surface. //! diff --git a/src/Geom/Geom_BSplineSurface_1.cxx b/src/Geom/Geom_BSplineSurface_1.cxx index 0d75f681f7..3a768cc522 100644 --- a/src/Geom/Geom_BSplineSurface_1.cxx +++ b/src/Geom/Geom_BSplineSurface_1.cxx @@ -426,7 +426,7 @@ gp_Vec Geom_BSplineSurface::LocalDN (const Standard_Real U, //purpose : //======================================================================= -gp_Pnt Geom_BSplineSurface::Pole (const Standard_Integer UIndex, +const gp_Pnt& Geom_BSplineSurface::Pole(const Standard_Integer UIndex, const Standard_Integer VIndex) const { Standard_OutOfRange_Raise_if diff --git a/src/Geom/Geom_BezierCurve.cxx b/src/Geom/Geom_BezierCurve.cxx index c379a60597..6cba54802f 100644 --- a/src/Geom/Geom_BezierCurve.cxx +++ b/src/Geom/Geom_BezierCurve.cxx @@ -655,7 +655,7 @@ Standard_Integer Geom_BezierCurve::NbPoles () const //purpose : //======================================================================= -gp_Pnt Geom_BezierCurve::Pole (const Standard_Integer Index) const +const gp_Pnt& Geom_BezierCurve::Pole (const Standard_Integer Index) const { if(Index < 1 || Index > poles->Length()) Standard_OutOfRange::Raise("Geom_BezierCurve::Pole"); diff --git a/src/Geom/Geom_BezierCurve.hxx b/src/Geom/Geom_BezierCurve.hxx index b186aa256a..38cf013566 100644 --- a/src/Geom/Geom_BezierCurve.hxx +++ b/src/Geom/Geom_BezierCurve.hxx @@ -288,7 +288,7 @@ public: //! Returns the pole of range Index. //! Raised if Index is not in the range [1, NbPoles] - Standard_EXPORT gp_Pnt Pole (const Standard_Integer Index) const; + Standard_EXPORT const gp_Pnt& Pole (const Standard_Integer Index) const; //! Returns all the poles of the curve. //! diff --git a/src/Geom/Geom_BezierSurface.cxx b/src/Geom/Geom_BezierSurface.cxx index 587d6121b5..9d5364ffa7 100644 --- a/src/Geom/Geom_BezierSurface.cxx +++ b/src/Geom/Geom_BezierSurface.cxx @@ -1587,7 +1587,7 @@ Standard_Integer Geom_BezierSurface::NbVPoles () const //purpose : //======================================================================= -gp_Pnt Geom_BezierSurface::Pole (const Standard_Integer UIndex, +const gp_Pnt& Geom_BezierSurface::Pole (const Standard_Integer UIndex, const Standard_Integer VIndex) const { Standard_OutOfRange_Raise_if diff --git a/src/Geom/Geom_BezierSurface.hxx b/src/Geom/Geom_BezierSurface.hxx index 351121e09d..0519edf9bc 100644 --- a/src/Geom/Geom_BezierSurface.hxx +++ b/src/Geom/Geom_BezierSurface.hxx @@ -466,7 +466,7 @@ public: //! Returns the pole of range UIndex, VIndex //! Raised if UIndex < 1 or UIndex > NbUPoles, or //! VIndex < 1 or VIndex > NbVPoles. - Standard_EXPORT gp_Pnt Pole (const Standard_Integer UIndex, const Standard_Integer VIndex) const; + Standard_EXPORT const gp_Pnt& Pole(const Standard_Integer UIndex, const Standard_Integer VIndex) const; //! Returns the poles of the Bezier surface. //! diff --git a/src/Geom/Geom_OffsetSurface.cxx b/src/Geom/Geom_OffsetSurface.cxx index ac6c3cd32b..13f019c9d3 100644 --- a/src/Geom/Geom_OffsetSurface.cxx +++ b/src/Geom/Geom_OffsetSurface.cxx @@ -49,6 +49,7 @@ #include #include #include +#include #include #include #include @@ -456,7 +457,7 @@ public: Standard_Integer *ErrorCode); private: - Handle(Geom_Surface) CurrentSurface; + GeomAdaptor_Surface CurrentSurface; Standard_Real IsoPar; }; @@ -469,14 +470,14 @@ void Geom_OffsetSurface_UIsoEvaluator::Evaluate(Standard_Integer *,/*Dimension*/ { gp_Pnt P; if (*DerivativeRequest == 0) { - P = CurrentSurface->Value(IsoPar,*Parameter); + P = CurrentSurface.Value(IsoPar,*Parameter); Result[0] = P.X(); Result[1] = P.Y(); Result[2] = P.Z(); } else { gp_Vec DU,DV; - CurrentSurface->D1(IsoPar,*Parameter,P,DU,DV); + CurrentSurface.D1(IsoPar,*Parameter,P,DU,DV); Result[0] = DV.X(); Result[1] = DV.Y(); Result[2] = DV.Z(); diff --git a/src/Geom2d/Geom2d_BSplineCurve.hxx b/src/Geom2d/Geom2d_BSplineCurve.hxx index 08aab57407..948a01f849 100644 --- a/src/Geom2d/Geom2d_BSplineCurve.hxx +++ b/src/Geom2d/Geom2d_BSplineCurve.hxx @@ -762,7 +762,7 @@ public: //! Returns the pole of range Index. //! Raised if Index < 1 or Index > NbPoles. - Standard_EXPORT gp_Pnt2d Pole (const Standard_Integer Index) const; + Standard_EXPORT const gp_Pnt2d& Pole (const Standard_Integer Index) const; //! Returns the poles of the B-spline curve; //! diff --git a/src/Geom2d/Geom2d_BSplineCurve_1.cxx b/src/Geom2d/Geom2d_BSplineCurve_1.cxx index 2253cf6989..a4142a5b2f 100644 --- a/src/Geom2d/Geom2d_BSplineCurve_1.cxx +++ b/src/Geom2d/Geom2d_BSplineCurve_1.cxx @@ -678,7 +678,7 @@ Standard_Integer Geom2d_BSplineCurve::NbPoles () const //purpose : //======================================================================= -gp_Pnt2d Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const +const gp_Pnt2d& Geom2d_BSplineCurve::Pole (const Standard_Integer Index) const { Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), "Geom2d_BSplineCurve::Pole"); diff --git a/src/Geom2d/Geom2d_BezierCurve.cxx b/src/Geom2d/Geom2d_BezierCurve.cxx index 8ee3af99f2..76e4e680d5 100644 --- a/src/Geom2d/Geom2d_BezierCurve.cxx +++ b/src/Geom2d/Geom2d_BezierCurve.cxx @@ -656,7 +656,7 @@ Standard_Integer Geom2d_BezierCurve::NbPoles () const //purpose : //======================================================================= -gp_Pnt2d Geom2d_BezierCurve::Pole (const Standard_Integer Index) const +const gp_Pnt2d& Geom2d_BezierCurve::Pole (const Standard_Integer Index) const { Standard_OutOfRange_Raise_if (Index < 1 || Index > poles->Length(), "Geom2d_BezierCurve::Pole"); diff --git a/src/Geom2d/Geom2d_BezierCurve.hxx b/src/Geom2d/Geom2d_BezierCurve.hxx index 62c51e07f8..0d61dc4b45 100644 --- a/src/Geom2d/Geom2d_BezierCurve.hxx +++ b/src/Geom2d/Geom2d_BezierCurve.hxx @@ -266,7 +266,7 @@ public: //! Returns the pole of range Index. //! Raised if Index is not in the range [1, NbPoles] - Standard_EXPORT gp_Pnt2d Pole (const Standard_Integer Index) const; + Standard_EXPORT const gp_Pnt2d& Pole (const Standard_Integer Index) const; //! Returns all the poles of the curve. //! diff --git a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx index 047faa2b2b..b025ffe8f7 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx +++ b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.cxx @@ -180,10 +180,10 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, { myFirst = UFirst; myLast = ULast; + myCurveCache.Nullify(); if ( myCurve != C) { myCurve = C; - myCurveCache.Nullify(); myNestedEvaluator.Nullify(); myBSplineCurve.Nullify(); @@ -209,20 +209,10 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, } else if ( TheType == STANDARD_TYPE(Geom2d_BezierCurve)) { myTypeCurve = GeomAbs_BezierCurve; - // Create cache for Bezier - Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve); - Standard_Integer aDeg = aBezier->Degree(); - TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); - myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, - aBezier->Poles(), aBezier->Weights()); } else if ( TheType == STANDARD_TYPE(Geom2d_BSplineCurve)) { myTypeCurve = GeomAbs_BSplineCurve; - // Create cache for B-spline - Handle(Geom2d_BSplineCurve) aBspl = Handle(Geom2d_BSplineCurve)::DownCast(myCurve); - myBSplineCurve = aBspl; - myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(), - aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights()); + myBSplineCurve = Handle(Geom2d_BSplineCurve)::DownCast(myCurve); } else if ( TheType == STANDARD_TYPE(Geom2d_OffsetCurve)) { @@ -237,8 +227,6 @@ void Geom2dAdaptor_Curve::load(const Handle(Geom2d_Curve)& C, myTypeCurve = GeomAbs_OtherCurve; } } - else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same - RebuildCache(myFirst); } // -- @@ -569,14 +557,22 @@ void Geom2dAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const { if (myTypeCurve == GeomAbs_BezierCurve) { + // Create cache for Bezier Handle(Geom2d_BezierCurve) aBezier = Handle(Geom2d_BezierCurve)::DownCast(myCurve); Standard_Integer aDeg = aBezier->Degree(); TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); + if (myCurveCache.IsNull()) + myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, + aBezier->Poles(), aBezier->Weights()); myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots, aBezier->Poles(), aBezier->Weights()); } else if (myTypeCurve == GeomAbs_BSplineCurve) { + // Create cache for B-spline + if (myCurveCache.IsNull()) + myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(), + myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights()); myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights()); @@ -643,14 +639,13 @@ void Geom2dAdaptor_Curve::D0(const Standard_Real U, gp_Pnt2d& P) const { myBSplineCurve->LocalD0(U, aStart, aFinish, P); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D0(U, P); } - else - myCurve->D0(U, P); break; } @@ -681,14 +676,13 @@ void Geom2dAdaptor_Curve::D1(const Standard_Real U, { myBSplineCurve->LocalD1(U, aStart, aFinish, P, V); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D1(U, P, V); } - else - myCurve->D1(U, P, V); break; } @@ -719,14 +713,13 @@ void Geom2dAdaptor_Curve::D2(const Standard_Real U, { myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D2(U, P, V1, V2); } - else - myCurve->D2(U, P, V1, V2); break; } @@ -758,14 +751,13 @@ void Geom2dAdaptor_Curve::D3(const Standard_Real U, { myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D3(U, P, V1, V2, V3); } - else - myCurve->D3(U, P, V1, V2, V3); break; } diff --git a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx index 1bf3d2aa6b..6ecbf6a5c4 100644 --- a/src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx +++ b/src/Geom2dAdaptor/Geom2dAdaptor_Curve.hxx @@ -198,7 +198,7 @@ private: Standard_Real myLast; Handle(Geom2d_BSplineCurve) myBSplineCurve; ///< B-spline representation to prevent castings - Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve + mutable Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve Handle(Geom2dEvaluator_Curve) myNestedEvaluator; ///< Calculates value of offset curve diff --git a/src/GeomAdaptor/GeomAdaptor_Curve.cxx b/src/GeomAdaptor/GeomAdaptor_Curve.cxx index 6408cab9c4..5be1665b1d 100644 --- a/src/GeomAdaptor/GeomAdaptor_Curve.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Curve.cxx @@ -136,10 +136,10 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C, { myFirst = UFirst; myLast = ULast; + myCurveCache.Nullify(); if ( myCurve != C) { myCurve = C; - myCurveCache.Nullify(); myNestedEvaluator.Nullify(); myBSplineCurve.Nullify(); @@ -164,20 +164,10 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C, } else if ( TheType == STANDARD_TYPE(Geom_BezierCurve)) { myTypeCurve = GeomAbs_BezierCurve; - // Create cache for Bezier - Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve); - Standard_Integer aDeg = aBezier->Degree(); - TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); - myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, - aBezier->Poles(), aBezier->Weights()); } else if ( TheType == STANDARD_TYPE(Geom_BSplineCurve)) { myTypeCurve = GeomAbs_BSplineCurve; - // Create cache for B-spline - Handle(Geom_BSplineCurve) aBspl = Handle(Geom_BSplineCurve)::DownCast(myCurve); - myBSplineCurve = aBspl; - myCurveCache = new BSplCLib_Cache(aBspl->Degree(), aBspl->IsPeriodic(), - aBspl->KnotSequence(), aBspl->Poles(), aBspl->Weights()); + myBSplineCurve = Handle(Geom_BSplineCurve)::DownCast(myCurve); } else if ( TheType == STANDARD_TYPE(Geom_OffsetCurve)) { myTypeCurve = GeomAbs_OffsetCurve; @@ -192,8 +182,6 @@ void GeomAdaptor_Curve::load(const Handle(Geom_Curve)& C, myTypeCurve = GeomAbs_OtherCurve; } } - else // rebuild cache of Bezier and B-spline curve even if the loaded curve is same - RebuildCache(myFirst); } // -- @@ -544,14 +532,22 @@ void GeomAdaptor_Curve::RebuildCache(const Standard_Real theParameter) const { if (myTypeCurve == GeomAbs_BezierCurve) { + // Create cache for Bezier Handle(Geom_BezierCurve) aBezier = Handle(Geom_BezierCurve)::DownCast(myCurve); Standard_Integer aDeg = aBezier->Degree(); TColStd_Array1OfReal aFlatKnots(BSplCLib::FlatBezierKnots(aDeg), 1, 2 * (aDeg + 1)); - myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots, + if (myCurveCache.IsNull()) + myCurveCache = new BSplCLib_Cache(aDeg, aBezier->IsPeriodic(), aFlatKnots, aBezier->Poles(), aBezier->Weights()); + myCurveCache->BuildCache(theParameter, aDeg, aBezier->IsPeriodic(), aFlatKnots, + aBezier->Poles(), aBezier->Weights()); } else if (myTypeCurve == GeomAbs_BSplineCurve) { + // Create cache for B-spline + if (myCurveCache.IsNull()) + myCurveCache = new BSplCLib_Cache(myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(), + myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights()); myCurveCache->BuildCache(theParameter, myBSplineCurve->Degree(), myBSplineCurve->IsPeriodic(), myBSplineCurve->KnotSequence(), myBSplineCurve->Poles(), myBSplineCurve->Weights()); @@ -618,14 +614,13 @@ void GeomAdaptor_Curve::D0(const Standard_Real U, gp_Pnt& P) const { myBSplineCurve->LocalD0(U, aStart, aFinish, P); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D0(U, P); } - else - myCurve->D0(U, P); break; } @@ -655,14 +650,13 @@ void GeomAdaptor_Curve::D1(const Standard_Real U, gp_Pnt& P, gp_Vec& V) const { myBSplineCurve->LocalD1(U, aStart, aFinish, P, V); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D1(U, P, V); } - else - myCurve->D1(U, P, V); break; } @@ -693,14 +687,13 @@ void GeomAdaptor_Curve::D2(const Standard_Real U, { myBSplineCurve->LocalD2(U, aStart, aFinish, P, V1, V2); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D2(U, P, V1, V2); } - else - myCurve->D2(U, P, V1, V2); break; } @@ -732,14 +725,13 @@ void GeomAdaptor_Curve::D3(const Standard_Real U, { myBSplineCurve->LocalD3(U, aStart, aFinish, P, V1, V2, V3); } - else if (!myCurveCache.IsNull()) // use cached data + else { - if (!myCurveCache->IsCacheValid(U)) + // use cached data + if (myCurveCache.IsNull() || !myCurveCache->IsCacheValid(U)) RebuildCache(U); myCurveCache->D3(U, P, V1, V2, V3); } - else - myCurve->D3(U, P, V1, V2, V3); break; } diff --git a/src/GeomAdaptor/GeomAdaptor_Curve.hxx b/src/GeomAdaptor/GeomAdaptor_Curve.hxx index 62f981a7e0..1cc735c78f 100644 --- a/src/GeomAdaptor/GeomAdaptor_Curve.hxx +++ b/src/GeomAdaptor/GeomAdaptor_Curve.hxx @@ -237,7 +237,7 @@ private: Standard_Real myLast; Handle(Geom_BSplineCurve) myBSplineCurve; ///< B-spline representation to prevent castings - Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve + mutable Handle(BSplCLib_Cache) myCurveCache; ///< Cached data for B-spline or Bezier curve Handle(GeomEvaluator_Curve) myNestedEvaluator; ///< Calculates value of offset curve diff --git a/src/GeomAdaptor/GeomAdaptor_Surface.cxx b/src/GeomAdaptor/GeomAdaptor_Surface.cxx index dc479ccb5d..c043cfacda 100644 --- a/src/GeomAdaptor/GeomAdaptor_Surface.cxx +++ b/src/GeomAdaptor/GeomAdaptor_Surface.cxx @@ -132,10 +132,10 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, myULast = ULast; myVFirst = VFirst; myVLast = VLast; + mySurfaceCache.Nullify(); if ( mySurface != S) { mySurface = S; - mySurfaceCache.Nullify(); myNestedEvaluator.Nullify(); myBSplineSurface.Nullify(); @@ -181,26 +181,10 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, else if (TheType == STANDARD_TYPE(Geom_BezierSurface)) { mySurfaceType = GeomAbs_BezierSurface; - // Create cache for Bezier - Handle(Geom_BezierSurface) aBezier = Handle(Geom_BezierSurface)::DownCast(mySurface); - Standard_Integer aDegU = aBezier->UDegree(); - Standard_Integer aDegV = aBezier->VDegree(); - TColStd_Array1OfReal aFlatKnotsU(BSplCLib::FlatBezierKnots(aDegU), 1, 2 * (aDegU + 1)); - TColStd_Array1OfReal aFlatKnotsV(BSplCLib::FlatBezierKnots(aDegV), 1, 2 * (aDegV + 1)); - mySurfaceCache = new BSplSLib_Cache( - aDegU, aBezier->IsUPeriodic(), aFlatKnotsU, - aDegV, aBezier->IsVPeriodic(), aFlatKnotsV, - aBezier->Poles(), aBezier->Weights()); } else if (TheType == STANDARD_TYPE(Geom_BSplineSurface)) { mySurfaceType = GeomAbs_BSplineSurface; - Handle(Geom_BSplineSurface) myBspl = Handle(Geom_BSplineSurface)::DownCast(mySurface); - myBSplineSurface = myBspl; - // Create cache for B-spline - mySurfaceCache = new BSplSLib_Cache( - myBspl->UDegree(), myBspl->IsUPeriodic(), myBspl->UKnotSequence(), - myBspl->VDegree(), myBspl->IsVPeriodic(), myBspl->VKnotSequence(), - myBspl->Poles(), myBspl->Weights()); + myBSplineSurface = Handle(Geom_BSplineSurface)::DownCast(mySurface); } else if ( TheType == STANDARD_TYPE(Geom_OffsetSurface)) { @@ -216,8 +200,6 @@ void GeomAdaptor_Surface::load(const Handle(Geom_Surface)& S, else mySurfaceType = GeomAbs_OtherSurface; } - else // rebuild cache of Bezier and B-spline surface even if the loaded surface is same - RebuildCache(myUFirst, myVFirst); } // -- @@ -679,11 +661,17 @@ void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU, { if (mySurfaceType == GeomAbs_BezierSurface) { + // Create cache for Bezier Handle(Geom_BezierSurface) aBezier = Handle(Geom_BezierSurface)::DownCast(mySurface); Standard_Integer aDegU = aBezier->UDegree(); Standard_Integer aDegV = aBezier->VDegree(); TColStd_Array1OfReal aFlatKnotsU(BSplCLib::FlatBezierKnots(aDegU), 1, 2 * (aDegU + 1)); TColStd_Array1OfReal aFlatKnotsV(BSplCLib::FlatBezierKnots(aDegV), 1, 2 * (aDegV + 1)); + if (mySurfaceCache.IsNull()) + mySurfaceCache = new BSplSLib_Cache( + aDegU, aBezier->IsUPeriodic(), aFlatKnotsU, + aDegV, aBezier->IsVPeriodic(), aFlatKnotsV, + aBezier->Poles(), aBezier->Weights()); mySurfaceCache->BuildCache(theU, theV, aDegU, aBezier->IsUPeriodic(), aFlatKnotsU, aDegV, aBezier->IsVPeriodic(), aFlatKnotsV, @@ -691,10 +679,16 @@ void GeomAdaptor_Surface::RebuildCache(const Standard_Real theU, } else if (mySurfaceType == GeomAbs_BSplineSurface) { - mySurfaceCache->BuildCache(theU, theV, + // Create cache for B-spline + if (mySurfaceCache.IsNull()) + mySurfaceCache = new BSplSLib_Cache( myBSplineSurface->UDegree(), myBSplineSurface->IsUPeriodic(), myBSplineSurface->UKnotSequence(), myBSplineSurface->VDegree(), myBSplineSurface->IsVPeriodic(), myBSplineSurface->VKnotSequence(), myBSplineSurface->Poles(), myBSplineSurface->Weights()); + mySurfaceCache->BuildCache(theU, theV, + myBSplineSurface->UDegree(), myBSplineSurface->IsUPeriodic(), myBSplineSurface->UKnotSequence(), + myBSplineSurface->VDegree(), myBSplineSurface->IsVPeriodic(), myBSplineSurface->VKnotSequence(), + myBSplineSurface->Poles(), myBSplineSurface->Weights()); } } @@ -723,14 +717,9 @@ void GeomAdaptor_Surface::D0(const Standard_Real U, { case GeomAbs_BezierSurface: case GeomAbs_BSplineSurface: - if (!mySurfaceCache.IsNull()) - { - if (!mySurfaceCache->IsCacheValid(U, V)) - RebuildCache(U, V); - mySurfaceCache->D0(U, V, P); - } - else - mySurface->D0(U, V, P); + if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) + RebuildCache(U, V); + mySurfaceCache->D0(U, V, P); break; case GeomAbs_OffsetSurface: @@ -772,14 +761,12 @@ void GeomAdaptor_Surface::D1(const Standard_Real U, (USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) myBSplineSurface->LocalD1(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V); - else if (!mySurfaceCache.IsNull()) + else { - if (!mySurfaceCache->IsCacheValid(U, V)) + if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) RebuildCache(U, V); mySurfaceCache->D1(U, V, P, D1U, D1V); } - else - mySurface->D1(u, v, P, D1U, D1V); break; } @@ -824,14 +811,12 @@ void GeomAdaptor_Surface::D2(const Standard_Real U, (USide != 0 || VSide != 0) && IfUVBound(u, v, Ideb, Ifin, IVdeb, IVfin, USide, VSide)) myBSplineSurface->LocalD2(u, v, Ideb, Ifin, IVdeb, IVfin, P, D1U, D1V, D2U, D2V, D2UV); - else if (!mySurfaceCache.IsNull()) + else { - if (!mySurfaceCache->IsCacheValid(U, V)) + if (mySurfaceCache.IsNull() || !mySurfaceCache->IsCacheValid(U, V)) RebuildCache(U, V); mySurfaceCache->D2(U, V, P, D1U, D1V, D2U, D2V, D2UV); } - else - mySurface->D2(u, v, P, D1U, D1V, D2U, D2V, D2UV); break; } diff --git a/src/GeomAdaptor/GeomAdaptor_Surface.hxx b/src/GeomAdaptor/GeomAdaptor_Surface.hxx index bef6e8a392..2f0d4838c3 100644 --- a/src/GeomAdaptor/GeomAdaptor_Surface.hxx +++ b/src/GeomAdaptor/GeomAdaptor_Surface.hxx @@ -272,7 +272,7 @@ private: Standard_Real myTolV; Handle(Geom_BSplineSurface) myBSplineSurface; ///< B-spline representation to prevent downcasts - Handle(BSplSLib_Cache) mySurfaceCache; ///< Cached data for B-spline or Bezier surface + mutable Handle(BSplSLib_Cache) mySurfaceCache; ///< Cached data for B-spline or Bezier surface protected: GeomAbs_SurfaceType mySurfaceType; diff --git a/src/MeshTest/FILES b/src/MeshTest/FILES index 2dbafbe0b1..5ae491e3f3 100755 --- a/src/MeshTest/FILES +++ b/src/MeshTest/FILES @@ -5,3 +5,4 @@ MeshTest_CheckTopology.hxx MeshTest_DrawableMesh.cxx MeshTest_DrawableMesh.hxx MeshTest_PluginCommands.cxx +MeshTest_Debug.cxx diff --git a/src/MeshTest/MeshTest_Debug.cxx b/src/MeshTest/MeshTest_Debug.cxx new file mode 100644 index 0000000000..d801433f8c --- /dev/null +++ b/src/MeshTest/MeshTest_Debug.cxx @@ -0,0 +1,109 @@ +// Created on: 2016-05-31 +// Created by: Mikhail Sazonov +// Copyright (c) 2016 OPEN CASCADE SAS +// +// This file is part of Open CASCADE Technology software library. +// +// This library is free software; you can redistribute it and/or modify it under +// the terms of the GNU Lesser General Public License version 2.1 as published +// by the Free Software Foundation, with special exception defined in the file +// OCCT_LGPL_EXCEPTION.txt. Consult the file LICENSE_LGPL_21.txt included in OCCT +// distribution for complete text of the license and disclaimer of any warranty. +// +// Alternatively, this file may be used under the terms of Open CASCADE +// commercial license or contractual agreement. + +#include +#include +#include +#include +#include +#include +#include + +// This file defines global functions not declared in any public header, +// intended for use from debugger prompt (Command Window in Visual Studio) + +//======================================================================= +//function : MeshTest_DrawLinks +//purpose : Draw links from mesh data structure of type BRepMesh_FaceAttribute +//======================================================================= +Standard_EXPORT const char* MeshTest_DrawLinks(const char* theNameStr, void* theFaceAttr) +{ + if (theNameStr == 0 || theFaceAttr == 0) + { + return "Error: name or face attribute is null"; + } + try { + const Handle(BRepMesh_FaceAttribute)& aFaceAttr = *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr; + const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure(); + if (aMeshData.IsNull()) + return "Null mesh data structure"; + Standard_Integer nbLinks = aMeshData->NbLinks(); + cout << "nblink=" << nbLinks << endl; + TCollection_AsciiString aName(theNameStr); + for (Standard_Integer i = 1; i <= nbLinks; i++) + { + const BRepMesh_Edge& aLink = aMeshData->GetLink(i); + if (aLink.Movability() == BRepMesh_Deleted) + continue; + Standard_Integer n1 = aLink.FirstNode(); + Standard_Integer n2 = aLink.LastNode(); + const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n1); + const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n2); + const gp_Pnt& aP1 = aFaceAttr->GetPoint(aV1); + const gp_Pnt& aP2 = aFaceAttr->GetPoint(aV2); + Handle(Draw_Segment3D) aSeg = new Draw_Segment3D(aP1, aP2, Draw_bleu); + Draw::Set((aName + "_" + i).ToCString(), aSeg); + } + return theNameStr; + } + catch (Standard_Failure) + { + return Standard_Failure::Caught()->GetMessageString(); + } +} + +//======================================================================= +//function : MeshTest_DrawTriangles +//purpose : Draw triangles from mesh data structure of type BRepMesh_FaceAttribute +//======================================================================= +Standard_EXPORT const char* MeshTest_DrawTriangles(const char* theNameStr, void* theFaceAttr) +{ + if (theNameStr == 0 || theFaceAttr == 0) + { + return "Error: name or face attribute is null"; + } + try { + const Handle(BRepMesh_FaceAttribute)& aFaceAttr = + *(Handle(BRepMesh_FaceAttribute)*)theFaceAttr; + const Handle(BRepMesh_DataStructureOfDelaun)& aMeshData = aFaceAttr->ChangeStructure(); + if (aMeshData.IsNull()) + return "Null mesh data structure"; + Standard_Integer nbElem = aMeshData->NbElements(); + cout << "nbelem=" << nbElem << endl; + TCollection_AsciiString aName(theNameStr); + for (Standard_Integer i = 1; i <= nbElem; i++) + { + const BRepMesh_Triangle& aTri = aMeshData->GetElement(i); + if (aTri.Movability() == BRepMesh_Deleted) + continue; + Standard_Integer n[3]; + aMeshData->ElementNodes(aTri, n); + const BRepMesh_Vertex& aV1 = aMeshData->GetNode(n[0]); + const BRepMesh_Vertex& aV2 = aMeshData->GetNode(n[1]); + const BRepMesh_Vertex& aV3 = aMeshData->GetNode(n[2]); + gp_Pnt aP[4] = { aFaceAttr->GetPoint(aV1), aFaceAttr->GetPoint(aV2), + aFaceAttr->GetPoint(aV3), aFaceAttr->GetPoint(aV1) }; + TColgp_Array1OfPnt aPnts(aP[0], 1, 4); + Handle(Poly_Polygon3D) aPoly = new Poly_Polygon3D(aPnts); + Handle(DrawTrSurf_Polygon3D) aDPoly = new DrawTrSurf_Polygon3D(aPoly); + Draw::Set((aName + "_" + i).ToCString(), aDPoly); + } + return theNameStr; + } + catch (Standard_Failure) + { + return Standard_Failure::Caught()->GetMessageString(); + } +} diff --git a/tests/blend/simple/G6 b/tests/blend/simple/G6 index 26e50ded7a..1257265661 100644 --- a/tests/blend/simple/G6 +++ b/tests/blend/simple/G6 @@ -1,5 +1,3 @@ -puts "TODO OCC26932 Linux: Faulty shapes in variables faulty_1 to faulty" - beziercurve w1 5 0 0 0 20 0 0 20 5 0 25 10 0 10 20 0 mkedge w1 w1 polyline w2 10 20 0 0 0 0 diff --git a/tests/bugs/iges/bug306 b/tests/bugs/iges/bug306 index 83a670511c..30ca1814f4 100755 --- a/tests/bugs/iges/bug306 +++ b/tests/bugs/iges/bug306 @@ -20,7 +20,7 @@ vsetdispmode result 1 vdisplay result vfit -checktrinfo result -tri 9243 -nod 7586 +checktrinfo result -tri 9250 -nod 7593 checkmaxtol result -ref 0.92213088179312575 checknbshapes result -shell 1 diff --git a/tests/bugs/mesh/bug23631 b/tests/bugs/mesh/bug23631 index edd2750129..84563aaf85 100644 --- a/tests/bugs/mesh/bug23631 +++ b/tests/bugs/mesh/bug23631 @@ -13,7 +13,7 @@ restore [locate_data_file OCC396_f2903.brep] result incmesh result 0.01 triangles result -checktrinfo result -tri 39 -nod 41 +checktrinfo result -tri 79 -nod 81 vinit vdisplay result diff --git a/tests/bugs/mesh/bug25378_1_1 b/tests/bugs/mesh/bug25378_1_1 index 3ab8cef57c..6036829a96 100755 --- a/tests/bugs/mesh/bug25378_1_1 +++ b/tests/bugs/mesh/bug25378_1_1 @@ -30,7 +30,8 @@ if { [regexp {Debug mode} [dversion]] } { } } -if {${max_t_1} > ${t_1}} { - puts "Error. Time of building of triangulation, ${t_1} seconds, is less than expected minimum time - ${max_t_1} seconds" -} +# this test case is redundant, as we must not set lower limit for computation time +#if {${max_t_1} > ${t_1}} { +# puts "Error. Time of building of triangulation, ${t_1} seconds, is less than expected minimum time - ${max_t_1} seconds" +#} diff --git a/tests/bugs/mesh/bug25378_1_2 b/tests/bugs/mesh/bug25378_1_2 index a29de1caad..696e3a7f4b 100755 --- a/tests/bugs/mesh/bug25378_1_2 +++ b/tests/bugs/mesh/bug25378_1_2 @@ -26,6 +26,7 @@ if { [regexp {Debug mode} [dversion]] } { set max_t_01 1 } -if {${max_t_01} > ${t_01}} { - puts "Error. Time of building of triangulation, ${t_01} seconds, is less than expected minimum time - ${max_t_01} seconds" -} +# this test case is redundant, as we must not set lower limit for computation time +#if {${max_t_01} > ${t_01}} { +# puts "Error. Time of building of triangulation, ${t_01} seconds, is less than expected minimum time - ${max_t_01} seconds" +#} diff --git a/tests/bugs/mesh/bug25378_1_3 b/tests/bugs/mesh/bug25378_1_3 index a216c15494..fb834de728 100755 --- a/tests/bugs/mesh/bug25378_1_3 +++ b/tests/bugs/mesh/bug25378_1_3 @@ -31,6 +31,7 @@ if { [regexp {Debug mode} [dversion]] } { } } -if {${max_t_001} > ${t_001}} { - puts "Error. Time of building of triangulation, ${t_001} seconds, is less than expected minimum time - ${max_t_001} seconds" -} \ No newline at end of file +# this test case is redundant, as we must not set lower limit for computation time +#if {${max_t_001} > ${t_001}} { +# puts "Error. Time of building of triangulation, ${t_001} seconds, is less than expected minimum time - ${max_t_001} seconds" +#} \ No newline at end of file diff --git a/tests/bugs/mesh/bug25378_3_3 b/tests/bugs/mesh/bug25378_3_3 index 274598f445..45489a7f7c 100644 --- a/tests/bugs/mesh/bug25378_3_3 +++ b/tests/bugs/mesh/bug25378_3_3 @@ -18,7 +18,7 @@ if { [regexp {Debug mode} [dversion]] } { set max_t_001 50 } else { if { [regexp {Windows} [dversion]] } { - set max_t_001 20 + set max_t_001 30 } else { set max_t_001 55 } diff --git a/tests/bugs/mesh/bug25519 b/tests/bugs/mesh/bug25519 index 48d0d7c793..2501ae389f 100755 --- a/tests/bugs/mesh/bug25519 +++ b/tests/bugs/mesh/bug25519 @@ -15,5 +15,5 @@ fit isos a 0 triangles a -checktrinfo a -tri 1874 -nod 983 -defl 0.26446929234386068 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05 +checktrinfo a -tri 3347 -nod 1780 -defl 0.08541878790375132 -tol_rel_defl 0.05 -tol_rel_tri 0.05 -tol_rel_nod 0.05 checkview -screenshot -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/mesh/bug25612 b/tests/bugs/mesh/bug25612 index 3cee3d0aef..db0cc9ba0c 100644 --- a/tests/bugs/mesh/bug25612 +++ b/tests/bugs/mesh/bug25612 @@ -9,13 +9,13 @@ puts "" restore [locate_data_file bug25519_testtriangulation.brep] a tclean a -incmesh a 0.001 +incmesh a 0.01 -a 50 set bug_info [trinfo a] set TNumber_1 [lindex $bug_info 3] set NNumber_1 [lindex $bug_info 5] tclean a -incmesh a 0.001 -surf_def_off +incmesh a 0.01 -a 50 -surf_def_off set bug_info [trinfo a] set TNumber_2 [lindex $bug_info 3] set NNumber_2 [lindex $bug_info 5] diff --git a/tests/bugs/modalg_2/bug264_0 b/tests/bugs/modalg_2/bug264_0 index 8346596003..40abec633d 100755 --- a/tests/bugs/modalg_2/bug264_0 +++ b/tests/bugs/modalg_2/bug264_0 @@ -15,6 +15,6 @@ vclear isos result 0 triangles result -checktrinfo result -tri 8 -nod 10 +checktrinfo result -tri 11 -nod 13 checkprops result -s 1.3135 checkview -display result -3d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_2/bug287 b/tests/bugs/modalg_2/bug287 index 143941e983..62ddd97749 100755 --- a/tests/bugs/modalg_2/bug287 +++ b/tests/bugs/modalg_2/bug287 @@ -14,7 +14,7 @@ isos result 0 incmesh result .1 triangles result -checktrinfo result -tri !604 -nod !363 +checktrinfo result -tri !1315 -nod !784 checkprops result -s 0 checkshape result checkview -display result -3d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/modalg_2/bug292 b/tests/bugs/modalg_2/bug292 index f4b2c78c00..d57ecb3691 100755 --- a/tests/bugs/modalg_2/bug292 +++ b/tests/bugs/modalg_2/bug292 @@ -19,6 +19,6 @@ vsetdispmode result 1 isos result 0 triangles result -checktrinfo result -tri 8 -nod 10 +checktrinfo result -tri 11 -nod 13 checkprops result -s 1.3135 checkview -display result -3d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_1/bug22759 b/tests/bugs/moddata_1/bug22759 index 5e1dbf075e..ee0042c42d 100755 --- a/tests/bugs/moddata_1/bug22759 +++ b/tests/bugs/moddata_1/bug22759 @@ -22,7 +22,7 @@ tclean result set Deflection 0.001 incmesh result ${Deflection} -checktrinfo result -tri 311280 -nod 159373 -defl 0.0092442421472206764 -tol_rel_defl 0.001 -tol_rel_tri 0.001 -tol_rel_nod 0.001 +checktrinfo result -tri 394128 -nod 201035 -defl 0.0092442421472207319 -tol_rel_defl 0.001 -tol_rel_tri 0.001 -tol_rel_nod 0.001 vinit vdisplay result diff --git a/tests/bugs/moddata_2/bug453_3 b/tests/bugs/moddata_2/bug453_3 index 9445f94b93..b0b20a9b4c 100755 --- a/tests/bugs/moddata_2/bug453_3 +++ b/tests/bugs/moddata_2/bug453_3 @@ -1,7 +1,7 @@ puts "TODO OCC24156 MacOS: Tcl Exception: tolerance ang" puts "TODO OCC24156 MacOS: TEST INCOMPLETE" puts "TODO OCC27203 ALL: Error: Max tolerance" -puts "TODO OCC27203 Linux: Error : The area of result shape is" +puts "TODO OCC27203 All: Error : The area of result shape is" puts "========" puts "OCC453" @@ -38,11 +38,12 @@ if { $z2 > 85 } { puts "Elapsed time is less then 85 seconds - OK" } +# Note: The reference values of area and tolerance are wanted theoretical values # Properties check -checkprops result -s 5.48216e+006 +checkprops result -s 3.51e+006 # Tolerance check -checkmaxtol result -ref 1628.2217761833963 +checkmaxtol result -ref 1. # Visual check checkview -display result -2d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_2/fra62476_2 b/tests/bugs/moddata_2/fra62476_2 index 7e4f0fc089..fb3f593257 100755 --- a/tests/bugs/moddata_2/fra62476_2 +++ b/tests/bugs/moddata_2/fra62476_2 @@ -13,5 +13,5 @@ tclean result incmesh result .1 triangles result -checktrinfo result -tri 559 -nod 329 +checktrinfo result -tri 424 -nod 266 checkview -display result -3d -path ${imagedir}/${test_image}.png diff --git a/tests/bugs/moddata_3/bug25737_1 b/tests/bugs/moddata_3/bug25737_1 index 9b4834836a..4681550bb1 100755 --- a/tests/bugs/moddata_3/bug25737_1 +++ b/tests/bugs/moddata_3/bug25737_1 @@ -24,7 +24,7 @@ if {$report != ""} { # Checking triangulation area (triarea command)... set max_rel_tol_diff 1 -set rel_tol 0.42 +set rel_tol 0.56 set area_eps 0 smallview diff --git a/tests/bugs/vis/bug288_5 b/tests/bugs/vis/bug288_5 index 8e6961a46f..7612d607a9 100755 --- a/tests/bugs/vis/bug288_5 +++ b/tests/bugs/vis/bug288_5 @@ -13,5 +13,5 @@ isos result 0 triangles result vfit -checktrinfo result -tri 7984 -nod 8350 +checktrinfo result -tri 8000 -nod 8358 checkview -screenshot -3d -path ${imagedir}/${test_image}.png diff --git a/tests/mesh/data/advanced/A7 b/tests/mesh/data/advanced/A7 index 45b1b6a0ca..0f5b4b5b5f 100755 --- a/tests/mesh/data/advanced/A7 +++ b/tests/mesh/data/advanced/A7 @@ -1,7 +1,8 @@ set TheFileName bug22025_s.brep -set bug_area "OCC22687" set rel_tol 1.3 +set max_rel_tol_diff 0.1 if { [string compare $command "shading"] == 0 } { + set bug_area "OCC22687" set bug_withouttri "OCC22687" set nbwithouttri(ALL) 74 } diff --git a/tests/mesh/data/standard/C7 b/tests/mesh/data/standard/C7 index a7ae54ceae..1e1cbc02d7 100755 --- a/tests/mesh/data/standard/C7 +++ b/tests/mesh/data/standard/C7 @@ -3,18 +3,7 @@ set bug_freenodes "OCC22687" if { [string compare $command "shading"] == 0 } { set nbfreenodes(All) 3 } else { - set bug_withouttri "OCC27226" set bug_freelinks "OCC23105" - ###set nbfree(ALL) 4 - if { [string compare $command "mesh"] == 0 } { -### set nbfree(ALL) 8 ### OCC23106 - set nbfree(ALL) 2 - set nbwithouttri(All) 1 - set nbfreenodes(All) 37 - } else { - set nbfree(ALL) 2 - set nbwithouttri(All) 1 - set nbfreenodes(All) 37 - } - ###set nbfreenodes(All) 37 + set nbfree(ALL) 2 + set nbfreenodes(All) 4 } diff --git a/tests/mesh/data/standard/J8 b/tests/mesh/data/standard/J8 index 92f29bcc48..c3b441454a 100755 --- a/tests/mesh/data/standard/J8 +++ b/tests/mesh/data/standard/J8 @@ -1,5 +1,6 @@ set TheFileName shading_089.brep if { [string compare $command "shading"] != 0 } { - set bug_area "OCC22687" - set rel_tol 1.42 + #set bug_area "OCC22687" + set max_rel_tol_diff 1 + set rel_tol 4 } diff --git a/tests/mesh/data/standard/L2 b/tests/mesh/data/standard/L2 index 46e62ea3f3..0595a0f37b 100755 --- a/tests/mesh/data/standard/L2 +++ b/tests/mesh/data/standard/L2 @@ -1 +1,5 @@ set TheFileName shading_101.brep +if { [string compare $command "shading"] != 0 } { + set max_rel_tol_diff 0.1 + set rel_tol 0.5 +} diff --git a/tests/mesh/data/standard/L6 b/tests/mesh/data/standard/L6 index d7b4b791b9..46e6826434 100755 --- a/tests/mesh/data/standard/L6 +++ b/tests/mesh/data/standard/L6 @@ -4,5 +4,5 @@ set max_rel_tol_diff 1 if { [string compare $command "shading"] == 0 } { set rel_tol 2.64 } else { - set rel_tol 2.55 + set rel_tol 2.59 } diff --git a/tests/mesh/data/standard/U7 b/tests/mesh/data/standard/U7 index 00637a9fd6..dda24459c3 100755 --- a/tests/mesh/data/standard/U7 +++ b/tests/mesh/data/standard/U7 @@ -18,7 +18,7 @@ if { [string compare $command "shading"] == 0 } { ##set nbt 14 set nbt 8 set nbn 60 - set nbl 12 + set nbl 11 set nbwithouttri([checkplatform]) $nbt set nbfree([checkplatform]) $nbl set nbfreenodes([checkplatform]) $nbn diff --git a/tests/mesh/data/standard/V4 b/tests/mesh/data/standard/V4 index d89a624ef4..3042513f7a 100755 --- a/tests/mesh/data/standard/V4 +++ b/tests/mesh/data/standard/V4 @@ -2,6 +2,6 @@ set TheFileName shading_wrongshape_015.brep set bug_withouttri "OCC22687" if { [string compare $command "shading"] != 0 } { set bug_freenodes "OCC23105" -# set nbfreenodes(ALL) 4 + set nbfreenodes(ALL) 3 } set nbwithouttri(All) 7 diff --git a/tests/mesh/data/standard/W4 b/tests/mesh/data/standard/W4 index 3ba08c8363..9d3de035de 100755 --- a/tests/mesh/data/standard/W4 +++ b/tests/mesh/data/standard/W4 @@ -2,12 +2,10 @@ set TheFileName shading_wrongshape_024.brep set bug_cross "OCC22687" set nbcross(All) 1 - +set bug_area "OCC22687" set bug_freenodes "OCC22687" - set bug_withouttri "OCC22687" if { [string compare $command "shading"] == 0 } { - set bug_area "OCC22687" set rel_tol 1.2 set nbwithouttri(ALL) 6 set nbfreenodes(ALL) 1 diff --git a/tests/mesh/data/standard/X3 b/tests/mesh/data/standard/X3 index 60426d2e87..11372ae97e 100644 --- a/tests/mesh/data/standard/X3 +++ b/tests/mesh/data/standard/X3 @@ -8,7 +8,7 @@ set bug_area "OCC358" set max_rel_tol_diff 1 puts $command if { [string compare $command "shading"] == 0 } { - set rel_tol 2.07 + set rel_tol 0.43 } else { set rel_tol 0.676 } \ No newline at end of file -- 2.20.1