1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
3 // File: GeomAlgoAPI_EdgeBuilder.cpp
4 // Created: 23 Apr 2014
5 // Author: Mikhail PONIKAROV
7 #include <GeomAlgoAPI_EdgeBuilder.h>
9 #include <BRepBuilderAPI_MakeEdge.hxx>
10 #include <TopoDS_Edge.hxx>
11 #include <TopoDS_Face.hxx>
13 #include <BRep_Tool.hxx>
14 #include <Geom_Plane.hxx>
15 #include <Geom_CylindricalSurface.hxx>
16 #include <Geom_RectangularTrimmedSurface.hxx>
19 #include <gp_Circ.hxx>
20 #include <Bnd_Box.hxx>
21 #include <BRepBndLib.hxx>
23 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
24 std::shared_ptr<GeomAPI_Pnt> theStart, std::shared_ptr<GeomAPI_Pnt> theEnd)
26 const gp_Pnt& aStart = theStart->impl<gp_Pnt>();
27 const gp_Pnt& anEnd = theEnd->impl<gp_Pnt>();
29 if (aStart.IsEqual(anEnd, Precision::Confusion()))
30 return std::shared_ptr<GeomAPI_Edge>();
31 if (Abs(aStart.SquareDistance(anEnd)) > 1.e+100)
32 return std::shared_ptr<GeomAPI_Edge>();
33 BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
34 std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
35 TopoDS_Edge anEdge = anEdgeBuilder.Edge();
36 aRes->setImpl(new TopoDS_Shape(anEdge));
39 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::line(
40 double theDX, double theDY, double theDZ)
43 const gp_Pnt& aStart = gp_Pnt(0, 0, 0);
44 const gp_Pnt& anEnd = gp_Pnt(theDX, theDY, theDZ);
46 if (aStart.IsEqual(anEnd, Precision::Confusion()))
47 return std::shared_ptr<GeomAPI_Edge>();
48 if (Abs(aStart.SquareDistance(anEnd)) > 1.e+100)
49 return std::shared_ptr<GeomAPI_Edge>();
50 BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
51 std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
52 TopoDS_Edge anEdge = anEdgeBuilder.Edge();
53 aRes->setImpl(new TopoDS_Shape(anEdge));
57 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::cylinderAxis(
58 std::shared_ptr<GeomAPI_Shape> theCylindricalFace)
60 std::shared_ptr<GeomAPI_Edge> aResult;
61 const TopoDS_Shape& aShape = theCylindricalFace->impl<TopoDS_Shape>();
64 TopoDS_Face aFace = TopoDS::Face(aShape);
68 Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace, aLoc);
71 Handle(Geom_RectangularTrimmedSurface) aTrimmed =
72 Handle(Geom_RectangularTrimmedSurface)::DownCast(aSurf);
73 if (!aTrimmed.IsNull())
74 aSurf = aTrimmed->BasisSurface();
75 Handle(Geom_CylindricalSurface) aCyl = Handle(Geom_CylindricalSurface)::DownCast(aSurf);
78 gp_Ax1 anAxis = aCyl->Axis();
79 // compute the start and the end points of the resulting edge by the bounding box of the face
80 // (vertices projected to the axis) plus 10%
82 BRepBndLib::Add(aFace, aFaceBnd);
83 gp_Pnt aBoxMin(aFaceBnd.CornerMin()), aBoxMax(aFaceBnd.CornerMax());
85 double aParamMin = 0, aParamMax = 0;
86 for(int aX = 0; aX < 2; aX++) {
87 for(int aY = 0; aY < 2; aY++) {
88 for(int aZ = 0; aZ < 2; aZ++) {
89 gp_XYZ aBoxVertex(aX == 0 ? aBoxMin.X() : aBoxMax.X(),
90 aY == 0 ? aBoxMin.Y() : aBoxMax.Y(), aZ == 0 ? aBoxMin.Z() : aBoxMax.Z());
91 gp_XYZ aVec(aBoxVertex - anAxis.Location().XYZ());
92 double aProjParam = aVec.Dot(anAxis.Direction().XYZ());
95 aParamMin = aProjParam;
96 aParamMax = aProjParam;
98 if (aParamMin > aProjParam)
99 aParamMin = aProjParam;
100 else if (aParamMax < aProjParam)
101 aParamMax = aProjParam;
107 double aDelta = aParamMax - aParamMin;
108 if (aDelta < 1.e-4) aDelta = 1.e-4;
109 aParamMin -= aDelta * 0.1;
110 aParamMax += aDelta * 0.1;
112 gp_Pnt aStart(aParamMin * anAxis.Direction().XYZ() + anAxis.Location().XYZ());
113 gp_Pnt anEnd(aParamMax * anAxis.Direction().XYZ() + anAxis.Location().XYZ());
115 gp_Pnt aStart(anAxis.Location().Transformed(aLoc.Transformation()));
116 // edge length is 100, "-" because cylinder of extrusion has negative direction with the cylinder
117 gp_Pnt anEnd(anAxis.Location().XYZ() - anAxis.Direction().XYZ() * 100.);
118 anEnd.Transform(aLoc.Transformation());
121 BRepBuilderAPI_MakeEdge anEdgeBuilder(aStart, anEnd);
122 std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
123 TopoDS_Edge anEdge = anEdgeBuilder.Edge();
124 // an axis is an infinite object
125 anEdge.Infinite(Standard_True);
126 aRes->setImpl(new TopoDS_Shape(anEdge));
130 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircle(
131 std::shared_ptr<GeomAPI_Pnt> theCenter, std::shared_ptr<GeomAPI_Dir> theNormal,
134 const gp_Pnt& aCenter = theCenter->impl<gp_Pnt>();
135 const gp_Dir& aDir = theNormal->impl<gp_Dir>();
137 gp_Circ aCircle(gp_Ax2(aCenter, aDir), theRadius);
139 BRepBuilderAPI_MakeEdge anEdgeBuilder(aCircle);
140 std::shared_ptr<GeomAPI_Edge> aRes(new GeomAPI_Edge);
141 TopoDS_Edge anEdge = anEdgeBuilder.Edge();
142 aRes->setImpl(new TopoDS_Shape(anEdge));
146 std::shared_ptr<GeomAPI_Edge> GeomAlgoAPI_EdgeBuilder::lineCircleArc(
147 std::shared_ptr<GeomAPI_Pnt> theCenter, std::shared_ptr<GeomAPI_Pnt> theStartPoint,
148 std::shared_ptr<GeomAPI_Pnt> theEndPoint, std::shared_ptr<GeomAPI_Dir> theNormal)
150 std::shared_ptr<GeomAPI_Edge> aRes;
152 const gp_Pnt& aCenter = theCenter->impl<gp_Pnt>();
153 const gp_Dir& aDir = theNormal->impl<gp_Dir>();
155 /// OCCT creates an edge on a circle with empty radius, but visualization
156 /// is not able to process it
157 if (theCenter->isEqual(theStartPoint))
160 double aRadius = theCenter->distance(theStartPoint);
161 gp_Circ aCircle(gp_Ax2(aCenter, aDir), aRadius);
163 const gp_Pnt& aStart = theStartPoint->impl<gp_Pnt>();
164 const gp_Pnt& anEnd = theEndPoint->impl<gp_Pnt>();
166 BRepBuilderAPI_MakeEdge anEdgeBuilder;
167 anEdgeBuilder = BRepBuilderAPI_MakeEdge(aCircle, aStart, anEnd);
169 anEdgeBuilder.Build();
171 if (anEdgeBuilder.IsDone()) {
172 aRes = std::shared_ptr<GeomAPI_Edge>(new GeomAPI_Edge);
173 aRes->setImpl(new TopoDS_Shape(anEdgeBuilder.Edge()));