Salome HOME
Merge remote-tracking branch 'remotes/origin/HigherLevelObjectsHistory'
[modules/shaper.git] / src / ConstructionAPI / ConstructionAPI_Point.cpp
1 // Copyright (C) 2014-2019  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 : ModelHighAPI_Interface(theFeature)
114 {
115   if (initialize())
116   {
117     if (theIsCircularEdge) {
118       setByCenterOfCircle(theObject);
119     } else if (theObject.shapeType() == "VERTEX") {
120       // This is tricky way to get vertex shape.
121       fillAttribute(theObject, mypointToProject);
122       GeomShapePtr aShape = mypointToProject->value();
123       if (!aShape.get()) {
124         ResultPtr aContext = mypointToProject->context();
125         if (!aContext.get()) {
126           fillAttribute(ModelHighAPI_Selection(), mypointToProject);
127           return;
128         }
129         aShape = aContext->shape();
130       }
131
132       if (!aShape.get()) {
133         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
134         return;
135       }
136
137       GeomVertexPtr aVertex = aShape->vertex();
138       if (!aVertex.get()) {
139         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
140         return;
141       }
142
143       GeomPointPtr aPnt = aVertex->point();
144       if (!aPnt.get()) {
145         fillAttribute(ModelHighAPI_Selection(), mypointToProject);
146         return;
147       }
148
149       fillAttribute(ModelHighAPI_Selection(), mypointToProject);
150       setByXYZ(aPnt->x(), aPnt->y(), aPnt->z());
151     } else {
152       setByCenterOfGravity(theObject);
153     }
154   }
155 }
156
157 //==================================================================================================
158 ConstructionAPI_Point::~ConstructionAPI_Point()
159 {
160
161 }
162
163 //==================================================================================================
164 void ConstructionAPI_Point::setByXYZ(const ModelHighAPI_Double& theX,
165                                      const ModelHighAPI_Double& theY,
166                                      const ModelHighAPI_Double& theZ)
167 {
168   //fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ(), mycreationMethod);
169
170   // TODO: Fill point attribute
171   //fillAttribute(theX, myx);
172   //fillAttribute(theY, myy);
173   //fillAttribute(theZ, myz);
174
175   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ(), mycreationMethod);
176   fillAttribute(theX, theY, theZ, mypoint);
177
178   execute(false);
179 }
180
181 //==================================================================================================
182 void ConstructionAPI_Point::setByOffsetOnEdge(const ModelHighAPI_Selection& theEdge,
183                                               const ModelHighAPI_Double& theOffset,
184                                               const bool theUseRatio,
185                                               const bool theReverse)
186 {
187   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE(), mycreationMethod);
188   fillAttribute(theEdge, myedge);
189   if (theUseRatio) {
190     fillAttribute(ConstructionPlugin_Point::OFFSET_TYPE_BY_RATIO(), myoffsetType);
191     fillAttribute(theOffset, myratio);
192   }
193   else {
194     fillAttribute(ConstructionPlugin_Point::OFFSET_TYPE_BY_DISTANCE(), myoffsetType);
195     fillAttribute(theOffset, mydistance);
196   }
197   fillAttribute(theReverse, myreverse);
198
199   execute();
200 }
201
202 //==================================================================================================
203 void ConstructionAPI_Point::setByProjectionOnEdge(const ModelHighAPI_Selection& theVertex,
204                                                   const ModelHighAPI_Selection& theEdge)
205 {
206   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION(),
207                 mycreationMethod);
208   fillAttribute(ConstructionPlugin_Point::PROJECTION_TYPE_ON_EDGE(),
209                 myprojectionType);
210   fillAttribute(theVertex, mypointToProject);
211   fillAttribute(theEdge, myedgeForPointProjection);
212
213   execute();
214 }
215
216 //==================================================================================================
217 void ConstructionAPI_Point::setByProjectionOnFace(const ModelHighAPI_Selection& theVertex,
218                                                   const ModelHighAPI_Selection& theFace)
219 {
220   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION(),
221                 mycreationMethod);
222   fillAttribute(ConstructionPlugin_Point::PROJECTION_TYPE_ON_FACE(),
223                 myprojectionType);
224   fillAttribute(theVertex, mypointToProject);
225   fillAttribute(theFace, myfaceForPointProjection);
226
227   execute();
228 }
229
230 //==================================================================================================
231 void ConstructionAPI_Point::setByLinesIntersection(const ModelHighAPI_Selection& theEdge1,
232                                                    const ModelHighAPI_Selection& theEdge2)
233 {
234   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
235   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINES(),
236                 myintersectionType);
237   fillAttribute(theEdge1, myintersectionLine1);
238   fillAttribute(theEdge2, myintersectionLine2);
239
240   execute();
241 }
242
243 //==================================================================================================
244 void ConstructionAPI_Point::setByLineAndPlaneIntersection(const ModelHighAPI_Selection& theEdge,
245                                                           const ModelHighAPI_Selection& theFace)
246 {
247   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
248   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINE_AND_PLANE(),
249                 myintersectionType);
250   fillAttribute(theEdge, myintersectionLine);
251   fillAttribute(theFace, myintersectionPlane);
252   fillAttribute("", useOffset()); // not used by default
253   execute();
254 }
255
256 //==================================================================================================
257 void ConstructionAPI_Point::setByPlanesIntersection(const ModelHighAPI_Selection& theFace1,
258                                                     const ModelHighAPI_Selection& theFace2,
259                                                     const ModelHighAPI_Selection& theFace3)
260 {
261   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION(), mycreationMethod);
262   fillAttribute(ConstructionPlugin_Point::INTERSECTION_TYPE_BY_PLANES(),
263                 myintersectionType);
264   fillAttribute(theFace1, myintersectionPlane1);
265   fillAttribute(theFace2, myintersectionPlane2);
266   fillAttribute(theFace3, myintersectionPlane3);
267
268   execute();
269 }
270
271 //==================================================================================================
272 void ConstructionAPI_Point::setByCenterOfGravity(const ModelHighAPI_Selection& theObject)
273 {
274   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY(),
275                 mycreationMethod);
276   fillAttribute(ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_GRAVITY(),
277                 mygeometricalPropertyType);
278   fillAttribute(theObject, myobjectForCenterOfGravity);
279 }
280
281 //==================================================================================================
282 void ConstructionAPI_Point::setByCenterOfCircle(const ModelHighAPI_Selection& theObject)
283 {
284   fillAttribute(ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY(),
285                 mycreationMethod);
286   fillAttribute(ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_CIRCLE(),
287                 mygeometricalPropertyType);
288   fillAttribute(theObject, myobjectForCenterOfCircle);
289 }
290
291 //==================================================================================================
292 void ConstructionAPI_Point::dump(ModelHighAPI_Dumper& theDumper) const
293 {
294   FeaturePtr aBase = feature();
295   const std::string& aDocName = theDumper.name(aBase->document());
296   const std::string aMeth = creationMethod()->value();
297
298   // common part
299   theDumper << aBase << " = model.addPoint(" << aDocName << ", ";
300
301   if (aMeth == "" || // default is XYZ
302       aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_XYZ()) {
303     theDumper << point();
304   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_INTERSECTION()) {
305     const std::string anIntersectionType = intersectionType()->value();
306     if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINES())
307     {
308       theDumper << intersectionLine1() << ", " << intersectionLine2();
309     }
310     else if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_LINE_AND_PLANE())
311     {
312       theDumper << intersectionLine() << ", " << intersectionPlane();
313       if (!useOffset()->value().empty()) { // call method with defined offset
314         theDumper << ", " << offset() << ", " << reverseOffset();
315       }
316     }
317     else if (anIntersectionType == ConstructionPlugin_Point::INTERSECTION_TYPE_BY_PLANES())
318     {
319       theDumper << intersectionPlane1() << ", "
320                 << intersectionPlane2() << ", "
321                 << intersectionPlane3();
322     }
323   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_DISTANCE_ON_EDGE()) {
324     theDumper << edge() << ", ";
325     if (offsetType()->value() == ConstructionPlugin_Point::OFFSET_TYPE_BY_DISTANCE()) {
326       theDumper << distance() << ", " << false;
327     }
328     else {
329       theDumper << ratio() << ", " << true;
330     }
331     theDumper << ", " << reverse()->value();
332   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_PROJECTION()) {
333     theDumper << pointToProject() << ", ";
334     if (projectionType()->value() == ConstructionPlugin_Point::PROJECTION_TYPE_ON_EDGE()) {
335       theDumper << edgeForPointProjection();
336     } else {
337       theDumper << faceForPointProjection();
338     }
339   } else if (aMeth == ConstructionPlugin_Point::CREATION_METHOD_BY_GEOMETRICAL_PROPERTY()) {
340     if (geometricalPropertyType()->value() ==
341           ConstructionPlugin_Point::GEOMETRICAL_PROPERTY_TYPE_BY_CENTER_OF_GRAVITY())
342     {
343       theDumper << objectForCenterOfGravity();
344     }
345     else
346     {
347       theDumper << objectForCenterOfCircle() << ", " << true;
348     }
349   }
350
351   theDumper << ")" << std::endl;
352 }
353
354 //==================================================================================================
355 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document>& thePart,
356                   const ModelHighAPI_Double& theX,
357                   const ModelHighAPI_Double& theY,
358                   const ModelHighAPI_Double& theZ)
359 {
360   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
361   return PointPtr(new ConstructionAPI_Point(aFeature, theX, theY, theZ));
362 }
363
364 //==================================================================================================
365 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
366                   const ModelHighAPI_Selection& theEdge,
367                   const ModelHighAPI_Double& theOffset,
368                   const bool theUseRatio,
369                   const bool theReverse)
370 {
371   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
372   return PointPtr(new ConstructionAPI_Point(aFeature, theEdge, theOffset, theUseRatio, theReverse));
373 }
374
375 //==================================================================================================
376 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
377                   const ModelHighAPI_Selection& theObject1,
378                   const ModelHighAPI_Selection& theObject2)
379 {
380   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
381   return PointPtr(new ConstructionAPI_Point(aFeature, theObject1, theObject2));
382 }
383
384 //==================================================================================================
385 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
386                   const ModelHighAPI_Selection& theObject1,
387                   const ModelHighAPI_Selection& theObject2,
388                   const ModelHighAPI_Double& theDistanceValue,
389                   const bool theReverse)
390 {
391   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
392   PointPtr anAPI(new ConstructionAPI_Point(aFeature, theObject1, theObject2));
393
394   fillAttribute(ConstructionPlugin_Point::USE_OFFSET(), anAPI->useOffset());
395   fillAttribute(theDistanceValue, anAPI->offset());
396   fillAttribute(theReverse, anAPI->reverseOffset());
397
398   return anAPI;
399 }
400
401 //==================================================================================================
402 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
403                   const ModelHighAPI_Selection& theObject1,
404                   const ModelHighAPI_Selection& theObject2,
405                   const ModelHighAPI_Selection& theObject3)
406 {
407   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
408   return PointPtr(new ConstructionAPI_Point(aFeature, theObject1, theObject2, theObject3));
409 }
410
411 //==================================================================================================
412 PointPtr addPoint(const std::shared_ptr<ModelAPI_Document> & thePart,
413                   const ModelHighAPI_Selection& theObject,
414                   const bool theIsCircularEdge)
415 {
416   std::shared_ptr<ModelAPI_Feature> aFeature = thePart->addFeature(ConstructionAPI_Point::ID());
417   return PointPtr(new ConstructionAPI_Point(aFeature, theObject, theIsCircularEdge));
418 }