From 50c26f8bb70e02bfe1f70e0f3545611378433e77 Mon Sep 17 00:00:00 2001 From: mpv Date: Wed, 19 Aug 2015 14:48:39 +0300 Subject: [PATCH] Issue #736: axis size correct computation basing on bounding box of cylindrical face --- src/GeomAPI/GeomAPI_Face.cpp | 9 +++++ src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp | 44 +++++++++++++++++++++ 2 files changed, 53 insertions(+) diff --git a/src/GeomAPI/GeomAPI_Face.cpp b/src/GeomAPI/GeomAPI_Face.cpp index 4b3004759..826b8477a 100644 --- a/src/GeomAPI/GeomAPI_Face.cpp +++ b/src/GeomAPI/GeomAPI_Face.cpp @@ -18,6 +18,7 @@ #include #include #include +#include GeomAPI_Face::GeomAPI_Face() : GeomAPI_Shape() @@ -66,6 +67,10 @@ bool GeomAPI_Face::isPlanar() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape)); + Handle(Geom_RectangularTrimmedSurface) aTrimmed = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf); + if (!aTrimmed.IsNull()) + aSurf = aTrimmed->BasisSurface(); GeomLib_IsPlanarSurface isPlanar(aSurf); return isPlanar.IsPlanar() == Standard_True; } @@ -74,6 +79,10 @@ bool GeomAPI_Face::isCylindrical() const { const TopoDS_Shape& aShape = const_cast(this)->impl(); Handle(Geom_Surface) aSurf = BRep_Tool::Surface(TopoDS::Face(aShape)); + Handle(Geom_RectangularTrimmedSurface) aTrimmed = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf); + if (!aTrimmed.IsNull()) + aSurf = aTrimmed->BasisSurface(); return aSurf->IsKind(STANDARD_TYPE(Geom_CylindricalSurface)) == Standard_True; } diff --git a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp index fdf2fc434..3c177a178 100644 --- a/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp +++ b/src/GeomAlgoAPI/GeomAlgoAPI_EdgeBuilder.cpp @@ -13,9 +13,12 @@ #include #include #include +#include #include #include +#include +#include std::shared_ptr GeomAlgoAPI_EdgeBuilder::line( std::shared_ptr theStart, std::shared_ptr theEnd) @@ -48,14 +51,55 @@ std::shared_ptr GeomAlgoAPI_EdgeBuilder::cylinderAxis( Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc); if (aSurf.IsNull()) return aResult; + Handle(Geom_RectangularTrimmedSurface) aTrimmed = + Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf); + if (!aTrimmed.IsNull()) + aSurf = aTrimmed->BasisSurface(); Handle(Geom_CylindricalSurface) aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf); if (aCyl.IsNull()) return aResult; gp_Ax1 anAxis = aCyl->Axis(); + // compute the start and the end points of the resulting edge by the bounding box of the face + // (vertices projected to the axis) plus 10% + Bnd_Box aFaceBnd; + BRepBndLib::Add(aFace, aFaceBnd); + gp_Pnt aBoxMin(aFaceBnd.CornerMin()), aBoxMax(aFaceBnd.CornerMax()); + bool isFirst = true; + double aParamMin = 0, aParamMax = 0; + for(int aX = 0; aX < 2; aX++) { + for(int aY = 0; aY < 2; aY++) { + for(int aZ = 0; aZ < 2; aZ++) { + gp_XYZ aBoxVertex(aX == 0 ? aBoxMin.X() : aBoxMax.X(), + aY == 0 ? aBoxMin.Y() : aBoxMax.Y(), aZ == 0 ? aBoxMin.Z() : aBoxMax.Z()); + gp_XYZ aVec(aBoxVertex - anAxis.Location().XYZ()); + double aProjParam = aVec.Dot(anAxis.Direction().XYZ()); + if (isFirst) { + isFirst = false; + aParamMin = aProjParam; + aParamMax = aProjParam; + } else { + if (aParamMin > aProjParam) + aParamMin = aProjParam; + else if (aParamMax < aProjParam) + aParamMax = aProjParam; + } + } + } + } + // add 10% + double aDelta = aParamMax - aParamMin; + if (aDelta < 1.e-4) aDelta = 1.e-4; + aParamMin -= aDelta * 0.1; + aParamMax += aDelta * 0.1; + + gp_Pnt aStart(aParamMin * anAxis.Direction().XYZ() + anAxis.Location().XYZ()); + gp_Pnt anEnd(aParamMax * anAxis.Direction().XYZ() + anAxis.Location().XYZ()); + /* gp_Pnt aStart(anAxis.Location().Transformed(aLoc.Transformation())); // edge length is 100, "-" because cylinder of extrusion has negative direction with the cylinder gp_Pnt anEnd(anAxis.Location().XYZ() - anAxis.Direction().XYZ() * 100.); anEnd.Transform(aLoc.Transformation()); + */ BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd); std::shared_ptr aRes(new GeomAPI_Edge); -- 2.39.2