Salome HOME
8ba0e92194ec5f60ac85f99c81250466623a39f0
[modules/shaper.git] / src / ConstructionAPI / ConstructionAPI_Point.cpp
1 // Copyright (C) 2014-2022  CEA/DEN, EDF R&D
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 "ConstructionAPI_Point.h"
21
22 #include <GeomAPI_Pnt.h>
23 #include <GeomAPI_Shape.h>
24 #include <GeomAPI_Vertex.h>
25
26 #include <ModelHighAPI_Double.h>
27 #include <ModelHighAPI_Dumper.h>
28 #include <ModelHighAPI_Selection.h>
29 #include <ModelHighAPI_Tools.h>
30
31 //==================================================================================================
32 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature)
33 : ModelHighAPI_Interface(theFeature)
34 {
35   initialize();
36 }
37
38 //==================================================================================================
39 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature,
40                                              const ModelHighAPI_Double& theX,
41                                              const ModelHighAPI_Double& theY,
42                                              const ModelHighAPI_Double& theZ)
43 : ModelHighAPI_Interface(theFeature)
44 {
45   if(initialize()) {
46     setByXYZ(theX, theY, theZ);
47   }
48 }
49
50 //==================================================================================================
51 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature,
52                                              const ModelHighAPI_Selection& theEdge,
53                                              const ModelHighAPI_Double& theOffset,
54                                              const bool theUseRatio,
55                                              const bool theReverse)
56 : ModelHighAPI_Interface(theFeature)
57 {
58   if(initialize()) {
59     setByOffsetOnEdge(theEdge, theOffset, theUseRatio, theReverse);
60   }
61 }
62
63 //==================================================================================================
64 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature,
65                                              const ModelHighAPI_Selection& theObject1,
66                                              const ModelHighAPI_Selection& theObject2)
67 : ModelHighAPI_Interface(theFeature)
68 {
69   if(initialize()) {
70     GeomAPI_Shape::ShapeType aType1 = getShapeType(theObject1);
71     GeomAPI_Shape::ShapeType aType2 = getShapeType(theObject2);
72     if(aType1 == GeomAPI_Shape::VERTEX && aType2 == GeomAPI_Shape::FACE) {
73       // If first object is vertex and second object is face then set by projection.
74       setByProjectionOnFace(theObject1, theObject2);
75     } else if (aType1 == GeomAPI_Shape::VERTEX && aType2 == GeomAPI_Shape::EDGE) {
76       // If first object is vertex and second object is edge then set by projection.
77       setByProjectionOnEdge(theObject1, theObject2);
78     } else if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::EDGE) {
79       // If both objects are edges then set by lines intersection.
80       setByLinesIntersection(theObject1, theObject2);
81     } else if(aType1 == GeomAPI_Shape::EDGE && aType2 == GeomAPI_Shape::FACE) {
82       // If first object is edge and second object is face then set by line and plane intersection.
83       setByLineAndPlaneIntersection(theObject1, theObject2);
84     }
85   }
86 }
87
88 //==================================================================================================
89 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature,
90                                              const ModelHighAPI_Selection& theObject1,
91                                              const ModelHighAPI_Selection& theObject2,
92                                              const ModelHighAPI_Selection& theObject3)
93 : ModelHighAPI_Interface(theFeature)
94 {
95   if (initialize())
96   {
97     GeomAPI_Shape::ShapeType aType1 = getShapeType(theObject1);
98     GeomAPI_Shape::ShapeType aType2 = getShapeType(theObject2);
99     GeomAPI_Shape::ShapeType aType3 = getShapeType(theObject3);
100     if (aType1 == GeomAPI_Shape::FACE
101         && aType2 == GeomAPI_Shape::FACE
102         && aType3 == GeomAPI_Shape::FACE)
103     {
104       setByPlanesIntersection(theObject1, theObject2, theObject3);
105     }
106   }
107 }
108
109 //==================================================================================================
110 ConstructionAPI_Point::ConstructionAPI_Point(const std::shared_ptr<ModelAPI_Feature>& theFeature,
111                                              const ModelHighAPI_Selection& theObject,
112                                              const bool theIsCircularEdge,
113                                              const bool theIsXYZSelection)
114 : ModelHighAPI_Interface(theFeature)
115 {
116   if (initialize())
117   {
118     if (theIsCircularEdge) {
119       setByCenterOfCircle(theObject);
120     } else if (theObject.shapeType() == "VERTEX" && theIsXYZSelection) {
121       // This is tricky way to get vertex shape.
122       fillAttribute(theObject, mypointToProject);
123       GeomShapePtr aShape = mypointToProject->value();
124       if (!aShape.get()) {
125         ResultPtr aContext = mypointToProject->context();
126         if (!aContext.get()) {
127           fillAttribute(ModelHighAPI_Selection(), mypointToProject);
128           return;
129         }
130         aShape = aContext->shape();
131       }
132
133       if (!aShape.get()) {
134         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
135         return;
136       }
137
138       GeomVertexPtr aVertex = aShape->vertex();
139       if (!aVertex.get()) {
140         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
141         return;
142       }
143
144       GeomPointPtr aPnt = aVertex->point();
145       if (!aPnt.get()) {
146         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
147         return;
148       }
149
150       fillAttribute(ModelHighAPI_Selection(), mypointToProject);
151       setByXYZ(aPnt->x(), aPnt->y(), aPnt->z());
152     } else {
153       setByCenterOfGravity(theObject);
154     }
155   }
156 }
157
158 //==================================================================================================
159 ConstructionAPI_Point::~ConstructionAPI_Point()
160 {
161
162 }
163
164 //==================================================================================================
165 void ConstructionAPI_Point::setByXYZ(const ModelHighAPI_Double& theX,
166                                      const ModelHighAPI_Double& theY,
167                                      const ModelHighAPI_Double& theZ)
168 {
169   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ(), mycreationMethod);
170   fillAttribute(theX, theY, theZ, mypoint);
171
172   execute(false);
173 }
174
175 //==================================================================================================
176 void ConstructionAPI_Point::setByOffsetOnEdge(const ModelHighAPI_Selection& theEdge,
177                                               const ModelHighAPI_Double& theOffset,
178                                               const bool theUseRatio,
179                                               const bool theReverse)
180 {
181   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE(), mycreationMethod);
182   fillAttribute(theEdge, myedge);
183   if (theUseRatio) {
184     fillAttribute(ConstructionPlugin_Point::OFFSET_TYPE_BY_RATIO(), myoffsetType);
185     fillAttribute(theOffset, myratio);
186   }
187   else {
188     fillAttribute(ConstructionPlugin_Point::OFFSET_TYPE_BY_DISTANCE(), myoffsetType);
189     fillAttribute(theOffset, mydistance);
190   }
191   fillAttribute(theReverse, myreverse);
192
193   execute();
194 }
195
196 //==================================================================================================
197 void ConstructionAPI_Point::setByProjectionOnEdge(const ModelHighAPI_Selection& theVertex,
198                                                   const ModelHighAPI_Selection& theEdge)
199 {
200   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION(),
201                 mycreationMethod);
202   fillAttribute(ConstructionPlugin_Point::PROJECTION_TYPE_ON_EDGE(),
203                 myprojectionType);
204   fillAttribute(theVertex, mypointToProject);
205   fillAttribute(theEdge, myedgeForPointProjection);
206
207   execute();
208 }
209
210 //==================================================================================================
211 void ConstructionAPI_Point::setByProjectionOnFace(const ModelHighAPI_Selection& theVertex,
212                                                   const ModelHighAPI_Selection& theFace)
213 {
214   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION(),
215                 mycreationMethod);
216   fillAttribute(ConstructionPlugin_Point::PROJECTION_TYPE_ON_FACE(),
217                 myprojectionType);
218   fillAttribute(theVertex, mypointToProject);
219   fillAttribute(theFace, myfaceForPointProjection);
220
221   execute();
222 }
223
224 //==================================================================================================
225 void ConstructionAPI_Point::setByLinesIntersection(const ModelHighAPI_Selection& theEdge1,
226                                                    const ModelHighAPI_Selection& theEdge2)
227 {
228   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
229   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINES(),
230                 myintersectionType);
231   fillAttribute(theEdge1, myintersectionLine1);
232   fillAttribute(theEdge2, myintersectionLine2);
233
234   execute();
235 }
236
237 //==================================================================================================
238 void ConstructionAPI_Point::setByLineAndPlaneIntersection(const ModelHighAPI_Selection& theEdge,
239                                                           const ModelHighAPI_Selection& theFace)
240 {
241   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
242   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINE_AND_PLANE(),
243                 myintersectionType);
244   fillAttribute(theEdge, myintersectionLine);
245   fillAttribute(theFace, myintersectionPlane);
246   fillAttribute("", useOffset()); // not used by default
247   execute();
248 }
249
250 //==================================================================================================
251 void ConstructionAPI_Point::setByPlanesIntersection(const ModelHighAPI_Selection& theFace1,
252                                                     const ModelHighAPI_Selection& theFace2,
253                                                     const ModelHighAPI_Selection& theFace3)
254 {
255   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
256   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_PLANES(),
257                 myintersectionType);
258   fillAttribute(theFace1, myintersectionPlane1);
259   fillAttribute(theFace2, myintersectionPlane2);
260   fillAttribute(theFace3, myintersectionPlane3);
261
262   execute();
263 }
264
265 //==================================================================================================
266 void ConstructionAPI_Point::setByCenterOfGravity(const ModelHighAPI_Selection& theObject)
267 {
268   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY(),
269                 mycreationMethod);
270   fillAttribute(ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_GRAVITY(),
271                 mygeometricalPropertyType);
272   fillAttribute(theObject, myobjectForCenterOfGravity);
273
274   execute();
275 }
276
277 //==================================================================================================
278 void ConstructionAPI_Point::setByCenterOfCircle(const ModelHighAPI_Selection& theObject)
279 {
280   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY(),
281                 mycreationMethod);
282   fillAttribute(ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_CIRCLE(),
283                 mygeometricalPropertyType);
284   fillAttribute(theObject, myobjectForCenterOfCircle);
285
286   execute();
287 }
288
289 //==================================================================================================
290 void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
291 {
292   FeaturePtr aBase = feature();
293   const std::string& aDocName = theDumper.name(aBase->document());
294   const std::string aMeth = creationMethod()->value();
295
296   // common part
297   theDumper << aBase << " = model.addPoint(" << aDocName << ", ";
298
299   if (aMeth == "" || // default is XYZ
300       aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ()) {
301     theDumper << point();
302   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION()) {
303     const std::string anIntersectionType = intersectionType()->value();
304     if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINES())
305     {
306       theDumper << intersectionLine1() << ", " << intersectionLine2();
307     }
308     else if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINE_AND_PLANE())
309     {
310       theDumper << intersectionLine() << ", " << intersectionPlane();
311       if (!useOffset()->value().empty()) { // call method with defined offset
312         theDumper << ", " << offset() << ", " << reverseOffset();
313       }
314     }
315     else if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_PLANES())
316     {
317       theDumper << intersectionPlane1() << ", "
318                 << intersectionPlane2() << ", "
319                 << intersectionPlane3();
320     }
321   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
322     theDumper << edge() << ", ";
323     if (offsetType()->value() == ConstructionPlugin_Point::OFFSET_TYPE_BY_DISTANCE()) {
324       theDumper << distance() << ", " << false;
325     }
326     else {
327       theDumper << ratio() << ", " << true;
328     }
329     theDumper << ", " << reverse()->value();
330   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION()) {
331     theDumper << pointToProject() << ", ";
332     if (projectionType()->value() == ConstructionPlugin_Point::PROJECTION_TYPE_ON_EDGE()) {
333       theDumper << edgeForPointProjection();
334     } else {
335       theDumper << faceForPointProjection();
336     }
337   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY()) {
338     if (geometricalPropertyType()->value() ==
339           ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_GRAVITY())
340     {
341       theDumper << objectForCenterOfGravity();
342     }
343     else
344     {
345       theDumper << objectForCenterOfCircle() << ", " << true;
346     }
347   }
348
349   theDumper << ")" << std::endl;
350 }
351
352 //==================================================================================================
353 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document>& thePart,
354                   const ModelHighAPI_Double& theX,
355                   const ModelHighAPI_Double& theY,
356                   const ModelHighAPI_Double& theZ)
357 {
358   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
359   return PointPtr(new ConstructionAPI_Point(aFeature, theX, theY, theZ));
360 }
361
362 //==================================================================================================
363 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
364                   const ModelHighAPI_Selection& theEdge,
365                   const ModelHighAPI_Double& theOffset,
366                   const bool theUseRatio,
367                   const bool theReverse)
368 {
369   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
370   return PointPtr(new ConstructionAPI_Point(aFeature, theEdge, theOffset, theUseRatio, theReverse));
371 }
372
373 //==================================================================================================
374 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
375                   const ModelHighAPI_Selection& theObject1,
376                   const ModelHighAPI_Selection& theObject2)
377 {
378   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
379   return PointPtr(new ConstructionAPI_Point(aFeature, theObject1, theObject2));
380 }
381
382 //==================================================================================================
383 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
384                   const ModelHighAPI_Selection& theObject1,
385                   const ModelHighAPI_Selection& theObject2,
386                   const ModelHighAPI_Double& theDistanceValue,
387                   const bool theReverse)
388 {
389   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
390   PointPtr anAPI(new ConstructionAPI_Point(aFeature, theObject1, theObject2));
391
392   fillAttribute(ConstructionPlugin_Point::USE_OFFSET(), anAPI->useOffset());
393   fillAttribute(theDistanceValue, anAPI->offset());
394   fillAttribute(theReverse, anAPI->reverseOffset());
395
396   return anAPI;
397 }
398
399 //==================================================================================================
400 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
401                   const ModelHighAPI_Selection& theObject1,
402                   const ModelHighAPI_Selection& theObject2,
403                   const ModelHighAPI_Selection& theObject3)
404 {
405   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
406   return PointPtr(new ConstructionAPI_Point(aFeature, theObject1, theObject2, theObject3));
407 }
408
409 //==================================================================================================
410 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
411                   const ModelHighAPI_Selection& theObject,
412                   const bool theIsCircularEdge)
413 {
414   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
415   return PointPtr(new ConstructionAPI_Point(aFeature, theObject, theIsCircularEdge));
416 }
417
418 //==================================================================================================
419 PointPtr addPointXYZ(const std::shared_ptr<ModelAPI_Document> & thePart,
420                      const ModelHighAPI_Selection& theObject)
421 {
422   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
423   return PointPtr(new ConstructionAPI_Point(aFeature, theObject, false, true));
424 }