Salome HOME
Added option to create Construction Point by projection point on plane. Fixed CPP...
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_PointBuilder.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_PointBuilder.cpp
4 // Created:     02 Jun 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include "GeomAlgoAPI_PointBuilder.h"
8
9 #include <GeomAPI_Edge.h>
10 #include <GeomAPI_Face.h>
11 #include <GeomAPI_Pln.h>
12 #include <GeomAPI_Pnt.h>
13 #include <GeomAPI_Shape.h>
14 #include <GeomAPI_Vertex.h>
15
16 #include <BRep_Tool.hxx>
17 #include <BRepBuilderAPI_MakeVertex.hxx>
18 #include <GCPnts_AbscissaPoint.hxx>
19 #include <GeomAdaptor_Curve.hxx>
20 #include <gp_Pln.hxx>
21 #include <gp_Pnt.hxx>
22 #include <TopoDS.hxx>
23 #include <TopoDS_Vertex.hxx>
24
25 //==================================================================================================
26 std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertex(const std::shared_ptr<GeomAPI_Pnt> thePoint)
27 {
28   const gp_Pnt& aPnt = thePoint->impl<gp_Pnt>();
29   BRepBuilderAPI_MakeVertex aMaker(aPnt);
30   TopoDS_Vertex aVertex = aMaker.Vertex();
31   std::shared_ptr<GeomAPI_Vertex> aRes(new GeomAPI_Vertex);
32   aRes->setImpl(new TopoDS_Shape(aVertex));
33   return aRes;
34 }
35
36 //==================================================================================================
37 std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertex(const double theX,
38                                                                  const double theY,
39                                                                  const double theZ)
40 {
41   const gp_Pnt aPnt(theX, theY, theZ);
42   BRepBuilderAPI_MakeVertex aMaker(aPnt);
43   TopoDS_Vertex aVertex = aMaker.Vertex();
44   std::shared_ptr<GeomAPI_Vertex> aRes(new GeomAPI_Vertex);
45   aRes->setImpl(new TopoDS_Shape(aVertex));
46   return aRes;
47 }
48
49 //==================================================================================================
50 std::shared_ptr<GeomAPI_Pnt> GeomAlgoAPI_PointBuilder::point(const std::shared_ptr<GeomAPI_Shape> theVertex)
51 {
52   TopoDS_Shape aShape = theVertex->impl<TopoDS_Shape>();
53   if ((!aShape.IsNull()) && (aShape.ShapeType() == TopAbs_VERTEX)) {
54     TopoDS_Vertex aVertex = TopoDS::Vertex(aShape);
55     gp_Pnt aPoint = BRep_Tool::Pnt(aVertex);
56     std::shared_ptr<GeomAPI_Pnt> aPnt(new GeomAPI_Pnt(aPoint.X(), aPoint.Y(), aPoint.Z()));
57     return aPnt;
58   }
59   return std::shared_ptr<GeomAPI_Pnt>();
60 }
61
62 //==================================================================================================
63 std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertexOnEdge(const std::shared_ptr<GeomAPI_Edge> theEdge,
64                                                                        const double theValue,
65                                                                        const bool theIsPercent,
66                                                                        const bool theIsReverse)
67 {
68   if(!theEdge.get()) {
69     return NULL;
70   }
71
72   double aValue = theValue;
73   if(theIsPercent) {
74     aValue = theEdge->length() / 100.0 * aValue;
75   }
76
77   const TopoDS_Edge& anEdge = TopoDS::Edge(theEdge->impl<TopoDS_Shape>());
78   Standard_Real aUFirst, aULast;
79   Handle(Geom_Curve) anEdgeCurve = BRep_Tool::Curve(anEdge, aUFirst, aULast);
80
81   std::shared_ptr<GeomAPI_Vertex> aVertex;
82   if(!anEdgeCurve.IsNull() ) {
83     Handle(Geom_Curve) aReOrientedCurve = anEdgeCurve;
84
85     if(theIsReverse) {
86       aReOrientedCurve = anEdgeCurve->Reversed();
87       aUFirst = anEdgeCurve->ReversedParameter(aULast);
88     }
89
90     // Get the point by length
91     GeomAdaptor_Curve anAdapCurve = GeomAdaptor_Curve(aReOrientedCurve);
92     GCPnts_AbscissaPoint anAbsPnt(anAdapCurve, aValue, aUFirst);
93     Standard_Real aParam = anAbsPnt.Parameter();
94     gp_Pnt aPnt = anAdapCurve.Value(aParam);
95     BRepBuilderAPI_MakeVertex aMkVertex(aPnt);
96     const TopoDS_Vertex& aShape = aMkVertex.Vertex();
97     aVertex.reset(new GeomAPI_Vertex());
98     aVertex->setImpl(new TopoDS_Vertex(aShape));
99   }
100
101   return aVertex;
102 }
103
104 //==================================================================================================
105 std::shared_ptr<GeomAPI_Vertex> GeomAlgoAPI_PointBuilder::vertexByProjection(
106     const std::shared_ptr<GeomAPI_Vertex> theVertex,
107     const std::shared_ptr<GeomAPI_Face> thePlane)
108 {
109   if(!theVertex.get() || !thePlane.get() || !thePlane->isPlanar()) {
110     return NULL;
111   }
112
113   std::shared_ptr<GeomAPI_Pnt> aGeomPnt = theVertex->point();
114   gp_Pnt aPnt = aGeomPnt->impl<gp_Pnt>();
115
116   std::shared_ptr<GeomAPI_Pln> aGeomPln = thePlane->getPlane();
117   gp_Pln aPln = aGeomPln->impl<gp_Pln>();
118
119   gp_Dir aPntAxis = aPnt.XYZ() - aPln.Location().XYZ();
120   gp_Dir aPlnNorm = aPln.Axis().Direction();
121
122   if(aPntAxis * aPlnNorm > 0) {
123     aPlnNorm.Reverse();
124   }
125
126   double aDistance = aPln.Distance(aPnt);
127   aPnt.Translate(gp_Vec(aPlnNorm) * aDistance);
128
129   return std::shared_ptr<GeomAPI_Vertex>(new GeomAPI_Vertex(aPnt.X(), aPnt.Y(), aPnt.Z()));
130 }