]> SALOME platform Git repositories - modules/shaper.git/blob - src/FeaturesPlugin/FeaturesPlugin_Validators.cpp
Salome HOME
Replace of Events_Error by Events_InfoMessage. Provide storing of non translated...
[modules/shaper.git] / src / FeaturesPlugin / FeaturesPlugin_Validators.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        FeaturesPlugin_Validators.cpp
4 // Created:     22 March 2016
5 // Author:      Dmitry Bobylev
6
7 #include "FeaturesPlugin_Validators.h"
8
9 #include <ModelAPI_Attribute.h>
10 #include <ModelAPI_AttributeInteger.h>
11 #include <ModelAPI_AttributeSelectionList.h>
12 #include <ModelAPI_AttributeString.h>
13 #include <ModelAPI_AttributeReference.h>
14 #include <ModelAPI_Feature.h>
15 #include <ModelAPI_ResultConstruction.h>
16
17 #include <GeomValidators_BodyShapes.h>
18 #include <GeomValidators_FeatureKind.h>
19 #include <GeomValidators_ShapeType.h>
20
21 #include <GeomAPI_DataMapOfShapeShape.h>
22 #include <GeomAPI_PlanarEdges.h>
23 #include <GeomAPI_ShapeExplorer.h>
24 #include <GeomAlgoAPI_WireBuilder.h>
25
26 //==================================================================================================
27 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
28                                                     const std::list<std::string>& theArguments,
29                                                     std::string& theError) const
30 {
31   static const std::string aCreationMethodID = "creation_method";
32   static const std::string aBaseObjectsID = "base_objects";
33   static const std::string aLocationsID = "locations_objects";
34
35   if(theFeature->getKind() != "Pipe") {
36     theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
37     return false;
38   }
39
40   AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
41   if(!aCreationMethodAttr.get()) {
42     theError = "Could not get \"" + aCreationMethodID + "\" attribute.";
43     return false;
44   }
45
46   if(aCreationMethodAttr->value() != "locations") {
47     return true;
48   }
49
50   AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
51   if(!aBaseObjectsSelectionList.get()) {
52     theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
53     return false;
54   }
55
56   AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
57   if(!aLocationsSelectionList.get()) {
58     theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
59     return false;
60   }
61
62   if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
63     theError = "Number of locations should be the same as base objects.";
64     return false;
65   }
66
67   return true;
68 }
69
70 //==================================================================================================
71 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
72 {
73   return false;
74 }
75
76 //==================================================================================================
77 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
78                                                         const std::list<std::string>& theArguments,
79                                                         std::string& theError) const
80 {
81   if(theArguments.empty()) {
82     theError = "Validator parameters is empty.";
83     return false;
84   }
85
86   // Checking attribute.
87   if(!isValidAttribute(theAttribute, theArguments, theError)) {
88     if(theError.empty()) {
89       theError = "Attribute contains unacceptable shape.";
90     }
91     return false;
92   }
93
94   std::set<ResultConstructionPtr> aSelectedSketches;
95   std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
96   GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
97   std::string anAttributeType = theAttribute->attributeType();
98   if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
99     AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
100     for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
101       AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
102       ResultConstructionPtr aContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelectionAttr->context());
103       if(!aContext.get()) {
104         // It is not a result construction, continue.
105         continue;
106       }
107
108       GeomShapePtr aShape = aSelectionAttr->value();
109       GeomShapePtr aContextShape = aContext->shape();
110       if(!aShape.get()) {
111         // Whole sketch selected.
112         if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) {
113           theError = "Object from this sketch is already selected. Sketch is not allowed for selection.";
114           return false;
115         }
116
117         aSelectedSketches.insert(aContext);
118       } else {
119         // Object from sketch selected.
120         if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) {
121           theError = "Whole sketch with this object is already selected. Don't allow to select this object.";
122           return false;
123         }
124
125         for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
126           GeomShapePtr aWire = anExp.current();
127           if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
128             theError = "Wire with wrong orientation selected.";
129             return false;
130           }
131
132           if(aSelectedWiresFromObjects.isBound(aWire)) {
133             theError = "Objects with such wire already selected. Don't allow to select this object.";
134             return false;
135           }
136
137           aSelectedWiresFromObjects.bind(aWire, aWire);
138           aSelectedSketchesFromObjects.insert(aContext);
139         }
140       }
141     }
142   }
143
144   return true;
145 }
146
147 //==================================================================================================
148 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
149                                                                  const std::list<std::string>& theArguments,
150                                                                  std::string& theError) const
151 {
152   if(!theAttribute.get()) {
153     theError = "Empty attribute.";
154     return false;
155   }
156
157   std::string anAttributeType = theAttribute->attributeType();
158   if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
159     AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
160     for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
161       // If at least one attribute is invalid, the result is false.
162       if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
163         return false;
164       }
165     }
166   } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
167     // Getting context.
168     AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
169     ResultPtr aContext = anAttr->context();
170     if(!aContext.get()) {
171       theError = "Attribute have empty context.";
172       return false;
173     }
174
175     GeomShapePtr aShape = anAttr->value();
176     GeomShapePtr aContextShape = aContext->shape();
177     if(!aShape.get()) {
178       aShape = aContextShape;
179     }
180     if(!aShape.get()) {
181       theError = "Empty shape selected";
182       return false;
183     }
184
185     ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
186     if(aConstruction.get()) {
187       // Construciotn selected. Check that is is not infinite.
188       if(aConstruction->isInfinite()) {
189         theError = "Infinite constructions is not allowed as base.";
190         return false;
191       }
192
193       if(aShape->isEqual(aContextShape)) {
194         // Whole construction selected. Check that it have faces.
195         if(aConstruction->facesNum() > 0) {
196           return true;
197         }
198       } else {
199         // Shape on construction selected. Check that it is a face or wire.
200         if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
201           return true;
202         }
203       }
204
205       return false;
206     }
207
208     if(!aShape->isEqual(aContextShape)) {
209       // Local selection on body does not allowed.
210       theError = "Selected shape is in the local selection. Only global selection is allowed.";
211       return false;
212     }
213
214     // Check that object is a shape with allowed type.
215     GeomValidators_ShapeType aShapeTypeValidator;
216     if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
217       theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, "
218                  "whole sketch(if it has at least one face), and whole objects with shape types: ";
219       std::list<std::string>::const_iterator anIt = theArguments.cbegin();
220       theError += *anIt;
221       for(++anIt; anIt != theArguments.cend(); ++anIt) {
222         theError += ", " + *anIt;
223       }
224       return false;
225     }
226
227   } else {
228     theError = "Following attribute does not supported: " + anAttributeType + ".";
229     return false;
230   }
231
232   return true;
233 }
234
235 //==================================================================================================
236 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
237                                                         const std::list<std::string>& theArguments,
238                                                         std::string& theError) const
239 {
240   if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
241     theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
242     return false;
243   }
244   if (theArguments.size() != 2) {
245     theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
246     return false;
247   }
248   // first argument is for the base attribute, second - for skipping feature kind
249   std::list<std::string>::const_iterator anIt = theArguments.begin();
250   std::string aBaseAttributeId = *anIt;
251   FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
252   AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
253   if (!aBaseAttribute.get()) {
254     theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
255     return false;
256   }
257   if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
258     // this validator is not necessary anymore
259     return true;
260
261   anIt++;
262   std::string aFeatureAttributeKind = *anIt;
263   GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
264   // check whether the selection is on the sketch
265   std::list<std::string> anArguments;
266   anArguments.push_back(aFeatureAttributeKind);
267
268   bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
269   bool aPlanarFace = false;
270   // check if selection has Face selected
271   GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
272   anArguments.clear();
273   anArguments.push_back("face");
274   aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
275
276   bool aValid = !aFeatureKind && aPlanarFace;
277   return aValid;
278 }
279
280 //==================================================================================================
281 bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
282                                                  const std::list<std::string>& theArguments,
283                                                  std::string& theError) const
284 {
285   if(theArguments.size() != 2) {
286     theError = "Validator should be used with 2 parameters for extrusion.";
287     return false;
288   }
289
290   std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
291
292   AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
293   ++anArgsIt;
294
295   if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
296     return true;
297   }
298
299   AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
300   if(!aSelAttr.get()) {
301     theError = "Could not get selection attribute \"" + *anArgsIt + "\".";
302     return false;
303   }
304
305   GeomShapePtr aShape = aSelAttr->value();
306   if(!aShape.get()) {
307     ResultPtr aContext = aSelAttr->context();
308     if(!aContext.get()) {
309       theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
310                + "\" can not be used with default value. Select direction for extrusion.";
311       return false;
312     }
313
314     aShape = aContext->shape();
315   }
316
317   if(!aShape.get()) {
318     theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
319               + "\" can not be used with default value. Select direction for extrusion.";
320     return false;
321   }
322
323   return true;
324 }
325
326 //==================================================================================================
327 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
328 {
329   return false;
330 }
331
332 //==================================================================================================
333 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
334                                                             std::string& theError) const
335 {
336   if(!theAttribute.get()) {
337     return true;
338   }
339
340   std::string anAttributeType = theAttribute->attributeType();
341   if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
342     AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
343     for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
344       // If at least one attribute is invalid, the result is false.
345       if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
346         return false;
347       }
348     }
349   } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
350     // Getting context.
351     AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
352     ResultPtr aContext = anAttr->context();
353     if(!aContext.get()) {
354       return false;
355     }
356
357     GeomShapePtr aShape = anAttr->value();
358     GeomShapePtr aContextShape = aContext->shape();
359     if(!aShape.get()) {
360       aShape = aContextShape;
361     }
362     if(!aShape.get()) {
363       return false;
364     }
365
366     if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
367        aShape->shapeType() == GeomAPI_Shape::EDGE ||
368        !aShape->isPlanar()) {
369       return false;
370     }
371   } else {
372     return false;
373   }
374
375   return true;
376 }
377
378 //==================================================================================================
379 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
380                                                        const std::list<std::string>& theArguments,
381                                                        std::string& theError) const
382 {
383   AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
384   if(!anAttrSelectionList.get()) {
385     theError = "Error: this validator can only work with selection list attributes in Boolean feature.";
386     return false;
387   }
388   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
389   int anOperationType = aFeature->integer("bool_type")->value();
390
391   for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
392     AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
393     if(!anAttrSelection.get()) {
394       theError = "Error: empty attribute selection.";
395       return false;
396     }
397     ResultPtr aContext = anAttrSelection->context();
398     if(!aContext.get()) {
399       theError = "Error: empty selection context.";
400       return false;
401     }
402     ResultConstructionPtr aResultConstruction =
403       std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
404     if(aResultConstruction.get()) {
405       theError = "Error: Result construction not allowed for selection.";
406       return false;
407     }
408     std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
409     if(!aShape.get()) {
410       aShape = aContext->shape();
411     }
412     if(!aShape.get()) {
413       theError = "Error: empty shape.";
414       return false;
415     }
416     int aShapeType = aShape->shapeType();
417     if(anOperationType == 1) {
418       // Fuse operation. Allow to select edges, faces and solids.
419       if(aShapeType != GeomAPI_Shape::EDGE &&
420          aShapeType != GeomAPI_Shape::FACE &&
421          aShapeType != GeomAPI_Shape::SOLID &&
422          aShapeType != GeomAPI_Shape::COMPSOLID &&
423          aShapeType != GeomAPI_Shape::COMPOUND) {
424         theError = "Error: selected shape has the wrong type.";
425         return false;
426       }
427     } else {
428       if(aShapeType != GeomAPI_Shape::SOLID &&
429          aShapeType != GeomAPI_Shape::COMPSOLID &&
430          aShapeType != GeomAPI_Shape::COMPOUND) {
431         theError = "Error: selected shape has the wrong type.";
432         return false;
433       }
434     }
435   }
436
437   return true;
438 }
439
440 //==================================================================================================
441 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
442                                                          const std::list<std::string>& theArguments,
443                                                          std::string& theError) const
444 {
445   std::string anAttributeType = theAttribute->attributeType();
446   if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
447     AttributeSelectionListPtr aSelectionListAttr =
448         std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
449
450     for(int anIndex = 0; anIndex < aSelectionListAttr->size(); ++anIndex) {
451       AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(anIndex);
452
453       GeomValidators_BodyShapes aBodyValidator;
454       if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
455         continue;
456       }
457
458       GeomValidators_FeatureKind aFeatureKindValidator;
459       if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
460         continue;
461       }
462
463       theError = "Only body shapes and construction planes are allowed for selection.";
464       return false;
465     }
466   } else {
467     theError = "This validator supports only " + ModelAPI_AttributeSelectionList::typeId() + " attribute type.";
468     return false;
469   }
470
471   return true;
472 }