diff --git a/src/Aspect/Aspect_AspectLine.hxx b/src/Aspect/Aspect_AspectLine.hxx index 0e81548076..237e8a4724 100644 --- a/src/Aspect/Aspect_AspectLine.hxx +++ b/src/Aspect/Aspect_AspectLine.hxx @@ -81,7 +81,7 @@ protected: -private: +protected: Quantity_Color MyColor; diff --git a/src/Graphic3d/Graphic3d_AspectLine3d.hxx b/src/Graphic3d/Graphic3d_AspectLine3d.hxx index 197269d142..45dad22d3b 100644 --- a/src/Graphic3d/Graphic3d_AspectLine3d.hxx +++ b/src/Graphic3d/Graphic3d_AspectLine3d.hxx @@ -60,7 +60,19 @@ public: Standard_EXPORT const Handle(Graphic3d_ShaderProgram)& ShaderProgram() const; + //! Check for equality with another line aspect. + bool IsEqual (const Graphic3d_AspectLine3d& theOther) + { + if (this == &theOther) + { + return true; + } + return MyShaderProgram == theOther.MyShaderProgram + && MyType == theOther.MyType + && MyColor == theOther.MyColor + && MyWidth == theOther.MyWidth; + } DEFINE_STANDARD_RTTIEXT(Graphic3d_AspectLine3d,Aspect_AspectLine) diff --git a/src/Prs3d/Prs3d.cxx b/src/Prs3d/Prs3d.cxx index 9e6c85543f..ccd9cd5f7f 100644 --- a/src/Prs3d/Prs3d.cxx +++ b/src/Prs3d/Prs3d.cxx @@ -14,13 +14,17 @@ // Alternatively, this file may be used under the terms of Open CASCADE // commercial license or contractual agreement. +#include #include #include #include -#include +#include #include +#include +#include #include +#include //======================================================================= //function : MatchSegment @@ -78,3 +82,56 @@ Standard_Real Prs3d::GetDeflection (const TopoDS_Shape& theShape, } return aDeflection; } + +//================================================================== +// function: PrimitivesFromPolylines +// purpose: +//================================================================== +Handle(Graphic3d_ArrayOfPrimitives) Prs3d::PrimitivesFromPolylines (const Prs3d_NListOfSequenceOfPnt& thePoints) +{ + if (thePoints.IsEmpty()) + { + return Handle(Graphic3d_ArrayOfPrimitives)(); + } + + Standard_Integer aNbVertices = 0; + for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next()) + { + aNbVertices += anIt.Value()->Length(); + } + const Standard_Integer aSegmentEdgeNb = (aNbVertices - thePoints.Size()) * 2; + Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNbVertices, aSegmentEdgeNb); + for (Prs3d_NListOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next()) + { + const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); + + Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1; + aSegments->AddVertex (aPoints->First()); + for (Standard_Integer aPntIter = aPoints->Lower() + 1; aPntIter <= aPoints->Upper(); ++aPntIter) + { + aSegments->AddVertex (aPoints->Value (aPntIter)); + aSegments->AddEdge ( aSegmentEdge); + aSegments->AddEdge (++aSegmentEdge); + } + } + + return aSegments; +} + +//================================================================== +// function: AddPrimitivesGroup +// purpose: +//================================================================== +void Prs3d::AddPrimitivesGroup (const Handle(Prs3d_Presentation)& thePrs, + const Handle(Prs3d_LineAspect)& theAspect, + Prs3d_NListOfSequenceOfPnt& thePolylines) +{ + Handle(Graphic3d_ArrayOfPrimitives) aPrims = Prs3d::PrimitivesFromPolylines (thePolylines); + thePolylines.Clear(); + if (!aPrims.IsNull()) + { + Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePrs); + aGroup->SetPrimitivesAspect (theAspect->Aspect()); + aGroup->AddPrimitiveArray (aPrims); + } +} diff --git a/src/Prs3d/Prs3d.hxx b/src/Prs3d/Prs3d.hxx index dc3530503e..ec8fc7d190 100644 --- a/src/Prs3d/Prs3d.hxx +++ b/src/Prs3d/Prs3d.hxx @@ -17,34 +17,18 @@ #ifndef _Prs3d_HeaderFile #define _Prs3d_HeaderFile +#include #include #include #include - #include #include #include #include -class gp_Pnt; +#include + class TopoDS_Shape; class Prs3d_Presentation; -class Prs3d_BasicAspect; -class Prs3d_PointAspect; -class Prs3d_LineAspect; -class Prs3d_ShadingAspect; -class Prs3d_TextAspect; -class Prs3d_IsoAspect; -class Prs3d_ArrowAspect; -class Prs3d_PlaneAspect; -class Prs3d_DimensionAspect; -class Prs3d_DatumAspect; -class Prs3d_Projector; -class Prs3d_PlaneSet; -class Prs3d_Root; -class Prs3d_Text; -class Prs3d_ShapeTool; -class Prs3d_Arrow; - //! The Prs3d package provides the following services //! - a presentation object (the context for all @@ -64,7 +48,6 @@ class Prs3d public: DEFINE_STANDARD_ALLOC - //! draws an arrow at a given location, with respect //! to a given direction. @@ -84,44 +67,16 @@ public: //! between different representations of the shape and undesirable visual artifacts. Standard_EXPORT static Standard_Real GetDeflection (const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer); + //! Assembles array of primitives for sequence of polylines. + //! @param thePoints [in] the polylines sequence + //! @return array of primitives + Standard_EXPORT static Handle(Graphic3d_ArrayOfPrimitives) PrimitivesFromPolylines (const Prs3d_NListOfSequenceOfPnt& thePoints); - - -protected: - - - - - -private: - - - - -friend class Prs3d_Presentation; -friend class Prs3d_BasicAspect; -friend class Prs3d_PointAspect; -friend class Prs3d_LineAspect; -friend class Prs3d_ShadingAspect; -friend class Prs3d_TextAspect; -friend class Prs3d_IsoAspect; -friend class Prs3d_ArrowAspect; -friend class Prs3d_PlaneAspect; -friend class Prs3d_DimensionAspect; -friend class Prs3d_DatumAspect; -friend class Prs3d_Projector; -friend class Prs3d_PlaneSet; -friend class Prs3d_Root; -friend class Prs3d_Text; -friend class Prs3d_ShapeTool; -friend class Prs3d_Arrow; + //! Add primitives into new group in presentation and clear the list of polylines. + Standard_EXPORT static void AddPrimitivesGroup (const Handle(Prs3d_Presentation)& thePrs, + const Handle(Prs3d_LineAspect)& theAspect, + Prs3d_NListOfSequenceOfPnt& thePolylines); }; - - - - - - #endif // _Prs3d_HeaderFile diff --git a/src/Prs3d/Prs3d_Drawer.cxx b/src/Prs3d/Prs3d_Drawer.cxx index b3bdcc79c5..374e32d877 100644 --- a/src/Prs3d/Prs3d_Drawer.cxx +++ b/src/Prs3d/Prs3d_Drawer.cxx @@ -474,7 +474,7 @@ const Handle(Prs3d_IsoAspect)& Prs3d_Drawer::UIsoAspect() } if (myUIsoAspect.IsNull()) { - myUIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1); + myUIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 1.0, 1); } } return myUIsoAspect; @@ -506,7 +506,7 @@ const Handle(Prs3d_IsoAspect)& Prs3d_Drawer::VIsoAspect() } if (myVIsoAspect.IsNull()) { - myVIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 0.5, 1); + myVIsoAspect = new Prs3d_IsoAspect (Quantity_NOC_GRAY75, Aspect_TOL_SOLID, 1.0, 1); } } return myVIsoAspect; @@ -827,7 +827,7 @@ const Handle(Prs3d_LineAspect)& Prs3d_Drawer::HiddenLineAspect() } if (myHiddenLineAspect.IsNull()) { - myHiddenLineAspect = new Prs3d_LineAspect (Quantity_NOC_YELLOW, Aspect_TOL_DASH, 0.5); + myHiddenLineAspect = new Prs3d_LineAspect (Quantity_NOC_YELLOW, Aspect_TOL_DASH, 1.0); } } return myHiddenLineAspect; diff --git a/src/StdPrs/StdPrs_DeflectionCurve.cxx b/src/StdPrs/StdPrs_DeflectionCurve.cxx index aa60e72070..5111b19740 100644 --- a/src/StdPrs/StdPrs_DeflectionCurve.cxx +++ b/src/StdPrs/StdPrs_DeflectionCurve.cxx @@ -285,25 +285,26 @@ void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentati const Handle (Prs3d_Drawer)& aDrawer, const Standard_Boolean theToDrawCurve) { - Prs3d_Root::CurrentGroup(aPresentation)->SetPrimitivesAspect(aDrawer->LineAspect()->Aspect()); + Handle(Graphic3d_Group) aGroup; + if (theToDrawCurve) + { + aGroup = Prs3d_Root::CurrentGroup(aPresentation); + aGroup->SetPrimitivesAspect (aDrawer->LineAspect()->Aspect()); + } Standard_Real V1, V2; if (FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2)) { TColgp_SequenceOfPnt Points; - Handle(Graphic3d_Group) aGroup; - if (theToDrawCurve) - { - aGroup = Prs3d_Root::CurrentGroup (aPresentation); - } - drawCurve(aCurve, aGroup, GetDeflection(aCurve, V1, V2, aDrawer), aDrawer->DeviationAngle(), V1, V2, Points); - if (aDrawer->LineArrowDraw()) { + if (aDrawer->LineArrowDraw() + && !aGroup.IsNull()) + { gp_Pnt Location; gp_Vec Direction; aCurve.D1(V2, Location,Direction); @@ -348,7 +349,9 @@ void StdPrs_DeflectionCurve::Add (const Handle (Prs3d_Presentation)& aPresentati aDrawer->DeviationAngle(), V1 , V2, Points); - if (aDrawer->LineArrowDraw()) { + if (aDrawer->LineArrowDraw() + && !aGroup.IsNull()) + { gp_Pnt Location; gp_Vec Direction; aCurve.D1(V2, Location,Direction); diff --git a/src/StdPrs/StdPrs_Isolines.cxx b/src/StdPrs/StdPrs_Isolines.cxx index cc3211ca8e..ad2b1017d7 100644 --- a/src/StdPrs/StdPrs_Isolines.cxx +++ b/src/StdPrs/StdPrs_Isolines.cxx @@ -18,12 +18,6 @@ #include #include #include -#include -#include -#include -#include -#include -#include #include #include #include @@ -32,67 +26,57 @@ #include #include #include -#include #include -#include -#include #include #include -#include -#include #include -#include -#include -#include -#include +#include +#include #include -#include -#include #include #include #include #include -#include #include #include #include -typedef NCollection_Sequence Prs3d_NSequenceOfSequenceOfPnt; +#include namespace { const gp_Lin2d isoU (const Standard_Real theU) { return gp_Lin2d (gp_Pnt2d (theU, 0.0), gp::DY2d()); } const gp_Lin2d isoV (const Standard_Real theV) { return gp_Lin2d (gp_Pnt2d (0.0, theV), gp::DX2d()); } - //! Assembles array of primitives for sequence of polyine points. - //! @param thePoints [in] the polyline points. - //! @return array of primitives. - template - inline Handle(T) primitivesForPolyline (const Prs3d_NSequenceOfSequenceOfPnt& thePoints) - { - if (thePoints.IsEmpty()) - { - return Handle(T)(); - } + typedef NCollection_Shared< NCollection_Vector > VecOfSegments; + typedef NCollection_Sequence SeqOfVecOfSegments; - Standard_Integer aNbBounds = thePoints.Size(); - Standard_Integer aNbVertices = 0; - for (Prs3d_NSequenceOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.Next()) + //! Pack isoline segments into polylines. + static void sortSegments (const SeqOfVecOfSegments& theSegments, + Prs3d_NListOfSequenceOfPnt& thePolylines) + { + for (SeqOfVecOfSegments::Iterator aLineIter (theSegments); aLineIter.More(); aLineIter.Next()) { - aNbVertices += anIt.Value()->Length(); - } - Handle(T) aPrimitives = new T (aNbVertices, aNbBounds); - for (NCollection_Sequence::Iterator anIt (thePoints); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - aPrimitives->AddBound (aPoints->Length()); - for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI) + Handle(VecOfSegments)& anIsoSegs = aLineIter.ChangeValue(); + std::stable_sort (anIsoSegs->begin(), anIsoSegs->end()); + + Handle(TColgp_HSequenceOfPnt) aPolyline = new TColgp_HSequenceOfPnt(); + thePolylines.Append (aPolyline); + Standard_Real aLast = 0.0; + for (VecOfSegments::Iterator aSegIter (*anIsoSegs); aSegIter.More(); aSegIter.Next()) { - aPrimitives->AddVertex (aPoints->Value (anI)); + if (!aPolyline->IsEmpty() + && Abs (aSegIter.Value()[0].Param - aLast) > Precision::PConfusion()) + { + aPolyline = new TColgp_HSequenceOfPnt(); + thePolylines.Append (aPolyline); + } + + aPolyline->Append (aSegIter.Value()[0].Pnt); + aPolyline->Append (aSegIter.Value()[1].Pnt); + aLast = aSegIter.Value()[1].Param; } } - - return aPrimitives; } //! Reoder and adjust to the limit a curve's parameter values. @@ -163,6 +147,21 @@ namespace void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, const TopoDS_Face& theFace, const Handle(Prs3d_Drawer)& theDrawer) +{ + Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; + AddOnTriangulation (theFace, theDrawer, aUPolylines, aVPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UIsoAspect(), aUPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->VIsoAspect(), aVPolylines); +} + +//================================================================== +// function : AddOnTriangulation +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnTriangulation (const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines) { const Standard_Integer aNbIsoU = theDrawer->UIsoAspect()->Number(); const Standard_Integer aNbIsoV = theDrawer->VIsoAspect()->Number(); @@ -171,7 +170,7 @@ void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& theP return; } - // Evalute parameters for uv isolines. + // Evaluate parameters for uv isolines. TColStd_SequenceOfReal aUIsoParams; TColStd_SequenceOfReal aVIsoParams; UVIsoParameters (theFace, aNbIsoU, aNbIsoV, theDrawer->MaximalParameterValue(), aUIsoParams, aVIsoParams); @@ -195,13 +194,7 @@ void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& theP aSurface->Transformed ((aLocSurface / aLocTriangulation).Transformation())); } - AddOnTriangulation (thePresentation, - aTriangulation, - aSurface, - aLocTriangulation, - theDrawer, - aUIsoParams, - aVIsoParams); + addOnTriangulation (aTriangulation, aSurface, aLocTriangulation, aUIsoParams, aVIsoParams, theUPolylines, theVPolylines); } //================================================================== @@ -215,12 +208,29 @@ void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& theP const Handle(Prs3d_Drawer)& theDrawer, const TColStd_SequenceOfReal& theUIsoParams, const TColStd_SequenceOfReal& theVIsoParams) +{ + Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; + addOnTriangulation (theTriangulation, theSurface, theLocation, theUIsoParams, theVIsoParams, aUPolylines, aVPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UIsoAspect(), aUPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->VIsoAspect(), aVPolylines); +} + +//================================================================== +// function : addOnTriangulation +// purpose : +//================================================================== +void StdPrs_Isolines::addOnTriangulation (const Handle(Poly_Triangulation)& theTriangulation, + const Handle(Geom_Surface)& theSurface, + const TopLoc_Location& theLocation, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines) { const Standard_Integer aNbIsoU = theUIsoParams.Length(); const Standard_Integer aNbIsoV = theVIsoParams.Length(); - Prs3d_NSequenceOfSequenceOfPnt aUPolylines; - Prs3d_NSequenceOfSequenceOfPnt aVPolylines; + SeqOfVecOfSegments aUPolylines, aVPolylines; const Poly_Array1OfTriangle& aTriangles = theTriangulation->Triangles(); const TColgp_Array1OfPnt& aNodes = theTriangulation->Nodes(); @@ -245,66 +255,59 @@ void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& theP // Evaluate polyline points for u isolines. for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoU; ++anIsoIdx) { - gp_Pnt aSegment[2]; + SegOnIso aSegment; const gp_Lin2d anIsolineUV = isoU (theUIsoParams.Value (anIsoIdx)); // Find intersections with triangle in uv space and its projection on triangulation. - if (!findSegmentOnTriangulation (theSurface, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) + if (!findSegmentOnTriangulation (theSurface, true, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) { continue; } if (aUIsoIndexes.Value (anIsoIdx) == -1) { - aUPolylines.Append (new TColgp_HSequenceOfPnt()); + aUPolylines.Append (new VecOfSegments()); aUIsoIndexes.SetValue (anIsoIdx, aUPolylines.Size()); } - Handle(TColgp_HSequenceOfPnt) anIsoPnts = aUPolylines.ChangeValue (aUIsoIndexes.Value (anIsoIdx)); - anIsoPnts->Append (theLocation.IsIdentity() ? aSegment[0] : aSegment[0].Transformed (theLocation)); - anIsoPnts->Append (theLocation.IsIdentity() ? aSegment[1] : aSegment[1].Transformed (theLocation)); + Handle(VecOfSegments) anIsoPnts = aUPolylines.ChangeValue (aUIsoIndexes.Value (anIsoIdx)); + if (!theLocation.IsIdentity()) + { + aSegment[0].Pnt.Transform (theLocation); + aSegment[1].Pnt.Transform (theLocation); + } + anIsoPnts->Append (aSegment); } // Evaluate polyline points for v isolines. for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoV; ++anIsoIdx) { - gp_Pnt aSegment[2]; + SegOnIso aSegment; const gp_Lin2d anIsolineUV = isoV (theVIsoParams.Value (anIsoIdx)); - if (!findSegmentOnTriangulation (theSurface, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) + if (!findSegmentOnTriangulation (theSurface, false, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) { continue; } if (aVIsoIndexes.Value (anIsoIdx) == -1) { - aVPolylines.Append (new TColgp_HSequenceOfPnt()); + aVPolylines.Append (new VecOfSegments()); aVIsoIndexes.SetValue (anIsoIdx, aVPolylines.Size()); } - Handle(TColgp_HSequenceOfPnt) anIsoPnts = aVPolylines.ChangeValue (aVIsoIndexes.Value (anIsoIdx)); - anIsoPnts->Append (theLocation.IsIdentity() ? aSegment[0] : aSegment[0].Transformed (theLocation)); - anIsoPnts->Append (theLocation.IsIdentity() ? aSegment[1] : aSegment[1].Transformed (theLocation)); + Handle(VecOfSegments) anIsoPnts = aVPolylines.ChangeValue (aVIsoIndexes.Value (anIsoIdx)); + if (!theLocation.IsIdentity()) + { + aSegment[0].Pnt.Transform (theLocation); + aSegment[1].Pnt.Transform (theLocation); + } + anIsoPnts->Append (aSegment); } } - // Add primitive arrays for isoline segments. - Handle(Graphic3d_ArrayOfSegments) aUPrimitives = primitivesForPolyline (aUPolylines); - Handle(Graphic3d_ArrayOfSegments) aVPrimitives = primitivesForPolyline (aVPolylines); - - if (!aUPrimitives.IsNull()) - { - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->UIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (aUPrimitives); - } - - if (!aVPrimitives.IsNull()) - { - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->VIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (aVPrimitives); - } + sortSegments (aUPolylines, theUPolylines); + sortSegments (aVPolylines, theVPolylines); } //================================================================== @@ -315,6 +318,22 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePresent const TopoDS_Face& theFace, const Handle(Prs3d_Drawer)& theDrawer, const Standard_Real theDeflection) +{ + Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; + AddOnSurface (theFace, theDrawer, theDeflection, aUPolylines, aVPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UIsoAspect(), aUPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->VIsoAspect(), aVPolylines); +} + +//================================================================== +// function : AddOnSurface +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnSurface (const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines) { const Standard_Integer aNbIsoU = theDrawer->UIsoAspect()->Number(); const Standard_Integer aNbIsoV = theDrawer->VIsoAspect()->Number(); @@ -323,18 +342,18 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePresent return; } - // Evalute parameters for uv isolines. - TColStd_SequenceOfReal aUIsoParams; - TColStd_SequenceOfReal aVIsoParams; + // Evaluate parameters for uv isolines. + TColStd_SequenceOfReal aUIsoParams, aVIsoParams; UVIsoParameters (theFace, aNbIsoU, aNbIsoV, theDrawer->MaximalParameterValue(), aUIsoParams, aVIsoParams); BRepAdaptor_Surface aSurface (theFace); - AddOnSurface (thePresentation, - new BRepAdaptor_HSurface (aSurface), + addOnSurface (new BRepAdaptor_HSurface (aSurface), theDrawer, theDeflection, aUIsoParams, - aVIsoParams); + aVIsoParams, + theUPolylines, + theVPolylines); } //================================================================== @@ -347,6 +366,24 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePrese const Standard_Real theDeflection, const TColStd_SequenceOfReal& theUIsoParams, const TColStd_SequenceOfReal& theVIsoParams) +{ + Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; + addOnSurface (theSurface, theDrawer, theDeflection, theUIsoParams, theVIsoParams, aUPolylines, aVPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->UIsoAspect(), aUPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->VIsoAspect(), aVPolylines); +} + +//================================================================== +// function : addOnSurface +// purpose : +//================================================================== +void StdPrs_Isolines::addOnSurface (const Handle(BRepAdaptor_HSurface)& theSurface, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines) { // Choose a deflection for sampling edge uv curves. Standard_Real aUVLimit = theDrawer->MaximalParameterValue(); @@ -356,8 +393,6 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePrese Standard_Real aVmax = Min (theSurface->LastVParameter(), aUVLimit); Standard_Real aSamplerDeflection = Max (aUmax - aUmin, aVmax - aVmin) * theDrawer->DeviationCoefficient(); Standard_Real aHatchingTolerance = RealLast(); - Prs3d_NSequenceOfSequenceOfPnt aUPolylines; - Prs3d_NSequenceOfSequenceOfPnt aVPolylines; try { @@ -522,7 +557,7 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePrese : (Adaptor3d_Curve*) &aBSurfaceCurve; Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt(); - StdPrs_DeflectionCurve::Add (thePresentation, + StdPrs_DeflectionCurve::Add (Handle(Prs3d_Presentation)(), *aCurve, aSegmentP1, aSegmentP2, @@ -537,11 +572,11 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePrese if (isIsoU) { - aUPolylines.Append (aPoints); + theUPolylines.Append (aPoints); } else { - aVPolylines.Append (aPoints); + theVPolylines.Append (aPoints); } } } @@ -550,24 +585,6 @@ void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePrese { // ... } - - // Add primitive arrays for isoline segments. - Handle(Graphic3d_ArrayOfPolylines) aUPrimitives = primitivesForPolyline (aUPolylines); - Handle(Graphic3d_ArrayOfPolylines) aVPrimitives = primitivesForPolyline (aVPolylines); - - if (!aUPrimitives.IsNull()) - { - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->UIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (aUPrimitives); - } - - if (!aVPrimitives.IsNull()) - { - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->VIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (aVPrimitives); - } } //================================================================== @@ -630,10 +647,11 @@ void StdPrs_Isolines::UVIsoParameters (const TopoDS_Face& theFace, // purpose : //================================================================== Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_Surface)& theSurface, + const bool theIsU, const gp_Lin2d& theIsoline, const gp_Pnt* theNodesXYZ, const gp_Pnt2d* theNodesUV, - gp_Pnt* theSegment) + SegOnIso& theSegment) { Standard_Integer aNPoints = 0; @@ -660,15 +678,20 @@ Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_ // Isoline crosses first point of an edge. if (Abs (aDistanceUV1) < Precision::PConfusion()) { - theSegment[aNPoints++] = aNode1; + theSegment[aNPoints].Param = theIsU ? aNodeUV1.Y() : aNodeUV1.X(); + theSegment[aNPoints].Pnt = aNode1; + ++aNPoints; continue; } // Isoline crosses second point of an edge. if (Abs (aDistanceUV2) < Precision::PConfusion()) { - theSegment[aNPoints++] = aNode2; - aLinkIter++; + theSegment[aNPoints].Param = theIsU ? aNodeUV2.Y() : aNodeUV2.X(); + theSegment[aNPoints].Pnt = aNode2; + + ++aNPoints; + ++aLinkIter; continue; } @@ -681,7 +704,9 @@ Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_ // Isoline crosses degenerated link. if (aNode1.SquareDistance (aNode2) < Precision::PConfusion()) { - theSegment[aNPoints++] = aNode1; + theSegment[aNPoints].Param = theIsU ? aNodeUV1.Y() : aNodeUV1.X(); + theSegment[aNPoints].Pnt = aNode1; + ++aNPoints; continue; } @@ -692,12 +717,12 @@ Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_ Standard_Real anAlpha = Abs (aDistanceUV1) / (Abs (aDistanceUV1) + Abs (aDistanceUV2)); gp_Pnt aCross (0.0, 0.0, 0.0); - - // Is surface definition available? + Standard_Real aCrossU = aNodeUV1.X() + anAlpha * (aNodeUV2.X() - aNodeUV1.X()); + Standard_Real aCrossV = aNodeUV1.Y() + anAlpha * (aNodeUV2.Y() - aNodeUV1.Y()); + Standard_Real aCrossParam = theIsU ? aCrossV : aCrossU; if (theSurface.IsNull()) { - // Do linear interpolation of point coordinates using - // triangulation nodes. + // Do linear interpolation of point coordinates using triangulation nodes. aCross.SetX (aNode1.X() + anAlpha * (aNode2.X() - aNode1.X())); aCross.SetY (aNode1.Y() + anAlpha * (aNode2.Y() - aNode1.Y())); aCross.SetZ (aNode1.Z() + anAlpha * (aNode2.Z() - aNode1.Z())); @@ -705,9 +730,6 @@ Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_ else { // Do linear interpolation of point coordinates by triangulation nodes. - Standard_Real aCrossU = aNodeUV1.X() + anAlpha * (aNodeUV2.X() - aNodeUV1.X()); - Standard_Real aCrossV = aNodeUV1.Y() + anAlpha * (aNodeUV2.Y() - aNodeUV1.Y()); - // Get 3d point on surface. Handle(Geom_Curve) anIso1, anIso2, anIso3; Standard_Real aPntOnNode1Iso = 0.0; @@ -740,15 +762,29 @@ Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_ Standard_Real aLength2 = GCPnts_AbscissaPoint::Length (aCurveAdaptor2, aPntOnNode2Iso, aPntOnNode3Iso, 1e-2); if (Abs (aLength1) < Precision::Confusion() || Abs (aLength2) < Precision::Confusion()) { - theSegment[aNPoints++] = (aNode2.XYZ() - aNode1.XYZ()) * anAlpha + aNode1.XYZ(); + theSegment[aNPoints].Param = aCrossParam; + theSegment[aNPoints].Pnt = (aNode2.XYZ() - aNode1.XYZ()) * anAlpha + aNode1.XYZ(); + ++aNPoints; continue; } aCross = (aNode2.XYZ() - aNode1.XYZ()) * (aLength1 / (aLength1 + aLength2)) + aNode1.XYZ(); } - theSegment[aNPoints++] = aCross; + theSegment[aNPoints].Param = aCrossParam; + theSegment[aNPoints].Pnt = aCross; + ++aNPoints; } - return aNPoints == 2; + if (aNPoints != 2 + || Abs (theSegment[1].Param - theSegment[0].Param) <= Precision::PConfusion()) + { + return false; + } + + if (theSegment[1].Param < theSegment[0].Param) + { + std::swap (theSegment[0], theSegment[1]); + } + return true; } diff --git a/src/StdPrs/StdPrs_Isolines.hxx b/src/StdPrs/StdPrs_Isolines.hxx index 0f6ae13545..129abadc00 100644 --- a/src/StdPrs/StdPrs_Isolines.hxx +++ b/src/StdPrs/StdPrs_Isolines.hxx @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include @@ -65,6 +66,29 @@ public: } } + //! Computes isolines presentation for a TopoDS face. + //! This method chooses proper version of isoline builder algorithm : on triangulation + //! or surface depending on the flag passed from Prs3d_Drawer attributes. + //! This method is a default way to display isolines for a given TopoDS face. + //! @param theFace [in] the face. + //! @param theDrawer [in] the display settings. + //! @param theDeflection [in] the deflection for isolines-on-surface version. + static void Add (const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines) + { + if (theDrawer->IsoOnTriangulation() && StdPrs_ToolTriangulatedShape::IsTriangulated (theFace)) + { + AddOnTriangulation (theFace, theDrawer, theUPolylines, theVPolylines); + } + else + { + AddOnSurface (theFace, theDrawer, theDeflection, theUPolylines, theVPolylines); + } + } + //! Computes isolines on triangulation and adds them to a presentation. //! @param thePresentation [in] the presentation. //! @param theFace [in] the face. @@ -73,6 +97,16 @@ public: const TopoDS_Face& theFace, const Handle(Prs3d_Drawer)& theDrawer); + //! Computes isolines on triangulation. + //! @param theFace [in] the face. + //! @param theDrawer [in] the display settings. + //! @param theUPolylines [out] the sequence of result polylines + //! @param theVPolylines [out] the sequence of result polylines + Standard_EXPORT static void AddOnTriangulation (const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines); + //! Computes isolines on triangulation and adds them to a presentation. //! @param thePresentation [in] the presentation. //! @param theTriangulation [in] the triangulation. @@ -103,6 +137,18 @@ public: const Handle(Prs3d_Drawer)& theDrawer, const Standard_Real theDeflection); + //! Computes isolines on surface and adds them to presentation. + //! @param theFace [in] the face + //! @param theDrawer [in] the display settings + //! @param theDeflection [in] the deflection value + //! @param theUPolylines [out] the sequence of result polylines + //! @param theVPolylines [out] the sequence of result polylines + Standard_EXPORT static void AddOnSurface (const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines); + //! Computes isolines on surface and adds them to presentation. //! @param thePresentation [in] the presentation. //! @param theSurface [in] the surface. @@ -131,20 +177,87 @@ public: TColStd_SequenceOfReal& theUIsoParams, TColStd_SequenceOfReal& theVIsoParams); +public: + + //! Auxiliary structure defining 3D point on isoline. + struct PntOnIso + { + gp_Pnt Pnt; //!< 3D point + double Param; //!< parameter along the line (for sorting) + }; + + //! Auxiliary structure defining segment of isoline. + struct SegOnIso + { + + PntOnIso Pnts[2]; + + operator PntOnIso*() { return Pnts; } + operator const PntOnIso*() const { return Pnts; } + + bool operator< (const SegOnIso& theOther) const + { + return Pnts[1].Param < theOther.Pnts[0].Param; + } + + }; + private: + //! Computes isolines on surface. + //! @param theSurface [in] the surface + //! @param theDrawer [in] the display settings + //! @param theDeflection [in] the deflection value + //! @param theUIsoParams [in] the parameters of u isolines to compute + //! @param theVIsoParams [in] the parameters of v isolines to compute + //! @param theUPolylines [out] the sequence of result polylines + //! @param theVPolylines [out] the sequence of result polylines + Standard_EXPORT static void addOnSurface (const Handle(BRepAdaptor_HSurface)& theSurface, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines); + + //! Computes isolines on triangulation. + //! @param thePresentation [in] the presentation + //! @param theTriangulation [in] the triangulation + //! @param theSurface [in] the definition of triangulated surface. The surface + //! adapter is used to precisely evaluate isoline points using surface + //! law and fit them on triangulation. If NULL is passed, the method will + //! use linear interpolation of triangle node's UV coordinates to evaluate + //! isoline points + //! @param theLocation [in] the location transformation defined for triangulation (surface) + //! @param theDrawer [in] the display settings + //! @param theUIsoParams [in] the parameters of u isolines to compute + //! @param theVIsoParams [in] the parameters of v isolines to compute + //! @param theUPolylines [out] the sequence of result polylines + //! @param theVPolylines [out] the sequence of result polylines + Standard_EXPORT static void addOnTriangulation (const Handle(Poly_Triangulation)& theTriangulation, + const Handle(Geom_Surface)& theSurface, + const TopLoc_Location& theLocation, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams, + Prs3d_NListOfSequenceOfPnt& theUPolylines, + Prs3d_NListOfSequenceOfPnt& theVPolylines); + //! Find isoline segment on a triangle. //! @param theSurface [in] the surface. + //! @param theIsU [in] when true than U isoline is specified, V isoline otherwise //! @param theIsoline [in] the isoline in uv coordinates. //! @param theNodesXYZ [in] the XYZ coordinates of triangle nodes. //! @param theNodesUV [in] the UV coordinates of triangle nodes. //! @param theSegment [out] the XYZ points of crossed triangle's links. + //! with U cross point parameter for V isoline + //! or V parameters for U isoline (depending on theIsU) //! @return TRUE if the isoline passes through the triangle. Standard_EXPORT static Standard_Boolean findSegmentOnTriangulation (const Handle(Geom_Surface)& theSurface, + const bool theIsU, const gp_Lin2d& theIsoline, const gp_Pnt* theNodesXYZ, const gp_Pnt2d* theNodesUV, - gp_Pnt* theSegment); + SegOnIso& theSegment); }; #endif // _StdPrs_Isolines_H__ diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index 98c6bcb52e..534d8a2225 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -309,110 +309,96 @@ namespace // for computing boundaries presentation NCollection_List aNodeCollection; Standard_Integer aNodeNumber = 0; + Standard_Integer aNbPolylines = 0; TopLoc_Location aTrsf; // explore all boundary edges TopTools_IndexedDataMapOfShapeListOfShape anEdgesMap; - TopExp::MapShapesAndAncestors ( - theShape, TopAbs_EDGE, TopAbs_FACE, anEdgesMap); - - Standard_Integer anEdgeIdx = 1; - for ( ; anEdgeIdx <= anEdgesMap.Extent (); anEdgeIdx++) + TopExp::MapShapesAndAncestors (theShape, TopAbs_EDGE, TopAbs_FACE, anEdgesMap); + for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgesMap); anEdgeIter.More(); anEdgeIter.Next()) { // reject free edges - const TopTools_ListOfShape& aFaceList = anEdgesMap.FindFromIndex (anEdgeIdx); - if (aFaceList.Extent() == 0) - continue; - - // take one of the shared edges and get edge triangulation - const TopoDS_Face& aFace = TopoDS::Face (aFaceList.First ()); - const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesMap.FindKey (anEdgeIdx)); - - Handle(Poly_Triangulation) aTriangulation = - BRep_Tool::Triangulation (aFace, aTrsf); - - if (aTriangulation.IsNull ()) - continue; - - Handle(Poly_PolygonOnTriangulation) anEdgePoly = - BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); - - if (anEdgePoly.IsNull ()) - continue; - - // get edge nodes indexes from face triangulation - const TColgp_Array1OfPnt& aTriNodes = aTriangulation->Nodes (); - const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes (); - - if (anEdgeNodes.Length () < 2) - continue; - - // collect the edge nodes - Handle(TColgp_HArray1OfPnt) aCollected = - new TColgp_HArray1OfPnt (anEdgeNodes.Lower (), anEdgeNodes.Upper ()); - - Standard_Integer aNodeIdx = anEdgeNodes.Lower (); - for ( ; aNodeIdx <= anEdgeNodes.Upper (); aNodeIdx++) + if (anEdgeIter.Value().Extent() == 0) { - // node index in face triangulation - Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx); - - // get node and apply location transformation to the node - gp_Pnt aTriNode = aTriNodes.Value (aTriIndex); - if (!aTrsf.IsIdentity ()) - aTriNode.Transform (aTrsf); - - // add node to the boundary array - aCollected->SetValue (aNodeIdx, aTriNode); + continue; } - aNodeNumber += anEdgeNodes.Length (); - aNodeCollection.Append (aCollected); + // take one of the shared edges and get edge triangulation + const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First()); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf); + if (aTriangulation.IsNull()) + { + continue; + } + + const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); + if (!anEdgePoly.IsNull() + && anEdgePoly->Nodes().Length() >= 2) + { + aNodeNumber += anEdgePoly->Nodes().Length(); + ++aNbPolylines; + } + } + if (aNodeNumber == 0) + { + return; } - // check if it possible to continue building the presentation - if (aNodeNumber == 0) - return; - - // allocate polyline array for presentation - Standard_Integer aSegmentEdgeNb = - (aNodeNumber - aNodeCollection.Extent()) * 2; - - Handle(Graphic3d_ArrayOfSegments) aSegments = - new Graphic3d_ArrayOfSegments (aNodeNumber, aSegmentEdgeNb); - - // build presentation for edge bondaries - NCollection_List::Iterator - aCollIt (aNodeCollection); - - // the edge index is increased in each iteration step to - // avoid contiguous segments between different face edges. - for ( ; aCollIt.More(); aCollIt.Next () ) + // create indexed segments array to pack polylines from different edges into single array + const Standard_Integer aSegmentEdgeNb = (aNodeNumber - aNbPolylines) * 2; + Handle(Graphic3d_ArrayOfSegments) aSegments = new Graphic3d_ArrayOfSegments (aNodeNumber, aSegmentEdgeNb); + for (TopTools_IndexedDataMapOfShapeListOfShape::Iterator anEdgeIter (anEdgesMap); anEdgeIter.More(); anEdgeIter.Next()) { - const Handle(TColgp_HArray1OfPnt)& aNodeArray = aCollIt.Value (); - - Standard_Integer aNodeIdx = aNodeArray->Lower (); - - // add first node (this node is not shared with previous segment). - // for each face edge, indices for sharing nodes - // between segments begin from the first added node. - Standard_Integer aSegmentEdge = - aSegments->AddVertex (aNodeArray->Value (aNodeIdx)); - - // add subsequent nodes and provide edge indexes for sharing - // the nodes between the sequential segments. - for ( aNodeIdx++; aNodeIdx <= aNodeArray->Upper (); aNodeIdx++ ) + if (anEdgeIter.Value().Extent() == 0) { - aSegments->AddVertex (aNodeArray->Value (aNodeIdx)); - aSegments->AddEdge ( aSegmentEdge); - aSegments->AddEdge (++aSegmentEdge); + continue; + } + + const TopoDS_Face& aFace = TopoDS::Face (anEdgeIter.Value().First()); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aTrsf); + if (aTriangulation.IsNull()) + { + continue; + } + + const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); + if (anEdgePoly.IsNull() + || anEdgePoly->Nodes().Length () < 2) + { + continue; + } + + // get edge nodes indexes from face triangulation + const TColgp_Array1OfPnt& aTriNodes = aTriangulation->Nodes(); + const TColStd_Array1OfInteger& anEdgeNodes = anEdgePoly->Nodes(); + + // collect the edge nodes + Standard_Integer aSegmentEdge = aSegments->VertexNumber() + 1; + for (Standard_Integer aNodeIdx = anEdgeNodes.Lower(); aNodeIdx <= anEdgeNodes.Upper(); ++aNodeIdx) + { + // node index in face triangulation + // get node and apply location transformation to the node + const Standard_Integer aTriIndex = anEdgeNodes.Value (aNodeIdx); + gp_Pnt aTriNode = aTriNodes.Value (aTriIndex); + if (!aTrsf.IsIdentity()) + { + aTriNode.Transform (aTrsf); + } + + aSegments->AddVertex (aTriNode); + if (aNodeIdx != anEdgeNodes.Lower()) + { + aSegments->AddEdge ( aSegmentEdge); + aSegments->AddEdge (++aSegmentEdge); + } } } // set up aspect and add polyline data - Handle(Graphic3d_AspectLine3d) aBoundaryAspect = - theDrawer->FaceBoundaryAspect ()->Aspect (); + Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect(); Handle(Graphic3d_Group) aPrsGrp = Prs3d_Root::CurrentGroup (thePrs); aPrsGrp->SetGroupPrimitivesAspect (aBoundaryAspect); diff --git a/src/StdPrs/StdPrs_WFShape.cxx b/src/StdPrs/StdPrs_WFShape.cxx index 96bcf82839..878c4c3828 100644 --- a/src/StdPrs/StdPrs_WFShape.cxx +++ b/src/StdPrs/StdPrs_WFShape.cxx @@ -25,15 +25,12 @@ #include #include #include -#include -#include #include #include #include #include #include #include -#include #include #include #include @@ -43,12 +40,6 @@ #include #include #include -#include - -namespace -{ - typedef NCollection_List ListOfSequenceOfPnt; -} // ========================================================================= // function : Add @@ -78,54 +69,106 @@ void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, } } - TColgp_SequenceOfPnt aShapeVertices; - for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex()) - { - aShapeVertices.Append (BRep_Tool::Pnt (aTool.GetVertex())); - } - Standard_Real aShapeDeflection = Prs3d::GetDeflection (theShape, theDrawer); - // Draw shape elements. - TopTools_ListOfShape aDiscreteFaces; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) + // Draw shape elements { - if (!aTool.HasSurface()) + TopTools_ListOfShape aDiscreteFaces; + for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) { - aDiscreteFaces.Append (aTool.GetFace()); + if (!aTool.HasSurface()) + { + aDiscreteFaces.Append (aTool.GetFace()); + } } + addEdgesOnTriangulation (thePresentation, aDiscreteFaces, theDrawer->FreeBoundaryAspect()); + } + + Prs3d_NListOfSequenceOfPnt aCommonPolylines; + const Handle(Prs3d_LineAspect)& aWireAspect = theDrawer->WireAspect(); + + // Draw isolines + { + Prs3d_NListOfSequenceOfPnt aUPolylines, aVPolylines; + Prs3d_NListOfSequenceOfPnt* aUPolylinesPtr = &aUPolylines; + Prs3d_NListOfSequenceOfPnt* aVPolylinesPtr = &aVPolylines; + + const Handle(Prs3d_LineAspect)& anIsoAspectU = theDrawer->UIsoAspect(); + const Handle(Prs3d_LineAspect)& anIsoAspectV = theDrawer->VIsoAspect(); + if (anIsoAspectV->Aspect()->IsEqual (*anIsoAspectU->Aspect())) + { + aVPolylinesPtr = aUPolylinesPtr; + } + if (anIsoAspectU->Aspect()->IsEqual (*aWireAspect->Aspect())) + { + aUPolylinesPtr = &aCommonPolylines; + } + if (anIsoAspectV->Aspect()->IsEqual (*aWireAspect->Aspect())) + { + aVPolylinesPtr = &aCommonPolylines; + } + + for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) + { + if (aTool.IsPlanarFace() && !theDrawer->IsoOnPlane()) + { + continue; + } + + StdPrs_Isolines::Add (aTool.GetFace(), theDrawer, aShapeDeflection, *aUPolylinesPtr, *aVPolylinesPtr); + } + + Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectU, aUPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, anIsoAspectV, aVPolylines); } - addEdgesOnTriangulation (thePresentation, aDiscreteFaces, theDrawer->FreeBoundaryAspect()); if (!aLWire.IsEmpty() && theDrawer->WireDraw()) { - addEdges (thePresentation, aLWire, theDrawer->WireAspect(), theDrawer, aShapeDeflection); - } - - if (!aLFree.IsEmpty() && theDrawer->FreeBoundaryDraw()) - { - addEdges (thePresentation, aLFree, theDrawer->FreeBoundaryAspect(), theDrawer, aShapeDeflection); + addEdges (aLWire, theDrawer, aShapeDeflection, aCommonPolylines); } if (!aLUnFree.IsEmpty() && theDrawer->UnFreeBoundaryDraw()) { - addEdges (thePresentation, aLUnFree, theDrawer->UnFreeBoundaryAspect(), theDrawer, aShapeDeflection); - } - - if (!aShapeVertices.IsEmpty()) - { - addVertices (thePresentation, aShapeVertices, theDrawer->PointAspect()); - } - - // Draw isolines. - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - if (aTool.IsPlanarFace() && !theDrawer->IsoOnPlane()) + const Handle(Prs3d_LineAspect)& aLineAspect = theDrawer->UnFreeBoundaryAspect(); + if (!aLineAspect->Aspect()->IsEqual (*aWireAspect->Aspect())) { - continue; + Prs3d_NListOfSequenceOfPnt aPolylines; + addEdges (aLUnFree, theDrawer, aShapeDeflection, aPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, aLineAspect, aPolylines); } + else + { + addEdges (aLUnFree, theDrawer, aShapeDeflection, aCommonPolylines); + } + } - StdPrs_Isolines::Add (thePresentation, aTool.GetFace(), theDrawer, aShapeDeflection); + if (!aLFree.IsEmpty() && theDrawer->FreeBoundaryDraw()) + { + const Handle(Prs3d_LineAspect)& aLineAspect = theDrawer->FreeBoundaryAspect(); + if (!aLineAspect->Aspect()->IsEqual (*aWireAspect->Aspect())) + { + Prs3d_NListOfSequenceOfPnt aPolylines; + addEdges (aLFree, theDrawer, aShapeDeflection, aPolylines); + Prs3d::AddPrimitivesGroup (thePresentation, aLineAspect, aPolylines); + } + else + { + addEdges (aLFree, theDrawer, aShapeDeflection, aCommonPolylines); + } + } + + Prs3d::AddPrimitivesGroup (thePresentation, theDrawer->WireAspect(), aCommonPolylines); + + { + TColgp_SequenceOfPnt aShapeVertices; + for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex()) + { + aShapeVertices.Append (BRep_Tool::Pnt (aTool.GetVertex())); + } + if (!aShapeVertices.IsEmpty()) + { + addVertices (thePresentation, aShapeVertices, theDrawer->PointAspect()); + } } } @@ -133,14 +176,11 @@ void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, // function : AddEdges // purpose : // ========================================================================= -void StdPrs_WFShape::addEdges (const Handle (Prs3d_Presentation)& thePresentation, - const TopTools_ListOfShape& theEdges, - const Handle (Prs3d_LineAspect)& theAspect, - const Handle (Prs3d_Drawer)& theDrawer, - const Standard_Real theShapeDeflection) +void StdPrs_WFShape::addEdges (const TopTools_ListOfShape& theEdges, + const Handle (Prs3d_Drawer)& theDrawer, + const Standard_Real theShapeDeflection, + Prs3d_NListOfSequenceOfPnt& thePolylines) { - ListOfSequenceOfPnt aPointsOfEdges; - TopTools_ListIteratorOfListOfShape anEdgesIter; for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next()) { @@ -204,7 +244,7 @@ void StdPrs_WFShape::addEdges (const Handle (Prs3d_Presentation)& thePresentatio { // Default presentation for edges without triangulation. BRepAdaptor_Curve aCurve (anEdge); - StdPrs_DeflectionCurve::Add (thePresentation, + StdPrs_DeflectionCurve::Add (Handle(Prs3d_Presentation)(), aCurve, theShapeDeflection, theDrawer, @@ -214,40 +254,9 @@ void StdPrs_WFShape::addEdges (const Handle (Prs3d_Presentation)& thePresentatio if (!aPoints->IsEmpty()) { - aPointsOfEdges.Append (aPoints); + thePolylines.Append (aPoints); } } - - Standard_Integer aNbBounds = aPointsOfEdges.Size(); - Standard_Integer aNbVertices = 0; - - ListOfSequenceOfPnt::Iterator aPolylineIter; - for (aPolylineIter.Initialize (aPointsOfEdges); aPolylineIter.More(); aPolylineIter.Next()) - { - aNbVertices += aPolylineIter.Value()->Length(); - } - - if (aNbBounds < 1 || aNbVertices < 2) - { - return; - } - - // Construct array of primitives. - Handle(Graphic3d_ArrayOfPolylines) aPrimitiveArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (aPolylineIter.Initialize (aPointsOfEdges); aPolylineIter.More(); aPolylineIter.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = aPolylineIter.Value(); - aPrimitiveArray->AddBound (aPoints->Length()); - for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI) - { - aPrimitiveArray->AddVertex (aPoints->Value (anI)); - } - } - - // Add array of primitives to presentation. - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theAspect->Aspect()); - aGroup->AddPrimitiveArray (aPrimitiveArray); } // ========================================================================= @@ -342,11 +351,9 @@ void StdPrs_WFShape::addEdgesOnTriangulation (const Handle(Prs3d_Presentation)& } Standard_Integer aNbVertices = aSurfPoints.Length(); - Standard_Integer aNbBounds = aNbVertices / 2; - Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices, aNbBounds); + Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices); for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2) { - aSurfArray->AddBound (2); aSurfArray->AddVertex (aSurfPoints.Value (anI)); aSurfArray->AddVertex (aSurfPoints.Value (anI + 1)); } diff --git a/src/StdPrs/StdPrs_WFShape.hxx b/src/StdPrs/StdPrs_WFShape.hxx index 0db67cfb8f..8d27dbe9da 100755 --- a/src/StdPrs/StdPrs_WFShape.hxx +++ b/src/StdPrs/StdPrs_WFShape.hxx @@ -19,6 +19,7 @@ #include #include #include +#include #include #include #include @@ -39,16 +40,13 @@ public: private: //! Compute edge presentations for a shape. - //! @param thePresentation [in] the presentation. //! @param theEdges [in] the list of edges. - //! @param theAspect [in] the edge drawing aspect. //! @param theDrawer [in] the drawer settings. //! @param theShapeDeflection [in] the deflection for the wireframe shape. - static void addEdges (const Handle (Prs3d_Presentation)& thePresentation, - const TopTools_ListOfShape& theEdges, - const Handle (Prs3d_LineAspect)& theAspect, - const Handle (Prs3d_Drawer)& theDrawer, - const Standard_Real theShapeDeflection); + static void addEdges (const TopTools_ListOfShape& theEdges, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theShapeDeflection, + Prs3d_NListOfSequenceOfPnt& thePolylines); //! Compute free and boundary edges on a triangulation of a face. //! @param thePresentation [in] the presentation.