Salome HOME
a1e57461adf7b7379477ad9300c4fd19a6b221bc
[modules/shaper.git] / src / GeomValidators / GeomValidators_ZeroOffset.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 <GeomValidators_ZeroOffset.h>
21
22 #include <Events_InfoMessage.h>
23
24 #include <ModelAPI_AttributeDouble.h>
25 #include <ModelAPI_AttributeSelection.h>
26 #include <ModelAPI_AttributeSelectionList.h>
27 #include <ModelAPI_AttributeString.h>
28 #include <ModelAPI_ResultConstruction.h>
29
30 #include <GeomAPI_Dir.h>
31 #include <GeomAPI_Face.h>
32 #include <GeomAPI_Shape.h>
33 #include <GeomAPI_ShapeIterator.h>
34 #include <GeomAPI_Pln.h>
35 #include <GeomAPI_Pnt.h>
36
37 //=================================================================================================
38 bool GeomValidators_ZeroOffset::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
39                                         const std::list<std::string>& theArguments,
40                                         Events_InfoMessage& theError) const
41 {
42 // LCOV_EXCL_START
43   if(theArguments.size() != 9) {
44     theError = "Wrong number of validator arguments in xml (expected 9).";
45     return false;
46   }
47 // LCOV_EXCL_STOP
48
49   std::list<std::string>::const_iterator anIt = theArguments.begin();
50
51   std::string aSelectedMethod;
52   if(theFeature->string(*anIt)) {
53     aSelectedMethod = theFeature->string(*anIt)->value();
54   }
55   if (aSelectedMethod == "ThroughAll") return true;
56   anIt++;
57   std::string aCreationMethod = *anIt;
58   anIt++;
59
60   ListOfShape aFacesList;
61   if(theFeature->selection(*anIt)) {
62 // LCOV_EXCL_START
63     AttributeSelectionPtr aFaceSelection = theFeature->selection(*anIt);
64     ResultConstructionPtr aConstruction =
65       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aFaceSelection->context());
66     if(aConstruction.get()) {
67       int aSketchFacesNum = aConstruction->facesNum();
68       for(int aFaceIndex = 0; aFaceIndex < aSketchFacesNum; aFaceIndex++) {
69         std::shared_ptr<GeomAPI_Shape> aFace =
70           std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
71         if(aFace->isFace() && aFace->isPlanar()) {
72           aFacesList.push_back(aFace);
73         }
74       }
75     }
76 // LCOV_EXCL_STOP
77   } else if(theFeature->selectionList(*anIt)) {
78     AttributeSelectionListPtr aFacesSelectionList = theFeature->selectionList(*anIt);
79     for(int anIndex = 0; anIndex < aFacesSelectionList->size(); anIndex++) {
80       AttributeSelectionPtr aFaceSel = aFacesSelectionList->value(anIndex);
81       std::shared_ptr<GeomAPI_Shape> aFaceShape = aFaceSel->value();
82       if(aFaceShape.get() && !aFaceShape->isNull()) { // Getting face.
83         if(aFaceShape->isFace() && aFaceShape->isPlanar()) {
84           aFacesList.push_back(aFaceShape);
85         }
86       } else { // This may be the whole sketch result selected, check and get faces.
87         ResultPtr aContext = aFaceSel->context();
88         std::shared_ptr<GeomAPI_Shape> aContextShape = aContext->shape();
89         if(!aContextShape.get()) {
90           break;
91         }
92         ResultConstructionPtr aConstruction =
93           std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
94         if(!aConstruction.get()) {
95           break;
96         }
97         int aFacesNum = aConstruction->facesNum();
98         for(int aFaceIndex = 0; aFaceIndex < aFacesNum || aFacesNum == -1; aFaceIndex++) {
99           aFaceShape = std::dynamic_pointer_cast<GeomAPI_Shape>(aConstruction->face(aFaceIndex));
100           if(aFaceShape->isFace() && aFaceShape->isPlanar()) {
101             aFacesList.push_back(aFaceShape);
102           }
103         }
104       }
105     }
106   }
107   anIt++;
108
109   double aToSize = 0.0;
110   double aFromSize = 0.0;
111
112   if(theFeature->real(*anIt) && theFeature->real(*anIt)->isInitialized()) {
113     aToSize = theFeature->real(*anIt)->value();
114   }
115   anIt++;
116   if(theFeature->real(*anIt) && theFeature->real(*anIt)->isInitialized()) {
117     aFromSize = theFeature->real(*anIt)->value();
118   }
119   anIt++;
120
121   if(aSelectedMethod == aCreationMethod) {
122     if(aToSize == -aFromSize) {
123       theError = "ToSize = -FromSize.";
124       return false;
125     } else {
126       return true;
127     }
128   }
129
130   std::shared_ptr<GeomAPI_Shape> aToShape;
131   std::shared_ptr<GeomAPI_Shape> aFromShape;
132
133   std::shared_ptr<ModelAPI_AttributeSelection> anAttrSel = theFeature->selection(*anIt);
134   if(anAttrSel && anAttrSel->isInitialized()) {
135     aToShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
136     if(aToShape.get() == NULL && anAttrSel->context().get() != NULL) {
137       aToShape =  anAttrSel->context()->shape();
138     }
139     if (aToShape->isCompound()) {
140       GeomAPI_ShapeIterator aSIt(aToShape);
141       aToShape = aSIt.current();
142     }
143   }
144   anIt++;
145
146   std::shared_ptr<ModelAPI_AttributeDouble> anAttrDouble = theFeature->real(*anIt);
147   if(anAttrDouble && anAttrDouble->isInitialized()) {
148     aToSize = anAttrDouble->value();
149   }
150   anIt++;
151
152   anAttrSel = theFeature->selection(*anIt);
153   if(anAttrSel && anAttrSel->isInitialized()) {
154     aFromShape = std::dynamic_pointer_cast<GeomAPI_Shape>(anAttrSel->value());
155     if(aFromShape.get() == NULL && anAttrSel->context().get() != NULL) {
156       aFromShape = anAttrSel->context()->shape();
157     }
158     if (aFromShape->isCompound()) {
159       GeomAPI_ShapeIterator aSIt(aFromShape);
160       aFromShape = aSIt.current();
161     }
162   }
163   anIt++;
164
165   anAttrDouble = theFeature->real(*anIt);
166   if(anAttrDouble && anAttrDouble->isInitialized()) {
167     aFromSize = anAttrDouble->value();
168   }
169
170   bool isPlanesCoincident = false;
171   if(!aFromShape.get() && !aToShape.get()) {
172     isPlanesCoincident = true;
173   } else if(aFromShape.get() && aToShape.get()) {
174     std::shared_ptr<GeomAPI_Face> aFromFace(new GeomAPI_Face(aFromShape));
175     if (aFromFace->isNull()) {
176       theError = "From face selection is invalid.";
177       return false;
178     }
179     std::shared_ptr<GeomAPI_Pln>  aFromPln = aFromFace->getPlane();
180
181     std::shared_ptr<GeomAPI_Face> aToFace(new GeomAPI_Face(aToShape));
182     if (aToFace->isNull()) {
183       theError = "To face selection is invalid.";
184       return false;
185     }
186     std::shared_ptr<GeomAPI_Pln>  aToPln = aToFace->getPlane();
187
188     if(aFromPln.get()) {
189       isPlanesCoincident = aFromPln->isCoincident(aToPln);
190     }
191   } else {
192     std::shared_ptr<GeomAPI_Face> aFace;
193     if(aFromShape.get()) {
194       aFace.reset(new GeomAPI_Face(aFromShape));
195       if (aFace->isNull()) {
196         theError = "From face selection is invalid.";
197         return false;
198       }
199     } else {
200       aFace.reset(new GeomAPI_Face(aToShape));
201       if (aFace->isNull()) {
202         theError = "To face selection is invalid.";
203         return false;
204       }
205     }
206     std::shared_ptr<GeomAPI_Pln> aPln = aFace->getPlane();
207     if(aPln.get()) {
208       for(ListOfShape::const_iterator
209           anIter = aFacesList.cbegin(); anIter != aFacesList.cend(); anIter++) {
210         std::shared_ptr<GeomAPI_Shape> aSketchShape = *anIter;
211         std::shared_ptr<GeomAPI_Face> aSketchFace(new GeomAPI_Face(aSketchShape));
212         std::shared_ptr<GeomAPI_Pln>  aSketchPln = aSketchFace->getPlane();
213         if(aPln->isCoincident(aSketchPln)) {
214           isPlanesCoincident = true;
215           break;
216         }
217       }
218     }
219   }
220
221   if(isPlanesCoincident && aFromSize == -aToSize) {
222     theError = "FromSize = -ToSize and bounding planes are coincident.";
223     return false;
224   }
225
226   return true;
227 }
228
229 //=================================================================================================
230 // LCOV_EXCL_START
231 bool GeomValidators_ZeroOffset::isNotObligatory(std::string theFeature, std::string theAttribute)
232 {
233   if(theAttribute == "from_object" || theAttribute == "to_object") {
234     return true;
235   }
236
237   return false;
238 }
239 // LCOV_EXCL_STOP