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 "FeaturesPlugin_Union.h"
11 #include <Events_InfoMessage.h>
13 #include <ModelAPI_Attribute.h>
14 #include <ModelAPI_AttributeInteger.h>
15 #include <ModelAPI_AttributeSelectionList.h>
16 #include <ModelAPI_AttributeString.h>
17 #include <ModelAPI_AttributeReference.h>
18 #include <ModelAPI_AttributeRefList.h>
19 #include <ModelAPI_Feature.h>
20 #include <ModelAPI_ResultCompSolid.h>
21 #include <ModelAPI_ResultConstruction.h>
22 #include <ModelAPI_Tools.h>
24 #include <GeomValidators_BodyShapes.h>
25 #include <GeomValidators_FeatureKind.h>
26 #include <GeomValidators_ShapeType.h>
28 #include <GeomAPI_DataMapOfShapeShape.h>
29 #include <GeomAPI_Lin.h>
30 #include <GeomAPI_PlanarEdges.h>
31 #include <GeomAPI_ShapeExplorer.h>
32 #include <GeomAPI_ShapeIterator.h>
34 #include <GeomAlgoAPI_CompoundBuilder.h>
35 #include <GeomAlgoAPI_ShapeBuilder.h>
36 #include <GeomAlgoAPI_ShapeTools.h>
37 #include <GeomAlgoAPI_WireBuilder.h>
39 #define _USE_MATH_DEFINES
42 //==================================================================================================
43 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
44 const std::list<std::string>& theArguments,
45 Events_InfoMessage& theError) const
47 AttributeSelectionPtr aPathAttrSelection =
48 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
49 if(!aPathAttrSelection.get()) {
50 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
54 GeomShapePtr aPathShape = aPathAttrSelection->value();
55 ResultPtr aContext = aPathAttrSelection->context();
57 theError = "Error: Empty context.";
60 GeomShapePtr aContextShape = aContext->shape();
61 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
62 !aPathShape->isEqual(aContextShape)) {
63 theError = "Error: Local selection of wires not allowed.";
70 //==================================================================================================
71 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
72 const std::shared_ptr<ModelAPI_Feature>& theFeature,
73 const std::list<std::string>& theArguments,
74 Events_InfoMessage& theError) const
76 static const std::string aCreationMethodID = "creation_method";
77 static const std::string aBaseObjectsID = "base_objects";
78 static const std::string aLocationsID = "locations_objects";
80 if(theFeature->getKind() != "Pipe") {
81 theError = "Error: Feature \"%1\" does not supported by this validator.";
82 theError.arg(theFeature->getKind());
86 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
87 if(!aCreationMethodAttr.get()) {
88 theError = "Error: Could not get \"%1\" attribute.";
89 theError.arg(aCreationMethodID);
93 if(aCreationMethodAttr->value() != "locations") {
97 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
98 if(!aBaseObjectsSelectionList.get()) {
99 theError = "Error: Could not get \"%1\" attribute.";
100 theError.arg(aBaseObjectsID);
104 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
105 if(!aLocationsSelectionList.get()) {
106 theError = "Error: Could not get \"%1\" attribute.";
107 theError.arg(aBaseObjectsID);
111 if(aLocationsSelectionList->size() > 0 &&
112 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
113 theError = "Error: Number of locations should be the same as base objects.";
120 //==================================================================================================
121 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature,
122 std::string theAttribute)
127 //==================================================================================================
128 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
129 const std::list<std::string>& theArguments,
130 Events_InfoMessage& theError) const
132 if(theArguments.empty()) {
133 theError = "Error: Validator parameters is empty.";
137 // Checking attribute.
138 if(!isValidAttribute(theAttribute, theArguments, theError)) {
139 if(theError.empty()) {
140 theError = "Error: Attribute contains unacceptable shape.";
145 std::set<ResultConstructionPtr> aSelectedSketches;
146 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
147 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
148 std::string anAttributeType = theAttribute->attributeType();
149 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
150 AttributeSelectionListPtr aListAttr =
151 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
152 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
153 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
154 ResultPtr aContext = aSelectionAttr->context();
155 if(!aContext.get()) {
156 theError = "Error: Empty context.";
160 ResultConstructionPtr aResultConstruction =
161 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
162 if(!aResultConstruction.get()) {
163 // It is not a result construction.
164 // If shape is compound check that it contains only faces and edges.
165 GeomShapePtr aShape = aSelectionAttr->value();
167 aShape = aContext->shape();
170 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
171 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
172 GeomShapePtr aSubShape = anIt.current();
173 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
174 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
175 theError = "Error: Compound should contain only faces and edges.";
184 GeomShapePtr aShape = aSelectionAttr->value();
185 GeomShapePtr aContextShape = aResultConstruction->shape();
187 // Whole sketch selected.
188 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
189 aSelectedSketchesFromObjects.cend()) {
190 theError = "Error: Object from this sketch is already selected. "
191 "Sketch is not allowed for selection.";
195 aSelectedSketches.insert(aResultConstruction);
197 // Object from sketch selected.
198 if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {
199 theError = "Error: Whole sketch with this object is already selected. "
200 "Don't allow to select this object.";
204 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
205 GeomShapePtr aWire = anExp.current();
206 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
207 theError = "Error: Wire with wrong orientation selected.";
211 if(aSelectedWiresFromObjects.isBound(aWire)) {
213 "Error: Objects with such wire already selected. Don't allow to select this object.";
217 aSelectedWiresFromObjects.bind(aWire, aWire);
218 aSelectedSketchesFromObjects.insert(aResultConstruction);
227 //==================================================================================================
228 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
229 const std::list<std::string>& theArguments,
230 Events_InfoMessage& theError) const
232 if(!theAttribute.get()) {
233 theError = "Error: Empty attribute.";
237 std::string anAttributeType = theAttribute->attributeType();
238 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
239 AttributeSelectionListPtr aListAttr =
240 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
241 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
242 // If at least one attribute is invalid, the result is false.
243 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
247 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
249 AttributeSelectionPtr anAttr =
250 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
251 ResultPtr aContext = anAttr->context();
252 if(!aContext.get()) {
253 theError = "Error: Attribute have empty context.";
257 GeomShapePtr aShape = anAttr->value();
258 GeomShapePtr aContextShape = aContext->shape();
260 aShape = aContextShape;
263 theError = "Error: Empty shape selected";
267 ResultConstructionPtr aConstruction =
268 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
269 if(aConstruction.get()) {
270 // Construciotn selected. Check that is is not infinite.
271 if(aConstruction->isInfinite()) {
272 theError = "Error: Infinite constructions is not allowed as base.";
276 if(aShape->isEqual(aContextShape)) {
277 // Whole construction selected. Check that it have faces.
278 if(aConstruction->facesNum() > 0) {
282 // Shape on construction selected. Check that it is a face or wire.
283 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
284 aShape->shapeType() == GeomAPI_Shape::FACE) {
292 if(!aShape->isEqual(aContextShape)) {
293 // Local selection on body does not allowed.
295 "Error: Selected shape is in the local selection. Only global selection is allowed.";
299 // Check that object is a shape with allowed type.
300 GeomValidators_ShapeType aShapeTypeValidator;
301 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
302 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
303 "wires on sketch, whole sketch(if it has at least one face), "
304 "and whole objects with shape types: %1";
305 std::string anArgumentString;
306 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
307 if (!anArgumentString.empty())
308 anArgumentString += ", ";
309 anArgumentString += *anIt;
311 theError.arg(anArgumentString);
316 theError = "Error: Attribute \"%1\" does not supported by this validator.";
317 theError.arg(anAttributeType);
324 //==================================================================================================
325 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
326 const std::list<std::string>& theArguments,
327 Events_InfoMessage& theError) const
329 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
330 theError = "Error: The attribute with the %1 type is not processed";
331 theError.arg(theAttribute->attributeType());
334 if (theArguments.size() != 2) {
335 theError = "Error: Wrong parameters in XML definition for %1 type";
336 theError.arg(theAttribute->attributeType());
339 // first argument is for the base attribute, second - for skipping feature kind
340 std::list<std::string>::const_iterator anIt = theArguments.begin();
341 std::string aBaseAttributeId = *anIt;
342 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
343 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
344 if (!aBaseAttribute.get()) {
345 theError = "Wrong parameters in XML definition for %1 type";
346 theError.arg(theAttribute->attributeType());
349 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
350 // this validator is not necessary anymore
354 std::string aFeatureAttributeKind = *anIt;
355 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
356 // check whether the selection is on the sketch
357 std::list<std::string> anArguments;
358 anArguments.push_back(aFeatureAttributeKind);
360 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
361 bool aPlanarFace = false;
362 // check if selection has Face selected
363 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
365 anArguments.push_back("face");
366 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
368 bool aValid = !aFeatureKind && aPlanarFace;
372 //==================================================================================================
373 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
374 const std::shared_ptr<ModelAPI_Feature>& theFeature,
375 const std::list<std::string>& theArguments,
376 Events_InfoMessage& theError) const
378 if(theArguments.size() != 2) {
379 theError = "Error: Validator should be used with 2 parameters for extrusion.";
383 std::list<std::string>::const_iterator
384 anArgsIt = theArguments.begin(), aLast = theArguments.end();
386 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
389 GeomShapePtr aDirShape;
390 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
392 aDirShape = aSelAttr->value();
393 if(!aDirShape.get()) {
394 ResultPtr aContext = aSelAttr->context();
396 aDirShape = aContext->shape();
401 if(!aDirShape.get()) {
402 // Check that dir can be empty.
403 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
404 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
405 "can not be used with default value. Select direction for extrusion.";
406 theError.arg(*anArgsIt);
413 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
415 // If faces selected check that direction not parallel with them.
416 AttributeSelectionListPtr aListAttr =
417 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
418 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
419 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
420 GeomShapePtr aShapeInList = anAttr->value();
421 if(!aShapeInList.get()) {
422 aShapeInList = anAttr->context()->shape();
424 bool isParallel = true;
425 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
426 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
427 for(GeomAPI_ShapeExplorer
428 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
429 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
430 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
435 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
436 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
437 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
438 if(aPlanarEdges.get()) {
439 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
440 if(aDirEdge->isLine()) {
441 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
442 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
454 "Error: Direction is parallel to one of the selected face or face on selected shell.";
462 //==================================================================================================
463 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
464 std::string theAttribute)
469 //==================================================================================================
470 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
471 Events_InfoMessage& theError) const
473 if(!theAttribute.get()) {
477 std::string anAttributeType = theAttribute->attributeType();
478 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
479 AttributeSelectionListPtr aListAttr =
480 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
481 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
482 // If at least one attribute is invalid, the result is false.
483 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
487 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
489 AttributeSelectionPtr anAttr =
490 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
491 ResultPtr aContext = anAttr->context();
492 if(!aContext.get()) {
496 GeomShapePtr aShape = anAttr->value();
497 GeomShapePtr aContextShape = aContext->shape();
499 aShape = aContextShape;
505 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
506 aShape->shapeType() == GeomAPI_Shape::EDGE ||
507 !aShape->isPlanar()) {
517 //==================================================================================================
518 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
519 const std::list<std::string>& theArguments,
520 Events_InfoMessage& theError) const
522 AttributeSelectionListPtr anAttrSelectionList =
523 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
524 if(!anAttrSelectionList.get()) {
526 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
529 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
530 int anOperationType = aFeature->integer("bool_type")->value();
532 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
533 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
534 if(!anAttrSelection.get()) {
535 theError = "Error: Empty attribute selection.";
538 ResultPtr aContext = anAttrSelection->context();
539 if(!aContext.get()) {
540 theError = "Error: Empty selection context.";
543 ResultConstructionPtr aResultConstruction =
544 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
545 if(aResultConstruction.get()) {
546 theError = "Error: Result construction not allowed for selection.";
549 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
550 GeomShapePtr aContextShape = aContext->shape();
552 aShape = aContextShape;
555 theError = "Error: Empty shape.";
558 if(!aShape->isEqual(aContextShape)) {
559 theError = "Error: Local selection not allowed.";
563 int aShapeType = aShape->shapeType();
564 if(anOperationType == 1) {
565 // Fuse operation. Allow to select edges, faces and solids.
566 if(aShapeType != GeomAPI_Shape::EDGE &&
567 aShapeType != GeomAPI_Shape::FACE &&
568 aShapeType != GeomAPI_Shape::SOLID &&
569 aShapeType != GeomAPI_Shape::COMPSOLID &&
570 aShapeType != GeomAPI_Shape::COMPOUND) {
571 theError = "Error: Selected shape has the wrong type.";
575 if(aShapeType != GeomAPI_Shape::SOLID &&
576 aShapeType != GeomAPI_Shape::COMPSOLID &&
577 aShapeType != GeomAPI_Shape::COMPOUND) {
578 theError = "Error: Selected shape has the wrong type.";
587 //==================================================================================================
588 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
589 const std::list<std::string>& theArguments,
590 Events_InfoMessage& theError) const
592 AttributeSelectionListPtr anAttrSelectionList =
593 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
594 if(!anAttrSelectionList.get()) {
595 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
599 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
600 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
602 //GeomValidators_BodyShapes aBodyValidator;
603 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
607 GeomValidators_FeatureKind aFeatureKindValidator;
608 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
612 ResultPtr aContext = aSelectAttr->context();
613 ResultConstructionPtr aResultConstruction =
614 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
615 if(aResultConstruction.get()) {
616 theError = "Error: Only body shapes and construction planes are allowed for selection.";
620 ResultCompSolidPtr aResultCompsolid =
621 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
622 if(aResultCompsolid.get()) {
626 theError = "Error: Only body shapes and construction planes are allowed for selection.";
634 //==================================================================================================
635 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
636 const std::list<std::string>& theArguments,
637 Events_InfoMessage& theError) const
639 AttributeSelectionListPtr aSubShapesAttrList =
640 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
641 if(!aSubShapesAttrList.get()) {
643 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
647 static const std::string aBaseShapeID = "base_shape";
648 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
649 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
651 if(!aShapeAttrSelection.get()) {
652 theError = "Error: Could not get \"%1\" attribute.";
653 theError.arg(aBaseShapeID);
657 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
658 ResultPtr aContext = aShapeAttrSelection->context();
659 if(!aContext.get()) {
660 theError = "Error: Empty context.";
663 if(!aBaseShape.get()) {
664 aBaseShape = aContext->shape();
666 if(!aBaseShape.get()) {
667 theError = "Error: Empty base shape.";
671 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
672 bool isSameFound = false;
673 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
674 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
675 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
676 if(anIt.current()->isEqual(aShapeToAdd)) {
682 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
690 //==================================================================================================
691 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
692 const std::shared_ptr<ModelAPI_Feature>& theFeature,
693 const std::list<std::string>& theArguments,
694 Events_InfoMessage& theError) const
696 static const std::string aBaseShapeID = "base_shape";
697 static const std::string aSubShapesID = "subshapes";
699 if(theFeature->getKind() != "Remove_SubShapes") {
700 theError = "Error: Feature \"%1\" does not supported by this validator.";
701 theError.arg(theFeature->getKind());
705 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
706 if(!aShapeAttrSelection.get()) {
707 theError = "Error: Could not get \"%1\" attribute.";
708 theError.arg(aBaseShapeID);
712 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
713 if(!aSubShapesAttrList.get()) {
714 theError = "Error: Could not get \"%1\" attribute.";
715 theError.arg(aSubShapesID);
720 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
721 if(!aBaseShape.get()) {
722 theError = "Error: Base shape is empty.";
725 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
727 // Copy sub-shapes from list to new shape.
728 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
729 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
730 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
731 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
735 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
736 theError = "Error: Resulting shape is not valid.";
743 //==================================================================================================
744 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
745 std::string theAttribute)
750 //==================================================================================================
751 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
752 const std::list<std::string>& theArguments,
753 Events_InfoMessage& theError) const
755 AttributeSelectionListPtr aBaseObjectsAttrList =
756 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
757 if(!aBaseObjectsAttrList.get()) {
758 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
759 theError.arg(FeaturesPlugin_Union::ID());
763 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
764 bool isSameFound = false;
765 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
766 ResultCompSolidPtr aResult =
767 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
771 if(aResult->numberOfSubs() > 0) {
772 theError = "Error: Whole compsolids not allowed for selection.";
780 //==================================================================================================
781 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
782 const std::shared_ptr<ModelAPI_Feature>& theFeature,
783 const std::list<std::string>& theArguments,
784 Events_InfoMessage& theError) const
786 // Check feature kind.
787 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
788 theError = "Error: This validator supports only \"%1\" feature.";
789 theError.arg(FeaturesPlugin_Union::ID());
793 // Get base objects attribute list.
794 AttributeSelectionListPtr aBaseObejctsAttrList =
795 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
796 if(!aBaseObejctsAttrList.get()) {
797 theError = "Error: Could not get \"%1\" attribute.";
798 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
803 ListOfShape aBaseShapesList;
804 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
805 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
806 GeomShapePtr aShape = anAttrSelectionInList->value();
807 aBaseShapesList.push_back(aShape);
810 // Make componud and find connected.
811 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
812 ListOfShape aCombined, aFree;
813 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
815 if(aFree.size() > 0 || aCombined.size() > 1) {
816 theError = "Error: Not all shapes have shared topology.";
823 //==================================================================================================
824 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
825 std::string theAttribute)
830 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
831 const std::list<std::string>& theArguments,
832 Events_InfoMessage& theError) const
834 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
835 theError = "Error: The attribute with the %1 type is not processed";
836 theError.arg(theAttribute->attributeType());
840 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
842 ObjectPtr aRefObject = aRefAttribute->value();
843 if (!aRefObject.get()) {
844 theError = "Error: Empty feature.";
848 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
849 if (!aRefFeature.get()) {
850 theError = "Error: Empty feature.";
853 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
854 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
856 size_t aConcealedResults = aResults.size();
857 if (!aConcealedResults && !theArguments.empty()) {
858 // find if these results are touched by the feature in another attribute
859 std::list<std::string>::const_iterator anIt = theArguments.begin();
860 std::string aRecoveredList = *anIt;
861 if (!aRecoveredList.empty()) {
862 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
863 theAttribute->owner()->data()->reflist(aRecoveredList);
864 if (aParameterList.get())
865 aConcealedResults = aParameterList->size();
869 if (aConcealedResults == 0)
870 theError = "Error: No concealed results.";
872 return theError.empty();