Salome HOME
1031bf76ff592172b58ea27a4d7be5f256f6a6b6
[modules/shaper.git] / src / ConstructionPlugin / ConstructionPlugin_Validators.cpp
1 // Copyright (C) 2014-2023  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 "ConstructionPlugin_Validators.h"
21
22 #include <GeomAPI_Dir.h>
23 #include <GeomAPI_Edge.h>
24 #include <GeomAPI_Face.h>
25 #include <GeomAPI_Lin.h>
26 #include <GeomAPI_Pln.h>
27 #include <GeomAPI_Vertex.h>
28 #include <GeomAPI_Pnt.h>
29 #include <GeomAPI_ShapeIterator.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_Face> getFace(const GeomShapePtr theShape);
39 static std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape);
40 static std::shared_ptr<GeomAPI_Pln> getPln(const GeomShapePtr theShape);
41 static std::shared_ptr<GeomAPI_Pnt> getPnt(const GeomShapePtr theShape);
42
43 //==================================================================================================
44 bool ConstructionPlugin_ValidatorPointLines::isValid(const AttributePtr& theAttribute,
45                                                      const std::list<std::string>& theArguments,
46                                                      Events_InfoMessage& theError) const
47 {
48   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
49
50   AttributeSelectionPtr aLineAttribute1 =
51     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
52   AttributeSelectionPtr aLineAttribute2 = aFeature->selection(theArguments.front());
53
54   GeomShapePtr aLineShape1 = aLineAttribute1->value();
55   ResultPtr aContext1 = aLineAttribute1->context();
56   if(!aContext1.get()) {
57     theError = "One of the attribute is not initialized.";
58     return false;
59   }
60   if(!aLineShape1.get()) {
61     aLineShape1 = aContext1->shape();
62   }
63   if(!aLineShape1->isEdge()) {
64     theError = "One of the selected shapes not an edge.";
65     return false;
66   }
67
68   GeomShapePtr aLineShape2 = aLineAttribute2->value();
69   ResultPtr aContext2 = aLineAttribute2->context();
70   if(!aContext2.get()) {
71     return true;
72   }
73   if(!aLineShape2.get()) {
74     aLineShape2 = aContext2->shape();
75   }
76   if(!aLineShape2->isEdge()) {
77     theError = "One of the selected shapes not an edge.";
78     return false;
79   }
80
81   std::shared_ptr<GeomAPI_Edge> aLineEdge1(new GeomAPI_Edge(aLineShape1));
82   std::shared_ptr<GeomAPI_Edge> aLineEdge2(new GeomAPI_Edge(aLineShape2));
83
84   std::shared_ptr<GeomAPI_Lin> aLine1 = aLineEdge1->line();
85   std::shared_ptr<GeomAPI_Lin> aLine2 = aLineEdge2->line();
86
87   if (!aLine1.get() || !aLine2.get()) {
88     theError = "Selected edge is not a line.";
89     return false;
90   }
91
92   if(!aLine1->isCoplanar(aLine2)) {
93     theError = "Selected lines not coplanar.";
94     return false;
95   }
96
97   if(aLine1->isParallel(aLine2)) {
98     theError = "Selected lines are parallel.";
99     return false;
100   }
101
102   return true;
103 }
104
105 //==================================================================================================
106 bool ConstructionPlugin_ValidatorPointEdgeAndPlaneNotParallel::isValid(
107     const AttributePtr& theAttribute,
108     const std::list<std::string>& theArguments,
109     Events_InfoMessage& theError) const
110 {
111   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
112
113   AttributeSelectionPtr anAttribute1 =
114     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
115   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
116
117   std::shared_ptr<GeomAPI_Edge> anEdge;
118   std::shared_ptr<GeomAPI_Face> aFace;
119
120   GeomShapePtr aShape1 = anAttribute1->value();
121   ResultPtr aContext1 = anAttribute1->context();
122   if(!aContext1.get()) {
123     theError = "One of the attribute is not initialized.";
124     return false;
125   }
126   if(!aShape1.get()) {
127     aShape1 = aContext1->shape();
128   }
129
130   GeomShapePtr aShape2 = anAttribute2->value();
131   ResultPtr aContext2 = anAttribute2->context();
132   if(!aContext2.get()) {
133     return true;
134   }
135   if(!aShape2.get()) {
136     aShape2 = aContext2->shape();
137   }
138
139   anEdge = getEdge(aShape1);
140   aFace = getFace(aShape2);
141   if(!anEdge.get() || !aFace.get()) {
142     anEdge = getEdge(aShape2);
143     aFace = getFace(aShape1);
144   }
145
146   if(!anEdge.get() || !aFace.get()) {
147     theError = "Wrong shape types selected.";
148     return false;
149   }
150
151   if(GeomAlgoAPI_ShapeTools::isParallel(anEdge, aFace)) {
152     theError = "Plane and edge are parallel.";
153     return false;
154   }
155
156   return true;
157 }
158
159 //==================================================================================================
160 bool ConstructionPlugin_ValidatorPlaneThreePoints::isValid(const AttributePtr& theAttribute,
161                                                         const std::list<std::string>& theArguments,
162                                                         Events_InfoMessage& theError) const
163 {
164   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
165
166   AttributeSelectionPtr aPointAttribute1 =
167     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
168   AttributeSelectionPtr aPointAttribute2 = aFeature->selection(theArguments.front());
169   AttributeSelectionPtr aPointAttribute3 = aFeature->selection(theArguments.back());
170
171   GeomShapePtr aPointShape1 = aPointAttribute1->value();
172   ResultPtr aContext1 = aPointAttribute1->context();
173   if(!aContext1.get()) {
174     theError = "One of the attribute is not initialized.";
175     return false;
176   }
177   if(!aPointShape1.get()) {
178     aPointShape1 = aContext1->shape();
179   }
180   if(!aPointShape1->isVertex()) {
181     theError = "One of the selected shapes not a vertex.";
182     return false;
183   }
184
185   GeomShapePtr aPointShape2 = aPointAttribute2->value();
186   ResultPtr aContext2 = aPointAttribute2->context();
187   if(!aContext2.get()) {
188     return true;
189   }
190   if(!aPointShape2.get()) {
191     aPointShape2 = aContext2->shape();
192   }
193   if(!aPointShape2->isVertex()) {
194     theError = "One of the selected shapes not a vertex.";
195     return false;
196   }
197
198   GeomShapePtr aPointShape3 = aPointAttribute3->value();
199   ResultPtr aContext3 = aPointAttribute3->context();
200   if(!aContext3.get()) {
201     return true;
202   }
203   if(!aPointShape3.get()) {
204     aPointShape3 = aContext3->shape();
205   }
206   if(!aPointShape3->isVertex()) {
207     theError = "One of the selected shapes not a vertex.";
208     return false;
209   }
210
211   std::shared_ptr<GeomAPI_Vertex> aVertex1(new GeomAPI_Vertex(aPointShape1));
212   std::shared_ptr<GeomAPI_Vertex> aVertex2(new GeomAPI_Vertex(aPointShape2));
213   std::shared_ptr<GeomAPI_Vertex> aVertex3(new GeomAPI_Vertex(aPointShape3));
214
215   std::shared_ptr<GeomAPI_Pnt> aPnt1 = aVertex1->point();
216   std::shared_ptr<GeomAPI_Pnt> aPnt2 = aVertex2->point();
217   std::shared_ptr<GeomAPI_Pnt> aPnt3 = aVertex3->point();
218
219   if (aPnt1->isEqual(aPnt2)) {
220     theError = "Selected points are equal";
221     return false;
222   }
223
224   std::shared_ptr<GeomAPI_Lin> aLin(new GeomAPI_Lin(aPnt1, aPnt2));
225
226   if(aLin->contains(aPnt3)) {
227     theError = "Selected points lie on a line.";
228     return false;
229   }
230
231   return true;
232 }
233
234 //==================================================================================================
235 bool ConstructionPlugin_ValidatorPlaneLinePoint::isValid(
236     const AttributePtr& theAttribute,
237     const std::list<std::string>& theArguments,
238     Events_InfoMessage& theError) const
239 {
240   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
241
242   AttributeSelectionPtr anAttribute1 =
243     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
244   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
245
246   std::shared_ptr<GeomAPI_Lin> aLin;
247   std::shared_ptr<GeomAPI_Pnt> aPnt;
248
249   GeomShapePtr aShape1 = anAttribute1->value();
250   ResultPtr aContext1 = anAttribute1->context();
251   if(!aContext1.get()) {
252     theError = "One of the attribute is not initialized.";
253     return false;
254   }
255   if(!aShape1.get()) {
256     aShape1 = aContext1->shape();
257   }
258
259   GeomShapePtr aShape2 = anAttribute2->value();
260   ResultPtr aContext2 = anAttribute2->context();
261   if(!aContext2.get()) {
262     return true;
263   }
264   if(!aShape2.get()) {
265     aShape2 = aContext2->shape();
266   }
267
268   aLin = getLin(aShape1);
269   aPnt = getPnt(aShape2);
270   if(!aLin.get() || !aPnt.get()) {
271     aLin = getLin(aShape2);
272     aPnt = getPnt(aShape1);
273   }
274
275   if(!aLin.get() || !aPnt.get()) {
276     theError = "Wrong shape types selected.";
277     return false;
278   }
279
280   // line should not contain point only for not-prependicular case
281   AttributeBooleanPtr aBoolAttr = aFeature->boolean(theArguments.back());
282   if (aBoolAttr.get() && !aBoolAttr->value()) {
283     if(aLin->contains(aPnt)) {
284       theError = "Point lies on the line.";
285       return false;
286     }
287   }
288
289   return true;
290 }
291
292 //==================================================================================================
293 bool ConstructionPlugin_ValidatorPlaneTwoParallelPlanes::isValid(
294     const AttributePtr& theAttribute,
295     const std::list<std::string>& theArguments,
296     Events_InfoMessage& theError) const
297 {
298   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
299
300   AttributeSelectionPtr anAttribute1 =
301     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
302   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
303
304   std::shared_ptr<GeomAPI_Pln> aPln1;
305   std::shared_ptr<GeomAPI_Pln> aPln2;
306
307   GeomShapePtr aShape1 = anAttribute1->value();
308   ResultPtr aContext1 = anAttribute1->context();
309   if(!aContext1.get()) {
310     theError = "One of the attribute is not initialized.";
311     return false;
312   }
313   if(!aShape1.get()) {
314     aShape1 = aContext1->shape();
315   }
316
317   GeomShapePtr aShape2 = anAttribute2->value();
318   ResultPtr aContext2 = anAttribute2->context();
319   if(!aContext2.get()) {
320     return true;
321   }
322   if(!aShape2.get()) {
323     aShape2 = aContext2->shape();
324   }
325
326   aPln1 = getPln(aShape1);
327   aPln2 = getPln(aShape2);
328
329   if(!aPln1.get() || !aPln2.get()) {
330     theError = "Wrong shape types selected.";
331     return false;
332   }
333
334   std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
335   std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
336
337   if(!aDir1->isParallel(aDir2)) {
338     theError = "Planes not parallel.";
339     return false;
340   }
341
342   return true;
343 }
344
345 //==================================================================================================
346 bool ConstructionPlugin_ValidatorAxisTwoNotParallelPlanes::isValid(
347     const AttributePtr& theAttribute,
348     const std::list<std::string>& theArguments,
349     Events_InfoMessage& theError) const
350 {
351   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
352
353   AttributeSelectionPtr anAttribute1 =
354     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
355   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
356
357   std::shared_ptr<GeomAPI_Pln> aPln1;
358   std::shared_ptr<GeomAPI_Pln> aPln2;
359
360   GeomShapePtr aShape1 = anAttribute1->value();
361   ResultPtr aContext1 = anAttribute1->context();
362   if(!aContext1.get()) {
363     theError = "One of the attribute is not initialized.";
364     return false;
365   }
366   if(!aShape1.get()) {
367     aShape1 = aContext1->shape();
368   }
369
370   GeomShapePtr aShape2 = anAttribute2->value();
371   ResultPtr aContext2 = anAttribute2->context();
372   if(!aContext2.get()) {
373     return true;
374   }
375   if(!aShape2.get()) {
376     aShape2 = aContext2->shape();
377   }
378
379   aPln1 = getPln(aShape1);
380   aPln2 = getPln(aShape2);
381
382   if(!aPln1.get() || !aPln2.get()) {
383     theError = "Wrong shape types selected.";
384     return false;
385   }
386
387   std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
388   std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
389
390   if(aDir1->isParallel(aDir2)) {
391     theError = "Planes are parallel.";
392     return false;
393   }
394
395   return true;
396 }
397
398 //==================================================================================================
399 bool ConstructionPlugin_ValidatorPointThreeNonParallelPlanes::isValid(
400   const AttributePtr& theAttribute,
401   const std::list<std::string>& theArguments,
402   Events_InfoMessage& theError) const
403 {
404   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
405
406   AttributeSelectionPtr anAttribute1 =
407     std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
408   AttributeSelectionPtr anAttribute2 = aFeature->selection(theArguments.front());
409   AttributeSelectionPtr anAttribute3 = aFeature->selection(theArguments.back());
410
411   GeomShapePtr aShape1 = anAttribute1->value();
412   ResultPtr aContext1 = anAttribute1->context();
413   if (!aContext1.get()) {
414     theError = "One of the attribute is not initialized.";
415     return false;
416   }
417   if (!aShape1.get()) {
418     aShape1 = aContext1->shape();
419   }
420
421   std::shared_ptr<GeomAPI_Pln> aPln1 = getPln(aShape1);
422   if (!aPln1.get()) {
423     theError = "Wrong shape types selected.";
424     return false;
425   }
426   std::shared_ptr<GeomAPI_Dir> aDir1 = aPln1->direction();
427
428   if (anAttribute2.get()) {
429     GeomShapePtr aShape2 = anAttribute2->value();
430     ResultPtr aContext2 = anAttribute2->context();
431     if (!aShape2.get() && aContext2.get()) {
432       aShape2 = aContext2->shape();
433     }
434
435     if (aShape2.get()) {
436       std::shared_ptr<GeomAPI_Pln> aPln2 = getPln(aShape2);
437       if (!aPln2.get()) {
438         theError = "Wrong shape types selected.";
439         return false;
440       }
441       std::shared_ptr<GeomAPI_Dir> aDir2 = aPln2->direction();
442       if (aDir1->isParallel(aDir2)) {
443         theError = "Planes are parallel.";
444         return false;
445       }
446     }
447   }
448
449   if (anAttribute3.get()) {
450     GeomShapePtr aShape3 = anAttribute3->value();
451     ResultPtr aContext3 = anAttribute3->context();
452     if (!aShape3.get() && aContext3.get()) {
453       aShape3 = aContext3->shape();
454     }
455
456     if (aShape3.get()) {
457       std::shared_ptr<GeomAPI_Pln> aPln3 = getPln(aShape3);
458       if (!aPln3.get()) {
459         theError = "Wrong shape types selected.";
460         return false;
461       }
462       std::shared_ptr<GeomAPI_Dir> aDir3 = aPln3->direction();
463       if (aDir1->isParallel(aDir3)) {
464         theError = "Planes are parallel.";
465         return false;
466       }
467     }
468   }
469
470   return true;
471 }
472
473 //==================================================================================================
474 bool ConstructionPlugin_ValidatorNotFeature::isValid(
475     const AttributePtr& theAttribute,
476     const std::list<std::string>& /*theArguments*/,
477     Events_InfoMessage& theError) const
478 {
479   AttributeSelectionPtr aSelAttr =
480       std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
481   if (!aSelAttr) {
482     theError = "Wrong attribute";
483     return false;
484   }
485
486   FeaturePtr aContextFeature = aSelAttr->contextFeature();
487   if (aContextFeature) {
488     theError = "Feature should not be selected";
489     return false;
490   }
491   return true;
492 }
493
494 //==================================================================================================
495
496 std::shared_ptr<GeomAPI_Edge> getEdge(const GeomShapePtr theShape)
497 {
498   GeomEdgePtr anEdge;
499
500   if(theShape->isEdge()) {
501     anEdge = theShape->edge();
502   }
503   else if (theShape->isCompound()) {
504     GeomAPI_ShapeIterator anIt(theShape);
505     anEdge = anIt.current()->edge();
506   }
507
508   return anEdge;
509 }
510
511 GeomFacePtr getFace(const GeomShapePtr theShape)
512 {
513   GeomFacePtr aFace;
514
515   if (theShape->isFace()) {
516     aFace = theShape->face();
517   }
518   else if (theShape->isCompound()) {
519     GeomAPI_ShapeIterator anIt(theShape);
520     aFace = anIt.current()->face();
521   }
522
523   return aFace;
524 }
525
526 std::shared_ptr<GeomAPI_Lin> getLin(const GeomShapePtr theShape)
527 {
528   std::shared_ptr<GeomAPI_Lin> aLin;
529
530   GeomEdgePtr anEdge;
531
532   if (theShape->isEdge()) {
533     anEdge = theShape->edge();
534   }
535   else if (theShape->isCompound()) {
536     GeomAPI_ShapeIterator anIt(theShape);
537     anEdge = anIt.current()->edge();
538   }
539   else {
540     return aLin;
541   }
542
543   if(!anEdge->isLine()) {
544     return aLin;
545   }
546
547   aLin = anEdge->line();
548
549   return aLin;
550 }
551
552 std::shared_ptr<GeomAPI_Pln> getPln(const GeomShapePtr theShape)
553 {
554   std::shared_ptr<GeomAPI_Pln> aPln;
555
556   GeomFacePtr aFace;
557
558   if(theShape->isFace()) {
559     aFace = theShape->face();
560   }
561   else if (theShape->isCompound()) {
562     GeomAPI_ShapeIterator anIt(theShape);
563     aFace = anIt.current()->face();
564   }
565   else {
566     return aPln;
567   }
568
569   if(!aFace || !aFace->isPlanar()) {
570     return aPln;
571   }
572
573   aPln = aFace->getPlane();
574
575   return aPln;
576 }
577
578 std::shared_ptr<GeomAPI_Pnt> getPnt(const GeomShapePtr theShape)
579 {
580   std::shared_ptr<GeomAPI_Pnt> aPnt;
581
582   if(!theShape->isVertex()) {
583     return aPnt;
584   }
585
586   std::shared_ptr<GeomAPI_Vertex> aVertex(new GeomAPI_Vertex(theShape));
587
588   aPnt = aVertex->point();
589
590   return aPnt;
591 }