Salome HOME
updated copyright message
[modules/shaper.git] / src / GeomAlgoAPI / GeomAlgoAPI_Box.cpp
1 // Copyright (C) 2014-2023  CEA, EDF
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
18 //
19
20 #include <GeomAlgoAPI_Box.h>
21
22 #include <BRepPrimAPI_MakeBox.hxx>
23 #include <TopoDS_Shape.hxx>
24
25 //=================================================================================================
26 GeomAlgoAPI_Box::GeomAlgoAPI_Box()
27 {
28 }
29
30 //=================================================================================================
31 GeomAlgoAPI_Box::GeomAlgoAPI_Box(const double theDx, const double theDy, const double theDz)
32 {
33   myDx = theDx;
34   myDy = theDy;
35   myDz = theDz;
36   myMethodType = MethodType::BOX_DIM;
37   headError = "Box builder with dimensions";
38 }
39
40 //=================================================================================================
41 GeomAlgoAPI_Box::GeomAlgoAPI_Box(std::shared_ptr<GeomAPI_Pnt> theFirstPoint,
42                                  std::shared_ptr<GeomAPI_Pnt> theSecondPoint)
43 {
44   myFirstPoint = theFirstPoint;
45   mySecondPoint = theSecondPoint;
46   myMethodType = MethodType::BOX_POINTS;
47   headError = "Box builder with two points";
48 }
49
50 //=================================================================================================
51 GeomAlgoAPI_Box::GeomAlgoAPI_Box(const double theOx, const double theOy, const double theOz,
52                                  const double theDx, const double theDy, const double theDz)
53 {
54   myOx = theOx;
55   myOy = theOy;
56   myOz = theOz;
57   myDx = theDx;
58   myDy = theDy;
59   myDz = theDz;
60   myMethodType = MethodType::BOX_POINT_DIMS;
61   headError = "Box builder with coordinates and dimensions";
62 }
63
64 //=================================================================================================
65 bool GeomAlgoAPI_Box::check()
66 {
67   if (myMethodType == MethodType::BOX_DIM || myMethodType == MethodType::BOX_POINT_DIMS) {
68     if (myDx < Precision::Confusion()) {
69       myError = headError + " :: Dx is null or negative.";
70       return false;
71     } else if (myDy < Precision::Confusion()) {
72       myError = headError + " :: Dy is null or negative.";
73       return false;
74     } else if (myDz < Precision::Confusion()) {
75       myError = headError + " :: Dz is null or negative.";
76       return false;
77     }
78   } else if (myMethodType == MethodType::BOX_POINTS) {
79     if (!myFirstPoint.get()) {
80       myError = headError + " :: the first point is not valid.";
81       return false;
82     }
83     if (!mySecondPoint.get()) {
84       myError = headError + " :: the second point is not valid.";
85       return false;
86     }
87     if (myFirstPoint->distance(mySecondPoint) < Precision::Confusion()) {
88       myError = headError + " :: the distance between the two points is null.";
89       return false;
90     }
91     double aDiffX = myFirstPoint->x() - mySecondPoint->x();
92     double aDiffY = myFirstPoint->y() - mySecondPoint->y();
93     double aDiffZ = myFirstPoint->z() - mySecondPoint->z();
94     if (fabs(aDiffX)  < Precision::Confusion() ||
95         fabs(aDiffY)  < Precision::Confusion() ||
96         fabs(aDiffZ)  < Precision::Confusion()) {
97       myError =
98         headError + " :: the points belong both to one of the OXY, OYZ or OZX planes.";
99       return false;
100     }
101   } else {
102     myError = "Box builder :: Method not implemented.";
103     return false;
104   }
105   return true;
106 }
107
108 //=================================================================================================
109 void GeomAlgoAPI_Box::build()
110 {
111   if (myMethodType == MethodType::BOX_DIM) {
112     buildWithDimensions();
113   } else if (myMethodType == MethodType::BOX_POINTS) {
114     buildWithPoints();
115   } else if (myMethodType == MethodType::BOX_POINT_DIMS) {
116     buildWithPointAndDims();
117   } else {
118     myError = "Box builder :: Method not implemented.";
119     return;
120   }
121 }
122
123 //=================================================================================================
124 void GeomAlgoAPI_Box::buildWithDimensions()
125 {
126   myCreatedFaces.clear();
127
128   // Construct the box
129   BRepPrimAPI_MakeBox *aBoxMaker = new BRepPrimAPI_MakeBox(myDx, myDy, myDz);
130   aBoxMaker->Build();
131
132   // Test the algorithm
133   if (!aBoxMaker->IsDone()) {
134     myError = headError + " :: algorithm failed.";
135     return;
136   }
137
138   TopoDS_Shape aResult = aBoxMaker->Shape();
139   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
140   aShape->setImpl(new TopoDS_Shape(aResult));
141   setShape(aShape);
142
143   // Test on the shapes
144   if (!aShape.get() || aShape->isNull()) {
145     myError = headError + " :: resulting shape is null.";
146     return;
147   }
148
149   setImpl(aBoxMaker);
150
151   setDone(true);
152 }
153
154 //=================================================================================================
155 void GeomAlgoAPI_Box::buildWithPoints()
156 {
157   myCreatedFaces.clear();
158
159   const gp_Pnt& aFirstPoint = myFirstPoint->impl<gp_Pnt>();
160   const gp_Pnt& aSecondPoint = mySecondPoint->impl<gp_Pnt>();
161
162   // Construct the box
163   BRepPrimAPI_MakeBox *aBoxMaker = new  BRepPrimAPI_MakeBox(aFirstPoint, aSecondPoint);
164   aBoxMaker->Build();
165
166   // Test the algorithm
167   if(!aBoxMaker->IsDone()) {
168     myError = headError + " :: algorithm failed.";
169     return;
170   }
171
172   TopoDS_Shape aResult = aBoxMaker->Shape();
173
174   std::shared_ptr<GeomAPI_Shape> aShape(new GeomAPI_Shape());
175   aShape->setImpl(new TopoDS_Shape(aResult));
176   setShape(aShape);
177
178   // Tests on the shape
179   if (!aShape.get() || aShape->isNull()) {
180     myError = headError + " :: resulting shape is null.";
181     return;
182   }
183
184   setImpl(aBoxMaker);
185
186   setDone(true);
187 }
188
189 //=================================================================================================
190 void GeomAlgoAPI_Box::buildWithPointAndDims()
191 {
192   // Construct points from cordinates and dimensions to use the method with two points
193   myFirstPoint =
194     std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(myOx - myDx, myOy - myDy, myOz - myDz));
195   mySecondPoint =
196     std::shared_ptr<GeomAPI_Pnt>(new GeomAPI_Pnt(myOx + myDx, myOy + myDy, myOz + myDz));
197
198   buildWithPoints();
199 }
200
201 //=================================================================================================
202 void GeomAlgoAPI_Box::prepareNamingFaces()
203 {
204   BRepPrimAPI_MakeBox aBoxMaker = impl<BRepPrimAPI_MakeBox>();
205   std::shared_ptr<GeomAPI_Shape> aShapeFront(new GeomAPI_Shape);
206   aShapeFront->setImpl(new TopoDS_Shape(aBoxMaker.FrontFace()));
207   myCreatedFaces["Front"] = aShapeFront;
208   std::shared_ptr<GeomAPI_Shape> aShapeBack(new GeomAPI_Shape);
209   aShapeBack->setImpl(new TopoDS_Shape(aBoxMaker.BackFace()));
210   myCreatedFaces["Back"] = aShapeBack;
211   std::shared_ptr<GeomAPI_Shape> aShapeTop(new GeomAPI_Shape);
212   aShapeTop->setImpl(new TopoDS_Shape(aBoxMaker.TopFace()));
213   myCreatedFaces["Top"] = aShapeTop;
214   std::shared_ptr<GeomAPI_Shape> aShapeBottom(new GeomAPI_Shape);
215   aShapeBottom->setImpl(new TopoDS_Shape(aBoxMaker.BottomFace()));
216   myCreatedFaces["Bottom"] = aShapeBottom;
217   std::shared_ptr<GeomAPI_Shape> aShapeLeft(new GeomAPI_Shape);
218   aShapeLeft->setImpl(new TopoDS_Shape(aBoxMaker.LeftFace()));
219   myCreatedFaces["Left"] = aShapeLeft;
220   std::shared_ptr<GeomAPI_Shape> aShapeRight(new GeomAPI_Shape);
221   aShapeRight->setImpl(new TopoDS_Shape(aBoxMaker.RightFace()));
222   myCreatedFaces["Right"] = aShapeRight;
223 }