1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Validators.cpp
4 // Created: 22 March 2016
5 // Author: Dmitry Bobylev
7 #include "FeaturesPlugin_Validators.h"
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>
17 #include <GeomValidators_BodyShapes.h>
18 #include <GeomValidators_FeatureKind.h>
19 #include <GeomValidators_ShapeType.h>
21 #include <GeomAPI_DataMapOfShapeShape.h>
22 #include <GeomAPI_PlanarEdges.h>
23 #include <GeomAPI_ShapeExplorer.h>
24 #include <GeomAlgoAPI_WireBuilder.h>
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
31 static const std::string aCreationMethodID = "creation_method";
32 static const std::string aBaseObjectsID = "base_objects";
33 static const std::string aLocationsID = "locations_objects";
35 if(theFeature->getKind() != "Pipe") {
36 theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
40 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
41 if(!aCreationMethodAttr.get()) {
42 theError = "Could not get \"" + aCreationMethodID + "\" attribute.";
46 if(aCreationMethodAttr->value() != "locations") {
50 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
51 if(!aBaseObjectsSelectionList.get()) {
52 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
56 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
57 if(!aLocationsSelectionList.get()) {
58 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
62 if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
63 theError = "Number of locations should be the same as base objects.";
70 //==================================================================================================
71 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
76 //==================================================================================================
77 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
78 const std::list<std::string>& theArguments,
79 std::string& theError) const
81 if(theArguments.empty()) {
82 theError = "Validator parameters is empty.";
86 // Checking attribute.
87 if(!isValidAttribute(theAttribute, theArguments, theError)) {
88 if(theError.empty()) {
89 theError = "Attribute contains unacceptable shape.";
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.
108 GeomShapePtr aShape = aSelectionAttr->value();
109 GeomShapePtr aContextShape = aContext->shape();
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.";
117 aSelectedSketches.insert(aContext);
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.";
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.";
132 if(aSelectedWiresFromObjects.isBound(aWire)) {
133 theError = "Objects with such wire already selected. Don't allow to select this object.";
137 aSelectedWiresFromObjects.bind(aWire, aWire);
138 aSelectedSketchesFromObjects.insert(aContext);
147 //==================================================================================================
148 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
149 const std::list<std::string>& theArguments,
150 std::string& theError) const
152 if(!theAttribute.get()) {
153 theError = "Empty attribute.";
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)) {
166 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
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.";
175 GeomShapePtr aShape = anAttr->value();
176 GeomShapePtr aContextShape = aContext->shape();
178 aShape = aContextShape;
181 theError = "Empty shape selected";
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.";
193 if(aShape->isEqual(aContextShape)) {
194 // Whole construction selected. Check that it have faces.
195 if(aConstruction->facesNum() > 0) {
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) {
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.";
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();
221 for(++anIt; anIt != theArguments.cend(); ++anIt) {
222 theError += ", " + *anIt;
228 theError = "Following attribute does not supported: " + anAttributeType + ".";
235 //==================================================================================================
236 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
237 const std::list<std::string>& theArguments,
238 std::string& theError) const
240 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
241 theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
244 if (theArguments.size() != 2) {
245 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
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";
257 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
258 // this validator is not necessary anymore
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);
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();
273 anArguments.push_back("face");
274 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
276 bool aValid = !aFeatureKind && aPlanarFace;
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
285 if(theArguments.size() != 2) {
286 theError = "Validator should be used with 2 parameters for extrusion.";
290 std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
292 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
295 if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
299 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
300 if(!aSelAttr.get()) {
301 theError = "Could not get selection attribute \"" + *anArgsIt + "\".";
305 GeomShapePtr aShape = aSelAttr->value();
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.";
314 aShape = aContext->shape();
318 theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
319 + "\" can not be used with default value. Select direction for extrusion.";
326 //==================================================================================================
327 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
332 //==================================================================================================
333 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
334 std::string& theError) const
336 if(!theAttribute.get()) {
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)) {
349 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
351 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
352 ResultPtr aContext = anAttr->context();
353 if(!aContext.get()) {
357 GeomShapePtr aShape = anAttr->value();
358 GeomShapePtr aContextShape = aContext->shape();
360 aShape = aContextShape;
366 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
367 aShape->shapeType() == GeomAPI_Shape::EDGE ||
368 !aShape->isPlanar()) {
378 //==================================================================================================
379 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
380 const std::list<std::string>& theArguments,
381 std::string& theError) const
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.";
388 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
389 int anOperationType = aFeature->integer("bool_type")->value();
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.";
397 ResultPtr aContext = anAttrSelection->context();
398 if(!aContext.get()) {
399 theError = "Error: empty selection context.";
402 ResultConstructionPtr aResultConstruction =
403 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
404 if(aResultConstruction.get()) {
405 theError = "Error: Result construction not allowed for selection.";
408 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
410 aShape = aContext->shape();
413 theError = "Error: empty shape.";
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.";
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.";
440 //==================================================================================================
441 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
442 const std::list<std::string>& theArguments,
443 std::string& theError) const
445 std::string anAttributeType = theAttribute->attributeType();
446 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
447 AttributeSelectionListPtr aSelectionListAttr =
448 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
450 for(int anIndex = 0; anIndex < aSelectionListAttr->size(); ++anIndex) {
451 AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(anIndex);
453 GeomValidators_BodyShapes aBodyValidator;
454 if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
458 GeomValidators_FeatureKind aFeatureKindValidator;
459 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
463 theError = "Only body shapes and construction planes are allowed for selection.";
467 theError = "This validator supports only " + ModelAPI_AttributeSelectionList::typeId() + " attribute type.";