From 98eb4489d75c34441348940c83c081db040ad7ff Mon Sep 17 00:00:00 2001 From: kgv Date: Sun, 19 May 2019 15:57:54 +0300 Subject: [PATCH] 0030680: VIS - IVtkOCC_ShapeMesher displays Isoline wrong IVtkOCC_ShapeMesher now calls StdPrs_Isolines tool instead of code copy-paste. --- src/IVtkOCC/IVtkOCC_ShapeMesher.cxx | 503 ++-------------------------- src/IVtkOCC/IVtkOCC_ShapeMesher.hxx | 17 - 2 files changed, 24 insertions(+), 496 deletions(-) diff --git a/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx b/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx index 1388bcbc18..643f427ec9 100644 --- a/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx +++ b/src/IVtkOCC/IVtkOCC_ShapeMesher.cxx @@ -37,7 +37,9 @@ #include #include #include +#include #include +#include #include #include #include @@ -386,411 +388,6 @@ void IVtkOCC_ShapeMesher::addEdge (const TopoDS_Edge& theEdge, } } - -//================================================================ -// Function : FindLimits -// Purpose : Static internal function, finds parametrical limits of the curve. -//! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry -//! @param [in] theLimit maximum allowed absolute parameter value -//! @param [out] theFirst minimum parameter value for the curve -//! @param [out] theLast maximum parameter value for the curve -//================================================================ -static void FindLimits (const Adaptor3d_Curve& theCurve, - const Standard_Real& theLimit, - Standard_Real& theFirst, - Standard_Real& theLast) -{ - theFirst = Max(theCurve.FirstParameter(), theFirst); - theLast = Min(theCurve.LastParameter(), theLast); - Standard_Boolean isFirstInf = Precision::IsNegativeInfinite (theFirst); - Standard_Boolean isLastInf = Precision::IsPositiveInfinite (theLast); - - if (isFirstInf || isLastInf) - { - gp_Pnt aP1, aP2; - Standard_Real aDelta = 1; - if (isFirstInf && isLastInf) - { - do - { - aDelta *= 2; - theFirst = - aDelta; - theLast = aDelta; - theCurve.D0 (theFirst, aP1); - theCurve.D0 (theLast, aP2); - } while (aP1.Distance (aP2) < theLimit); - } - else if (isFirstInf) - { - theCurve.D0 (theLast, aP2); - do { - aDelta *= 2; - theFirst = theLast - aDelta; - theCurve.D0 (theFirst, aP1); - } while (aP1.Distance(aP2) < theLimit); - } - else if (isLastInf) - { - theCurve.D0 (theFirst, aP1); - do - { - aDelta *= 2; - theLast = theFirst + aDelta; - theCurve.D0 (theLast, aP2); - } while (aP1.Distance (aP2) < theLimit); - } - } -} - -//================================================================ -// Function : FindLimits -// Purpose :Static helper function, builds a discrete representation -//! (sequence of points) for the given curve. -//! -//! @param [in] theCurve 3D curve adaptor used to retrieve the curve geometry -//! @param [in] theDeflection absolute deflection value -//! @param [in] theAngle deviation angle value -//! @param [in] theU1 minimal curve parameter value -//! @param [in] theU2 maximal curve parameter value -//! @param [out] thePoints the container for generated polyline -//================================================================ -static void DrawCurve (Adaptor3d_Curve& theCurve, - const Standard_Real theDeflection, - const Standard_Real theAngle, - const Standard_Real theU1, - const Standard_Real theU2, - IVtk_Polyline& thePoints) -{ - switch (theCurve.GetType()) - { - case GeomAbs_Line: - { - gp_Pnt aPnt = theCurve.Value(theU1); - thePoints.Append (aPnt); - - aPnt = theCurve.Value(0.5 * (theU1 + theU2)); - thePoints.Append (aPnt); - - aPnt = theCurve.Value (theU2); - thePoints.Append(aPnt); - } - break; - default: - { - Standard_Integer aNbInter = theCurve.NbIntervals(GeomAbs_C1); - Standard_Integer anI, aJ; - TColStd_Array1OfReal aParams(1, aNbInter+1); - theCurve.Intervals(aParams, GeomAbs_C1); - Standard_Real anU1, anU2; - Standard_Integer NumberOfPoints; - - for (aJ = 1; aJ <= aNbInter; aJ++) - { - anU1 = aParams (aJ); anU2 = aParams (aJ + 1); - if (anU2 > anU1 && anU1 < anU2) - { - anU1 = Max(anU1, anU1); - anU2 = Min(anU2, anU2); - - GCPnts_TangentialDeflection anAlgo (theCurve, anU1, anU2, theAngle, theDeflection); - NumberOfPoints = anAlgo.NbPoints(); - - if (NumberOfPoints > 0) - { - for (anI = 1; anI < NumberOfPoints; anI++) - { - thePoints.Append(anAlgo.Value (anI)); - } - if (aJ == aNbInter) - { - thePoints.Append (anAlgo.Value (NumberOfPoints)); - } - } - } - } - } - } -} - -//================================================================ -// Function : buildIsoLines -// Purpose : -//================================================================ -void IVtkOCC_ShapeMesher::buildIsoLines (const Handle(BRepAdaptor_HSurface)& theFace, - const Standard_Boolean theIsDrawUIso, - const Standard_Boolean theIsDrawVIso, - const Standard_Integer theNBUiso, - const Standard_Integer theNBViso, - IVtk_PolylineList& thePolylines) -{ - Standard_Real anUF, anUL, aVF, aVL; - anUF = theFace->FirstUParameter(); - anUL = theFace->LastUParameter(); - aVF = theFace->FirstVParameter(); - aVL = theFace->LastVParameter(); - - // Restrict maximal parameter value - // in OCCT it's 5e+5 by default - const Standard_Real aLimit = 5e+5; - - // compute bounds of the restriction - Standard_Real anUMin, anUMax, aVMin, aVMax; - Standard_Integer anI; - - anUMin = Max (anUF, -aLimit); - anUMax = Min (anUL, aLimit); - aVMin = Max (aVF, -aLimit); - aVMax = Min (aVL, aLimit); - - // update min max for the hatcher. - gp_Pnt2d aP1,aP2; - gp_Pnt aDummyPnt; - - Standard_Real aDdefle = Max (anUMax - anUMin, aVMax - aVMin) * GetDeviationCoeff(); - TColgp_SequenceOfPnt2d aTabPoints; - - anUMin = aVMin = 1.e100; - anUMax = aVMax = -1.e100; - - // Process the edges - TopExp_Explorer aToolRst; - TopoDS_Face aTopoFace (((BRepAdaptor_Surface*)&(theFace->Surface()))->Face()); - for (aToolRst.Init (aTopoFace, TopAbs_EDGE); aToolRst.More(); aToolRst.Next()) - { - TopAbs_Orientation anOrient = aToolRst.Current().Orientation(); - // Skip INTERNAL and EXTERNAL edges - if (anOrient == TopAbs_FORWARD || anOrient == TopAbs_REVERSED) - { - Standard_Real anU1, anU2; - const Handle(Geom2d_Curve)& aCurve = - BRep_Tool::CurveOnSurface (TopoDS::Edge (aToolRst.Current()), - aTopoFace, - anU1, anU2); - if (aCurve.IsNull()) - { - continue; - } - - Geom2dAdaptor_Curve aRCurve; - aRCurve.Load (aCurve, anU1, anU2); - if (aRCurve.GetType() != GeomAbs_Line) - { - GCPnts_QuasiUniformDeflection aUDP(aRCurve, aDdefle); - if (aUDP.IsDone()) - { - Standard_Integer NumberOfPoints = aUDP.NbPoints(); - if ( NumberOfPoints >= 2 ) - { - aDummyPnt = aUDP.Value (1); - aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y()); - anUMin = Min (aP2.X(), anUMin); - anUMax = Max (aP2.X(), anUMax); - aVMin = Min (aP2.Y(), aVMin); - aVMax = Max (aP2.Y(), aVMax); - for (anI = 2; anI <= NumberOfPoints; anI++) - { - aP1 = aP2; - aDummyPnt = aUDP.Value (anI); - aP2.SetCoord (aDummyPnt.X(), aDummyPnt.Y()); - anUMin = Min(aP2.X(), anUMin); - anUMax = Max(aP2.X(), anUMax); - aVMin = Min(aP2.Y(), aVMin); - aVMax = Max(aP2.Y(), aVMax); - - if(anOrient == TopAbs_FORWARD ) - { - //isobuild.Trim(P1,P2); - aTabPoints.Append (aP1); - aTabPoints.Append (aP2); - } - else - { - //isobuild.Trim(P2,P1); - aTabPoints.Append (aP2); - aTabPoints.Append (aP1); - } - } - } - } - else - { - cout << "Cannot evaluate curve on surface"<IsUClosed(); - Standard_Boolean isVClosed = theFace->IsVClosed(); - - if (!isUClosed) - { - anUMin = anUMin + (anUMax - anUMin) / 1000.0; - anUMax = anUMax - (anUMax - anUMin) /1000.0; - } - - if (!isVClosed) - { - aVMin = aVMin + (aVMax - aVMin) /1000.0; - aVMax = aVMax - (aVMax - aVMin) /1000.0; - } - - if (theIsDrawUIso) - { - if (theNBUiso > 0) - { - isUClosed = Standard_False; - Standard_Real aDu= isUClosed ? (anUMax - anUMin) / theNBUiso : (anUMax - anUMin) / (1 + theNBUiso); - for (anI = 1; anI <= theNBUiso; anI++) - { - anIsoBuild.AddXLine (anUMin + aDu*anI); - } - } - } - if (theIsDrawVIso) - { - if (theNBViso > 0) - { - isVClosed = Standard_False; - Standard_Real aDv= isVClosed ? (aVMax - aVMin) / theNBViso : (aVMax - aVMin) / (1 + theNBViso); - for (anI = 1; anI <= theNBViso; anI++) - { - anIsoBuild.AddYLine (aVMin + aDv*anI); - } - } - } - - Standard_Integer aLength = aTabPoints.Length(); - for (anI = 1; anI <= aLength; anI += 2) - { - anIsoBuild.Trim (aTabPoints (anI),aTabPoints (anI + 1)); - } - - // Create the polylines for isos - Adaptor3d_IsoCurve anIso; - anIso.Load(theFace); - Handle(Geom_Curve) aBCurve; - const BRepAdaptor_Surface& aBSurf = *(BRepAdaptor_Surface*)&(theFace->Surface()); - GeomAbs_SurfaceType aType = theFace->GetType(); - - Standard_Integer aNumberOfLines = anIsoBuild.NbLines(); - Handle(Geom_Surface) aGeomSurf; - if (aType == GeomAbs_BezierSurface) - { - aGeomSurf = aBSurf.Bezier(); - } - else if (aType == GeomAbs_BSplineSurface) - { - aGeomSurf = aBSurf.BSpline(); - } - - Standard_Real aDeflection = GetDeflection(); - Standard_Real anAngle = GetDeviationAngle(); - for (anI = 1; anI <= aNumberOfLines; anI++) - { - Standard_Integer aNumberOfIntervals = anIsoBuild.NbIntervals(anI); - Standard_Real aCoord = anIsoBuild.Coordinate(anI); - for (Standard_Integer aJ = 1; aJ <= aNumberOfIntervals; aJ++) - { - Standard_Real aB1 = anIsoBuild.Start (anI, aJ); - Standard_Real aB2 = anIsoBuild.End(anI, aJ); - - if (!aGeomSurf.IsNull()) - { - if (anIsoBuild.IsXLine (anI)) - { - aBCurve = aGeomSurf->UIso (aCoord); - } - else - { - aBCurve = aGeomSurf->VIso (aCoord); - } - - GeomAdaptor_Curve aGeomCurve (aBCurve); - FindLimits (aGeomCurve, aLimit, aB1, aB2); - if (aB2 - aB1 > Precision::Confusion()) - { - IVtk_Polyline aPoints; - DrawCurve (aGeomCurve, aDeflection, anAngle, aB1, aB2, aPoints); - thePolylines.Append (aPoints); - } - } - else - { - if (anIsoBuild.IsXLine (anI)) - { - anIso.Load (GeomAbs_IsoU, aCoord, aB1, aB2); - } - else - { - anIso.Load (GeomAbs_IsoV, aCoord, aB1, aB2); - } - FindLimits (anIso, aLimit, aB1, aB2); - if (aB2 - aB1>Precision::Confusion()) - { - IVtk_Polyline aPoints; - DrawCurve (anIso, aDeflection, anAngle, aB1, aB2, aPoints); - thePolylines.Append (aPoints); - } - } - } - } -} - //================================================================ // Function : addWFFace // Purpose : @@ -813,8 +410,7 @@ void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace, // - StdPrs_DeflectionCurve::Add() // Add face's edges here but with the face ID - TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE ); - for (; anEdgeIter.More(); anEdgeIter.Next()) + for (TopExp_Explorer anEdgeIter (aFaceToMesh, TopAbs_EDGE); anEdgeIter.More(); anEdgeIter.Next()) { const TopoDS_Edge& anOcctEdge = TopoDS::Edge (anEdgeIter.Current()); addEdge (anOcctEdge, theShapeId, myEdgesTypes (anOcctEdge)); @@ -827,85 +423,34 @@ void IVtkOCC_ShapeMesher::addWFFace (const TopoDS_Face& theFace, return; } - BRepAdaptor_Surface aSurf; - aSurf.Initialize (aFaceToMesh); - Handle(BRepAdaptor_HSurface) aSurfAdaptor = new BRepAdaptor_HSurface (aSurf); + const Standard_Real aDeflection = GetDeflection(); + Handle(Prs3d_Drawer) aDrawer = new Prs3d_Drawer(); + aDrawer->SetUIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0f, myNbIsos[0])); + aDrawer->SetVIsoAspect (new Prs3d_IsoAspect (Quantity_NOC_WHITE, Aspect_TOL_SOLID, 1.0f, myNbIsos[1])); + aDrawer->SetDeviationAngle (myDevAngle); + aDrawer->SetDeviationCoefficient (myDevCoeff); + aDrawer->SetMaximalChordialDeviation (aDeflection); - IVtk_PolylineList aPolylines; - gp_Trsf aDummyTrsf; - - // Building U isolines - // Introducing a local scope here to simplify variable naming + Prs3d_NListOfSequenceOfPnt aPolylines; + StdPrs_Isolines::Add (theFace, aDrawer, aDeflection, aPolylines, aPolylines); + for (Prs3d_NListOfSequenceOfPnt::Iterator aPolyIter (aPolylines); aPolyIter.More(); aPolyIter.Next()) { - buildIsoLines (aSurfAdaptor, - myNbIsos[0] != 0, - Standard_False, - myNbIsos[0], - 0, - aPolylines); - - IVtk_PolylineList::Iterator anIt (aPolylines); - for (; anIt.More(); anIt.Next()) + const Handle(TColgp_HSequenceOfPnt)& aPoints = aPolyIter.Value(); + const Standard_Integer theNbNodes = aPoints->Length(); + if (theNbNodes < 2) { - const IVtk_Polyline& aPntSeq = anIt.Value(); - Standard_Integer aNbNodes = aPntSeq.Length(); - TColgp_Array1OfPnt aPoints (1, aNbNodes); - for (Standard_Integer aJ = 1; aJ <= aNbNodes; aJ++) - { - aPoints.SetValue (aJ, aPntSeq.Value(aJ)); - } - - TColStd_Array1OfInteger aPointIds (1, aNbNodes); - for (Standard_Integer anI = 1; anI <= aNbNodes; anI++) - { - aPointIds.SetValue (anI, anI); - } - - processPolyline (aNbNodes, - aPoints, - aPointIds, - theShapeId, - true, - aDummyTrsf, - MT_IsoLine); + continue; } - } - // Building V isolines - { - aPolylines.Clear(); - buildIsoLines (aSurfAdaptor, - Standard_False, - myNbIsos[1] != 0, - 0, - myNbIsos[1], - aPolylines); - - IVtk_PolylineList::Iterator anIt (aPolylines); - for (; anIt.More(); anIt.Next()) + IVtk_PointIdList aPolyPointIds; + for (TColgp_HSequenceOfPnt::Iterator aNodeIter (*aPoints); aNodeIter.More(); aNodeIter.Next()) { - const IVtk_Polyline& aPntSeq = anIt.Value(); - Standard_Integer aNbNodes = aPntSeq.Length(); - TColgp_Array1OfPnt aPoints (1, aNbNodes); - for (int aJ = 1; aJ <= aNbNodes; aJ++) - { - aPoints.SetValue (aJ, aPntSeq.Value (aJ)); - } - - TColStd_Array1OfInteger aPointIds (1, aNbNodes); - for (Standard_Integer anI = 1; anI <= aNbNodes; anI++) - { - aPointIds.SetValue (anI, anI); - } - - processPolyline (aNbNodes, - aPoints, - aPointIds, - theShapeId, - true, - aDummyTrsf, - MT_IsoLine); + const gp_Pnt& aPnt = aNodeIter.Value(); + const IVtk_PointId anId = myShapeData->InsertCoordinate (aPnt.X(), aPnt.Y(), aPnt.Z()); + aPolyPointIds.Append (anId); } + + myShapeData->InsertLine (theShapeId, &aPolyPointIds, MT_IsoLine); } } diff --git a/src/IVtkOCC/IVtkOCC_ShapeMesher.hxx b/src/IVtkOCC/IVtkOCC_ShapeMesher.hxx index 00fe88d698..3c522f50f2 100644 --- a/src/IVtkOCC/IVtkOCC_ShapeMesher.hxx +++ b/src/IVtkOCC/IVtkOCC_ShapeMesher.hxx @@ -145,23 +145,6 @@ private: void addShadedFace (const TopoDS_Face& theFace, const IVtk_IdType theShapeId); - //! Internal function, builds polylines for boundary edges - //! and isolines of the face. It has been made a class method in order - //! to facilitate passing deflection, etc. here. - //! - //! @param [in] theFace surface adaptor for the face - //! @param [in] theIsDrawUIso if equal to Standard_True, U isolines are built - //! @param [in] theIsDrawVIso if equal to Standard_True, V isolines are built - //! @param [in] theNBUiso number of U isolines - //! @param [in] theNBViso number of V isolines - //! @param [out] thePolylines container for the generated polylines - void buildIsoLines (const Handle(BRepAdaptor_HSurface)& theFace, - const Standard_Boolean theIsDrawUIso, - const Standard_Boolean theIsDrawVIso, - const Standard_Integer theNBUiso, - const Standard_Integer theNBViso, - IVtk_PolylineList& thePolylines); - //! Internal helper method that unpacks the input arrays of points and //! connectivity and creates the polyline using IPolyData interface. //! Optionally, the transformation specified through the last argument