From 5ad8c033aa1cc1f91e49dc423491499ae8445faf Mon Sep 17 00:00:00 2001 From: vpa Date: Wed, 22 Apr 2015 00:53:37 +0300 Subject: [PATCH] 0025300: Visualization - Build wireframe representation consistent with the shape's triangulation 1) Remove duplicating presentation algorithms for shapes StdPrs_WFShape, StdPrs_WFDeflectionShape. 2) Rewrite Prs3d_WFShape to use deflection for non-triangulated shapes and rename it to StdPrs_WFShape. 3) Revise and correct references in code. 4) Rename StdPrs_ToolShadedShape to StdPrs_ToolTriangulatedShape (reused in StdPrs_WFShape, StdPrs_ShadedShape). 5) Add StdPrs_BndBox for drawing bounding box presentation. 6) Implemented on-triangulation isoline builder. 7) Add option -isoontriangulation to vaspects command to enable on-triangulation isoline builder for shape. 8) Drawer's maximum UV parameter value is taken into account in isolines calculation correctly. 9) Add option -setMaxParamValue to vaspects command to change drawer's maximum UV parameter value. --- samples/mfc/standard/01_Geometry/src/StdAfx.h | 1 - .../Common/ISession2D/ISession2D_Shape.cpp | 2 +- samples/mfc/standard/Common/StdAfx.h | 1 - samples/mfc/standard/Common/User_Cylinder.cxx | 6 +- src/AIS/AIS.cxx | 55 +- src/AIS/AIS_ColoredShape.cxx | 14 +- src/AIS/AIS_ConnectedInteractive.cxx | 4 +- src/AIS/AIS_IdenticRelation.cxx | 1 - src/AIS/AIS_InteractiveContext.cxx | 32 + src/AIS/AIS_InteractiveContext.hxx | 16 +- src/AIS/AIS_InteractiveObject.cxx | 9 + src/AIS/AIS_InteractiveObject.hxx | 2 + src/AIS/AIS_OffsetDimension.cxx | 17 +- src/AIS/AIS_PointCloud.cxx | 4 +- src/AIS/AIS_Relation.cxx | 52 +- src/AIS/AIS_Shape.cxx | 110 ++- src/AIS/AIS_TexturedShape.cxx | 14 +- src/Prs3d/FILES | 2 - src/Prs3d/Prs3d_Drawer.cxx | 13 + src/Prs3d/Prs3d_Drawer.hxx | 16 + src/Prs3d/Prs3d_WFShape.cxx | 730 ----------------- src/Prs3d/Prs3d_WFShape.hxx | 121 --- src/StdPrs/FILES | 13 +- src/StdPrs/StdPrs_BndBox.cxx | 65 ++ src/StdPrs/StdPrs_BndBox.hxx | 38 + src/StdPrs/StdPrs_Curve.cxx | 14 +- src/StdPrs/StdPrs_Curve.hxx | 4 +- src/StdPrs/StdPrs_Isolines.cxx | 753 ++++++++++++++++++ src/StdPrs/StdPrs_Isolines.hxx | 150 ++++ src/StdPrs/StdPrs_ShadedShape.cxx | 51 +- src/StdPrs/StdPrs_ShadedShape.hxx | 3 - src/StdPrs/StdPrs_ToolShadedShape.hxx | 50 -- ...e.cxx => StdPrs_ToolTriangulatedShape.cxx} | 74 +- src/StdPrs/StdPrs_ToolTriangulatedShape.hxx | 64 ++ .../StdPrs_WFDeflectionRestrictedFace.cxx | 45 +- .../StdPrs_WFDeflectionRestrictedFace.hxx | 3 - src/StdPrs/StdPrs_WFDeflectionShape.hxx | 130 --- src/StdPrs/StdPrs_WFRestrictedFace.cxx | 36 +- src/StdPrs/StdPrs_WFRestrictedFace.hxx | 1 - src/StdPrs/StdPrs_WFShape.cxx | 381 +++++++++ src/StdPrs/StdPrs_WFShape.hxx | 136 +--- src/StdPrs/StdPrs_WFSurface.cxx | 115 ++- src/StdSelect/StdSelect_Shape.cxx | 6 +- src/ViewerTest/ViewerTest.cxx | 89 ++- src/ViewerTest/ViewerTest_ObjectCommands.cxx | 8 +- tests/bugs/vis/bug129_2 | 15 +- tests/bugs/vis/bug25300_1 | 43 + tests/bugs/vis/bug25300_2 | 43 + tests/bugs/vis/bug25935 | 6 +- 49 files changed, 2075 insertions(+), 1483 deletions(-) delete mode 100755 src/Prs3d/Prs3d_WFShape.cxx delete mode 100755 src/Prs3d/Prs3d_WFShape.hxx create mode 100644 src/StdPrs/StdPrs_BndBox.cxx create mode 100644 src/StdPrs/StdPrs_BndBox.hxx create mode 100644 src/StdPrs/StdPrs_Isolines.cxx create mode 100644 src/StdPrs/StdPrs_Isolines.hxx delete mode 100644 src/StdPrs/StdPrs_ToolShadedShape.hxx rename src/StdPrs/{StdPrs_ToolShadedShape.cxx => StdPrs_ToolTriangulatedShape.cxx} (77%) create mode 100644 src/StdPrs/StdPrs_ToolTriangulatedShape.hxx delete mode 100755 src/StdPrs/StdPrs_WFDeflectionShape.hxx create mode 100644 src/StdPrs/StdPrs_WFShape.cxx create mode 100644 tests/bugs/vis/bug25300_1 create mode 100644 tests/bugs/vis/bug25300_2 diff --git a/samples/mfc/standard/01_Geometry/src/StdAfx.h b/samples/mfc/standard/01_Geometry/src/StdAfx.h index 83f6ce6a61..6cc9ea2eca 100755 --- a/samples/mfc/standard/01_Geometry/src/StdAfx.h +++ b/samples/mfc/standard/01_Geometry/src/StdAfx.h @@ -234,7 +234,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/mfc/standard/Common/ISession2D/ISession2D_Shape.cpp b/samples/mfc/standard/Common/ISession2D/ISession2D_Shape.cpp index 6c46537bd8..f95256a033 100755 --- a/samples/mfc/standard/Common/ISession2D/ISession2D_Shape.cpp +++ b/samples/mfc/standard/Common/ISession2D/ISession2D_Shape.cpp @@ -320,7 +320,7 @@ void ISession2D_Shape::DrawCompound(const Handle(Prs3d_Presentation)& thePresent if (theCompound.IsNull()) return; myDrawer->SetWireAspect(theAspect); - StdPrs_WFDeflectionShape::Add(thePresentation,TopoDS_Shape(theCompound),myDrawer); + StdPrs_WFShape::Add(thePresentation,TopoDS_Shape(theCompound),myDrawer); } void ISession2D_Shape::ComputeSelection(const Handle(SelectMgr_Selection)& /*aSelection*/, diff --git a/samples/mfc/standard/Common/StdAfx.h b/samples/mfc/standard/Common/StdAfx.h index 122108e25e..36d25e7f3c 100755 --- a/samples/mfc/standard/Common/StdAfx.h +++ b/samples/mfc/standard/Common/StdAfx.h @@ -94,7 +94,6 @@ #include #include #include -#include #include #include #include diff --git a/samples/mfc/standard/Common/User_Cylinder.cxx b/samples/mfc/standard/Common/User_Cylinder.cxx index 314da9a092..0982dd1753 100755 --- a/samples/mfc/standard/Common/User_Cylinder.cxx +++ b/samples/mfc/standard/Common/User_Cylinder.cxx @@ -12,7 +12,7 @@ IMPLEMENT_STANDARD_RTTIEXT(User_Cylinder,AIS_InteractiveObject) #include #include #include -#include +#include #include #include #include @@ -58,7 +58,7 @@ void User_Cylinder::Compute(const Handle_PrsMgr_PresentationManager3d& /*aPresen { switch (aMode) { case 0: - StdPrs_WFDeflectionShape::Add(aPresentation,myShape, myDrawer ); + StdPrs_WFShape::Add(aPresentation,myShape, myDrawer ); break; case 1: { @@ -238,7 +238,7 @@ case 6: //color const Poly_Array1OfTriangle& triangles = myT->Triangles(); TColgp_Array1OfDir myNormal(Nodes.Lower(), Nodes.Upper()); - StdPrs_ToolShadedShape::Normal(myFace, pc, myNormal); + StdPrs_ToolTriangulatedShape::Normal(myFace, pc, myNormal); BRepTools::UVBounds(myFace,Umin, Umax, Vmin, Vmax); dUmax = (Umax - Umin); dVmax = (Vmax - Vmin); diff --git a/src/AIS/AIS.cxx b/src/AIS/AIS.cxx index ea39f44522..087bd812ad 100644 --- a/src/AIS/AIS.cxx +++ b/src/AIS/AIS.cxx @@ -68,7 +68,7 @@ #include #include #include -#include +#include #include #include #include @@ -1451,7 +1451,7 @@ void AIS::ComputeProjEdgePresentation (const Handle(Prs3d_Presentation)& aPresen BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl); E = MakEd.Edge(); } - StdPrs_WFDeflectionShape::Add(aPresentation, E, aDrawer); + StdPrs_WFShape::Add (aPresentation, E, aDrawer); //Calculate the presentation of line connections aDrawer->WireAspect()->SetTypeOfLine(aCallTOL); @@ -1461,31 +1461,31 @@ void AIS::ComputeProjEdgePresentation (const Handle(Prs3d_Presentation)& aPresen ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge))); // it is patch! - if (FirstP.SquareDistance( ppf ) > SquareTolerance) - { - BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf); - StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer); - } + if (FirstP.SquareDistance (ppf) > SquareTolerance) + { + BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); + StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer); + } else - { - BRepBuilderAPI_MakeVertex MakVert1( FirstP ); - StdPrs_WFDeflectionShape::Add(aPresentation, MakVert1.Vertex(), aDrawer); - } - if (LastP.SquareDistance( ppl ) > SquareTolerance) - { - BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl); - StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer); - } + { + BRepBuilderAPI_MakeVertex MakVert1 (FirstP); + StdPrs_WFShape::Add (aPresentation, MakVert1.Vertex(), aDrawer); + } + if (LastP.SquareDistance (ppl) > SquareTolerance) + { + BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); + StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer); + } else - { - BRepBuilderAPI_MakeVertex MakVert2( LastP ); - StdPrs_WFDeflectionShape::Add(aPresentation, MakVert2.Vertex(), aDrawer); - } + { + BRepBuilderAPI_MakeVertex MakVert2 (LastP); + StdPrs_WFShape::Add (aPresentation, MakVert2.Vertex(), aDrawer); + } /* - BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf); - StdPrs_WFDeflectionShape::Add(aPresentation, MakEd1.Edge(), aDrawer); - BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl); - StdPrs_WFDeflectionShape::Add(aPresentation, MakEd2.Edge(), aDrawer); + BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); + StdPrs_WFShape::Add (aPresentation, MakEd1.Edge(), aDrawer); + BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); + StdPrs_WFShape::Add (aPresentation, MakEd2.Edge(), aDrawer); */ } } @@ -1531,9 +1531,10 @@ void AIS::ComputeProjVertexPresentation (const Handle( Prs3d_Presentation )& aPr } // If the points are not mixed... - if (!ProjPoint.IsEqual (BRep_Tool::Pnt(aVertex),Precision::Confusion())) { + if (!ProjPoint.IsEqual (BRep_Tool::Pnt (aVertex), Precision::Confusion())) + { // calculate the lines of recall - BRepBuilderAPI_MakeEdge MakEd(ProjPoint,BRep_Tool::Pnt(aVertex)); - StdPrs_WFDeflectionShape::Add(aPresentation, MakEd.Edge(), aDrawer); + BRepBuilderAPI_MakeEdge MakEd (ProjPoint, BRep_Tool::Pnt (aVertex)); + StdPrs_WFShape::Add (aPresentation, MakEd.Edge(), aDrawer); } } diff --git a/src/AIS/AIS_ColoredShape.cxx b/src/AIS/AIS_ColoredShape.cxx index 32ef9f978a..19af280b99 100644 --- a/src/AIS/AIS_ColoredShape.cxx +++ b/src/AIS/AIS_ColoredShape.cxx @@ -34,8 +34,8 @@ #include #include #include -#include -#include +#include +#include #include #include #include @@ -317,7 +317,13 @@ void AIS_ColoredShape::Compute (const Handle(PrsMgr_PresentationManager3d)& , } // After this call if type of deflection is relative // computed deflection coefficient is stored as absolute. - StdPrs_ShadedShape::Tessellate (myshape, myDrawer); + Standard_Boolean wasRecomputed = StdPrs_ToolTriangulatedShape::Tessellate (myshape, myDrawer); + + // Set to update wireframe presentation on triangulation. + if (myDrawer->IsoOnTriangulation() && wasRecomputed) + { + SetToUpdate (AIS_WireFrame); + } } } else // WireFrame mode @@ -416,7 +422,7 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation } else { - StdPrs_WFDeflectionShape::Add (thePrs, aShapeDraw, aDrawer); + StdPrs_WFShape::Add (thePrs, aShapeDraw, aDrawer); } aDrawer->SetTypeOfDeflection (aPrevType); } diff --git a/src/AIS/AIS_ConnectedInteractive.cxx b/src/AIS/AIS_ConnectedInteractive.cxx index 77bb0b85f0..6a3cbb2dd3 100644 --- a/src/AIS/AIS_ConnectedInteractive.cxx +++ b/src/AIS/AIS_ConnectedInteractive.cxx @@ -36,7 +36,7 @@ #include #include #include -#include +#include #include #include #include @@ -204,7 +204,7 @@ void AIS_ConnectedInteractive::Compute (const Handle(Prs3d_Projector)& theProjec case TopAbs_WIRE: { thePresentation->SetDisplayPriority (4); - StdPrs_WFDeflectionShape::Add (thePresentation, theShape, myDrawer); + StdPrs_WFShape::Add (thePresentation, theShape, myDrawer); break; } default: diff --git a/src/AIS/AIS_IdenticRelation.cxx b/src/AIS/AIS_IdenticRelation.cxx index 1b9ca4d35e..1fabed9483 100644 --- a/src/AIS/AIS_IdenticRelation.cxx +++ b/src/AIS/AIS_IdenticRelation.cxx @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include diff --git a/src/AIS/AIS_InteractiveContext.cxx b/src/AIS/AIS_InteractiveContext.cxx index ffedd38c4c..03d6429638 100644 --- a/src/AIS/AIS_InteractiveContext.cxx +++ b/src/AIS/AIS_InteractiveContext.cxx @@ -1841,6 +1841,21 @@ void AIS_InteractiveContext::SetColor (const Handle(AIS_InteractiveObject)& theI redisplayPrsRecModes (theIObj, theToUpdateViewer); } +//======================================================================= +//function : SetIsoOnTriangulation +//purpose : +//======================================================================= +void AIS_InteractiveContext::IsoOnTriangulation (const Standard_Boolean theIsEnabled, + const Handle(AIS_InteractiveObject)& theObject) +{ + if (theObject.IsNull()) + { + return; + } + + theObject->SetIsoOnTriangulation (theIsEnabled); +} + //======================================================================= //function : SetDeviationCoefficient //purpose : @@ -2665,6 +2680,23 @@ Standard_Boolean AIS_InteractiveContext::IsoOnPlane() const } //======================================================================= +//function : IsoOnTriangulation +//purpose : +//======================================================================= +void AIS_InteractiveContext::IsoOnTriangulation (const Standard_Boolean theToSwitchOn) +{ + myDefaultDrawer->SetIsoOnTriangulation (theToSwitchOn); +} + +//======================================================================= +//function : IsoOnTriangulation +//purpose : +//======================================================================= +Standard_Boolean AIS_InteractiveContext::IsoOnTriangulation() const +{ + return myDefaultDrawer->IsoOnTriangulation(); +} + //function : SetPixelTolerance //purpose : Disables the mechanism of adaptive tolerance calculation in // SelectMgr_ViewerSelector and sets the given tolerance for ALL diff --git a/src/AIS/AIS_InteractiveContext.hxx b/src/AIS/AIS_InteractiveContext.hxx index f8ba7b3d41..443ed2ed0a 100644 --- a/src/AIS/AIS_InteractiveContext.hxx +++ b/src/AIS/AIS_InteractiveContext.hxx @@ -826,7 +826,21 @@ public: //! Returns True if drawing isoparameters on planes is enabled. //! if = False, Standard_EXPORT Standard_Boolean IsoOnPlane() const; - + + //! Enables or disables on-triangulation build for isolines for a particular object. + //! In case if on-triangulation builder is disabled, default on-plane + //! builder will compute isolines for the object given. + Standard_EXPORT void IsoOnTriangulation (const Standard_Boolean theIsEnabled, + const Handle(AIS_InteractiveObject)& theObject); + + //! Enables or disables on-triangulation build for isolines for default drawer. + //! In case if on-triangulation builder is disabled, default on-plane + //! builder will compute isolines for the object given. + Standard_EXPORT void IsoOnTriangulation (const Standard_Boolean theToSwitchOn); + + //! Returns true if drawing isolines on triangulation algorithm is enabled. + Standard_EXPORT Standard_Boolean IsoOnTriangulation() const; + //! Sets the graphic basic aspect to the current presentation of //! ALL selected objects. //! When is TRUE , the full object presentation diff --git a/src/AIS/AIS_InteractiveObject.cxx b/src/AIS/AIS_InteractiveObject.cxx index f0813107d0..696b06ac25 100644 --- a/src/AIS/AIS_InteractiveObject.cxx +++ b/src/AIS/AIS_InteractiveObject.cxx @@ -663,3 +663,12 @@ void AIS_InteractiveObject::BoundingBox (Bnd_Box& theBndBox) } } } + +//======================================================================= +//function : SetIsoOnTriangulation +//purpose : Enables or disables isoline on triangulation building +//======================================================================= +void AIS_InteractiveObject::SetIsoOnTriangulation (const Standard_Boolean theIsEnabled) +{ + myDrawer->SetIsoOnTriangulation (theIsEnabled); +} diff --git a/src/AIS/AIS_InteractiveObject.hxx b/src/AIS/AIS_InteractiveObject.hxx index 3719cd0474..bd6551faf5 100644 --- a/src/AIS/AIS_InteractiveObject.hxx +++ b/src/AIS/AIS_InteractiveObject.hxx @@ -454,6 +454,8 @@ public: //! Returns bounding box of object correspondingly to its current display mode. Standard_EXPORT virtual void BoundingBox (Bnd_Box& theBndBox) Standard_OVERRIDE; + //! Enables or disables on-triangulation build of isolines according to the flag given. + Standard_EXPORT void SetIsoOnTriangulation (const Standard_Boolean theIsEnabled); friend class AIS_InteractiveContext; diff --git a/src/AIS/AIS_OffsetDimension.cxx b/src/AIS/AIS_OffsetDimension.cxx index dd557b99a3..bd8d8fa4e4 100644 --- a/src/AIS/AIS_OffsetDimension.cxx +++ b/src/AIS/AIS_OffsetDimension.cxx @@ -48,7 +48,7 @@ #include #include #include -#include +#include #include #include #include @@ -355,8 +355,8 @@ void AIS_OffsetDimension::ComputeTwoAxesOffset(const Handle(Prs3d_Presentation)& BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True); TopoDS_Shape myTSShape = transform2.Shape(); - StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer); - StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer); + StdPrs_WFShape::Add (aprs, myTFShape, myDrawer); + StdPrs_WFShape::Add (aprs, myTSShape, myDrawer); } //======================================================================= @@ -466,9 +466,8 @@ void AIS_OffsetDimension::ComputeTwoFacesOffset(const Handle(Prs3d_Presentation) BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True); TopoDS_Shape myTSShape = transform2.Shape(); - StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer); - StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer); - + StdPrs_WFShape::Add (aprs, myTFShape, myDrawer); + StdPrs_WFShape::Add (aprs, myTSShape, myDrawer); } //======================================================================= @@ -482,8 +481,8 @@ void AIS_OffsetDimension::ComputeAxeFaceOffset(const Handle(Prs3d_Presentation)& TopoDS_Shape myTFShape = transform1.Shape(); BRepBuilderAPI_Transform transform2 (mySShape, aTrsf, Standard_True); TopoDS_Shape myTSShape = transform2.Shape(); - - StdPrs_WFDeflectionShape::Add(aprs, myTFShape, myDrawer); - StdPrs_WFDeflectionShape::Add(aprs, myTSShape, myDrawer); + + StdPrs_WFShape::Add (aprs, myTFShape, myDrawer); + StdPrs_WFShape::Add (aprs, myTSShape, myDrawer); } diff --git a/src/AIS/AIS_PointCloud.cxx b/src/AIS/AIS_PointCloud.cxx index a432e8a63f..f055a5f143 100644 --- a/src/AIS/AIS_PointCloud.cxx +++ b/src/AIS/AIS_PointCloud.cxx @@ -29,7 +29,7 @@ #include #include #include -#include +#include //================================================== @@ -448,7 +448,7 @@ void AIS_PointCloud::Compute (const Handle(PrsMgr_PresentationManager3d)& /*theP return; } - StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, aBndBox, myDrawer); + StdPrs_BndBox::Add (thePrs, aBndBox, myDrawer); break; } } diff --git a/src/AIS/AIS_Relation.cxx b/src/AIS/AIS_Relation.cxx index a25b5f2d04..9498018e83 100644 --- a/src/AIS/AIS_Relation.cxx +++ b/src/AIS/AIS_Relation.cxx @@ -42,7 +42,7 @@ #include #include #include -#include +#include #include #include #include @@ -123,7 +123,7 @@ void AIS_Relation::ComputeProjEdgePresentation(const Handle(Prs3d_Presentation)& BRepBuilderAPI_MakeEdge MakEd(gc->Circ(),pf, pl); E = MakEd.Edge(); } - StdPrs_WFDeflectionShape::Add(aPrs, E, myDrawer); + StdPrs_WFShape::Add (aPrs, E, myDrawer); //Calcul de la presentation des lignes de raccord myDrawer->WireAspect()->SetTypeOfLine(aCallTOL); @@ -131,31 +131,31 @@ void AIS_Relation::ComputeProjEdgePresentation(const Handle(Prs3d_Presentation)& gp_Pnt ppf, ppl; ppf = BRep_Tool::Pnt( TopExp::FirstVertex(TopoDS::Edge(anEdge))); ppl = BRep_Tool::Pnt( TopExp::LastVertex(TopoDS::Edge(anEdge))); - if (FirstP.Distance( ppf ) > gp::Resolution()) - { - BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf); - StdPrs_WFDeflectionShape::Add(aPrs, MakEd1.Edge(), myDrawer); - } + if (FirstP.Distance (ppf) > gp::Resolution()) + { + BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); + StdPrs_WFShape::Add (aPrs, MakEd1.Edge(), myDrawer); + } else - { - BRepBuilderAPI_MakeVertex MakVert1( FirstP ); - StdPrs_WFDeflectionShape::Add(aPrs, MakVert1.Vertex(), myDrawer); - } - if (LastP.Distance( ppl ) > gp::Resolution()) - { - BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl); - StdPrs_WFDeflectionShape::Add(aPrs, MakEd2.Edge(), myDrawer); - } + { + BRepBuilderAPI_MakeVertex MakVert1 (FirstP); + StdPrs_WFShape::Add (aPrs, MakVert1.Vertex(), myDrawer); + } + if (LastP.Distance (ppl) > gp::Resolution()) + { + BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); + StdPrs_WFShape::Add (aPrs, MakEd2.Edge(), myDrawer); + } else - { - BRepBuilderAPI_MakeVertex MakVert2( LastP ); - StdPrs_WFDeflectionShape::Add(aPrs, MakVert2.Vertex(), myDrawer); - } + { + BRepBuilderAPI_MakeVertex MakVert2 (LastP); + StdPrs_WFShape::Add (aPrs, MakVert2.Vertex(), myDrawer); + } /* - BRepBuilderAPI_MakeEdge MakEd1(FirstP, ppf); - StdPrs_WFDeflectionShape::Add(aPrs, MakEd1.Edge(), myDrawer); - BRepBuilderAPI_MakeEdge MakEd2(LastP, ppl); - StdPrs_WFDeflectionShape::Add(aPrs, MakEd2.Edge(), myDrawer); + BRepBuilderAPI_MakeEdge MakEd1 (FirstP, ppf); + StdPrs_WFShape::Add (aPrs, MakEd1.Edge(), myDrawer); + BRepBuilderAPI_MakeEdge MakEd2 (LastP, ppl); + StdPrs_WFShape::Add (aPrs, MakEd2.Edge(), myDrawer); */ } } @@ -197,8 +197,8 @@ void AIS_Relation::ComputeProjVertexPresentation(const Handle(Prs3d_Presentation // Si les points ne sont pas confondus... if (!ProjPoint.IsEqual (BRep_Tool::Pnt(aVertex),Precision::Confusion())) { // calcul des lignes de rappel - BRepBuilderAPI_MakeEdge MakEd(ProjPoint,BRep_Tool::Pnt(aVertex)); - StdPrs_WFDeflectionShape::Add(aPrs, MakEd.Edge(), myDrawer); + BRepBuilderAPI_MakeEdge MakEd (ProjPoint,BRep_Tool::Pnt(aVertex)); + StdPrs_WFShape::Add (aPrs, MakEd.Edge(), myDrawer); } } diff --git a/src/AIS/AIS_Shape.cxx b/src/AIS/AIS_Shape.cxx index 2e381f7f9f..05d4e451cc 100644 --- a/src/AIS/AIS_Shape.cxx +++ b/src/AIS/AIS_Shape.cxx @@ -45,6 +45,8 @@ #include #include #include +#include +#include #include #include #include @@ -55,7 +57,6 @@ #include #include #include -#include #include #include #include @@ -142,21 +143,32 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat } } - if (IsInfinite()) aPrs->SetInfiniteState(Standard_True); //not taken in account duting FITALL - switch (aMode) { - case 0:{ - try { OCC_CATCH_SIGNALS StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); } - catch (Standard_Failure) { -#ifdef OCCT_DEBUG - cout << "AIS_Shape::Compute() failed"<< endl; - cout << "a Shape should be incorrect : No Compute can be maked on it "<< endl; -#endif -// presentation of the bounding box is calculated -// Compute(aPresentationManager,aPrs,2); - } - break; + if (IsInfinite()) + { + aPrs->SetInfiniteState (Standard_True); //not taken in account duting FITALL } - case 1: + + switch (aMode) + { + case AIS_WireFrame: + { + try + { + OCC_CATCH_SIGNALS + StdPrs_WFShape::Add (aPrs, myshape, myDrawer); + } + catch (Standard_Failure) + { + #ifdef OCCT_DEBUG + cout << "AIS_Shape::Compute() failed" << endl; + cout << "a Shape should be incorrect : No Compute can be maked on it " << endl; + #endif + // presentation of the bounding box is calculated + // Compute(aPresentationManager,aPrs,2); + } + break; + } + case AIS_Shaded: { if (myDrawer->IsAutoTriangulation()) { @@ -170,41 +182,57 @@ void AIS_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*aPresentat } } - //shading only on face... - if ((Standard_Integer) myshape.ShapeType()>4) - StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); - else { - myDrawer->SetShadingAspectGlobal(Standard_False); - if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); - else { + if ((Standard_Integer) myshape.ShapeType() > 4) + { + StdPrs_WFShape::Add (aPrs, myshape, myDrawer); + } + else + { + myDrawer->SetShadingAspectGlobal (Standard_False); + if (IsInfinite()) + { + StdPrs_WFShape::Add (aPrs, myshape, myDrawer); + } + else + { + try { - try { - OCC_CATCH_SIGNALS - StdPrs_ShadedShape::Add(aPrs,myshape,myDrawer); - } - catch (Standard_Failure) { -#ifdef OCCT_DEBUG - cout << "AIS_Shape::Compute() in ShadingMode failed"<< endl; -#endif - StdPrs_WFShape::Add(aPrs,myshape,myDrawer); - } + OCC_CATCH_SIGNALS + StdPrs_ShadedShape::Add (aPrs, myshape, myDrawer); + } + catch (Standard_Failure) + { + #ifdef OCCT_DEBUG + cout << "AIS_Shape::Compute() in ShadingMode failed" << endl; + #endif + StdPrs_WFShape::Add (aPrs, myshape, myDrawer); } } } - Standard_Real value = Transparency() ; - if( value > 0. ) { - SetTransparency( value ); + Standard_Real aTransparency = Transparency() ; + if (aTransparency > 0.0) + { + SetTransparency (aTransparency); } break; } - case 2: + + // Bounding box. + case 2: { - // bounding box - if (IsInfinite()) StdPrs_WFDeflectionShape::Add(aPrs,myshape,myDrawer); - else StdPrs_WFDeflectionRestrictedFace::AddBox (aPrs, BoundingBox(), myDrawer); + if (IsInfinite()) + { + StdPrs_WFShape::Add (aPrs, myshape, myDrawer); + } + else + { + StdPrs_BndBox::Add (aPrs, BoundingBox(), myDrawer); + } } - } // end switch - aPrs->ReCompute(); // for hidden line recomputation if necessary... + } + + // Recompute hidden line presentation (if necessary). + aPrs->ReCompute(); } //======================================================================= diff --git a/src/AIS/AIS_TexturedShape.cxx b/src/AIS/AIS_TexturedShape.cxx index 06922be623..cb5bc279f4 100644 --- a/src/AIS/AIS_TexturedShape.cxx +++ b/src/AIS/AIS_TexturedShape.cxx @@ -34,9 +34,9 @@ #include #include #include +#include #include -#include -#include +#include #include #include @@ -438,7 +438,7 @@ void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*t { case AIS_WireFrame: { - StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer); + StdPrs_WFShape::Add (thePrs, myshape, myDrawer); break; } case AIS_Shaded: @@ -462,14 +462,14 @@ void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*t if (myshape.ShapeType() > TopAbs_FACE) { - StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer); + StdPrs_WFShape::Add (thePrs, myshape, myDrawer); break; } myDrawer->SetShadingAspectGlobal (Standard_False); if (IsInfinite()) { - StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer); + StdPrs_WFShape::Add (thePrs, myshape, myDrawer); break; } try @@ -502,11 +502,11 @@ void AIS_TexturedShape::Compute (const Handle(PrsMgr_PresentationManager3d)& /*t { if (IsInfinite()) { - StdPrs_WFDeflectionShape::Add (thePrs, myshape, myDrawer); + StdPrs_WFShape::Add (thePrs, myshape, myDrawer); } else { - StdPrs_WFDeflectionRestrictedFace::AddBox (thePrs, BoundingBox(), myDrawer); + StdPrs_BndBox::Add (thePrs, BoundingBox(), myDrawer); } break; } diff --git a/src/Prs3d/FILES b/src/Prs3d/FILES index 974e990b47..daa96b6ca1 100755 --- a/src/Prs3d/FILES +++ b/src/Prs3d/FILES @@ -50,5 +50,3 @@ Prs3d_TextAspect.hxx Prs3d_TypeOfHLR.hxx Prs3d_TypeOfLinePicking.hxx Prs3d_VertexDrawMode.hxx -Prs3d_WFShape.cxx -Prs3d_WFShape.hxx diff --git a/src/Prs3d/Prs3d_Drawer.cxx b/src/Prs3d/Prs3d_Drawer.cxx index e7beea19f1..ccf8b96381 100644 --- a/src/Prs3d/Prs3d_Drawer.cxx +++ b/src/Prs3d/Prs3d_Drawer.cxx @@ -48,6 +48,8 @@ Prs3d_Drawer::Prs3d_Drawer() myHasOwnHLRDeviationAngle (Standard_False), myIsoOnPlane (Standard_False), myHasOwnIsoOnPlane (Standard_False), + myIsoOnTriangulation (Standard_False), + myHasOwnIsoOnTriangulation (Standard_False), myIsAutoTriangulated (Standard_True), myHasOwnIsAutoTriangulated (Standard_False), @@ -148,6 +150,16 @@ Prs3d_TypeOfHLR Prs3d_Drawer::TypeOfHLR() return myTypeOfHLR; } +// ======================================================================= +// function : SetIsoOnTriangulation +// purpose : +// ======================================================================= +void Prs3d_Drawer::SetIsoOnTriangulation (const Standard_Boolean theToEnable) +{ + myHasOwnIsoOnTriangulation = Standard_True; + myIsoOnTriangulation = theToEnable; +} + // ======================================================================= // function : SetMaximalParameterValue // purpose : @@ -1038,6 +1050,7 @@ void Prs3d_Drawer::ClearLocalAttributes() myHasOwnDeviationAngle = Standard_False; myHasOwnHLRDeviationAngle = Standard_False; myHasOwnIsoOnPlane = Standard_False; + myHasOwnIsoOnTriangulation = Standard_False; myHasOwnIsAutoTriangulated = Standard_False; myHasOwnWireDraw = Standard_False; myHasOwnShadingAspectGlobal = Standard_False; diff --git a/src/Prs3d/Prs3d_Drawer.hxx b/src/Prs3d/Prs3d_Drawer.hxx index 19ba6aaf39..ae7938bfab 100644 --- a/src/Prs3d/Prs3d_Drawer.hxx +++ b/src/Prs3d/Prs3d_Drawer.hxx @@ -128,6 +128,20 @@ public: //! Returns true if the drawer has IsoOnPlane setting active. Standard_Boolean HasOwnIsoOnPlane() const { return myHasOwnIsoOnPlane; } + //! Returns True if the drawing of isos on triangulation is enabled. + Standard_Boolean IsoOnTriangulation() const + { + return HasOwnIsoOnTriangulation() || myLink.IsNull() + ? myIsoOnTriangulation + : myLink->IsoOnTriangulation(); + } + + //! Returns true if the drawer has IsoOnTriangulation setting active. + Standard_Boolean HasOwnIsoOnTriangulation() const { return myHasOwnIsoOnTriangulation; } + + //! Enables or disables isolines on triangulation by setting the parameter theIsEnabled to true or false. + Standard_EXPORT void SetIsoOnTriangulation (const Standard_Boolean theToEnable); + //! Sets the discretisation parameter theValue. Standard_EXPORT void SetDiscretisation (const Standard_Integer theValue); @@ -849,6 +863,8 @@ protected: Standard_Real myPreviousHLRDeviationAngle; Standard_Boolean myIsoOnPlane; Standard_Boolean myHasOwnIsoOnPlane; + Standard_Boolean myIsoOnTriangulation; + Standard_Boolean myHasOwnIsoOnTriangulation; Standard_Boolean myIsAutoTriangulated; Standard_Boolean myHasOwnIsAutoTriangulated; diff --git a/src/Prs3d/Prs3d_WFShape.cxx b/src/Prs3d/Prs3d_WFShape.cxx deleted file mode 100755 index 2d0a7f1c32..0000000000 --- a/src/Prs3d/Prs3d_WFShape.cxx +++ /dev/null @@ -1,730 +0,0 @@ -// Copyright (c) 2013-2014 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 -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -namespace -{ - - //! Compare two aspects - inline Standard_Boolean IsSame (const Handle(Graphic3d_AspectLine3d)& theUAspect, - const Handle(Graphic3d_AspectLine3d)& theVAspect) - { - Quantity_Color aCU, aCV; - Aspect_TypeOfLine aTlU, aTlV; - Standard_Real aWU, aWV; - theUAspect->Values (aCU, aTlU, aWU); - theVAspect->Values (aCV, aTlV, aWV); - return aCU == aCV - && aTlU == aTlV - && aWU == aWV; - } - -}; - -// ========================================================================= -// function: AddPolygon -// purpose : -// ========================================================================= -Standard_Boolean Prs3d_WFShape::AddPolygon (const TopoDS_Edge& theEdge, - TColgp_SequenceOfPnt& thePoints) -{ - TopLoc_Location aLocation; - Handle(Poly_Polygon3D) aPolygon = BRep_Tool::Polygon3D (theEdge, aLocation); - if (!aPolygon.IsNull()) - { - const TColgp_Array1OfPnt& aPoints = aPolygon->Nodes(); - Standard_Integer anIndex = aPoints.Lower(); - if (aLocation.IsIdentity()) - { - for (; anIndex <= aPoints.Upper(); ++anIndex) - { - thePoints.Append (aPoints.Value (anIndex)); - } - } - else - { - for (; anIndex <= aPoints.Upper(); ++anIndex) - { - thePoints.Append (aPoints.Value (anIndex).Transformed (aLocation)); - } - } - return Standard_True; - } - - Handle(Poly_Triangulation) aTriangulation; - Handle(Poly_PolygonOnTriangulation) aHIndices; - BRep_Tool::PolygonOnTriangulation (theEdge, aHIndices, aTriangulation, aLocation); - if (!aHIndices.IsNull()) - { - const TColStd_Array1OfInteger& anIndices = aHIndices->Nodes(); - const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); - - Standard_Integer anIndex = anIndices.Lower(); - if (aLocation.IsIdentity()) - { - for (; anIndex <= anIndices.Upper(); ++anIndex) - { - thePoints.Append (aNodes (anIndices (anIndex))); - } - } - else - { - for (; anIndex <= anIndices.Upper(); ++anIndex) - { - thePoints.Append (aNodes (anIndices (anIndex)).Transformed (aLocation)); - } - } - return Standard_True; - } - return Standard_False; -} - -// ========================================================================= -// function: Add -// purpose : -// ========================================================================= -void Prs3d_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) -{ - if (theShape.IsNull()) - { - return; - } - - Prs3d_ShapeTool aTool (theShape, theDrawer->VertexDrawMode() == Prs3d_VDM_All); - TopTools_ListOfShape aLFree, aLUnFree, aLWire; - for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve()) - { - const TopoDS_Edge& anEdge = aTool.GetCurve(); - switch (aTool.Neighbours()) - { - case 0: aLWire.Append (anEdge); break; - case 1: aLFree.Append (anEdge); break; - default: aLUnFree.Append (anEdge); break; - } - } - - Standard_Real aDeflection = Prs3d::GetDeflection(theShape, theDrawer); - - Prs3d_NListOfSequenceOfPnt anUIsoCurves; - Prs3d_NListOfSequenceOfPnt aVIsoCurves; - Prs3d_NListOfSequenceOfPnt aWireCurves; - Prs3d_NListOfSequenceOfPnt aFreeCurves; - Prs3d_NListOfSequenceOfPnt anUnFreeCurves; - - const Standard_Integer anIsoU = theDrawer->UIsoAspect()->Number(); - const Standard_Integer anIsoV = theDrawer->VIsoAspect()->Number(); - - Standard_Boolean hasIsoU = anIsoU > 0; - Standard_Boolean hasIsoV = anIsoV > 0; - - if (IsSame (theDrawer->UIsoAspect()->Aspect(), - theDrawer->VIsoAspect()->Aspect())) - { - if (hasIsoU || hasIsoV) - { - BRepAdaptor_Surface aSurface; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - if (aTool.HasSurface()) - { - if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane()) - { - aSurface.Initialize (aTool.GetFace()); - Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface); - try - { - OCC_CATCH_SIGNALS - Prs3d_NListOfSequenceOfPnt aCurUIsoCurves; - myFaceAlgo.Add (thePresentation, aHSurface, - hasIsoU, hasIsoV, - aDeflection, - anIsoU, anIsoV, - theDrawer, - aCurUIsoCurves); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (aCurUIsoCurves); anIt.More(); anIt.Next()) - { - anUIsoCurves.Append (anIt.Value()); - } - } - catch (Standard_Failure) - { - } - } - } - } - } - } - else - { - if (hasIsoU) - { - BRepAdaptor_Surface aSurface; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - if (aTool.HasSurface()) - { - if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane()) - { - aSurface.Initialize (aTool.GetFace()); - Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface); - try - { - OCC_CATCH_SIGNALS - Prs3d_NListOfSequenceOfPnt aCurUIsoCurves; - myFaceAlgo.Add (thePresentation, aHSurface, - hasIsoU, Standard_False, - aDeflection, - anIsoU, 0, - theDrawer, - aCurUIsoCurves); - } - catch (Standard_Failure) - { - #ifdef OCCT_DEBUG - const TopoDS_Face& aFace = aSurface.Face(); - std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl; - #endif - } - } - } - } - } - if (hasIsoV) - { - BRepAdaptor_Surface aSurface; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - if (aTool.HasSurface()) - { - if (!aTool.IsPlanarFace() || theDrawer->IsoOnPlane()) - { - aSurface.Initialize (aTool.GetFace()); - Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface); - try - { - OCC_CATCH_SIGNALS - Prs3d_NListOfSequenceOfPnt aCurUIsoCurves; - myFaceAlgo.Add (thePresentation, aHSurface, - Standard_False, hasIsoV, - aDeflection, - 0, anIsoV, - theDrawer, - aCurUIsoCurves); - } - catch (Standard_Failure) - { - #ifdef OCCT_DEBUG - const TopoDS_Face& aFace = aSurface.Face(); - std::cout << "Problem with the face " << (void* ) &(*(aFace).TShape()) << std::endl; - #endif - } - } - } - } - } - } - - Standard_Integer aNbVertices = 0, aNbBounds = 0; - if (anUIsoCurves.Size() > 0) - { - aNbBounds = anUIsoCurves.Size(); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next()) - { - aNbVertices += anIt.Value()->Length(); - } - Handle(Graphic3d_ArrayOfPolylines) anUIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anIt.Init (anUIsoCurves); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - anUIsoArray->AddBound (aPoints->Length()); - for (Standard_Integer anI = 1; anI <= aPoints->Length(); ++anI) - { - anUIsoArray->AddVertex (aPoints->Value (anI)); - } - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->UIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (anUIsoArray); - } - - // NOTE: THIS BLOCK WILL NEVER EXECUTE AS aVIsoCurves IS NOT FILLED!! - if (aVIsoCurves.Size() > 0) - { - aNbBounds = aVIsoCurves.Size(); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next()) - { - aNbVertices += anIt.Value()->Length(); - } - Handle(Graphic3d_ArrayOfPolylines) VIsoArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anIt.Init (aVIsoCurves); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - VIsoArray->AddBound (aPoints->Length()); - for (int anI = 1; anI <= aPoints->Length(); anI++) - { - VIsoArray->AddVertex (aPoints->Value (anI)); - } - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->VIsoAspect()->Aspect()); - aGroup->AddPrimitiveArray (VIsoArray); - } - - TopLoc_Location aLocation; - Standard_Integer anI, aJ, aN[3]; - - TColgp_SequenceOfPnt aSurfPoints; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - if (!aTool.HasSurface()) - { - Handle(Poly_Triangulation) T = aTool.CurrentTriangulation (aLocation); - if (!T.IsNull()) - { - const TColgp_Array1OfPnt& aNodes = T->Nodes(); - // Build the connect tool - Poly_Connect aPolyConnect (T); - - Standard_Integer aNbTriangles = T->NbTriangles(); - Standard_Integer aT[3]; - - // Count the free edges - Standard_Integer aNbFree = 0; - for (anI = 1; anI <= aNbTriangles; ++anI) - { - aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); - for (aJ = 0; aJ < 3; ++aJ) - { - if (aT[aJ] == 0) - { - ++aNbFree; - } - } - } - - // Allocate the arrays - TColStd_Array1OfInteger aFree (1, 2 * aNbFree); - Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2; - TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal); - - Standard_Integer aFreeIndex = 1, anIntIndex = 1; - const Poly_Array1OfTriangle& aTriangles = T->Triangles(); - for (anI = 1; anI <= aNbTriangles; ++anI) - { - aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); - aTriangles (anI).Get (aN[0], aN[1], aN[2]); - for (aJ = 0; aJ < 3; aJ++) - { - Standard_Integer k = (aJ + 1) % 3; - if (aT[aJ] == 0) - { - aFree (aFreeIndex) = aN[aJ]; - aFree (aFreeIndex + 1) = aN[k]; - aFreeIndex += 2; - } - // internal edge if this triangle has a lower index than the adjacent - else if (anI < aT[aJ]) - { - anInternal (anIntIndex) = aN[aJ]; - anInternal (anIntIndex + 1) = aN[k]; - anIntIndex += 2; - } - } - } - - if (!aTool.HasSurface()) - { - // free edges - Standard_Integer aFreeHalfNb = aFree.Length() / 2; - for (anI = 1; anI <= aFreeHalfNb; ++anI) - { - gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation); - gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation); - aSurfPoints.Append (aPoint1); - aSurfPoints.Append (aPoint2); - } - } - } - } - } - if (aSurfPoints.Length() > 0) - { - aNbVertices = aSurfPoints.Length(); - aNbBounds = (Standard_Integer)aNbVertices / 2; - Handle(Graphic3d_ArrayOfPolylines) aSurfArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anI = 1; anI <= aNbVertices; anI += 2) - { - aSurfArray->AddBound (2); - aSurfArray->AddVertex (aSurfPoints.Value (anI)); - aSurfArray->AddVertex (aSurfPoints.Value (anI + 1)); - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect()); - aGroup->AddPrimitiveArray (aSurfArray); - } - - TopTools_ListIteratorOfListOfShape anIt; - if (theDrawer->WireDraw()) - { - // Wire (without any neighbour) - for (anIt.Initialize(aLWire); anIt.More(); anIt.Next()) - { - const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value()); - try - { - OCC_CATCH_SIGNALS - const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt; - if (!AddPolygon (anEdge, aPoints->ChangeSequence())) - { - if (BRep_Tool::IsGeometric (anEdge)) - { - BRepAdaptor_Curve aCurve (anEdge); - myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer, - aPoints->ChangeSequence(), Standard_False); - aWireCurves.Append (aPoints); - } - } - else - { - aWireCurves.Append (aPoints); - } - } - catch (Standard_Failure) - { - #ifdef OCCT_DEBUG - std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl; - #endif - } - } - } - - if (theDrawer->FreeBoundaryDraw()) - { - // aFree boundaries; - for (anIt.Initialize (aLFree); anIt.More(); anIt.Next()) - { - const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value()); - if (!BRep_Tool::Degenerated (anEdge)) - { - try - { - OCC_CATCH_SIGNALS - const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt; - if (!AddPolygon (anEdge, aPoints->ChangeSequence())) - { - if (BRep_Tool::IsGeometric (anEdge)) - { - BRepAdaptor_Curve aCurve (anEdge); - myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer, - aPoints->ChangeSequence(), Standard_False); - aFreeCurves.Append (aPoints); - } - } - else - { - aFreeCurves.Append (aPoints); - } - } - catch (Standard_Failure) - { - #ifdef OCCT_DEBUG - std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl; - #endif - } - } - } - } - - if (theDrawer->UnFreeBoundaryDraw()) - { - // Unfree boundaries; - for (anIt.Initialize (aLUnFree); anIt.More(); anIt.Next()) - { - const TopoDS_Edge& anEdge = TopoDS::Edge (anIt.Value()); - try - { - OCC_CATCH_SIGNALS - const Handle(TColgp_HSequenceOfPnt)& aPoints = new TColgp_HSequenceOfPnt; - if (!AddPolygon (anEdge, aPoints->ChangeSequence())) - { - if (BRep_Tool::IsGeometric (anEdge)) - { - BRepAdaptor_Curve aCurve (anEdge); - myCurveAlgo.Add (thePresentation, aCurve, aDeflection, theDrawer, aPoints->ChangeSequence(), Standard_False); - anUnFreeCurves.Append (aPoints); - } - } - else - { - anUnFreeCurves.Append (aPoints); - } - } - catch (Standard_Failure) - { - #ifdef OCCT_DEBUG - std::cout << "probleme sur aLocation'edge " << (void* ) &(*(anEdge).TShape()) << std::endl; - #endif - } - } - } - - if (aWireCurves.Size() > 0) - { - aNbBounds = aWireCurves.Size(); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (aWireCurves); anIt.More(); anIt.Next()) - { - aNbVertices += anIt.Value()->Length(); - } - Handle(Graphic3d_ArrayOfPolylines) WireArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anIt.Init (aWireCurves); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - WireArray->AddBound (aPoints->Length()); - for (anI = 1; anI <= aPoints->Length(); ++anI) - { - WireArray->AddVertex (aPoints->Value (anI)); - } - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->WireAspect()->Aspect()); - aGroup->AddPrimitiveArray (WireArray); - } - - if (aFreeCurves.Size() > 0) - { - aNbBounds = aFreeCurves.Size(); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (aFreeCurves); anIt.More(); anIt.Next()) - { - aNbVertices += anIt.Value()->Length(); - } - Handle(Graphic3d_ArrayOfPolylines) aFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anIt.Init(aFreeCurves); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - aFreeArray->AddBound (aPoints->Length()); - for (anI = 1; anI <= aPoints->Length(); ++anI) - { - aFreeArray->AddVertex (aPoints->Value (anI)); - } - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->FreeBoundaryAspect()->Aspect()); - aGroup->AddPrimitiveArray (aFreeArray); - } - - if (anUnFreeCurves.Size() > 0) - { - aNbBounds = anUnFreeCurves.Size(); - Prs3d_NListIteratorOfListOfSequenceOfPnt anIt; - for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next()) - { - aNbVertices += anIt.Value()->Length(); - } - Handle(Graphic3d_ArrayOfPolylines) anUnFreeArray = new Graphic3d_ArrayOfPolylines (aNbVertices, aNbBounds); - for (anIt.Init (anUnFreeCurves); anIt.More(); anIt.Next()) - { - const Handle(TColgp_HSequenceOfPnt)& aPoints = anIt.Value(); - anUnFreeArray->AddBound (aPoints->Length()); - for (anI = 1; anI <= aPoints->Length(); ++anI) - { - anUnFreeArray->AddVertex (aPoints->Value (anI)); - } - } - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->UnFreeBoundaryAspect()->Aspect()); - aGroup->AddPrimitiveArray (anUnFreeArray); - } - - // Points - TColgp_SequenceOfPnt aShapePoints; - for (aTool.InitVertex(); aTool.MoreVertex(); aTool.NextVertex()) - { - aShapePoints.Append (BRep_Tool::Pnt (aTool.GetVertex())); - } - - aNbVertices = aShapePoints.Length(); - if (aNbVertices > 0) - { - Handle(Graphic3d_ArrayOfPoints) aPointArray = new Graphic3d_ArrayOfPoints (aNbVertices); - for (anI = 1; anI <= aNbVertices; ++anI) - { - aPointArray->AddVertex (aShapePoints.Value (anI)); - } - - Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); - aGroup->SetPrimitivesAspect (theDrawer->PointAspect()->Aspect()); - aGroup->AddPrimitiveArray (aPointArray); - } -} - -// ========================================================================= -// function: PickCurve -// purpose : -// ========================================================================= -Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickCurve - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) -{ - Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape(); - Prs3d_ShapeTool aTool (theShape); - for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve()) - { - Bnd_Box aBndBox = aTool.CurveBound(); - aBndBox.Enlarge (theDistance); - if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ))) - { - if (myCurveAlgo.Match (theX, theY, theZ, theDistance, - BRepAdaptor_Curve (aTool.GetCurve()), theDrawer)) - { - Standard_Boolean isContain = Standard_False; - for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI) - { - if (aSeq->Value (anI) == (aTool.GetCurve())) - { - isContain = Standard_True; - break; - } - } - if (!isContain) - { - aSeq->Append (aTool.GetCurve()); - } - } - } - } - return aSeq; -} - -// ========================================================================= -// function: PickPatch -// purpose : -// ========================================================================= -Handle(TopTools_HSequenceOfShape) Prs3d_WFShape::PickPatch - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle(Prs3d_Drawer)& theDrawer) -{ - Handle(TopTools_HSequenceOfShape) aSeq = new TopTools_HSequenceOfShape(); - Prs3d_ShapeTool aTool (theShape); - - Standard_Boolean aRba1 = theDrawer->UIsoAspect()->Number() != 0; - Standard_Boolean aRba2 = theDrawer->VIsoAspect()->Number() != 0; - Standard_Boolean isContain; - - if (aRba1 || aRba2) - { - BRepAdaptor_Surface aSurface; - for (aTool.InitFace(); aTool.MoreFace(); aTool.NextFace()) - { - Bnd_Box aBndBox = aTool.FaceBound(); - aBndBox.Enlarge (theDistance); - if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ))) - { - aSurface.Initialize (aTool.GetFace()); - Handle(BRepAdaptor_HSurface) aHSurface = new BRepAdaptor_HSurface (aSurface); - if (myFaceAlgo.Match (theX, theY, theZ, theDistance, aHSurface, theDrawer)) - { - isContain = Standard_False; - for (Standard_Integer anI = 1; anI <= aSeq->Length(); ++anI) - { - if (aSeq->Value (anI) == (aTool.GetFace())) - { - isContain = Standard_True; - break; - } - } - if (!isContain) - { - aSeq->Append (aTool.GetFace()); - } - } - } - } - } - - for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve()) - { - Bnd_Box aBndBox = aTool.CurveBound(); - aBndBox.Enlarge (theDistance); - if (!aBndBox.IsOut (gp_Pnt (theX, theY, theZ))) - { - if (myCurveAlgo.Match (theX, theY, theZ, theDistance, - BRepAdaptor_Curve(aTool.GetCurve()), theDrawer)) - { - Handle(TopTools_HSequenceOfShape) aSurface = aTool.FacesOfEdge(); - for (Standard_Integer anI = 1; anI <= aSurface->Length(); ++anI) - { - isContain = Standard_False; - for (Standard_Integer aJ = 1; aJ <= aSeq->Length(); ++aJ) - { - if (aSeq->Value (aJ) == (aSurface->Value (anI))) - { - isContain = Standard_True; - break; - } - } - if (!isContain) - { - aSeq->Append (aSurface->Value (anI)); - } - } - } - } - } - return aSeq; -} diff --git a/src/Prs3d/Prs3d_WFShape.hxx b/src/Prs3d/Prs3d_WFShape.hxx deleted file mode 100755 index cd644b843a..0000000000 --- a/src/Prs3d/Prs3d_WFShape.hxx +++ /dev/null @@ -1,121 +0,0 @@ -// Copyright (c) 2013-2014 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. - -#ifndef _Prs3d_WFShape_H__ -#define _Prs3d_WFShape_H__ - -#include -#include -#include -#include - -class Adaptor3d_Curve; -class BRepAdaptor_HSurface; -class TopoDS_Edge; -class TopoDS_Shape; -class Prs3d_Drawer; - -class Prs3d_WFShape : Prs3d_Root -{ - -public: - - DEFINE_STANDARD_ALLOC - -public: - - class Face - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - const Handle(BRepAdaptor_HSurface)& theFace, - const Standard_Boolean theToDrawUIso, - const Standard_Boolean theToDrawVIso, - const Quantity_Length theDeflection, - const Standard_Integer theNBUiso, - const Standard_Integer theNBViso, - const Handle(Prs3d_Drawer)& theDrawer, - Prs3d_NListOfSequenceOfPnt& theCurves) const = 0; - - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Handle(BRepAdaptor_HSurface)& theFace, - const Handle(Prs3d_Drawer)& theDrawer) const = 0; - }; - - class Curve - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - Adaptor3d_Curve& theCurve, - const Quantity_Length theDeflection, - const Handle(Prs3d_Drawer)& theDrawer, - TColgp_SequenceOfPnt& thePoints, - const Standard_Boolean theToDrawCurve) const = 0; - - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Adaptor3d_Curve& theCurve, - const Handle(Prs3d_Drawer)& theDrawer) const = 0; - }; - - inline Prs3d_WFShape (const Face& theFace, - const Curve& theCurve) - : myFaceAlgo (theFace), - myCurveAlgo (theCurve) {} - -public: - - //! Add shape to presentation - Standard_EXPORT void Add (const Handle (Prs3d_Presentation)& thePresentation, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer); - - Standard_EXPORT Handle(TopTools_HSequenceOfShape) PickCurve - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer); - - Standard_EXPORT Handle(TopTools_HSequenceOfShape) PickPatch - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle(Prs3d_Drawer)& theDrawer); - -private: - - static Standard_Boolean AddPolygon (const TopoDS_Edge& theEdge, - TColgp_SequenceOfPnt& thePoints); - -private: - - const Face& myFaceAlgo; - const Curve& myCurveAlgo; - -private: - - Prs3d_WFShape (const Prs3d_WFShape& ); - Prs3d_WFShape& operator= (const Prs3d_WFShape& ); - -}; - -#endif // _Prs3d_WFShape_H__ diff --git a/src/StdPrs/FILES b/src/StdPrs/FILES index 3d346fef65..7144b189d3 100644 --- a/src/StdPrs/FILES +++ b/src/StdPrs/FILES @@ -1,3 +1,5 @@ +StdPrs_BndBox.cxx +StdPrs_BndBox.hxx StdPrs_Curve.cxx StdPrs_Curve.hxx StdPrs_DeflectionCurve.cxx @@ -8,6 +10,8 @@ StdPrs_HLRShape.cxx StdPrs_HLRShape.hxx StdPrs_HLRToolShape.cxx StdPrs_HLRToolShape.hxx +StdPrs_Isolines.cxx +StdPrs_Isolines.hxx StdPrs_Plane.cxx StdPrs_Plane.hxx StdPrs_Point.hxx @@ -21,21 +25,24 @@ StdPrs_ToolPoint.cxx StdPrs_ToolPoint.hxx StdPrs_ToolRFace.cxx StdPrs_ToolRFace.hxx -StdPrs_ToolShadedShape.cxx -StdPrs_ToolShadedShape.hxx +StdPrs_ToolTriangulatedShape.cxx +StdPrs_ToolTriangulatedShape.cxx +StdPrs_ToolTriangulatedShape.hxx +StdPrs_ToolTriangulatedShape.hxx StdPrs_ToolVertex.cxx StdPrs_ToolVertex.hxx StdPrs_Vertex.hxx StdPrs_Volume.hxx StdPrs_WFDeflectionRestrictedFace.cxx StdPrs_WFDeflectionRestrictedFace.hxx -StdPrs_WFDeflectionShape.hxx StdPrs_WFDeflectionSurface.cxx StdPrs_WFDeflectionSurface.hxx StdPrs_WFPoleSurface.cxx StdPrs_WFPoleSurface.hxx StdPrs_WFRestrictedFace.cxx +StdPrs_WFRestrictedFace.cxx StdPrs_WFRestrictedFace.hxx +StdPrs_WFShape.cxx StdPrs_WFShape.hxx StdPrs_WFSurface.cxx StdPrs_WFSurface.hxx diff --git a/src/StdPrs/StdPrs_BndBox.cxx b/src/StdPrs/StdPrs_BndBox.cxx new file mode 100644 index 0000000000..73aecef00a --- /dev/null +++ b/src/StdPrs/StdPrs_BndBox.cxx @@ -0,0 +1,65 @@ +// Created on: 2014-10-14 +// Created by: Anton POLETAEV +// Copyright (c) 2013-2014 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 + +namespace +{ + static const Standard_Integer THE_INDICES[][3] = + { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 }, + { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 }, + { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, + { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } }; +} + +//======================================================================= +//function : Add +//purpose : +//======================================================================= +void StdPrs_BndBox::Add (const Handle(Prs3d_Presentation)& thePresentation, + const Bnd_Box& theBndBox, + const Handle(Prs3d_Drawer)& theDrawer) +{ + if (theBndBox.IsVoid()) + { + return; + } + + Standard_Real X[2], Y[2], Z[2]; + theBndBox.Get (X[0], Y[0], Z[0], X[1], Y[1], Z[1]); + + Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePresentation); + Quantity_Color aColor; + Aspect_TypeOfLine aDummyLineType; + Standard_Real aWidth = 1.0; + theDrawer->LineAspect()->Aspect()->Values (aColor, aDummyLineType, aWidth); + + aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (aColor, Aspect_TOL_DOTDASH, aWidth)); + + Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16); + for(Standard_Integer aVertIter = 0; aVertIter < 16; ++aVertIter) + { + aPolyline->AddVertex (X[THE_INDICES[aVertIter][0]], + Y[THE_INDICES[aVertIter][1]], + Z[THE_INDICES[aVertIter][2]]); + } + aGroup->AddPrimitiveArray (aPolyline); +} diff --git a/src/StdPrs/StdPrs_BndBox.hxx b/src/StdPrs/StdPrs_BndBox.hxx new file mode 100644 index 0000000000..a68e999765 --- /dev/null +++ b/src/StdPrs/StdPrs_BndBox.hxx @@ -0,0 +1,38 @@ +// Created on: 2014-10-14 +// Created by: Anton POLETAEV +// Copyright (c) 2013-2014 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. + +#ifndef _StdPrs_BndBox_H__ +#define _StdPrs_BndBox_H__ + +#include +#include +#include +#include + +//! Tool for computing bounding box presentation. +class StdPrs_BndBox : public Prs3d_Root +{ +public: + + //! Computes presentation of a bounding box. + //! @param thePresentation [in] the presentation. + //! @param theBndBox [in] the bounding box. + //! @param theDrawer [in] the drawer. + Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation, + const Bnd_Box& theBndBox, + const Handle(Prs3d_Drawer)& theDrawer); +}; + +#endif // _StdPrs_BndBox_H__ diff --git a/src/StdPrs/StdPrs_Curve.cxx b/src/StdPrs/StdPrs_Curve.cxx index ec2501181d..3171a7db78 100644 --- a/src/StdPrs/StdPrs_Curve.cxx +++ b/src/StdPrs/StdPrs_Curve.cxx @@ -244,11 +244,10 @@ void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation, // purpose: //================================================================== void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation, - const Adaptor3d_Curve& aCurve, - const Quantity_Length /*aDeflection*/, + const Adaptor3d_Curve& aCurve, const Handle(Prs3d_Drawer)& aDrawer, - TColgp_SequenceOfPnt& Points, - const Standard_Boolean drawCurve) + TColgp_SequenceOfPnt& Points, + const Standard_Boolean drawCurve) { Standard_Real V1, V2; FindLimits(aCurve, aDrawer->MaximalParameterValue(), V1, V2); @@ -257,24 +256,21 @@ void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation, DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,V1,V2,Points,drawCurve); } - //================================================================== // function: Add // purpose: //================================================================== void StdPrs_Curve::Add (const Handle (Prs3d_Presentation)& aPresentation, - const Adaptor3d_Curve& aCurve, + const Adaptor3d_Curve& aCurve, const Standard_Real U1, const Standard_Real U2, - const Quantity_Length /*aDeflection*/, TColgp_SequenceOfPnt& Points, const Standard_Integer NbPoints, - const Standard_Boolean drawCurve) + const Standard_Boolean drawCurve) { DrawCurve(aCurve,Prs3d_Root::CurrentGroup(aPresentation),NbPoints,U1,U2,Points,drawCurve); } - //================================================================== // function: Add // purpose: diff --git a/src/StdPrs/StdPrs_Curve.hxx b/src/StdPrs/StdPrs_Curve.hxx index c303cda3d0..4721d3ecca 100644 --- a/src/StdPrs/StdPrs_Curve.hxx +++ b/src/StdPrs/StdPrs_Curve.hxx @@ -64,7 +64,7 @@ public: //! If drawCurve equals Standard_False the curve will not be displayed, //! it is used if the curve is a part of some shape and PrimitiveArray //! visualization approach is activated (it is activated by default). - Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& aPresentation, const Adaptor3d_Curve& aCurve, const Quantity_Length aDeflection, const Handle(Prs3d_Drawer)& aDrawer, TColgp_SequenceOfPnt& Points, const Standard_Boolean drawCurve = Standard_True); + Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& aPresentation, const Adaptor3d_Curve& aCurve, const Handle(Prs3d_Drawer)& aDrawer, TColgp_SequenceOfPnt& Points, const Standard_Boolean drawCurve = Standard_True); //! adds to the presentation aPresentation the drawing of the curve //! aCurve. @@ -76,7 +76,7 @@ public: //! If drawCurve equals Standard_False the curve will not be displayed, //! it is used if the curve is a part of some shape and PrimitiveArray //! visualization approach is activated (it is activated by default). - Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& aPresentation, const Adaptor3d_Curve& aCurve, const Standard_Real U1, const Standard_Real U2, const Quantity_Length aDeflection, TColgp_SequenceOfPnt& Points, const Standard_Integer aNbPoints = 30, const Standard_Boolean drawCurve = Standard_True); + Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& aPresentation, const Adaptor3d_Curve& aCurve, const Standard_Real U1, const Standard_Real U2, TColgp_SequenceOfPnt& Points, const Standard_Integer aNbPoints = 30, const Standard_Boolean drawCurve = Standard_True); //! returns true if the distance between the point (X,Y,Z) and the //! drawing of the curve is less than aDistance. diff --git a/src/StdPrs/StdPrs_Isolines.cxx b/src/StdPrs/StdPrs_Isolines.cxx new file mode 100644 index 0000000000..739c97c7e5 --- /dev/null +++ b/src/StdPrs/StdPrs_Isolines.cxx @@ -0,0 +1,753 @@ +// Created on: 2014-10-14 +// Created by: Anton POLETAEV +// Copyright (c) 2013-2014 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 +#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 +#include +#include +#include +#include +#include + +typedef NCollection_Sequence Prs3d_NSequenceOfSequenceOfPnt; + +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)(); + } + + Standard_Integer aNbBounds = thePoints.Size(); + Standard_Integer aNbVertices = 0; + for (Prs3d_NSequenceOfSequenceOfPnt::Iterator anIt (thePoints); anIt.More(); anIt.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) + { + aPrimitives->AddVertex (aPoints->Value (anI)); + } + } + + return aPrimitives; + } + + //! Reoder and adjust to the limit a curve's parameter values. + //! @param theCurve [in] the curve. + //! @param theLimit [in] the parameter limit value. + //! @param theFirst [in/out] the first parameter value. + //! @param theLast [in/out] the last parameter value. + 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) + { + return; + } + + gp_Pnt aP1, aP2; + Standard_Real aDelta = 1.0; + if (isFirstInf && isLastInf) + { + do + { + aDelta *= 2.0; + 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.0; + theFirst = theLast - aDelta; + theCurve.D0 (theFirst, aP1); + } + while (aP1.Distance (aP2) < theLimit); + } + else if (isLastInf) + { + theCurve.D0 (theFirst, aP1); + do + { + aDelta *= 2.0; + theLast = theFirst + aDelta; + theCurve.D0 (theLast, aP2); + } + while (aP1.Distance (aP2) < theLimit); + } + } + +} + +//================================================================== +// function : AddOnTriangulation +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer) +{ + const Standard_Integer aNbIsoU = theDrawer->UIsoAspect()->Number(); + const Standard_Integer aNbIsoV = theDrawer->VIsoAspect()->Number(); + if (aNbIsoU < 1 && aNbIsoV < 1) + { + return; + } + + // Evalute parameters for uv isolines. + TColStd_SequenceOfReal aUIsoParams; + TColStd_SequenceOfReal aVIsoParams; + UVIsoParameters (theFace, aNbIsoU, aNbIsoV, theDrawer->MaximalParameterValue(), aUIsoParams, aVIsoParams); + + // Access surface definition. + TopLoc_Location aLocSurface; + Handle(Geom_Surface) aSurface = BRep_Tool::Surface (theFace, aLocSurface); + + // Access triangulation. + TopLoc_Location aLocTriangulation; + const Handle(Poly_Triangulation)& aTriangulation = BRep_Tool::Triangulation (theFace, aLocTriangulation); + if (aTriangulation.IsNull()) + { + return; + } + + // Setup equal location for surface and triangulation. + if (!aLocTriangulation.IsEqual (aLocSurface)) + { + aSurface = Handle (Geom_Surface)::DownCast ( + aSurface->Transformed ((aLocSurface / aLocTriangulation).Transformation())); + } + + AddOnTriangulation (thePresentation, + aTriangulation, + aSurface, + aLocTriangulation, + theDrawer, + aUIsoParams, + aVIsoParams); +} + +//================================================================== +// function : AddOnTriangulation +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const Handle(Poly_Triangulation)& theTriangulation, + const Handle(Geom_Surface)& theSurface, + const TopLoc_Location& theLocation, + const Handle(Prs3d_Drawer)& theDrawer, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams) +{ + const Standard_Integer aNbIsoU = theUIsoParams.Length(); + const Standard_Integer aNbIsoV = theVIsoParams.Length(); + + Prs3d_NSequenceOfSequenceOfPnt aUPolylines; + Prs3d_NSequenceOfSequenceOfPnt aVPolylines; + + const Poly_Array1OfTriangle& aTriangles = theTriangulation->Triangles(); + const TColgp_Array1OfPnt& aNodes = theTriangulation->Nodes(); + const TColgp_Array1OfPnt2d& aUVNodes = theTriangulation->UVNodes(); + + TColStd_Array1OfInteger aUIsoIndexes (1, aNbIsoU); + TColStd_Array1OfInteger aVIsoIndexes (1, aNbIsoV); + aUIsoIndexes.Init (-1); + aVIsoIndexes.Init (-1); + + for (Standard_Integer anI = aTriangles.Lower(); anI <= aTriangles.Upper(); ++anI) + { + Standard_Integer aNodeIdxs[3]; + aTriangles.Value (anI).Get (aNodeIdxs[0], aNodeIdxs[1],aNodeIdxs[2]); + const gp_Pnt aNodesXYZ[3] = { aNodes.Value (aNodeIdxs[0]), + aNodes.Value (aNodeIdxs[1]), + aNodes.Value (aNodeIdxs[2]) }; + const gp_Pnt2d aNodesUV[3] = { aUVNodes.Value (aNodeIdxs[0]), + aUVNodes.Value (aNodeIdxs[1]), + aUVNodes.Value (aNodeIdxs[2]) }; + + // Evaluate polyline points for u isolines. + for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoU; ++anIsoIdx) + { + gp_Pnt aSegment[2]; + 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)) + { + continue; + } + + if (aUIsoIndexes.Value (anIsoIdx) == -1) + { + aUPolylines.Append (new TColgp_HSequenceOfPnt()); + 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)); + } + + // Evaluate polyline points for v isolines. + for (Standard_Integer anIsoIdx = 1; anIsoIdx <= aNbIsoV; ++anIsoIdx) + { + gp_Pnt aSegment[2]; + const gp_Lin2d anIsolineUV = isoV (theVIsoParams.Value (anIsoIdx)); + + if (!findSegmentOnTriangulation (theSurface, anIsolineUV, aNodesXYZ, aNodesUV, aSegment)) + { + continue; + } + + if (aVIsoIndexes.Value (anIsoIdx) == -1) + { + aVPolylines.Append (new TColgp_HSequenceOfPnt()); + 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)); + } + } + + // 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); + } +} + +//================================================================== +// function : AddOnSurface +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection) +{ + const Standard_Integer aNbIsoU = theDrawer->UIsoAspect()->Number(); + const Standard_Integer aNbIsoV = theDrawer->VIsoAspect()->Number(); + if (aNbIsoU < 1 && aNbIsoV < 1) + { + return; + } + + // Evalute parameters for uv isolines. + TColStd_SequenceOfReal aUIsoParams; + TColStd_SequenceOfReal aVIsoParams; + UVIsoParameters (theFace, aNbIsoU, aNbIsoV, theDrawer->MaximalParameterValue(), aUIsoParams, aVIsoParams); + + BRepAdaptor_Surface aSurface (theFace); + AddOnSurface (thePresentation, + new BRepAdaptor_HSurface (aSurface), + theDrawer, + theDeflection, + aUIsoParams, + aVIsoParams); +} + +//================================================================== +// function : AddOnSurface +// purpose : +//================================================================== +void StdPrs_Isolines::AddOnSurface (const Handle(Prs3d_Presentation)& thePresentation, + const Handle(BRepAdaptor_HSurface)& theSurface, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams) +{ + // Choose a deflection for sampling edge uv curves. + Standard_Real aUVLimit = theDrawer->MaximalParameterValue(); + Standard_Real aUmin = Max (theSurface->FirstUParameter(), -aUVLimit); + Standard_Real aUmax = Min (theSurface->LastUParameter(), aUVLimit); + Standard_Real aVmin = Max (theSurface->FirstVParameter(), -aUVLimit); + 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 + { + OCC_CATCH_SIGNALS + // Determine edge points for trimming uv hatch region. + TColgp_SequenceOfPnt2d aTrimPoints; + StdPrs_ToolRFace anEdgeTool (theSurface); + for (anEdgeTool.Init(); anEdgeTool.More(); anEdgeTool.Next()) + { + TopAbs_Orientation anOrientation = anEdgeTool.Orientation(); + if (anOrientation != TopAbs_FORWARD && anOrientation != TopAbs_REVERSED) + { + continue; + } + + Adaptor2d_Curve2dPtr anEdgeCurve = anEdgeTool.Value(); + if (anEdgeCurve->GetType() != GeomAbs_Line) + { + GCPnts_QuasiUniformDeflection aSampler (*anEdgeCurve, aSamplerDeflection); + if (!aSampler.IsDone()) + { +#ifdef OCCT_DEBUG + std::cout << "Cannot evaluate curve on surface" << std::endl; +#endif + continue; + } + + Standard_Integer aNumberOfPoints = aSampler.NbPoints(); + if (aNumberOfPoints < 2) + { + continue; + } + + for (Standard_Integer anI = 1; anI < aNumberOfPoints; ++anI) + { + gp_Pnt2d aP1 (aSampler.Value (anI ).X(), aSampler.Value (anI ).Y()); + gp_Pnt2d aP2 (aSampler.Value (anI + 1).X(), aSampler.Value (anI + 1).Y()); + + aHatchingTolerance = Min (aP1.SquareDistance (aP2), aHatchingTolerance); + + aTrimPoints.Append (anOrientation == TopAbs_FORWARD ? aP1 : aP2); + aTrimPoints.Append (anOrientation == TopAbs_FORWARD ? aP2 : aP1); + } + } + else + { + Standard_Real aU1 = anEdgeCurve->FirstParameter(); + Standard_Real aU2 = anEdgeCurve->LastParameter(); + + // MSV 17.08.06 OCC13144: U2 occured less than U1, to overcome it + // ensure that distance U2-U1 is not greater than aLimit*2, + // if greater then choose an origin and use aLimit to define + // U1 and U2 anew. + Standard_Real anOrigin = 0.0; + + if (!Precision::IsNegativeInfinite (aU1) || !Precision::IsPositiveInfinite(aU2)) + { + if (Precision::IsNegativeInfinite (aU1)) + { + anOrigin = aU2 - aUVLimit; + } + else if (Precision::IsPositiveInfinite (aU2)) + { + anOrigin = aU1 + aUVLimit; + } + else + { + anOrigin = (aU1 + aU2) * 0.5; + } + } + + aU1 = Max (anOrigin - aUVLimit, aU1); + aU2 = Min (anOrigin + aUVLimit, aU2); + + gp_Pnt2d aP1 = anEdgeCurve->Value (aU1); + gp_Pnt2d aP2 = anEdgeCurve->Value (aU2); + + aHatchingTolerance = Min (aP1.SquareDistance(aP2), aHatchingTolerance); + + aTrimPoints.Append (anOrientation == TopAbs_FORWARD ? aP1 : aP2); + aTrimPoints.Append (anOrientation == TopAbs_FORWARD ? aP2 : aP1); + } + } + + // Compute a hatching tolerance. + aHatchingTolerance *= 0.1; + aHatchingTolerance = Max (Precision::Confusion(), aHatchingTolerance); + aHatchingTolerance = Min (1.0E-5, aHatchingTolerance); + + // Load isolines into hatcher. + Hatch_Hatcher aHatcher (aHatchingTolerance, anEdgeTool.IsOriented()); + + for (Standard_Integer anIso = 1; anIso <= theUIsoParams.Length(); ++anIso) + { + aHatcher.AddXLine (theUIsoParams.Value (anIso)); + } + for (Standard_Integer anIso = 1; anIso <= theVIsoParams.Length(); ++anIso) + { + aHatcher.AddYLine (theVIsoParams.Value (anIso)); + } + + // Trim hatching region. + for (Standard_Integer anI = 1; anI <= aTrimPoints.Length(); anI += 2) + { + aHatcher.Trim (aTrimPoints (anI), aTrimPoints (anI + 1)); + } + + // Use surface definition for evaluation of Bezier, B-spline surface. + // Use isoline adapter for other types of surfaces. + GeomAbs_SurfaceType aSurfType = theSurface->GetType(); + Handle(Geom_Surface) aBSurface; + GeomAdaptor_Curve aBSurfaceCurve; + Adaptor3d_IsoCurve aCanonicalCurve; + if (aSurfType == GeomAbs_BezierSurface) + { + aBSurface = theSurface->Bezier(); + } + else if (aSurfType == GeomAbs_BSplineSurface) + { + aBSurface = theSurface->BSpline(); + } + else + { + aCanonicalCurve.Load (theSurface); + } + + // For each isoline: compute its segments. + for (Standard_Integer anI = 1; anI <= aHatcher.NbLines(); anI++) + { + Standard_Real anIsoParam = aHatcher.Coordinate (anI); + Standard_Boolean isIsoU = aHatcher.IsXLine (anI); + + // For each isoline's segment: evaluate its points. + for (Standard_Integer aJ = 1; aJ <= aHatcher.NbIntervals (anI); aJ++) + { + Standard_Real aSegmentP1 = aHatcher.Start (anI, aJ); + Standard_Real aSegmentP2 = aHatcher.End (anI, aJ); + + if (!aBSurface.IsNull()) + { + aBSurfaceCurve.Load (isIsoU ? aBSurface->UIso (anIsoParam) : aBSurface->VIso (anIsoParam)); + + findLimits (aBSurfaceCurve, aUVLimit, aSegmentP1, aSegmentP2); + + if (aSegmentP2 - aSegmentP1 <= Precision::Confusion()) + { + continue; + } + } + else + { + aCanonicalCurve.Load (isIsoU ? GeomAbs_IsoU : GeomAbs_IsoV, anIsoParam, aSegmentP1, aSegmentP2); + + findLimits (aCanonicalCurve, aUVLimit, aSegmentP1, aSegmentP2); + + if (aSegmentP2 - aSegmentP1 <= Precision::Confusion()) + { + continue; + } + } + Adaptor3d_Curve* aCurve = aBSurface.IsNull() ? (Adaptor3d_Curve*) &aCanonicalCurve + : (Adaptor3d_Curve*) &aBSurfaceCurve; + + Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt(); + StdPrs_DeflectionCurve::Add (thePresentation, + *aCurve, + aSegmentP1, + aSegmentP2, + theDeflection, + aPoints->ChangeSequence(), + theDrawer->DeviationAngle(), + Standard_False); + if (aPoints->IsEmpty()) + { + continue; + } + + if (isIsoU) + { + aUPolylines.Append (aPoints); + } + else + { + aVPolylines.Append (aPoints); + } + } + } + } + catch (Standard_Failure) + { + // ... + } + + // 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); + } +} + +//================================================================== +// function : UVIsoParameters +// purpose : +//================================================================== +void StdPrs_Isolines::UVIsoParameters (const TopoDS_Face& theFace, + const Standard_Integer theNbIsoU, + const Standard_Integer theNbIsoV, + const Standard_Real theUVLimit, + TColStd_SequenceOfReal& theUIsoParams, + TColStd_SequenceOfReal& theVIsoParams) +{ + Standard_Real aUmin = 0.0; + Standard_Real aUmax = 0.0; + Standard_Real aVmin = 0.0; + Standard_Real aVmax = 0.0; + + BRepTools::UVBounds (theFace, aUmin, aUmax, aVmin, aVmax); + + aUmin = Max (aUmin, -theUVLimit); + aUmax = Min (aUmax, theUVLimit); + aVmin = Max (aVmin, -theUVLimit); + aVmax = Min (aVmax, theUVLimit); + + TopLoc_Location aLocation; + Handle(Geom_Surface) aSurface = BRep_Tool::Surface (theFace, aLocation); + + const Standard_Boolean isUClosed = aSurface->IsUClosed(); + const Standard_Boolean isVClosed = aSurface->IsVClosed(); + + if (!isUClosed) + { + aUmin = aUmin + (aUmax - aUmin) / 1000.0; + aUmax = aUmax - (aUmax - aUmin) / 1000.0; + } + + if (!isVClosed) + { + aVmin = aVmin + (aVmax - aVmin) / 1000.0; + aVmax = aVmax - (aVmax - aVmin) / 1000.0; + } + + Standard_Real aUstep = (aUmax - aUmin) / (1 + theNbIsoU); + Standard_Real aVstep = (aVmax - aVmin) / (1 + theNbIsoV); + + for (Standard_Integer anIso = 1; anIso <= theNbIsoU; ++anIso) + { + theUIsoParams.Append (aUmin + aUstep * anIso); + } + + for (Standard_Integer anIso = 1; anIso <= theNbIsoV; ++anIso) + { + theVIsoParams.Append (aVmin + aVstep * anIso); + } +} + +//================================================================== +// function : FindSegmentOnTriangulation +// purpose : +//================================================================== +Standard_Boolean StdPrs_Isolines::findSegmentOnTriangulation (const Handle(Geom_Surface)& theSurface, + const gp_Lin2d& theIsoline, + const gp_Pnt* theNodesXYZ, + const gp_Pnt2d* theNodesUV, + gp_Pnt* theSegment) +{ + Standard_Integer aNPoints = 0; + + for (Standard_Integer aLinkIter = 0; aLinkIter < 3 && aNPoints < 2; ++aLinkIter) + { + // ... + // Check that uv isoline crosses the triangulation link in parametric space + // ... + + const gp_Pnt2d& aNodeUV1 = theNodesUV[aLinkIter]; + const gp_Pnt2d& aNodeUV2 = theNodesUV[(aLinkIter + 1) % 3]; + const gp_Pnt& aNode1 = theNodesXYZ[aLinkIter]; + const gp_Pnt& aNode2 = theNodesXYZ[(aLinkIter + 1) % 3]; + + // Compute distance of uv points to isoline taking into consideration their relative + // location against the isoline (left or right). Null value for a node means that the + // isoline crosses the node. Both positive or negative means that the isoline does not + // cross the segment. + Standard_Boolean isLeftUV1 = (theIsoline.Direction().XY() ^ gp_Vec2d (theIsoline.Location(), aNodeUV1).XY()) > 0.0; + Standard_Boolean isLeftUV2 = (theIsoline.Direction().XY() ^ gp_Vec2d (theIsoline.Location(), aNodeUV2).XY()) > 0.0; + Standard_Real aDistanceUV1 = isLeftUV1 ? theIsoline.Distance (aNodeUV1) : -theIsoline.Distance (aNodeUV1); + Standard_Real aDistanceUV2 = isLeftUV2 ? theIsoline.Distance (aNodeUV2) : -theIsoline.Distance (aNodeUV2); + + // Isoline crosses first point of an edge. + if (Abs (aDistanceUV1) < Precision::PConfusion()) + { + theSegment[aNPoints++] = aNode1; + continue; + } + + // Isoline crosses second point of an edge. + if (Abs (aDistanceUV2) < Precision::PConfusion()) + { + theSegment[aNPoints++] = aNode2; + aLinkIter++; + continue; + } + + // Isoline does not cross the triangle link. + if (aDistanceUV1 * aDistanceUV2 > 0.0) + { + continue; + } + + // Isoline crosses degenerated link. + if (aNode1.SquareDistance (aNode2) < Precision::PConfusion()) + { + theSegment[aNPoints++] = aNode1; + continue; + } + + // ... + // Derive cross-point from parametric coordinates + // ... + + Standard_Real anAlpha = Abs (aDistanceUV1) / (Abs (aDistanceUV1) + Abs (aDistanceUV2)); + + gp_Pnt aCross (0.0, 0.0, 0.0); + + // Is surface definition available? + if (theSurface.IsNull()) + { + // 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())); + } + 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; + Standard_Real aPntOnNode2Iso = 0.0; + Standard_Real aPntOnNode3Iso = 0.0; + + if (theIsoline.Direction().X() == 0.0) + { + aPntOnNode1Iso = aNodeUV1.X(); + aPntOnNode2Iso = aNodeUV2.X(); + aPntOnNode3Iso = aCrossU; + anIso1 = theSurface->VIso (aNodeUV1.Y()); + anIso2 = theSurface->VIso (aNodeUV2.Y()); + anIso3 = theSurface->VIso (aCrossV); + } + else if (theIsoline.Direction().Y() == 0.0) + { + aPntOnNode1Iso = aNodeUV1.Y(); + aPntOnNode2Iso = aNodeUV2.Y(); + aPntOnNode3Iso = aCrossV; + anIso1 = theSurface->UIso (aNodeUV1.X()); + anIso2 = theSurface->UIso (aNodeUV2.X()); + anIso3 = theSurface->UIso (aCrossU); + } + + GeomAdaptor_Curve aCurveAdaptor1 (anIso1); + GeomAdaptor_Curve aCurveAdaptor2 (anIso2); + GeomAdaptor_Curve aCurveAdaptor3 (anIso3); + Standard_Real aLength1 = GCPnts_AbscissaPoint::Length (aCurveAdaptor1, aPntOnNode1Iso, aPntOnNode3Iso, 1e-2); + 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(); + continue; + } + + aCross = (aNode2.XYZ() - aNode1.XYZ()) * (aLength1 / (aLength1 + aLength2)) + aNode1.XYZ(); + } + + theSegment[aNPoints++] = aCross; + } + + return aNPoints == 2; +} diff --git a/src/StdPrs/StdPrs_Isolines.hxx b/src/StdPrs/StdPrs_Isolines.hxx new file mode 100644 index 0000000000..0f6ae13545 --- /dev/null +++ b/src/StdPrs/StdPrs_Isolines.hxx @@ -0,0 +1,150 @@ +// Created on: 2014-10-14 +// Created by: Anton POLETAEV +// Copyright (c) 2013-2014 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. + +#ifndef _StdPrs_Isolines_H__ +#define _StdPrs_Isolines_H__ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +class Poly_Triangle; +class TopoDS_Face; +class TopLoc_Location; + +//! Tool for computing isoline representation for a face or surface. +//! Depending on a flags set to the given Prs3d_Drawer instance, on-surface (is used +//! by default) or on-triangulation isoline builder algorithm will be used. +//! If the given shape is not triangulated, on-surface isoline builder will be applied +//! regardless of Prs3d_Drawer flags. +class StdPrs_Isolines : public Prs3d_Root +{ +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 thePresentation [in] the presentation. + //! @param theFace [in] the face. + //! @param theDrawer [in] the display settings. + //! @param theDeflection [in] the deflection for isolines-on-surface version. + inline static void Add (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection) + { + if (theDrawer->IsoOnTriangulation() && StdPrs_ToolTriangulatedShape::IsTriangulated (theFace)) + { + AddOnTriangulation (thePresentation, theFace, theDrawer); + } + else + { + AddOnSurface (thePresentation, theFace, theDrawer, theDeflection); + } + } + + //! Computes isolines on triangulation and adds them to a presentation. + //! @param thePresentation [in] the presentation. + //! @param theFace [in] the face. + //! @param theDrawer [in] the display settings. + Standard_EXPORT static void AddOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer); + + //! Computes isolines on triangulation and adds them to a presentation. + //! @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. + Standard_EXPORT static void AddOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const Handle(Poly_Triangulation)& theTriangulation, + const Handle(Geom_Surface)& theSurface, + const TopLoc_Location& theLocation, + const Handle(Prs3d_Drawer)& theDrawer, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams); + + //! Computes isolines on surface and adds them to presentation. + //! @param thePresentation [in] the presentation. + //! @param theFace [in] the face. + //! @param theDrawer [in] the display settings. + //! @param theDeflection [in] the deflection value. + Standard_EXPORT static void AddOnSurface (const Handle(Prs3d_Presentation)& thePresentation, + const TopoDS_Face& theFace, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection); + + //! Computes isolines on surface and adds them to presentation. + //! @param thePresentation [in] the presentation. + //! @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. + Standard_EXPORT static void AddOnSurface (const Handle(Prs3d_Presentation)& thePresentation, + const Handle(BRepAdaptor_HSurface)& theSurface, + const Handle(Prs3d_Drawer)& theDrawer, + const Standard_Real theDeflection, + const TColStd_SequenceOfReal& theUIsoParams, + const TColStd_SequenceOfReal& theVIsoParams); + + //! Evalute sequence of parameters for drawing uv isolines for a given face. + //! @param theFace [in] the face. + //! @param theNbIsoU [in] the number of u isolines. + //! @param theNbIsoV [in] the number of v isolines. + //! @param theUVLimit [in] the u, v parameter value limit. + //! @param theUIsoParams [out] the sequence of u isoline parameters. + //! @param theVIsoParams [out] the sequence of v isoline parameters. + Standard_EXPORT static void UVIsoParameters (const TopoDS_Face& theFace, + const Standard_Integer theNbIsoU, + const Standard_Integer theNbIsoV, + const Standard_Real theUVLimit, + TColStd_SequenceOfReal& theUIsoParams, + TColStd_SequenceOfReal& theVIsoParams); + +private: + + //! Find isoline segment on a triangle. + //! @param theSurface [in] the surface. + //! @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. + //! @return TRUE if the isoline passes through the triangle. + Standard_EXPORT static Standard_Boolean findSegmentOnTriangulation (const Handle(Geom_Surface)& theSurface, + const gp_Lin2d& theIsoline, + const gp_Pnt* theNodesXYZ, + const gp_Pnt2d* theNodesUV, + gp_Pnt* theSegment); +}; + +#endif // _StdPrs_Isolines_H__ diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index 3a9ac5eacf..e55e1a29d2 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -17,11 +17,10 @@ #include #include -#include -#include -#include -#include #include +#include +#include +#include #include #include #include @@ -31,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -40,8 +38,7 @@ #include #include #include -#include -#include +#include #include #include #include @@ -74,7 +71,7 @@ namespace if (!aShapeIter.More()) { // compound contains no shaded elements at all - StdPrs_WFDeflectionShape::Add (thePrs, theShape, theDrawer); + StdPrs_WFShape::Add (thePrs, theShape, theDrawer); return; } @@ -103,7 +100,7 @@ namespace } if (hasElement) { - StdPrs_WFDeflectionShape::Add (thePrs, aCompoundWF, theDrawer); + StdPrs_WFShape::Add (thePrs, aCompoundWF, theDrawer); } } @@ -136,7 +133,7 @@ namespace theDrawer->UIsoAspect()->SetNumber (5); theDrawer->VIsoAspect()->SetNumber (5); - StdPrs_WFDeflectionShape::Add (thePrs, aCompoundWF, theDrawer); + StdPrs_WFShape::Add (thePrs, aCompoundWF, theDrawer); theDrawer->UIsoAspect()->SetNumber (aPrevUIsoNb); theDrawer->VIsoAspect()->SetNumber (aPrevVIsoNb); @@ -163,7 +160,7 @@ namespace for (; aFaceIt.More(); aFaceIt.Next()) { const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); - aT = StdPrs_ToolShadedShape::Triangulation (aFace, aLoc); + aT = BRep_Tool::Triangulation (aFace, aLoc); if (!aT.IsNull()) { aNbTriangles += aT->NbTriangles(); @@ -181,7 +178,7 @@ namespace for (aFaceIt.Init (theShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) { const TopoDS_Face& aFace = TopoDS::Face(aFaceIt.Current()); - aT = StdPrs_ToolShadedShape::Triangulation (aFace, aLoc); + aT = BRep_Tool::Triangulation (aFace, aLoc); if (aT.IsNull()) { continue; @@ -196,7 +193,7 @@ namespace const TColgp_Array1OfPnt& aNodes = aT->Nodes(); const TColgp_Array1OfPnt2d& aUVNodes = aT->UVNodes(); TColgp_Array1OfDir aNormals (aNodes.Lower(), aNodes.Upper()); - StdPrs_ToolShadedShape::Normal (aFace, aPolyConnect, aNormals); + StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals); if (theHasTexels) { @@ -456,7 +453,7 @@ void StdPrs_ShadedShape::ExploreSolids (const TopoDS_Shape& theShape, const TopoDS_Shape& aSubShape = anIter.Value(); const Standard_Boolean isClosed = aSubShape.ShapeType() == TopAbs_SHELL && BRep_Tool::IsClosed (aSubShape) && - StdPrs_ToolShadedShape::IsTriangulated (aSubShape); + StdPrs_ToolTriangulatedShape::IsTriangulated (aSubShape); theBuilder.Add (isClosed ? theClosed : theOpened, aSubShape); } return; @@ -497,30 +494,6 @@ void StdPrs_ShadedShape::Add (const Handle(Prs3d_Presentation)& thePrs, Standard_False, aDummy, aDummy, aDummy, theVolume); } -// ======================================================================= -// function : Tessellate -// purpose : -// ======================================================================= -void StdPrs_ShadedShape::Tessellate (const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) -{ - // Check if it is possible to avoid unnecessary recomputation of shape triangulation - Standard_Real aDeflection = Prs3d::GetDeflection (theShape, theDrawer); - if (BRepTools::Triangulation (theShape, aDeflection)) - { - return; - } - - // retrieve meshing tool from Factory - Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (theShape, - aDeflection, - theDrawer->HLRAngle()); - if (!aMeshAlgo.IsNull()) - { - aMeshAlgo->Perform(); - } -} - // ======================================================================= // function : Add // purpose : @@ -546,7 +519,7 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs, if (theDrawer->IsAutoTriangulation()) { // Triangulation completeness is important for "open-closed" analysis - perform tessellation beforehand - Tessellate (theShape, theDrawer); + StdPrs_ToolTriangulatedShape::Tessellate (theShape, theDrawer); } // add special wireframe presentation for faces without triangulation diff --git a/src/StdPrs/StdPrs_ShadedShape.hxx b/src/StdPrs/StdPrs_ShadedShape.hxx index 2c3d9d2d24..8d0ec72b78 100644 --- a/src/StdPrs/StdPrs_ShadedShape.hxx +++ b/src/StdPrs/StdPrs_ShadedShape.hxx @@ -52,9 +52,6 @@ public: //! or to perform Autodetection (would split input shape into two groups) Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& thePresentation, const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer, const Standard_Boolean theHasTexels, const gp_Pnt2d& theUVOrigin, const gp_Pnt2d& theUVRepeat, const gp_Pnt2d& theUVScale, const StdPrs_Volume theVolume = StdPrs_Volume_Autodetection); - //! Validates triangulation within the shape and performs tessellation if necessary. - Standard_EXPORT static void Tessellate (const TopoDS_Shape& theShape, const Handle(Prs3d_Drawer)& theDrawer); - //! Searches closed and unclosed subshapes in shape structure and puts them //! into two compounds for separate processing of closed and unclosed sub-shapes Standard_EXPORT static void ExploreSolids (const TopoDS_Shape& theShape, const BRep_Builder& theBuilder, TopoDS_Compound& theClosed, TopoDS_Compound& theOpened, const Standard_Boolean theIgnore1DSubShape); diff --git a/src/StdPrs/StdPrs_ToolShadedShape.hxx b/src/StdPrs/StdPrs_ToolShadedShape.hxx deleted file mode 100644 index fe29f3118d..0000000000 --- a/src/StdPrs/StdPrs_ToolShadedShape.hxx +++ /dev/null @@ -1,50 +0,0 @@ -// Copyright (c) 2013 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. - -#ifndef _StdPrs_ToolShadedShape_HeaderFile -#define _StdPrs_ToolShadedShape_HeaderFile - -#include -#include -#include -#include - -class TopoDS_Shape; -class Poly_Triangulation; -class TopoDS_Face; -class TopLoc_Location; -class Poly_Connect; - -class StdPrs_ToolShadedShape -{ -public: - - DEFINE_STANDARD_ALLOC - - //! Similar to BRepTools::Triangulation() but without extra checks. - //! @return true if all faces within shape are triangulated. - Standard_EXPORT static Standard_Boolean IsTriangulated (const TopoDS_Shape& theShape); - - //! Checks back faces visibility for specified shape (to activate back-face culling).
- //! @return true if shape is closed manifold Solid or compound of such Solids.
- Standard_EXPORT static Standard_Boolean IsClosed(const TopoDS_Shape& theShape); - - Standard_EXPORT static Handle(Poly_Triangulation) Triangulation(const TopoDS_Face& aFace, - TopLoc_Location& loc); - - Standard_EXPORT static void Normal(const TopoDS_Face& aFace, - Poly_Connect& PC, - TColgp_Array1OfDir& Nor); -}; - -#endif diff --git a/src/StdPrs/StdPrs_ToolShadedShape.cxx b/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx similarity index 77% rename from src/StdPrs/StdPrs_ToolShadedShape.cxx rename to src/StdPrs/StdPrs_ToolTriangulatedShape.cxx index 9429b8cda2..96fb16d2b2 100644 --- a/src/StdPrs/StdPrs_ToolShadedShape.cxx +++ b/src/StdPrs/StdPrs_ToolTriangulatedShape.cxx @@ -14,32 +14,35 @@ // 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 #include #include #include -#include +#include +#include #include #include #include #include #include #include -#include #include #include +#include //======================================================================= -//function : isTriangulated +//function : IsTriangulated //purpose : //======================================================================= -Standard_Boolean StdPrs_ToolShadedShape::IsTriangulated (const TopoDS_Shape& theShape) +Standard_Boolean StdPrs_ToolTriangulatedShape::IsTriangulated (const TopoDS_Shape& theShape) { TopLoc_Location aLocDummy; for (TopExp_Explorer aFaceIter (theShape, TopAbs_FACE); aFaceIter.More(); aFaceIter.Next()) @@ -58,7 +61,7 @@ Standard_Boolean StdPrs_ToolShadedShape::IsTriangulated (const TopoDS_Shape& the //function : IsClosed //purpose : //======================================================================= -Standard_Boolean StdPrs_ToolShadedShape::IsClosed (const TopoDS_Shape& theShape) +Standard_Boolean StdPrs_ToolTriangulatedShape::IsClosed (const TopoDS_Shape& theShape) { if (theShape.IsNull()) { @@ -127,23 +130,13 @@ Standard_Boolean StdPrs_ToolShadedShape::IsClosed (const TopoDS_Shape& theShape) } } -//======================================================================= -//function : Triangulation -//purpose : -//======================================================================= -Handle(Poly_Triangulation) StdPrs_ToolShadedShape::Triangulation (const TopoDS_Face& theFace, - TopLoc_Location& theLoc) -{ - return BRep_Tool::Triangulation (theFace, theLoc); -} - //======================================================================= //function : Normal //purpose : //======================================================================= -void StdPrs_ToolShadedShape::Normal (const TopoDS_Face& theFace, - Poly_Connect& thePolyConnect, - TColgp_Array1OfDir& theNormals) +void StdPrs_ToolTriangulatedShape::Normal (const TopoDS_Face& theFace, + Poly_Connect& thePolyConnect, + TColgp_Array1OfDir& theNormals) { const Handle(Poly_Triangulation)& aPolyTri = thePolyConnect.Triangulation(); const TColgp_Array1OfPnt& aNodes = aPolyTri->Nodes(); @@ -220,3 +213,42 @@ void StdPrs_ToolShadedShape::Normal (const TopoDS_Face& theFace, } } } + +//======================================================================= +//function : IsTessellated +//purpose : +//======================================================================= +Standard_Boolean StdPrs_ToolTriangulatedShape::IsTessellated (const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer) +{ + return BRepTools::Triangulation (theShape, Prs3d::GetDeflection (theShape, theDrawer)); +} + +// ======================================================================= +// function : Tessellate +// purpose : +// ======================================================================= +Standard_Boolean StdPrs_ToolTriangulatedShape::Tessellate (const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer) +{ + Standard_Boolean wasRecomputed = Standard_False; + // Check if it is possible to avoid unnecessary recomputation of shape triangulation + if (IsTessellated (theShape, theDrawer)) + { + return wasRecomputed; + } + + Standard_Real aDeflection = Prs3d::GetDeflection (theShape, theDrawer); + + // retrieve meshing tool from Factory + Handle(BRepMesh_DiscretRoot) aMeshAlgo = BRepMesh_DiscretFactory::Get().Discret (theShape, + aDeflection, + theDrawer->HLRAngle()); + if (!aMeshAlgo.IsNull()) + { + aMeshAlgo->Perform(); + wasRecomputed = Standard_True; + } + + return wasRecomputed; +} diff --git a/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx b/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx new file mode 100644 index 0000000000..31710fe009 --- /dev/null +++ b/src/StdPrs/StdPrs_ToolTriangulatedShape.hxx @@ -0,0 +1,64 @@ +// Copyright (c) 2013 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. + +#ifndef _StdPrs_ToolTriangulatedShape_HeaderFile +#define _StdPrs_ToolTriangulatedShape_HeaderFile + +#include +#include +#include +#include +#include + +class TopoDS_Face; +class TopLoc_Location; +class TopoDS_Shape; +class Prs3d_Drawer; +class Poly_Triangulation; +class Poly_Connect; + +class StdPrs_ToolTriangulatedShape +{ +public: + + //! Similar to BRepTools::Triangulation() but without extra checks. + //! @return true if all faces within shape are triangulated. + Standard_EXPORT static Standard_Boolean IsTriangulated (const TopoDS_Shape& theShape); + + //! Checks back faces visibility for specified shape (to activate back-face culling).
+ //! @return true if shape is closed manifold Solid or compound of such Solids.
+ Standard_EXPORT static Standard_Boolean IsClosed (const TopoDS_Shape& theShape); + + //! Evaluate normals for a triangle of a face. + //! @param theFace [in] the face. + //! @param thePolyConnect [in] the definition of a face triangulation. + //! @param theNormal [out] the array of normals for each triangle. + Standard_EXPORT static void Normal (const TopoDS_Face& theFace, + Poly_Connect& thePolyConnect, + TColgp_Array1OfDir& theNormals); + + //! Checks whether the shape is properly triangulated for a given display settings. + //! @param theShape [in] the shape. + //! @param theDrawer [in] the display settings. + Standard_EXPORT static Standard_Boolean IsTessellated (const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer); + + //! Validates triangulation within the shape and performs tessellation if necessary. + //! @param theShape [in] the shape. + //! @param theDrawer [in] the display settings. + //! @return true if tesselation was recomputed and false otherwise. + Standard_EXPORT static Standard_Boolean Tessellate (const TopoDS_Shape& theShape, + const Handle(Prs3d_Drawer)& theDrawer); +}; + +#endif diff --git a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx index 6c79403b23..96a8cc8af2 100644 --- a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx +++ b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.cxx @@ -89,7 +89,7 @@ static void FindLimits(const Adaptor3d_Curve& aCurve, aCurve.D0(Last,P2); } while (P1.Distance(P2) < aLimit); } - } + } } @@ -632,46 +632,3 @@ Standard_Boolean StdPrs_WFDeflectionRestrictedFace::MatchVIso aDrawer->UIsoAspect()->Number(), aDrawer->VIsoAspect()->Number()); } - -namespace -{ - static const Standard_Integer THE_INDICES[][3] = - { { 0, 0, 0 }, { 1, 0, 0 }, { 1, 0, 1 }, { 0, 0, 1 }, - { 0, 1, 1 }, { 1, 1, 1 }, { 1, 1, 0 }, { 0, 1, 0 }, - { 0, 0, 0 }, { 0, 0, 1 }, { 1, 0, 1 }, { 1, 1, 1 }, - { 0, 1, 1 }, { 0, 1, 0 }, { 1, 1, 0 }, { 1, 0, 0 } }; -} - -//======================================================================= -//function : AddBox -//purpose : -//======================================================================= -void StdPrs_WFDeflectionRestrictedFace::AddBox (const Handle(Prs3d_Presentation)& thePrs, - const Bnd_Box& theBndBox, - const Handle(Prs3d_Drawer)& theDrawer) -{ - if (theBndBox.IsVoid()) - { - return; - } - - Standard_Real X[2], Y[2], Z[2]; - theBndBox.Get (X[0], Y[0], Z[0], X[1], Y[1], Z[1]); - - Handle(Graphic3d_Group) aGroup = Prs3d_Root::CurrentGroup (thePrs); - Quantity_Color aColor; - Aspect_TypeOfLine aDummyLineType; - Standard_Real aWidth = 1.0; - theDrawer->LineAspect()->Aspect()->Values (aColor, aDummyLineType, aWidth); - - aGroup->SetGroupPrimitivesAspect (new Graphic3d_AspectLine3d (aColor, Aspect_TOL_DOTDASH, aWidth)); - - Handle(Graphic3d_ArrayOfPolylines) aPolyline = new Graphic3d_ArrayOfPolylines(16); - for(Standard_Integer aVertIter = 0; aVertIter < 16; ++aVertIter) - { - aPolyline->AddVertex (X[THE_INDICES[aVertIter][0]], - Y[THE_INDICES[aVertIter][1]], - Z[THE_INDICES[aVertIter][2]]); - } - aGroup->AddPrimitiveArray (aPolyline); -} diff --git a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.hxx b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.hxx index 4be4e873db..7c4c49b036 100644 --- a/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.hxx +++ b/src/StdPrs/StdPrs_WFDeflectionRestrictedFace.hxx @@ -112,9 +112,6 @@ public: //! visualization approach is activated (it is activated by default). Standard_EXPORT static void Add (const Handle(Prs3d_Presentation)& aPresentation, const Handle(BRepAdaptor_HSurface)& aFace, const Standard_Boolean DrawUIso, const Standard_Boolean DrawVIso, const Quantity_Length Deflection, const Standard_Integer NBUiso, const Standard_Integer NBViso, const Handle(Prs3d_Drawer)& aDrawer, Prs3d_NListOfSequenceOfPnt& Curves); - //! Adds box as polyline to the presentation object - Standard_EXPORT static void AddBox (const Handle(Prs3d_Presentation)& thePrs, const Bnd_Box& theBndBox, const Handle(Prs3d_Drawer)& theDrawer); - Standard_EXPORT static Standard_Boolean Match (const Quantity_Length X, const Quantity_Length Y, const Quantity_Length Z, const Quantity_Length aDistance, const Handle(BRepAdaptor_HSurface)& aFace, const Handle(Prs3d_Drawer)& aDrawer); Standard_EXPORT static Standard_Boolean MatchUIso (const Quantity_Length X, const Quantity_Length Y, const Quantity_Length Z, const Quantity_Length aDistance, const Handle(BRepAdaptor_HSurface)& aFace, const Handle(Prs3d_Drawer)& aDrawer); diff --git a/src/StdPrs/StdPrs_WFDeflectionShape.hxx b/src/StdPrs/StdPrs_WFDeflectionShape.hxx deleted file mode 100755 index 333d2e1ae2..0000000000 --- a/src/StdPrs/StdPrs_WFDeflectionShape.hxx +++ /dev/null @@ -1,130 +0,0 @@ -// Copyright (c) 2013-2014 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. - -#ifndef _StdPrs_WFDeflectionShape_H__ -#define _StdPrs_WFDeflectionShape_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -// Computes the wireframe presentation of surfaces -// by displaying planar sections. - -class StdPrs_WFDeflectionShape : public Prs3d_Root -{ - -public: - - //! Add shape to presentation - static inline void Add (const Handle (Prs3d_Presentation)& thePrs, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - anAlgo.Add (thePrs, theShape, theDrawer); - } - - static inline Handle(TopTools_HSequenceOfShape) PickCurve - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - return anAlgo.PickCurve (theX, theY, theZ, theDistance, theShape, theDrawer); - } - - static inline Handle(TopTools_HSequenceOfShape) PickPatch - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle(Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - return anAlgo.PickPatch (theX, theY, theZ, theDistance, theShape, theDrawer); - } - -private: - - class Face : public Prs3d_WFShape::Face - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - const Handle(BRepAdaptor_HSurface)& theFace, - const Standard_Boolean theToDrawUIso, - const Standard_Boolean theToDrawVIso, - const Quantity_Length theDeflection, - const Standard_Integer theNBUiso, - const Standard_Integer theNBViso, - const Handle(Prs3d_Drawer)& theDrawer, - Prs3d_NListOfSequenceOfPnt& theCurves) const - { - StdPrs_WFDeflectionRestrictedFace::Add (thePrs, theFace, theToDrawUIso, theToDrawVIso, theDeflection, - theNBUiso, theNBViso, theDrawer, theCurves); - } - - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Handle(BRepAdaptor_HSurface)& theFace, - const Handle(Prs3d_Drawer)& theDrawer) const - { - return StdPrs_WFDeflectionRestrictedFace::Match (theX, theY, theZ, theDistance, theFace, theDrawer); - } - }; - - class Curve : public Prs3d_WFShape::Curve - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - Adaptor3d_Curve& theCurve, - const Quantity_Length theDeflection, - const Handle(Prs3d_Drawer)& theDrawer, - TColgp_SequenceOfPnt& thePoints, - const Standard_Boolean theToDrawCurve) const - { - StdPrs_DeflectionCurve::Add (thePrs, theCurve, theDeflection, theDrawer, thePoints, theToDrawCurve); - } - - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Adaptor3d_Curve& theCurve, - const Handle(Prs3d_Drawer)& theDrawer) const - { - return StdPrs_DeflectionCurve::Match (theX, theY, theZ, theDistance, theCurve, theDrawer); - } - }; - -}; - -#endif // _StdPrs_WFDeflectionShape_H__ diff --git a/src/StdPrs/StdPrs_WFRestrictedFace.cxx b/src/StdPrs/StdPrs_WFRestrictedFace.cxx index aef9d1bbd5..3501db8d36 100755 --- a/src/StdPrs/StdPrs_WFRestrictedFace.cxx +++ b/src/StdPrs/StdPrs_WFRestrictedFace.cxx @@ -39,7 +39,6 @@ void StdPrs_WFRestrictedFace::Add const Handle(BRepAdaptor_HSurface)& theFace, const Standard_Boolean theDrawUIso, const Standard_Boolean theDrawVIso, - const Quantity_Length theDeflection, const Standard_Integer theNbUIso, const Standard_Integer theNBVIso, const Handle(Prs3d_Drawer)& theDrawer, @@ -180,26 +179,32 @@ void StdPrs_WFRestrictedFace::Add Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt; if (!aGeomBSurface.IsNull()) { - if (anIsoBuild.IsXLine(anI)) - aBCurve = aGeomBSurface->UIso(anIsoCoord); - else - aBCurve = aGeomBSurface->VIso(anIsoCoord); + if (anIsoBuild.IsXLine (anI)) + { + aBCurve = aGeomBSurface->UIso (anIsoCoord); + } + else + { + aBCurve = aGeomBSurface->VIso (anIsoCoord); + } //Note that the isos are the part of the shape, it will be displayed after a computation the whole shape //NbPoints = 30 - default parameter for computation of such curves - StdPrs_Curve::Add (thePresentation, GeomAdaptor_Curve(aBCurve), b1, b2, theDeflection, - aPoints->ChangeSequence(), 30, Standard_False); - theCurves.Append(aPoints); + StdPrs_Curve::Add (thePresentation, GeomAdaptor_Curve (aBCurve), b1, b2, aPoints->ChangeSequence(), 30, Standard_False); + theCurves.Append (aPoints); } else { - if (anIsoBuild.IsXLine(anI)) - anIsoCurve.Load(GeomAbs_IsoU,anIsoCoord,b1,b2); + if (anIsoBuild.IsXLine (anI)) + { + anIsoCurve.Load (GeomAbs_IsoU, anIsoCoord, b1, b2); + } else - anIsoCurve.Load(GeomAbs_IsoV,anIsoCoord,b1,b2); - StdPrs_Curve::Add (thePresentation, anIsoCurve, theDeflection, theDrawer, - aPoints->ChangeSequence(), Standard_False); - theCurves.Append(aPoints); + { + anIsoCurve.Load(GeomAbs_IsoV, anIsoCoord, b1, b2); + } + StdPrs_Curve::Add (thePresentation, anIsoCurve, theDrawer, aPoints->ChangeSequence(), Standard_False); + theCurves.Append (aPoints); } } } @@ -392,7 +397,6 @@ void StdPrs_WFRestrictedFace::Add theFace, Standard_True, Standard_True, - theDrawer->MaximalChordialDeviation(), theDrawer->UIsoAspect()->Number(), theDrawer->VIsoAspect()->Number(), theDrawer, @@ -415,7 +419,6 @@ void StdPrs_WFRestrictedFace::AddUIso theFace, Standard_True, Standard_False, - theDrawer->MaximalChordialDeviation(), theDrawer->UIsoAspect()->Number(), theDrawer->VIsoAspect()->Number(), theDrawer, @@ -438,7 +441,6 @@ void StdPrs_WFRestrictedFace::AddVIso theFace, Standard_False, Standard_True, - theDrawer->MaximalChordialDeviation(), theDrawer->UIsoAspect()->Number(), theDrawer->VIsoAspect()->Number(), theDrawer, diff --git a/src/StdPrs/StdPrs_WFRestrictedFace.hxx b/src/StdPrs/StdPrs_WFRestrictedFace.hxx index e763636766..8852424158 100755 --- a/src/StdPrs/StdPrs_WFRestrictedFace.hxx +++ b/src/StdPrs/StdPrs_WFRestrictedFace.hxx @@ -36,7 +36,6 @@ public: const Handle(BRepAdaptor_HSurface)& theFace, const Standard_Boolean theDrawUIso, const Standard_Boolean theDrawVIso, - const Quantity_Length theDeflection, const Standard_Integer theNbUIso, const Standard_Integer theNbVIso, const Handle(Prs3d_Drawer)& theDrawer, diff --git a/src/StdPrs/StdPrs_WFShape.cxx b/src/StdPrs/StdPrs_WFShape.cxx new file mode 100644 index 0000000000..96bcf82839 --- /dev/null +++ b/src/StdPrs/StdPrs_WFShape.cxx @@ -0,0 +1,381 @@ +// Created on: 2014-10-14 +// Created by: Anton POLETAEV +// Copyright (c) 2013-2014 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 +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace +{ + typedef NCollection_List ListOfSequenceOfPnt; +} + +// ========================================================================= +// function : Add +// purpose : +// ========================================================================= +void StdPrs_WFShape::Add (const Handle (Prs3d_Presentation)& thePresentation, + const TopoDS_Shape& theShape, + const Handle (Prs3d_Drawer)& theDrawer) +{ + if (theShape.IsNull()) + { + return; + } + + Prs3d_ShapeTool aTool (theShape, theDrawer->VertexDrawMode() == Prs3d_VDM_All); + + // Explore shape elements. + TopTools_ListOfShape aLFree, aLUnFree, aLWire; + for (aTool.InitCurve(); aTool.MoreCurve(); aTool.NextCurve()) + { + const TopoDS_Edge& anEdge = aTool.GetCurve(); + switch (aTool.Neighbours()) + { + case 0: aLWire.Append (anEdge); break; + case 1: aLFree.Append (anEdge); break; + default: aLUnFree.Append (anEdge); break; + } + } + + 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()) + { + if (!aTool.HasSurface()) + { + aDiscreteFaces.Append (aTool.GetFace()); + } + } + 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); + } + + 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()) + { + continue; + } + + StdPrs_Isolines::Add (thePresentation, aTool.GetFace(), theDrawer, aShapeDeflection); + } +} + +// ========================================================================= +// 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) +{ + ListOfSequenceOfPnt aPointsOfEdges; + + TopTools_ListIteratorOfListOfShape anEdgesIter; + for (anEdgesIter.Initialize (theEdges); anEdgesIter.More(); anEdgesIter.Next()) + { + const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgesIter.Value()); + if (BRep_Tool::Degenerated (anEdge)) + { + continue; + } + + Handle(TColgp_HSequenceOfPnt) aPoints = new TColgp_HSequenceOfPnt; + + TopLoc_Location aLocation; + Handle(Poly_Triangulation) aTriangulation; + Handle(Poly_PolygonOnTriangulation) anEdgeIndicies; + BRep_Tool::PolygonOnTriangulation (anEdge, anEdgeIndicies, aTriangulation, aLocation); + Handle(Poly_Polygon3D) aPolygon; + + if (!anEdgeIndicies.IsNull()) + { + // Presentation based on triangulation of a face. + const TColStd_Array1OfInteger& anIndices = anEdgeIndicies->Nodes(); + const TColgp_Array1OfPnt& aNodes = aTriangulation->Nodes(); + + Standard_Integer anIndex = anIndices.Lower(); + if (aLocation.IsIdentity()) + { + for (; anIndex <= anIndices.Upper(); ++anIndex) + { + aPoints->Append (aNodes (anIndices (anIndex))); + } + } + else + { + for (; anIndex <= anIndices.Upper(); ++anIndex) + { + aPoints->Append (aNodes (anIndices (anIndex)).Transformed (aLocation)); + } + } + } + else if (!(aPolygon = BRep_Tool::Polygon3D (anEdge, aLocation)).IsNull()) + { + // Presentation based on triangulation of the free edge on a surface. + const TColgp_Array1OfPnt& aNodes = aPolygon->Nodes(); + Standard_Integer anIndex = aNodes.Lower(); + if (aLocation.IsIdentity()) + { + for (; anIndex <= aNodes.Upper(); ++anIndex) + { + aPoints->Append (aNodes.Value (anIndex)); + } + } + else + { + for (; anIndex <= aNodes.Upper(); ++anIndex) + { + aPoints->Append (aNodes.Value (anIndex).Transformed (aLocation)); + } + } + } + else if (BRep_Tool::IsGeometric (anEdge)) + { + // Default presentation for edges without triangulation. + BRepAdaptor_Curve aCurve (anEdge); + StdPrs_DeflectionCurve::Add (thePresentation, + aCurve, + theShapeDeflection, + theDrawer, + aPoints->ChangeSequence(), + Standard_False); + } + + if (!aPoints->IsEmpty()) + { + aPointsOfEdges.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); +} + +// ========================================================================= +// function : AddEdgesOnTriangulation +// purpose : +// ========================================================================= +void StdPrs_WFShape::addEdgesOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const TopTools_ListOfShape& theFaces, + const Handle (Prs3d_LineAspect)& theAspect) +{ + TColgp_SequenceOfPnt aSurfPoints; + + TopLoc_Location aLocation; + TopTools_ListIteratorOfListOfShape aFaceIter; + for (aFaceIter.Initialize (theFaces); aFaceIter.More(); aFaceIter.Next()) + { + const TopoDS_Face& aFace = TopoDS::Face (aFaceIter.Value()); + + Handle(Poly_Triangulation) T = BRep_Tool::Triangulation (aFace, aLocation); + if (T.IsNull()) + { + continue; + } + + const TColgp_Array1OfPnt& aNodes = T->Nodes(); + + // Build the connect tool. + Poly_Connect aPolyConnect (T); + + Standard_Integer aNbTriangles = T->NbTriangles(); + Standard_Integer aT[3]; + Standard_Integer aN[3]; + + // Count the free edges. + Standard_Integer aNbFree = 0; + for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI) + { + aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); + for (Standard_Integer aJ = 0; aJ < 3; ++aJ) + { + if (aT[aJ] == 0) + { + ++aNbFree; + } + } + } + + // Allocate the arrays. + TColStd_Array1OfInteger aFree (1, 2 * aNbFree); + Standard_Integer aNbInternal = (3 * aNbTriangles - aNbFree) / 2; + TColStd_Array1OfInteger anInternal (0, 2 * aNbInternal); + + Standard_Integer aFreeIndex = 1, anIntIndex = 1; + const Poly_Array1OfTriangle& aTriangles = T->Triangles(); + for (Standard_Integer anI = 1; anI <= aNbTriangles; ++anI) + { + aPolyConnect.Triangles (anI, aT[0], aT[1], aT[2]); + aTriangles (anI).Get (aN[0], aN[1], aN[2]); + for (Standard_Integer aJ = 0; aJ < 3; aJ++) + { + Standard_Integer k = (aJ + 1) % 3; + if (aT[aJ] == 0) + { + aFree (aFreeIndex) = aN[aJ]; + aFree (aFreeIndex + 1) = aN[k]; + aFreeIndex += 2; + } + // internal edge if this triangle has a lower index than the adjacent. + else if (anI < aT[aJ]) + { + anInternal (anIntIndex) = aN[aJ]; + anInternal (anIntIndex + 1) = aN[k]; + anIntIndex += 2; + } + } + } + + // free edges + Standard_Integer aFreeHalfNb = aFree.Length() / 2; + for (Standard_Integer anI = 1; anI <= aFreeHalfNb; ++anI) + { + gp_Pnt aPoint1 = aNodes (aFree (2 * anI - 1)).Transformed (aLocation); + gp_Pnt aPoint2 = aNodes (aFree (2 * anI )).Transformed (aLocation); + aSurfPoints.Append (aPoint1); + aSurfPoints.Append (aPoint2); + } + } + + if (aSurfPoints.Length() < 2) + { + return; + } + + Standard_Integer aNbVertices = aSurfPoints.Length(); + Standard_Integer aNbBounds = aNbVertices / 2; + Handle(Graphic3d_ArrayOfSegments) aSurfArray = new Graphic3d_ArrayOfSegments (aNbVertices, aNbBounds); + for (Standard_Integer anI = 1; anI <= aNbVertices; anI += 2) + { + aSurfArray->AddBound (2); + aSurfArray->AddVertex (aSurfPoints.Value (anI)); + aSurfArray->AddVertex (aSurfPoints.Value (anI + 1)); + } + Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); + aGroup->SetPrimitivesAspect (theAspect->Aspect()); + aGroup->AddPrimitiveArray (aSurfArray); +} + +// ========================================================================= +// function : AddPoints +// purpose : +// ========================================================================= +void StdPrs_WFShape::addVertices (const Handle (Prs3d_Presentation)& thePresentation, + const TColgp_SequenceOfPnt& theVertices, + const Handle (Prs3d_PointAspect)& theAspect) +{ + Standard_Integer aNbVertices = theVertices.Length(); + if (aNbVertices < 1) + { + return; + } + + Handle(Graphic3d_ArrayOfPoints) aVertexArray = new Graphic3d_ArrayOfPoints (aNbVertices); + for (Standard_Integer anI = 1; anI <= aNbVertices; ++anI) + { + aVertexArray->AddVertex (theVertices.Value (anI)); + } + + Handle(Graphic3d_Group) aGroup = Prs3d_Root::NewGroup (thePresentation); + aGroup->SetPrimitivesAspect (theAspect->Aspect()); + aGroup->AddPrimitiveArray (aVertexArray); +} diff --git a/src/StdPrs/StdPrs_WFShape.hxx b/src/StdPrs/StdPrs_WFShape.hxx index 5b36d0f875..0db67cfb8f 100755 --- a/src/StdPrs/StdPrs_WFShape.hxx +++ b/src/StdPrs/StdPrs_WFShape.hxx @@ -15,113 +15,57 @@ #define _StdPrs_WFShape_H__ #include -#include #include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +//! Tool for computing wireframe presentation of a TopoDS_Shape. class StdPrs_WFShape : public Prs3d_Root { - public: - //! Add shape to presentation - static inline void Add (const Handle (Prs3d_Presentation)& thePrs, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - anAlgo.Add (thePrs, theShape, theDrawer); - } - - static inline Handle(TopTools_HSequenceOfShape) PickCurve - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle (Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - return anAlgo.PickCurve (theX, theY, theZ, theDistance, theShape, theDrawer); - } - - static inline Handle(TopTools_HSequenceOfShape) PickPatch - (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const TopoDS_Shape& theShape, - const Handle(Prs3d_Drawer)& theDrawer) - { - Face aFaceAlgo; - Curve aCurveAlgo; - Prs3d_WFShape anAlgo (aFaceAlgo, aCurveAlgo); - return anAlgo.PickPatch (theX, theY, theZ, theDistance, theShape, theDrawer); - } + //! Computes wireframe presentation of a shape. + //! @param thePresentation [in] the presentation. + //! @param theShape [in] the shape. + //! @param theDrawer [in] the draw settings. + Standard_EXPORT static void Add (const Handle (Prs3d_Presentation)& thePresentation, + const TopoDS_Shape& theShape, + const Handle (Prs3d_Drawer)& theDrawer); private: - class Face : public Prs3d_WFShape::Face - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - const Handle(BRepAdaptor_HSurface)& theFace, - const Standard_Boolean theToDrawUIso, - const Standard_Boolean theToDrawVIso, - const Quantity_Length theDeflection, - const Standard_Integer theNBUiso, - const Standard_Integer theNBViso, - const Handle(Prs3d_Drawer)& theDrawer, - Prs3d_NListOfSequenceOfPnt& theCurves) const - { - StdPrs_WFRestrictedFace::Add (thePrs, theFace, theToDrawUIso, theToDrawVIso, theDeflection, - theNBUiso, theNBViso, theDrawer, theCurves); - } + //! 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); - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Handle(BRepAdaptor_HSurface)& theFace, - const Handle(Prs3d_Drawer)& theDrawer) const - { - return StdPrs_WFRestrictedFace::Match (theX, theY, theZ, theDistance, theFace, theDrawer); - } - }; - - class Curve : public Prs3d_WFShape::Curve - { - public: - virtual void Add (const Handle(Prs3d_Presentation)& thePrs, - Adaptor3d_Curve& theCurve, - const Quantity_Length theDeflection, - const Handle(Prs3d_Drawer)& theDrawer, - TColgp_SequenceOfPnt& thePoints, - const Standard_Boolean theToDrawCurve) const - { - StdPrs_Curve::Add (thePrs, theCurve, theDeflection, theDrawer, thePoints, theToDrawCurve); - } - - virtual Standard_Boolean Match (const Quantity_Length theX, - const Quantity_Length theY, - const Quantity_Length theZ, - const Quantity_Length theDistance, - const Adaptor3d_Curve& theCurve, - const Handle(Prs3d_Drawer)& theDrawer) const - { - return StdPrs_Curve::Match (theX, theY, theZ, theDistance, theCurve, theDrawer); - } - }; + //! Compute free and boundary edges on a triangulation of a face. + //! @param thePresentation [in] the presentation. + //! @param theFaces [in] the list of triangulated faces. + //! @param theAspect [in] the edge drawing aspect. + //! @param theDrawer [in] the drawer settings. + static void addEdgesOnTriangulation (const Handle(Prs3d_Presentation)& thePresentation, + const TopTools_ListOfShape& theFaces, + const Handle (Prs3d_LineAspect)& theAspect); + //! Compute vertex presentation for a shape. + //! @param thePresentation [in] the presentation. + //! @param theVertices [in] the list of points. + //! @param theAspect [in] the point drawing aspect. + static void addVertices (const Handle (Prs3d_Presentation)& thePresentation, + const TColgp_SequenceOfPnt& theVertices, + const Handle (Prs3d_PointAspect)& theAspect); }; #endif // _StdPrs_WFShape_H__ diff --git a/src/StdPrs/StdPrs_WFSurface.cxx b/src/StdPrs/StdPrs_WFSurface.cxx index ecbf995c94..781454ee05 100644 --- a/src/StdPrs/StdPrs_WFSurface.cxx +++ b/src/StdPrs/StdPrs_WFSurface.cxx @@ -145,28 +145,6 @@ void StdPrs_WFSurface::Add (const Handle(Prs3d_Presentation)& aPresentation, Standard_Boolean UClosed = aSurface->IsUClosed(); Standard_Boolean VClosed = aSurface->IsVClosed(); - - Standard_Real TheDeflection; - Aspect_TypeOfDeflection TOD = aDrawer->TypeOfDeflection(); - if (TOD == Aspect_TOD_RELATIVE) { -// On calcule la fleche en fonction des min max globaux de la piece: - Bnd_Box Total; - BndLib_AddSurface::Add(aSurface->Surface(),U1, U2, V1, V2, 0.,Total); - Standard_Real m = aDrawer->MaximalChordialDeviation()/ - aDrawer->DeviationCoefficient(); - Standard_Real aXmin, aYmin, aZmin, aXmax, aYmax, aZmax; - Total.Get( aXmin, aYmin, aZmin, aXmax, aYmax, aZmax ); - if ( ! (Total.IsOpenXmin() || Total.IsOpenXmax() )) - m = Min ( m , Abs (aXmax-aXmin)); - if ( ! (Total.IsOpenYmin() || Total.IsOpenYmax() )) - m = Min ( m , Abs (aYmax-aYmin)); - if ( ! (Total.IsOpenZmin() || Total.IsOpenZmax() )) - m = Min ( m , Abs (aZmax-aZmin)); - - TheDeflection = m * aDrawer->DeviationCoefficient(); - } - else - TheDeflection = aDrawer->MaximalChordialDeviation(); Adaptor3d_IsoCurve anIso; anIso.Load(aSurface); @@ -174,66 +152,67 @@ void StdPrs_WFSurface::Add (const Handle(Prs3d_Presentation)& aPresentation, // Trace des frontieres. // ********************* // - if ( !(UClosed && VClosed) ) { - - (Prs3d_Root::CurrentGroup(aPresentation))->SetPrimitivesAspect - (aDrawer->FreeBoundaryAspect()->Aspect()); - if ( !UClosed ) - { - anIso.Load(GeomAbs_IsoU,U1,V1,V2); - Handle(TColgp_HSequenceOfPnt) aPntsU1 = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, aPntsU1->ChangeSequence(), Standard_False); - freeCurves.Append(aPntsU1); - anIso.Load(GeomAbs_IsoU,U2,V1,V2); - Handle(TColgp_HSequenceOfPnt) aPntsU2 = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, aPntsU2->ChangeSequence(), Standard_False); - freeCurves.Append(aPntsU2); - } - if ( !VClosed ) - { - anIso.Load(GeomAbs_IsoV,V1,U1,U2); - Handle(TColgp_HSequenceOfPnt) aPntsV1 = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, aPntsV1->ChangeSequence(), Standard_False); - freeCurves.Append(aPntsV1); - anIso.Load(GeomAbs_IsoV,V2,U1,U2); - Handle(TColgp_HSequenceOfPnt) aPntsV2 = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, aPntsV2->ChangeSequence(), Standard_False); - freeCurves.Append(aPntsV2); - } + if (!(UClosed && VClosed)) + { + Prs3d_Root::CurrentGroup (aPresentation)->SetPrimitivesAspect (aDrawer->FreeBoundaryAspect()->Aspect()); + if (!UClosed) + { + anIso.Load (GeomAbs_IsoU, U1, V1, V2); + Handle(TColgp_HSequenceOfPnt) aPntsU1 = new TColgp_HSequenceOfPnt; + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, aPntsU1->ChangeSequence(), Standard_False); + freeCurves.Append (aPntsU1); + + anIso.Load (GeomAbs_IsoU,U2,V1,V2); + Handle(TColgp_HSequenceOfPnt) aPntsU2 = new TColgp_HSequenceOfPnt; + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, aPntsU2->ChangeSequence(), Standard_False); + freeCurves.Append(aPntsU2); + } + if (!VClosed) + { + anIso.Load (GeomAbs_IsoV, V1, U1, U2); + Handle(TColgp_HSequenceOfPnt) aPntsV1 = new TColgp_HSequenceOfPnt; + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, aPntsV1->ChangeSequence(), Standard_False); + freeCurves.Append (aPntsV1); + + anIso.Load (GeomAbs_IsoV, V2, U1, U2); + Handle(TColgp_HSequenceOfPnt) aPntsV2 = new TColgp_HSequenceOfPnt; + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, aPntsV2->ChangeSequence(), Standard_False); + freeCurves.Append(aPntsV2); + } } // // Trace des isoparametriques. // *************************** // Standard_Integer fin = aDrawer->UIsoAspect()->Number(); - if ( fin != 0) { - - (Prs3d_Root::CurrentGroup(aPresentation))->SetPrimitivesAspect - (aDrawer->UIsoAspect()->Aspect()); - - Standard_Real du= UClosed ? (U2-U1)/fin : (U2-U1)/(1+fin); - for (Standard_Integer i=1; i<=fin;i++){ - anIso.Load(GeomAbs_IsoU,U1+du*i,V1,V2); + if (fin != 0) + { + Prs3d_Root::CurrentGroup (aPresentation)->SetPrimitivesAspect (aDrawer->UIsoAspect()->Aspect()); + + Standard_Real du= UClosed ? (U2-U1) / fin : (U2-U1) / (1 + fin); + for (Standard_Integer i = 1; i <= fin; i++) + { + anIso.Load (GeomAbs_IsoU, U1 + du * i, V1, V2); Handle(TColgp_HSequenceOfPnt) Pnts = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, Pnts->ChangeSequence(), Standard_False); - UIsoCurves.Append(Pnts); + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, Pnts->ChangeSequence(), Standard_False); + UIsoCurves.Append (Pnts); } } fin = aDrawer->VIsoAspect()->Number(); - if ( fin != 0) { + if (fin != 0) + { + Prs3d_Root::CurrentGroup (aPresentation)->SetPrimitivesAspect (aDrawer->VIsoAspect()->Aspect()); - (Prs3d_Root::CurrentGroup(aPresentation))->SetPrimitivesAspect - (aDrawer->VIsoAspect()->Aspect()); - - Standard_Real dv= VClosed ?(V2-V1)/fin : (V2-V1)/(1+fin); - for (Standard_Integer i=1; i<=fin;i++){ - anIso.Load(GeomAbs_IsoV,V1+dv*i,U1,U2); + Standard_Real dv = VClosed ? (V2 - V1) / fin : (V2 - V1) / (1 + fin); + for (Standard_Integer i = 1; i <= fin; i++) + { + anIso.Load (GeomAbs_IsoV, V1 + dv * i, U1, U2); Handle(TColgp_HSequenceOfPnt) Pnts = new TColgp_HSequenceOfPnt; - StdPrs_Curve::Add(aPresentation,anIso,TheDeflection, aDrawer, Pnts->ChangeSequence(), Standard_False); - VIsoCurves.Append(Pnts); + StdPrs_Curve::Add (aPresentation, anIso, aDrawer, Pnts->ChangeSequence(), Standard_False); + VIsoCurves.Append (Pnts); } } - + Standard_Integer nbVertices = 0, nbBounds = 0; //Draw surface via primitive array if(UIsoCurves.Size() > 0) { diff --git a/src/StdSelect/StdSelect_Shape.cxx b/src/StdSelect/StdSelect_Shape.cxx index 838a7b2180..613974575e 100644 --- a/src/StdSelect/StdSelect_Shape.cxx +++ b/src/StdSelect/StdSelect_Shape.cxx @@ -20,8 +20,8 @@ #include #include #include +#include #include -#include #include #include #include @@ -45,10 +45,10 @@ void StdSelect_Shape::Compute(const Handle(PrsMgr_PresentationManager3d)& /*PM*/ if(CanShade) StdPrs_ShadedShape::Add (P, mysh, myDrawer); else - StdPrs_WFDeflectionShape::Add (P, mysh, myDrawer); + StdPrs_WFShape::Add (P, mysh, myDrawer); } else if (aMode==0) - StdPrs_WFDeflectionShape::Add (P, mysh, myDrawer); + StdPrs_WFShape::Add (P, mysh, myDrawer); } void StdSelect_Shape::Compute(const Handle(Prs3d_Projector)& aProjector , diff --git a/src/ViewerTest/ViewerTest.cxx b/src/ViewerTest/ViewerTest.cxx index 51325abcb9..2461cb9c87 100644 --- a/src/ViewerTest/ViewerTest.cxx +++ b/src/ViewerTest/ViewerTest.cxx @@ -577,7 +577,8 @@ static int visos (Draw_Interpretor& di, Standard_Integer argc, const char** argv TheAISContext()->IsoNumber(AIS_TOI_IsoV) << "\n"; di << "IsoOnPlane mode is " << (TheAISContext()->IsoOnPlane() ? "ON" : "OFF") << "\n"; - + di << "IsoOnTriangulation mode is " << + (TheAISContext()->IsoOnTriangulation() ? "ON" : "OFF") << "\n"; return 0; } @@ -1468,6 +1469,11 @@ struct ViewerTest_AspectsChangeSet Standard_Integer ToSetFreeBoundaryColor; Quantity_Color FreeBoundaryColor; + Standard_Integer ToEnableIsoOnTriangulation; + + Standard_Integer ToSetMaxParamValue; + Standard_Real MaxParamValue; + //! Empty constructor ViewerTest_AspectsChangeSet() : ToSetVisibility (0), @@ -1482,11 +1488,14 @@ struct ViewerTest_AspectsChangeSet Transparency (0.0), ToSetMaterial (0), Material (Graphic3d_NOM_DEFAULT), - ToSetShowFreeBoundary (0), - ToSetFreeBoundaryWidth (0), - FreeBoundaryWidth (1.0), - ToSetFreeBoundaryColor (0), - FreeBoundaryColor (DEFAULT_FREEBOUNDARY_COLOR) {} + ToSetShowFreeBoundary (0), + ToSetFreeBoundaryWidth (0), + FreeBoundaryWidth (1.0), + ToSetFreeBoundaryColor (0), + FreeBoundaryColor (DEFAULT_FREEBOUNDARY_COLOR), + ToEnableIsoOnTriangulation (-1), + ToSetMaxParamValue (0), + MaxParamValue (500000) {} //! @return true if no changes have been requested Standard_Boolean IsEmpty() const @@ -1498,7 +1507,8 @@ struct ViewerTest_AspectsChangeSet && ToSetMaterial == 0 && ToSetShowFreeBoundary == 0 && ToSetFreeBoundaryColor == 0 - && ToSetFreeBoundaryWidth == 0; + && ToSetFreeBoundaryWidth == 0 + && ToSetMaxParamValue == 0; } //! @return true if properties are valid @@ -1540,6 +1550,11 @@ struct ViewerTest_AspectsChangeSet std::cout << "Error: the free boundary width should be within [1; 10] range (specified " << FreeBoundaryWidth << ")\n"; isOk = Standard_False; } + if (MaxParamValue < 0.0) + { + std::cout << "Error: the max parameter value should be greater than zero (specified " << MaxParamValue << ")\n"; + isOk = Standard_False; + } return isOk; } @@ -2069,6 +2084,42 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aChangeSet->ToSetFreeBoundaryWidth = -1; aChangeSet->FreeBoundaryWidth = 1.0; } + else if (anArg == "-isoontriangulation" + || anArg == "-isoontriang") + { + if (++anArgIter >= theArgNb) + { + std::cout << "Error: wrong syntax at " << anArg << "\n"; + return 1; + } + TCollection_AsciiString aValue (theArgVec[anArgIter]); + aValue.LowerCase(); + if (aValue == "on" + || aValue == "1") + { + aChangeSet->ToEnableIsoOnTriangulation = 1; + } + else if (aValue == "off" + || aValue == "0") + { + aChangeSet->ToEnableIsoOnTriangulation = 0; + } + else + { + std::cout << "Error: wrong syntax at " << anArg << "\n"; + return 1; + } + } + else if (anArg == "-setmaxparamvalue") + { + if (++anArgIter >= theArgNb) + { + std::cout << "Error: wrong syntax at " << anArg << "\n"; + return 1; + } + aChangeSet->ToSetMaxParamValue = 1; + aChangeSet->MaxParamValue = Draw::Atof (theArgVec[anArgIter]); + } else { std::cout << "Error: wrong syntax at " << anArg << "\n"; @@ -2146,6 +2197,14 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, { aDrawer->FreeBoundaryAspect()->SetColor (aChangeSet->FreeBoundaryColor); } + if (aChangeSet->ToEnableIsoOnTriangulation != -1) + { + aDrawer->SetIsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1); + } + if (aChangeSet->ToSetMaxParamValue != 0) + { + aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue); + } // redisplay all objects in context for (ViewTest_PrsIter aPrsIter (aNames); aPrsIter.More(); aPrsIter.Next()) @@ -2229,6 +2288,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, { aCtx->UnsetWidth (aPrs, Standard_False); } + else if (aChangeSet->ToEnableIsoOnTriangulation != -1) + { + aCtx->IsoOnTriangulation (aChangeSet->ToEnableIsoOnTriangulation == 1, aPrs); + toRedisplay = Standard_True; + } if (!aDrawer.IsNull()) { if (aChangeSet->ToSetShowFreeBoundary == 1) @@ -2268,6 +2332,10 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, aDrawer->SeenLineAspect()->SetTypeOfLine (aChangeSet->TypeOfLine); toRedisplay = Standard_True; } + if (aChangeSet->ToSetMaxParamValue != 0) + { + aDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue); + } } for (aChangesIter.Next(); aChangesIter.More(); aChangesIter.Next()) @@ -2295,6 +2363,11 @@ static Standard_Integer VAspects (Draw_Interpretor& /*theDI*/, { aColoredPrs->UnsetCustomAspects (aSubShape, Standard_True); } + if (aChangeSet->ToSetMaxParamValue != 0) + { + Handle(AIS_ColoredDrawer) aCurColDrawer = aColoredPrs->CustomAspects (aSubShape); + aCurColDrawer->SetMaximalParameterValue (aChangeSet->MaxParamValue); + } } } if (toDisplay) @@ -5465,6 +5538,8 @@ void ViewerTest::Commands(Draw_Interpretor& theCommands) "\n\t\t: [-setFreeBoundaryWidth Width] [-unsetFreeBoundaryWidth]" "\n\t\t: [-setFreeBoundaryColor {ColorName | R G B}] [-unsetFreeBoundaryColor]" "\n\t\t: [-subshapes subname1 [subname2 [...]]]" + "\n\t\t: [-isoontriangulation 0|1]" + "\n\t\t: [-setMaxParamValue {value}]" "\n\t\t: Manage presentation properties of all, selected or named objects." "\n\t\t: When -subshapes is specified than following properties will be" "\n\t\t: assigned to specified sub-shapes." diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 5787882f48..a0635ab42a 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -2755,7 +2755,7 @@ static int VDrawText (Draw_Interpretor& theDI, #include #include -#include +#include #include #include #include @@ -5848,7 +5848,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI, for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) { const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); - Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation); if (!aTriangulation.IsNull()) { aNbPoints += aTriangulation->NbNodes(); @@ -5864,7 +5864,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI, for (TopExp_Explorer aFaceIt (aShape, TopAbs_FACE); aFaceIt.More(); aFaceIt.Next()) { const TopoDS_Face& aFace = TopoDS::Face (aFaceIt.Current()); - Handle(Poly_Triangulation) aTriangulation = StdPrs_ToolShadedShape::Triangulation (aFace, aLocation); + Handle(Poly_Triangulation) aTriangulation = BRep_Tool::Triangulation (aFace, aLocation); if (aTriangulation.IsNull()) { continue; @@ -5878,7 +5878,7 @@ static Standard_Integer VPointCloud (Draw_Interpretor& theDI, if (hasNormals) { Poly_Connect aPolyConnect (aTriangulation); - StdPrs_ToolShadedShape::Normal (aFace, aPolyConnect, aNormals); + StdPrs_ToolTriangulatedShape::Normal (aFace, aPolyConnect, aNormals); } for (Standard_Integer aNodeIter = aNodes.Lower(); aNodeIter <= aNodes.Upper(); ++aNodeIter) diff --git a/tests/bugs/vis/bug129_2 b/tests/bugs/vis/bug129_2 index fd6725c39d..9d5fda9d5b 100755 --- a/tests/bugs/vis/bug129_2 +++ b/tests/bugs/vis/bug129_2 @@ -13,6 +13,9 @@ trimv ct c -1e+9 1e+9 mkface ft ct vinit +# change maximum uv parameter value in drawer to display +# isolines correctly +vaspects -defaults -setMaxParamValue 1e+9 vdisplay ft set x1 207 @@ -29,4 +32,14 @@ checkcolor ${x1} ${y1} 0.8 0.8 0.8 vselect ${x2} ${y2} checkcolor ${x1} ${y1} 1 1 0 -set only_screen 0 +# dump image, than restore default maximum parameter value +set aViewInfo [split [vviewlist long] "/"] +set aImgFile ${imagedir}/${casename} +foreach aStr $aViewInfo { + append aImgFile "_" [string trim $aStr] +} +append aImgFile ".png" +vdump $aImgFile + +vaspects -defaults -setMaxParamValue 500000 +vclose diff --git a/tests/bugs/vis/bug25300_1 b/tests/bugs/vis/bug25300_1 new file mode 100644 index 0000000000..66416b8f9c --- /dev/null +++ b/tests/bugs/vis/bug25300_1 @@ -0,0 +1,43 @@ +puts "============" +puts "CR25300" +puts "============" +puts "" + +########################################################################################## +puts "Visualization - Build wireframe representation consistent with the shape's triangulation" +# +# Case 1: Test isolines on conic shape where usual algorithm builds isos beyond the +# shape's boundaries +########################################################################################## + +pload VISUALIZATION + +restore [locate_data_file bug25300_pencil.brep] aPencil + +set aSimpleIsoImg $imagedir/${casename}_iso.png +set aIsoOnTrgImg $imagedir/${casename}_iso_on_triang.png + +vinit View1 +vclear +vaxo +vdisplay aPencil +vviewparams -scale 9787.997 -proj -0.0115 -0.9998 0.0145 +vviewparams -up -0.0155 0.0147 0.9998 -at 0.0503 0 0 +vsetdispmode 1 + +# shows that default isoline builder has problemas with proper +# construction of isolines on top of the pencil +vmoveto 200 200 +vdump $aSimpleIsoImg +checkcolor 337 162 0 1 1 + +vmoveto 0 0 + +# enable isoline-on-triangulation builder +vaspects aPencil -isoontriang on + +# shows that isoline-on-triangulation builder constructs isos that +# do not extend beyond the boundaries of shape's triangulation +vmoveto 200 200 +vdump $aIsoOnTrgImg +checkcolor 337 162 0 0 0 diff --git a/tests/bugs/vis/bug25300_2 b/tests/bugs/vis/bug25300_2 new file mode 100644 index 0000000000..2c06eec5e1 --- /dev/null +++ b/tests/bugs/vis/bug25300_2 @@ -0,0 +1,43 @@ +puts "============" +puts "CR25300" +puts "============" +puts "" + +########################################################################################## +puts "Visualization - Build wireframe representation consistent with the shape's triangulation" +# +# Case 2: Conic shape where isolines are build outside of its displayed triangulation +########################################################################################## + +pload VISUALIZATION MODELING + +pcone aCone 90 0 150 360 + +set aSimpleIsoImg $imagedir/${casename}_iso.png +set aIsoOnTrgImg $imagedir/${casename}_iso_on_triang.png + +vinit View1 +vclear +vaxo +vdisplay aCone +vviewparams -scale 122.2874 -proj 0.0353 -0.9281 0.3706 +vviewparams -up -0.2791 0.3469 0.8954 -at -5.5784 62.4399 122.7242 +vviewparams -eye 12.0732 -401.6167 308.0344 +vsetdispmode 1 + +# shows that default isoline builder has problemas with proper +# construction of isolines on top of the conic surface +vmoveto 300 300 +vdump $aSimpleIsoImg +checkcolor 347 179 0 1 1 + +vmoveto 0 0 + +# enable isoline-on-triangulation builder +vaspects aCone -isoontriang on + +# shows that isoline-on-triangulation builder constructs isos that +# do not extend beyond the boundaries of shape's triangulation +vmoveto 300 300 +vdump $aIsoOnTrgImg +checkcolor 347 179 0 0 0 diff --git a/tests/bugs/vis/bug25935 b/tests/bugs/vis/bug25935 index 640146b626..f773af714b 100644 --- a/tests/bugs/vis/bug25935 +++ b/tests/bugs/vis/bug25935 @@ -13,8 +13,8 @@ vinit # check displaying and selection of a sub-shell of the shape vdisplay aShape_3 vfit -vmoveto 214 200 -checkcolor 214 200 0 1 1 +vmoveto 210 200 +checkcolor 210 200 0 1 1 vremove -all @@ -25,4 +25,4 @@ vmoveto 192 211 vmoveto 213 191 vmoveto 205 205 vmoveto 197 194 -checkcolor 205 205 0 1 1 +checkcolor 205 212 0 1 1