diff --git a/src/AIS/AIS_ColoredShape.cxx b/src/AIS/AIS_ColoredShape.cxx index f3396308d0..e4519984ae 100644 --- a/src/AIS/AIS_ColoredShape.cxx +++ b/src/AIS/AIS_ColoredShape.cxx @@ -562,7 +562,7 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation const DataMapOfDrawerCompd& theDrawerClosedFaces, const Standard_Integer theMode) { - Handle(Graphic3d_Group) anOpenGroup, aClosedGroup; + Handle(Graphic3d_Group) anOpenGroup, aClosedGroup, anEdgesGroup; for (size_t aShType = 0; aShType <= (size_t )TopAbs_SHAPE; ++aShType) { const Standard_Boolean isClosed = aShType == TopAbs_SHAPE; @@ -616,7 +616,7 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation { if (aShadedGroup.IsNull()) { - aShadedGroup = Prs3d_Root::NewGroup (thePrs); + aShadedGroup = thePrs->NewGroup(); aShadedGroup->SetClosed (isClosed); } aShadedGroup->SetPrimitivesAspect (aDrawer->ShadingAspect()->Aspect()); @@ -625,18 +625,15 @@ void AIS_ColoredShape::addShapesWithCustomProps (const Handle(Prs3d_Presentation if (aDrawer->FaceBoundaryDraw()) { - Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw); - if (!aBndSegments.IsNull()) + if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = StdPrs_ShadedShape::FillFaceBoundaries (aShapeDraw, aDrawer->FaceBoundaryUpperContinuity())) { - if (aShadedGroup.IsNull()) + if (anEdgesGroup.IsNull()) { - aShadedGroup = Prs3d_Root::NewGroup (thePrs); - aShadedGroup->SetClosed (isClosed); + anEdgesGroup = thePrs->NewGroup(); } - Handle(Graphic3d_AspectLine3d) aBoundaryAspect = aDrawer->FaceBoundaryAspect()->Aspect(); - aShadedGroup->SetPrimitivesAspect (aBoundaryAspect); - aShadedGroup->AddPrimitiveArray (aBndSegments); + anEdgesGroup->SetPrimitivesAspect (aDrawer->FaceBoundaryAspect()->Aspect()); + anEdgesGroup->AddPrimitiveArray (aBndSegments); } } } diff --git a/src/BRep/BRep_Tool.cxx b/src/BRep/BRep_Tool.cxx index 9118d62375..d4bade16eb 100644 --- a/src/BRep/BRep_Tool.cxx +++ b/src/BRep/BRep_Tool.cxx @@ -1180,6 +1180,29 @@ Standard_Boolean BRep_Tool::HasContinuity(const TopoDS_Edge& E) return Standard_False; } +//======================================================================= +//function : MaxContinuity +//purpose : +//======================================================================= +GeomAbs_Shape BRep_Tool::MaxContinuity (const TopoDS_Edge& theEdge) +{ + GeomAbs_Shape aMaxCont = GeomAbs_C0; + for (BRep_ListIteratorOfListOfCurveRepresentation aReprIter ((*((Handle(BRep_TEdge)*)&theEdge.TShape()))->ChangeCurves()); + aReprIter.More(); aReprIter.Next()) + { + const Handle(BRep_CurveRepresentation)& aRepr = aReprIter.Value(); + if (aRepr->IsRegularity()) + { + const GeomAbs_Shape aCont = aRepr->Continuity(); + if ((Standard_Integer )aCont > (Standard_Integer )aMaxCont) + { + aMaxCont = aCont; + } + } + } + return aMaxCont; +} + //======================================================================= //function : Pnt //purpose : Returns the 3d point. diff --git a/src/BRep/BRep_Tool.hxx b/src/BRep/BRep_Tool.hxx index e81a3ef3fb..fa6efbe69d 100644 --- a/src/BRep/BRep_Tool.hxx +++ b/src/BRep/BRep_Tool.hxx @@ -227,6 +227,9 @@ public: //! Returns True if the edge has regularity on some //! two surfaces Standard_EXPORT static Standard_Boolean HasContinuity (const TopoDS_Edge& E); + + //! Returns the max continuity of edge between some surfaces or GeomAbs_C0 if there no such surfaces. + Standard_EXPORT static GeomAbs_Shape MaxContinuity (const TopoDS_Edge& theEdge); //! Returns the 3d point. Standard_EXPORT static gp_Pnt Pnt (const TopoDS_Vertex& V); diff --git a/src/Prs3d/Prs3d_Drawer.cxx b/src/Prs3d/Prs3d_Drawer.cxx index 855093d43e..9745bcb608 100644 --- a/src/Prs3d/Prs3d_Drawer.cxx +++ b/src/Prs3d/Prs3d_Drawer.cxx @@ -86,6 +86,7 @@ Prs3d_Drawer::Prs3d_Drawer() myHasOwnUnFreeBoundaryAspect (Standard_False), myUnFreeBoundaryDraw (Standard_True), myHasOwnUnFreeBoundaryDraw (Standard_False), + myFaceBoundaryUpperContinuity(-1), myHasOwnFaceBoundaryAspect (Standard_False), myFaceBoundaryDraw (Standard_False), myHasOwnFaceBoundaryDraw (Standard_False), @@ -1086,7 +1087,7 @@ inline void setAspectProgram (const Handle(Graphic3d_ShaderProgram)& theProgram, } // ======================================================================= -// function : SetShaderProgram +// function : SetOwnLineAspects // purpose : // ======================================================================= void Prs3d_Drawer::SetShaderProgram (const Handle(Graphic3d_ShaderProgram)& theProgram, diff --git a/src/Prs3d/Prs3d_Drawer.hxx b/src/Prs3d/Prs3d_Drawer.hxx index ac1b395314..ab5da3f800 100644 --- a/src/Prs3d/Prs3d_Drawer.hxx +++ b/src/Prs3d/Prs3d_Drawer.hxx @@ -29,6 +29,7 @@ #include #include #include +#include class Prs3d_IsoAspect; class Prs3d_LineAspect; @@ -722,6 +723,10 @@ public: //! face boundaries aspect that overrides the one in the link. Standard_Boolean HasOwnFaceBoundaryAspect() const { return myHasOwnFaceBoundaryAspect; } + //! Sets own face boundary aspect. + //! Returns FALSE if the drawer already has its own attribute for face boundary aspect. + Standard_EXPORT Standard_Boolean SetupOwnFaceBoundaryAspect (const Handle(Prs3d_Drawer)& theDefaults = Handle(Prs3d_Drawer)()); + //! Enables or disables face boundary drawing for shading presentations. //! The method sets drawing flag owned by the drawer that will be used during //! visualization instead of the one set in link. @@ -740,6 +745,25 @@ public: //! "draw face boundaries" flag that overrides the one in the link. Standard_Boolean HasOwnFaceBoundaryDraw() const { return myHasOwnFaceBoundaryDraw; } + //! Returns true if the drawer has its own attribute for face boundaries upper edge continuity class that overrides the one in the link. + Standard_Boolean HasOwnFaceBoundaryUpperContinuity() const { return myFaceBoundaryUpperContinuity != -1; } + + //! Get the most edge continuity class; GeomAbs_CN by default (all edges). + GeomAbs_Shape FaceBoundaryUpperContinuity() const + { + return HasOwnFaceBoundaryUpperContinuity() + ? (GeomAbs_Shape )myFaceBoundaryUpperContinuity + : (!myLink.IsNull() + ? myLink->FaceBoundaryUpperContinuity() + : GeomAbs_CN); + } + + //! Set the most edge continuity class for face boundaries. + void SetFaceBoundaryUpperContinuity (GeomAbs_Shape theMostAllowedEdgeClass) { myFaceBoundaryUpperContinuity = theMostAllowedEdgeClass; } + + //! Unset the most edge continuity class for face boundaries. + void UnsetFaceBoundaryUpperContinuity() { myFaceBoundaryUpperContinuity = -1; } + //! Returns settings for the appearance of dimensions. Standard_EXPORT const Handle(Prs3d_DimensionAspect)& DimensionAspect(); @@ -923,6 +947,7 @@ protected: Standard_Boolean myUnFreeBoundaryDraw; Standard_Boolean myHasOwnUnFreeBoundaryDraw; Handle(Prs3d_LineAspect) myFaceBoundaryAspect; + Standard_Integer myFaceBoundaryUpperContinuity; //!< the most edge continuity class (GeomAbs_Shape) to be included to face boundaries presentation, or -1 if undefined Standard_Boolean myHasOwnFaceBoundaryAspect; Standard_Boolean myFaceBoundaryDraw; Standard_Boolean myHasOwnFaceBoundaryDraw; @@ -935,7 +960,6 @@ protected: Prs3d_DimensionUnits myDimensionDisplayUnits; Standard_Boolean myHasOwnDimLengthDisplayUnits; Standard_Boolean myHasOwnDimAngleDisplayUnits; - }; Standard_DEPRECATED("Class name is deprecated - use Prs3d_Drawer instead") diff --git a/src/StdPrs/StdPrs_ShadedShape.cxx b/src/StdPrs/StdPrs_ShadedShape.cxx index e29b6950c0..774c0ca850 100644 --- a/src/StdPrs/StdPrs_ShadedShape.cxx +++ b/src/StdPrs/StdPrs_ShadedShape.cxx @@ -299,7 +299,8 @@ namespace } //! Compute boundary presentation for faces of the shape. - static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape) + static Handle(Graphic3d_ArrayOfSegments) fillFaceBoundaries (const TopoDS_Shape& theShape, + GeomAbs_Shape theUpperContinuity) { // collection of all triangulation nodes on edges // for computing boundaries presentation @@ -339,6 +340,13 @@ namespace } const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); + if (theUpperContinuity < GeomAbs_CN + && anEdgeIter.Value().Extent() >= 2 + && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity) + { + continue; + } + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); if (!anEdgePoly.IsNull() && anEdgePoly->Nodes().Length() >= 2) @@ -382,6 +390,13 @@ namespace } const TopoDS_Edge& anEdge = TopoDS::Edge (anEdgeIter.Key()); + if (theUpperContinuity < GeomAbs_CN + && anEdgeIter.Value().Extent() >= 2 + && BRep_Tool::MaxContinuity (anEdge) > theUpperContinuity) + { + continue; + } + Handle(Poly_PolygonOnTriangulation) anEdgePoly = BRep_Tool::PolygonOnTriangulation (anEdge, aTriangulation, aTrsf); if (anEdgePoly.IsNull() || anEdgePoly->Nodes().Length () < 2) @@ -576,12 +591,10 @@ void StdPrs_ShadedShape::Add (const Handle (Prs3d_Presentation)& thePrs, if (theDrawer->FaceBoundaryDraw()) { - Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape); - if (!aBndSegments.IsNull()) + if (Handle(Graphic3d_ArrayOfSegments) aBndSegments = fillFaceBoundaries (theShape, theDrawer->FaceBoundaryUpperContinuity())) { - Handle(Graphic3d_AspectLine3d) aBoundaryAspect = theDrawer->FaceBoundaryAspect()->Aspect(); Handle(Graphic3d_Group) aPrsGrp = Prs3d_Root::CurrentGroup (thePrs); - aPrsGrp->SetGroupPrimitivesAspect (aBoundaryAspect); + aPrsGrp->SetGroupPrimitivesAspect (theDrawer->FaceBoundaryAspect()->Aspect()); aPrsGrp->AddPrimitiveArray (aBndSegments); } } @@ -604,9 +617,10 @@ Handle(Graphic3d_ArrayOfTriangles) StdPrs_ShadedShape::FillTriangles (const Topo // function : FillFaceBoundaries // purpose : // ======================================================================= -Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape) +Handle(Graphic3d_ArrayOfSegments) StdPrs_ShadedShape::FillFaceBoundaries (const TopoDS_Shape& theShape, + GeomAbs_Shape theUpperContinuity) { - return fillFaceBoundaries (theShape); + return fillFaceBoundaries (theShape, theUpperContinuity); } // ======================================================================= diff --git a/src/StdPrs/StdPrs_ShadedShape.hxx b/src/StdPrs/StdPrs_ShadedShape.hxx index cbb2a7df75..0bd9d8bd34 100644 --- a/src/StdPrs/StdPrs_ShadedShape.hxx +++ b/src/StdPrs/StdPrs_ShadedShape.hxx @@ -17,10 +17,7 @@ #ifndef _StdPrs_ShadedShape_HeaderFile #define _StdPrs_ShadedShape_HeaderFile -#include -#include -#include - +#include #include #include #include @@ -90,7 +87,9 @@ public: //! Define primitive array of boundary segments for specified shape. //! @param theShape segments array or NULL if specified face does not have computed triangulation - Standard_EXPORT static Handle(Graphic3d_ArrayOfSegments) FillFaceBoundaries (const TopoDS_Shape& theShape); + //! @param theUpperContinuity the most edge continuity class to be included to result (edges with more continuity will be ignored) + Standard_EXPORT static Handle(Graphic3d_ArrayOfSegments) FillFaceBoundaries (const TopoDS_Shape& theShape, + GeomAbs_Shape theUpperContinuity = GeomAbs_CN); }; diff --git a/src/ViewerTest/ViewerTest_ObjectCommands.cxx b/src/ViewerTest/ViewerTest_ObjectCommands.cxx index 4161bab034..0c6ba77c99 100644 --- a/src/ViewerTest/ViewerTest_ObjectCommands.cxx +++ b/src/ViewerTest/ViewerTest_ObjectCommands.cxx @@ -5033,7 +5033,7 @@ static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/, return 1; } - if ((argc != 3 && argc < 6) || argc > 8) + if ((argc != 3 && argc < 6) || argc > 9) { std::cout << "Usage :\n " << argv[0] << " ObjectName isOn [R G B [LineWidth [LineStyle]]]\n" @@ -5064,6 +5064,7 @@ static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/, Standard_Real aBlue = 0.0; Standard_Real aWidth = 1.0; Aspect_TypeOfLine aLineType = Aspect_TOL_SOLID; + GeomAbs_Shape aMaxContinuity = GeomAbs_CN; // find object Handle(AIS_InteractiveObject) anInterObj; @@ -5111,7 +5112,7 @@ static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/, } // select appropriate line type - if (argc == 8) + if (argc >= 8) { if (!ViewerTest::ParseLineType (argv[7], aLineType)) { @@ -5120,12 +5121,52 @@ static Standard_Integer VShowFaceBoundary (Draw_Interpretor& /*di*/, } } + if (argc >= 9) + { + TCollection_AsciiString aClassArg (argv[8]); + aClassArg.LowerCase(); + if (aClassArg == "c0") + { + aMaxContinuity = GeomAbs_C0; + } + else if (aClassArg == "c1") + { + aMaxContinuity = GeomAbs_C1; + } + else if (aClassArg == "g1") + { + aMaxContinuity = GeomAbs_G1; + } + else if (aClassArg == "c2") + { + aMaxContinuity = GeomAbs_C2; + } + else if (aClassArg == "g2") + { + aMaxContinuity = GeomAbs_G2; + } + else if (aClassArg == "c3") + { + aMaxContinuity = GeomAbs_C3; + } + else if (aClassArg == "cn") + { + aMaxContinuity = GeomAbs_CN; + } + else + { + std::cout << "Syntax error at '" << aClassArg << "'\n"; + return 1; + } + } + Quantity_Color aColor (aRed, aGreen, aBlue, Quantity_TOC_RGB); Handle(Prs3d_LineAspect) aBoundaryAspect = new Prs3d_LineAspect (aColor, aLineType, aWidth); aDrawer->SetFaceBoundaryAspect (aBoundaryAspect); + aDrawer->SetFaceBoundaryUpperContinuity (aMaxContinuity); TheAISContext()->Redisplay (anInterObj, Standard_True); @@ -6756,7 +6797,7 @@ void ViewerTest::ObjectCommands(Draw_Interpretor& theCommands) __FILE__, VPolygonOffset, group); theCommands.Add ("vshowfaceboundary", - "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]]" + "vshowfaceboundary : ObjectName isOn (1/0) [R G B [LineWidth [LineStyle]]] [{c0|c1|c2|c3|cn}]" "- turns on/off drawing of face boundaries for ais object " "and defines boundary line style.", __FILE__, VShowFaceBoundary, group);