Salome HOME
Issue #1649: Added options to create plane by three points;
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_FaceBuilder.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        GeomAlgoAPI_FaceBuilder.cpp
4 // Created:     23 Apr 2014
5 // Author:      Mikhail PONIKAROV
6
7 #include "GeomAlgoAPI_FaceBuilder.h"
8
9 #include <GeomAPI_Face.h>
10 #include <GeomAPI_Dir.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_MakeFace.hxx>
18 #include <GC_MakePlane.hxx>
19 #include <Geom_Plane.hxx>
20 #include <GeomLib_IsPlanarSurface.hxx>
21 #include <gp_Pln.hxx>
22 #include <TopoDS.hxx>
23 #include <TopoDS_Face.hxx>
24
25 //==================================================================================================
26 std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::squareFace(const std::shared_ptr<GeomAPI_Pnt> theCenter,
27                                                                   const std::shared_ptr<GeomAPI_Dir> theNormal,
28                                                                   const double theSize)
29 {
30   const gp_Pnt& aCenter = theCenter->impl<gp_Pnt>();
31   const gp_Dir& aDir = theNormal->impl<gp_Dir>();
32   gp_Pln aPlane(aCenter, aDir);
33   // half of the size in each direction from the center
34   BRepBuilderAPI_MakeFace aFaceBuilder(aPlane, -theSize / 2., theSize / 2., -theSize / 2.,
35                                        theSize / 2.);
36   std::shared_ptr<GeomAPI_Face> aRes(new GeomAPI_Face());
37   aRes->setImpl(new TopoDS_Face(aFaceBuilder.Face()));
38   return aRes;
39 }
40
41 //==================================================================================================
42 std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::squareFace(const std::shared_ptr<GeomAPI_Pln> thePlane,
43                                                                   const double theSize)
44 {
45   // half of the size in each direction from the center
46   BRepBuilderAPI_MakeFace aFaceBuilder(thePlane->impl<gp_Pln>(),
47                                        -theSize / 2., theSize / 2.,
48                                        -theSize / 2., theSize / 2.);
49   std::shared_ptr<GeomAPI_Face> aRes(new GeomAPI_Face());
50   const TopoDS_Face& aFace = aFaceBuilder.Face();
51   aRes->setImpl(new TopoDS_Face(aFace));
52   return aRes;
53 }
54
55 //==================================================================================================
56 std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::planarFace(const std::shared_ptr<GeomAPI_Pnt> theCenter,
57                                                                   const std::shared_ptr<GeomAPI_Dir> theNormal)
58 {
59   const gp_Pnt& aCenter = theCenter->impl<gp_Pnt>();
60   const gp_Dir& aDir = theNormal->impl<gp_Dir>();
61   gp_Pln aPlane(aCenter, aDir);
62   BRepBuilderAPI_MakeFace aFaceBuilder(aPlane);
63   std::shared_ptr<GeomAPI_Face> aRes(new GeomAPI_Face());
64   aRes->setImpl(new TopoDS_Face(aFaceBuilder.Face()));
65   return aRes;
66 }
67
68 //==================================================================================================
69 std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::planarFace(const std::shared_ptr<GeomAPI_Pln> thePlane,
70                                                                   const double theX, const double theY,
71                                                                   const double theWidth, const double theHeight)
72 {
73   double aA, aB, aC, aD;
74   thePlane->coefficients(aA, aB, aC, aD);
75   gp_Pln aPlane(aA, aB, aC, aD);
76
77   // half of the size in each direction from the center
78   BRepBuilderAPI_MakeFace aFaceBuilder(aPlane, theX, theX + theWidth, 
79                                        theY, theY + theHeight);
80   std::shared_ptr<GeomAPI_Face> aRes(new GeomAPI_Face());
81   aRes->setImpl(new TopoDS_Face(aFaceBuilder.Face()));
82   return aRes;
83 }
84
85 //==================================================================================================
86 std::shared_ptr<GeomAPI_Face> GeomAlgoAPI_FaceBuilder::planarFaceByThreeVertices(
87     const std::shared_ptr<GeomAPI_Vertex> theVertex1,
88     const std::shared_ptr<GeomAPI_Vertex> theVertex2,
89     const std::shared_ptr<GeomAPI_Vertex> theVertex3)
90 {
91   gp_Pnt aPnt1 = theVertex1->point()->impl<gp_Pnt>();
92   gp_Pnt aPnt2 = theVertex2->point()->impl<gp_Pnt>();
93   gp_Pnt aPnt3 = theVertex3->point()->impl<gp_Pnt>();
94
95   std::shared_ptr<GeomAPI_Face> aFace;
96   GC_MakePlane aMakePlane(aPnt1, aPnt2, aPnt3);
97   if(!aMakePlane.IsDone()) {
98     return aFace;
99   }
100
101   BRepBuilderAPI_MakeFace aMakeFace(aMakePlane.Value()->Pln());
102   aFace.reset(new GeomAPI_Face());
103   aFace->setImpl(new TopoDS_Face(aMakeFace.Face()));
104   return aFace;
105 }
106
107 //==================================================================================================
108 std::shared_ptr<GeomAPI_Pln> GeomAlgoAPI_FaceBuilder::plane(const std::shared_ptr<GeomAPI_Face> theFace)
109 {
110   std::shared_ptr<GeomAPI_Pln> aResult;
111   if (!theFace)
112     return aResult;  // bad shape
113   TopoDS_Shape aShape = theFace->impl<TopoDS_Shape>();
114   if (aShape.IsNull())
115     return aResult;  // null shape
116   if (aShape.ShapeType() != TopAbs_FACE)
117     return aResult;  // not face
118   TopoDS_Face aFace = TopoDS::Face(aShape);
119   if (aFace.IsNull())
120     return aResult;  // not face
121   Handle(Geom_Surface) aSurf = BRep_Tool::Surface(aFace);
122   if (aSurf.IsNull())
123     return aResult;  // no surface
124   GeomLib_IsPlanarSurface isPlanar(aSurf);
125   if(!isPlanar.IsPlanar()) {
126     return aResult;
127   }
128   gp_Pln aPln = isPlanar.Plan();
129   double aA, aB, aC, aD;
130   aPln.Coefficients(aA, aB, aC, aD);
131   if (aFace.Orientation() == TopAbs_REVERSED) {
132     aA = -aA;
133     aB = -aB;
134     aC = -aC;
135     aD = -aD;
136   }
137   aResult = std::shared_ptr<GeomAPI_Pln>(new GeomAPI_Pln(aA, aB, aC, aD));
138   return aResult;
139 }