Salome HOME
Fix for the issue #2461: crash when changing points on plane creation
[modules/shaper.git] / src / ConstructionPlugin / ConstructionPlugin_Validators.cpp
1 // Copyright (C) 2014-2017  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
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
19 //
20
21 #include "ConstructionPlugin_Validators.h"
22
23 #include <GeomAPI_Dir.h>
24 #include <GeomAPI_Edge.h>
25 #include <GeomAPI_Face.h>
26 #include <GeomAPI_Lin.h>
27 #include <GeomAPI_Pln.h>
28 #include <GeomAPI_Vertex.h>
29 #include <GeomAPI_Pnt.h>
30 #include <GeomAlgoAPI_ShapeTools.h>
31
32 #include <ModelAPI_AttributeSelection.h>
33 #include <ModelAPI_AttributeBoolean.h>
34
35 #include <Events_InfoMessage.h>
36
37 static std::shared_ptr<GeomAPI_Edge> getEdge(const GeomShapePtr theShape);
38 static std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape);
39 static std::shared_ptr<GeomAPI_Pln> getPln(const GeomShapePtr theShape);
40 static std::shared_ptr<GeomAPI_Pnt> getPnt(const GeomShapePtr theShape);
41
42 //==================================================================================================
43 bool ConstructionPlugin_ValidatorPointLines::isValid(const AttributePtr& theAttribute,
44                                                      const std::list<std::string>& theArguments,
45                                                      Events_InfoMessage& theError) const
46 {
47   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
48
49   AttributeSelectionPtr aLineAttribute1 =
50     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
51   AttributeSelectionPtr aLineAttribute2 = aFeature->selection(theArguments.front());
52
53   GeomShapePtr aLineShape1 = aLineAttribute1->value();
54   ResultPtr aContext1 = aLineAttribute1->context();
55   if(!aContext1.get()) {
56     theError = "One of the attribute not initialized.";
57     return false;
58   }
59   if(!aLineShape1.get()) {
60     aLineShape1 = aContext1->shape();
61   }
62   if(!aLineShape1->isEdge()) {
63     theError = "One of the selected shapes not an edge.";
64     return false;
65   }
66
67   GeomShapePtr aLineShape2 = aLineAttribute2->value();
68   ResultPtr aContext2 = aLineAttribute2->context();
69   if(!aContext2.get()) {
70     return true;
71   }
72   if(!aLineShape2.get()) {
73     aLineShape2 = aContext2->shape();
74   }
75   if(!aLineShape2->isEdge()) {
76     theError = "One of the selected shapes not an edge.";
77     return false;
78   }
79
80   std::shared_ptr<GeomAPI_Edge> aLineEdge1(new GeomAPI_Edge(aLineShape1));
81   std::shared_ptr<GeomAPI_Edge> aLineEdge2(new GeomAPI_Edge(aLineShape2));
82
83   std::shared_ptr<GeomAPI_Lin> aLine1 = aLineEdge1->line();
84   std::shared_ptr<GeomAPI_Lin> aLine2 = aLineEdge2->line();
85
86   if(!aLine1->isCoplanar(aLine2)) {
87     theError = "Selected lines not coplanar.";
88     return false;
89   }
90
91   if(aLine1->isParallel(aLine2)) {
92     theError = "Selected lines are parallel.";
93     return false;
94   }
95
96   return true;
97 }
98
99 //==================================================================================================
100 bool ConstructionPlugin_ValidatorPointEdgeAndPlaneNotParallel::isValid(
101     const AttributePtr& theAttribute,
102     const std::list<std::string>& theArguments,
103     Events_InfoMessage& theError) const
104 {
105   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
106
107   AttributeSelectionPtr anAttribute1 =
108     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
109   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
110
111   std::shared_ptr<GeomAPI_Edge> anEdge;
112   std::shared_ptr<GeomAPI_Pln> aPln;
113
114   GeomShapePtr aShape1 = anAttribute1->value();
115   ResultPtr aContext1 = anAttribute1->context();
116   if(!aContext1.get()) {
117     theError = "One of the attribute not initialized.";
118     return false;
119   }
120   if(!aShape1.get()) {
121     aShape1 = aContext1->shape();
122   }
123
124   GeomShapePtr aShape2 = anAttribute2->value();
125   ResultPtr aContext2 = anAttribute2->context();
126   if(!aContext2.get()) {
127     return true;
128   }
129   if(!aShape2.get()) {
130     aShape2 = aContext2->shape();
131   }
132
133   bool isPlaneFirst = false;
134   anEdge = getEdge(aShape1);
135   aPln = getPln(aShape2);
136   if(!anEdge.get() || !aPln.get()) {
137     anEdge = getEdge(aShape2);
138     aPln = getPln(aShape1);
139     isPlaneFirst = true;
140   }
141
142   if(!anEdge.get() || !aPln.get()) {
143     theError = "Wrong shape types selected.";
144     return false;
145   }
146
147   std::shared_ptr<GeomAPI_Face> aPlaneFace(new GeomAPI_Face(isPlaneFirst ? aShape1 : aShape2));
148   if(GeomAlgoAPI_ShapeTools::isParallel(anEdge, aPlaneFace)) {
149     theError = "Plane and edge are parallel.";
150     return false;
151   }
152
153   return true;
154 }
155
156 //==================================================================================================
157 bool ConstructionPlugin_ValidatorPlaneThreePoints::isValid(const AttributePtr& theAttribute,
158                                                         const std::list<std::string>& theArguments,
159                                                         Events_InfoMessage& theError) const
160 {
161   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
162
163   AttributeSelectionPtr aPointAttribute1 =
164     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
165   AttributeSelectionPtr aPointAttribute2 = aFeature->selection(theArguments.front());
166   AttributeSelectionPtr aPointAttribute3 = aFeature->selection(theArguments.back());
167
168   GeomShapePtr aPointShape1 = aPointAttribute1->value();
169   ResultPtr aContext1 = aPointAttribute1->context();
170   if(!aContext1.get()) {
171     theError = "One of the attribute not initialized.";
172     return false;
173   }
174   if(!aPointShape1.get()) {
175     aPointShape1 = aContext1->shape();
176   }
177   if(!aPointShape1->isVertex()) {
178     theError = "One of the selected shapes not a vertex.";
179     return false;
180   }
181
182   GeomShapePtr aPointShape2 = aPointAttribute2->value();
183   ResultPtr aContext2 = aPointAttribute2->context();
184   if(!aContext2.get()) {
185     return true;
186   }
187   if(!aPointShape2.get()) {
188     aPointShape2 = aContext2->shape();
189   }
190   if(!aPointShape2->isVertex()) {
191     theError = "One of the selected shapes not a vertex.";
192     return false;
193   }
194
195   GeomShapePtr aPointShape3 = aPointAttribute3->value();
196   ResultPtr aContext3 = aPointAttribute3->context();
197   if(!aContext3.get()) {
198     return true;
199   }
200   if(!aPointShape3.get()) {
201     aPointShape3 = aContext3->shape();
202   }
203   if(!aPointShape3->isVertex()) {
204     theError = "One of the selected shapes not a vertex.";
205     return false;
206   }
207
208   std::shared_ptr<GeomAPI_Vertex> aVertex1(new GeomAPI_Vertex(aPointShape1));
209   std::shared_ptr<GeomAPI_Vertex> aVertex2(new GeomAPI_Vertex(aPointShape2));
210   std::shared_ptr<GeomAPI_Vertex> aVertex3(new GeomAPI_Vertex(aPointShape3));
211
212   std::shared_ptr<GeomAPI_Pnt> aPnt1 = aVertex1->point();
213   std::shared_ptr<GeomAPI_Pnt> aPnt2 = aVertex2->point();
214   std::shared_ptr<GeomAPI_Pnt> aPnt3 = aVertex3->point();
215
216   if (aPnt1->isEqual(aPnt2)) {
217     theError = "Selected points are equal";
218     return false;
219   }
220
221   std::shared_ptr<GeomAPI_Lin> aLin(new GeomAPI_Lin(aPnt1, aPnt2));
222
223   if(aLin->contains(aPnt3)) {
224     theError = "Selected points lie on a line.";
225     return false;
226   }
227
228   return true;
229 }
230
231 //==================================================================================================
232 bool ConstructionPlugin_ValidatorPlaneLinePoint::isValid(
233     const AttributePtr& theAttribute,
234     const std::list<std::string>& theArguments,
235     Events_InfoMessage& theError) const
236 {
237   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
238
239   AttributeSelectionPtr anAttribute1 =
240     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
241   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
242
243   std::shared_ptr<GeomAPI_Lin> aLin;
244   std::shared_ptr<GeomAPI_Pnt> aPnt;
245
246   GeomShapePtr aShape1 = anAttribute1->value();
247   ResultPtr aContext1 = anAttribute1->context();
248   if(!aContext1.get()) {
249     theError = "One of the attribute not initialized.";
250     return false;
251   }
252   if(!aShape1.get()) {
253     aShape1 = aContext1->shape();
254   }
255
256   GeomShapePtr aShape2 = anAttribute2->value();
257   ResultPtr aContext2 = anAttribute2->context();
258   if(!aContext2.get()) {
259     return true;
260   }
261   if(!aShape2.get()) {
262     aShape2 = aContext2->shape();
263   }
264
265   aLin = getLin(aShape1);
266   aPnt = getPnt(aShape2);
267   if(!aLin.get() || !aPnt.get()) {
268     aLin = getLin(aShape2);
269     aPnt = getPnt(aShape1);
270   }
271
272   if(!aLin.get() || !aPnt.get()) {
273     theError = "Wrong shape types selected.";
274     return false;
275   }
276
277   // line should not contain point only for not-prependicular case
278   AttributeBooleanPtr aBoolAttr = aFeature->boolean(theArguments.back());
279   if (aBoolAttr.get() && !aBoolAttr->value()) {
280     if(aLin->contains(aPnt)) {
281       theError = "Point lies on the line.";
282       return false;
283     }
284   }
285
286   return true;
287 }
288
289 //==================================================================================================
290 bool ConstructionPlugin_ValidatorPlaneTwoParallelPlanes::isValid(
291     const AttributePtr& theAttribute,
292     const std::list<std::string>& theArguments,
293     Events_InfoMessage& theError) const
294 {
295   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
296
297   AttributeSelectionPtr anAttribute1 =
298     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
299   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
300
301   std::shared_ptr<GeomAPI_Pln> aPln1;
302   std::shared_ptr<GeomAPI_Pln> aPln2;
303
304   GeomShapePtr aShape1 = anAttribute1->value();
305   ResultPtr aContext1 = anAttribute1->context();
306   if(!aContext1.get()) {
307     theError = "One of the attribute not initialized.";
308     return false;
309   }
310   if(!aShape1.get()) {
311     aShape1 = aContext1->shape();
312   }
313
314   GeomShapePtr aShape2 = anAttribute2->value();
315   ResultPtr aContext2 = anAttribute2->context();
316   if(!aContext2.get()) {
317     return true;
318   }
319   if(!aShape2.get()) {
320     aShape2 = aContext2->shape();
321   }
322
323   aPln1 = getPln(aShape1);
324   aPln2 = getPln(aShape2);
325
326   if(!aPln1.get() || !aPln2.get()) {
327     theError = "Wrong shape types selected.";
328     return false;
329   }
330
331   std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
332   std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
333
334   if(!aDir1->isParallel(aDir2)) {
335     theError = "Planes not parallel.";
336     return false;
337   }
338
339   return true;
340 }
341
342 //==================================================================================================
343 bool ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes::isValid(
344     const AttributePtr& theAttribute,
345     const std::list<std::string>& theArguments,
346     Events_InfoMessage& theError) const
347 {
348   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
349
350   AttributeSelectionPtr anAttribute1 =
351     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
352   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
353
354   std::shared_ptr<GeomAPI_Pln> aPln1;
355   std::shared_ptr<GeomAPI_Pln> aPln2;
356
357   GeomShapePtr aShape1 = anAttribute1->value();
358   ResultPtr aContext1 = anAttribute1->context();
359   if(!aContext1.get()) {
360     theError = "One of the attribute not initialized.";
361     return false;
362   }
363   if(!aShape1.get()) {
364     aShape1 = aContext1->shape();
365   }
366
367   GeomShapePtr aShape2 = anAttribute2->value();
368   ResultPtr aContext2 = anAttribute2->context();
369   if(!aContext2.get()) {
370     return true;
371   }
372   if(!aShape2.get()) {
373     aShape2 = aContext2->shape();
374   }
375
376   aPln1 = getPln(aShape1);
377   aPln2 = getPln(aShape2);
378
379   if(!aPln1.get() || !aPln2.get()) {
380     theError = "Wrong shape types selected.";
381     return false;
382   }
383
384   std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
385   std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
386
387   if(aDir1->isParallel(aDir2)) {
388     theError = "Planes are parallel.";
389     return false;
390   }
391
392   return true;
393 }
394
395 std::shared_ptr<GeomAPI_Edge> getEdge(const GeomShapePtr theShape)
396 {
397   if(!theShape->isEdge()) {
398     return std::shared_ptr<GeomAPI_Edge>();
399   }
400
401   std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theShape));
402
403   return anEdge;
404 }
405
406 std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape)
407 {
408   std::shared_ptr<GeomAPI_Lin> aLin;
409
410   if(!theShape->isEdge()) {
411     return aLin;
412   }
413
414   std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(theShape));
415
416   if(!anEdge->isLine()) {
417     return aLin;
418   }
419
420   aLin = anEdge->line();
421
422   return aLin;
423 }
424
425 std::shared_ptr<GeomAPI_Pln> getPln(const GeomShapePtr theShape)
426 {
427   std::shared_ptr<GeomAPI_Pln> aPln;
428
429   if(!theShape->isFace()) {
430     return aPln;
431   }
432
433   std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(theShape));
434
435   if(!aFace->isPlanar()) {
436     return aPln;
437   }
438
439   aPln = aFace->getPlane();
440
441   return aPln;
442 }
443
444 std::shared_ptr<GeomAPI_Pnt> getPnt(const GeomShapePtr theShape)
445 {
446   std::shared_ptr<GeomAPI_Pnt> aPnt;
447
448   if(!theShape->isVertex()) {
449     return aPnt;
450   }
451
452   std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(theShape));
453
454   aPnt = aVertex->point();
455
456   return aPnt;
457 }