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 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
146 std::string anAttributeType = theAttribute->attributeType();
147 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
148 AttributeSelectionListPtr aListAttr =
149 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
150 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
151 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
152 ResultPtr aContext = aSelectionAttr->context();
153 if(!aContext.get()) {
154 theError = "Error: Empty context.";
158 ResultConstructionPtr aResultConstruction =
159 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
160 if(!aResultConstruction.get()) {
161 // It is not a result construction.
162 // If shape is compound check that it contains only faces and edges.
163 GeomShapePtr aShape = aSelectionAttr->value();
165 aShape = aContext->shape();
168 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
169 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
170 GeomShapePtr aSubShape = anIt.current();
171 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
172 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
173 theError = "Error: Compound should contain only faces and edges.";
182 GeomShapePtr aShape = aSelectionAttr->value();
183 GeomShapePtr aContextShape = aResultConstruction->shape();
185 // Whole sketch selected.
188 // Object from sketch selected.
189 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
190 GeomShapePtr aWire = anExp.current();
191 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
192 theError = "Error: Wire with wrong orientation selected.";
196 if(aSelectedWiresFromObjects.isBound(aWire)) {
198 "Error: Objects with such wire already selected. Don't allow to select this object.";
202 aSelectedWiresFromObjects.bind(aWire, aWire);
211 //==================================================================================================
212 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
213 const std::shared_ptr<ModelAPI_Feature>& theFeature,
214 const std::list<std::string>& theArguments,
215 Events_InfoMessage& theError) const
217 const std::string aBaseObjectsID = theArguments.front();
219 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
220 if(!aListAttr.get()) {
221 theError = "Error: Could not get \"%1\" attribute.";
222 theError.arg(aBaseObjectsID);
226 std::set<ResultConstructionPtr> aSelectedSketches;
227 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
229 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
230 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
231 ResultPtr aContext = aSelectionAttr->context();
232 if(!aContext.get()) {
233 theError = "Error: Empty context.";
237 ResultConstructionPtr aResultConstruction =
238 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
239 if(!aResultConstruction.get()) {
240 // It is not a result construction.
244 GeomShapePtr aShape = aSelectionAttr->value();
245 GeomShapePtr aContextShape = aResultConstruction->shape();
247 // Whole sketch selected.
248 aSelectedSketches.insert(aResultConstruction);
250 // Object from sketch selected.
251 aSelectedSketchesFromObjects.insert(aResultConstruction);
256 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
257 anIt != aSelectedSketches.cend();
259 ResultConstructionPtr aResultConstruction = *anIt;
260 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
261 aSelectedSketchesFromObjects.cend()) {
262 theError = "Sketch and objects from it can not be selected at the same time.";
270 //==================================================================================================
271 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isNotObligatory(
272 std::string theFeature,
273 std::string theAttribute)
278 //==================================================================================================
279 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
280 const std::list<std::string>& theArguments,
281 Events_InfoMessage& theError) const
283 if(!theAttribute.get()) {
284 theError = "Error: Empty attribute.";
288 std::string anAttributeType = theAttribute->attributeType();
289 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
290 AttributeSelectionListPtr aListAttr =
291 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
292 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
293 // If at least one attribute is invalid, the result is false.
294 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
298 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
300 AttributeSelectionPtr anAttr =
301 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
302 ResultPtr aContext = anAttr->context();
303 if(!aContext.get()) {
304 theError = "Error: Attribute have empty context.";
308 GeomShapePtr aShape = anAttr->value();
309 GeomShapePtr aContextShape = aContext->shape();
311 aShape = aContextShape;
314 theError = "Error: Empty shape selected";
318 ResultConstructionPtr aConstruction =
319 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
320 if(aConstruction.get()) {
321 // Construciotn selected. Check that is is not infinite.
322 if(aConstruction->isInfinite()) {
323 theError = "Error: Infinite constructions is not allowed as base.";
327 if(aShape->isEqual(aContextShape)) {
328 // Whole construction selected. Check that it have faces.
329 if(aConstruction->facesNum() > 0) {
333 // Shape on construction selected. Check that it is a face or wire.
334 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
335 aShape->shapeType() == GeomAPI_Shape::FACE) {
343 if(!aShape->isEqual(aContextShape)) {
344 // Local selection on body does not allowed.
346 "Error: Selected shape is in the local selection. Only global selection is allowed.";
350 // Check that object is a shape with allowed type.
351 GeomValidators_ShapeType aShapeTypeValidator;
352 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
353 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
354 "wires on sketch, whole sketch(if it has at least one face), "
355 "and whole objects with shape types: %1";
356 std::string anArgumentString;
357 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
358 if (!anArgumentString.empty())
359 anArgumentString += ", ";
360 anArgumentString += *anIt;
362 theError.arg(anArgumentString);
367 theError = "Error: Attribute \"%1\" does not supported by this validator.";
368 theError.arg(anAttributeType);
375 //==================================================================================================
376 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
377 const std::list<std::string>& theArguments,
378 Events_InfoMessage& theError) const
380 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
381 theError = "Error: The attribute with the %1 type is not processed";
382 theError.arg(theAttribute->attributeType());
385 if (theArguments.size() != 2) {
386 theError = "Error: Wrong parameters in XML definition for %1 type";
387 theError.arg(theAttribute->attributeType());
390 // first argument is for the base attribute, second - for skipping feature kind
391 std::list<std::string>::const_iterator anIt = theArguments.begin();
392 std::string aBaseAttributeId = *anIt;
393 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
394 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
395 if (!aBaseAttribute.get()) {
396 theError = "Wrong parameters in XML definition for %1 type";
397 theError.arg(theAttribute->attributeType());
400 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
401 // this validator is not necessary anymore
405 std::string aFeatureAttributeKind = *anIt;
406 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
407 // check whether the selection is on the sketch
408 std::list<std::string> anArguments;
409 anArguments.push_back(aFeatureAttributeKind);
411 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
412 bool aPlanarFace = false;
413 // check if selection has Face selected
414 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
416 anArguments.push_back("face");
417 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
419 bool aValid = !aFeatureKind && aPlanarFace;
423 //==================================================================================================
424 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
425 const std::shared_ptr<ModelAPI_Feature>& theFeature,
426 const std::list<std::string>& theArguments,
427 Events_InfoMessage& theError) const
429 if(theArguments.size() != 2) {
430 theError = "Error: Validator should be used with 2 parameters for extrusion.";
434 std::list<std::string>::const_iterator
435 anArgsIt = theArguments.begin(), aLast = theArguments.end();
437 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
440 GeomShapePtr aDirShape;
441 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
443 aDirShape = aSelAttr->value();
444 if(!aDirShape.get()) {
445 ResultPtr aContext = aSelAttr->context();
447 aDirShape = aContext->shape();
452 if(!aDirShape.get()) {
453 // Check that dir can be empty.
454 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
455 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
456 "can not be used with default value. Select direction for extrusion.";
457 theError.arg(*anArgsIt);
464 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
466 // If faces selected check that direction not parallel with them.
467 AttributeSelectionListPtr aListAttr =
468 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
469 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
470 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
471 GeomShapePtr aShapeInList = anAttr->value();
472 if(!aShapeInList.get()) {
473 aShapeInList = anAttr->context()->shape();
475 bool isParallel = true;
476 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
477 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
478 for(GeomAPI_ShapeExplorer
479 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
480 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
481 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
486 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
487 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
488 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
489 if(aPlanarEdges.get()) {
490 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
491 if(aDirEdge->isLine()) {
492 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
493 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
505 "Error: Direction is parallel to one of the selected face or face on selected shell.";
513 //==================================================================================================
514 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
515 std::string theAttribute)
520 //==================================================================================================
521 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
522 Events_InfoMessage& theError) const
524 if(!theAttribute.get()) {
528 std::string anAttributeType = theAttribute->attributeType();
529 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
530 AttributeSelectionListPtr aListAttr =
531 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
532 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
533 // If at least one attribute is invalid, the result is false.
534 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
538 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
540 AttributeSelectionPtr anAttr =
541 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
542 ResultPtr aContext = anAttr->context();
543 if(!aContext.get()) {
547 GeomShapePtr aShape = anAttr->value();
548 GeomShapePtr aContextShape = aContext->shape();
550 aShape = aContextShape;
556 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
557 aShape->shapeType() == GeomAPI_Shape::EDGE ||
558 !aShape->isPlanar()) {
568 //==================================================================================================
569 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
570 const std::list<std::string>& theArguments,
571 Events_InfoMessage& theError) const
573 AttributeSelectionListPtr anAttrSelectionList =
574 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
575 if(!anAttrSelectionList.get()) {
577 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
580 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
581 int anOperationType = aFeature->integer("bool_type")->value();
583 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
584 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
585 if(!anAttrSelection.get()) {
586 theError = "Error: Empty attribute selection.";
589 ResultPtr aContext = anAttrSelection->context();
590 if(!aContext.get()) {
591 theError = "Error: Empty selection context.";
594 ResultConstructionPtr aResultConstruction =
595 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
596 if(aResultConstruction.get()) {
597 theError = "Error: Result construction not allowed for selection.";
600 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
601 GeomShapePtr aContextShape = aContext->shape();
603 aShape = aContextShape;
606 theError = "Error: Empty shape.";
609 if(!aShape->isEqual(aContextShape)) {
610 theError = "Error: Local selection not allowed.";
614 int aShapeType = aShape->shapeType();
615 if(anOperationType == 1) {
616 // Fuse operation. Allow to select edges, faces and solids.
617 if(aShapeType != GeomAPI_Shape::EDGE &&
618 aShapeType != GeomAPI_Shape::FACE &&
619 aShapeType != GeomAPI_Shape::SOLID &&
620 aShapeType != GeomAPI_Shape::COMPSOLID &&
621 aShapeType != GeomAPI_Shape::COMPOUND) {
622 theError = "Error: Selected shape has the wrong type.";
626 if(aShapeType != GeomAPI_Shape::SOLID &&
627 aShapeType != GeomAPI_Shape::COMPSOLID &&
628 aShapeType != GeomAPI_Shape::COMPOUND) {
629 theError = "Error: Selected shape has the wrong type.";
638 //==================================================================================================
639 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
640 const std::list<std::string>& theArguments,
641 Events_InfoMessage& theError) const
643 AttributeSelectionListPtr anAttrSelectionList =
644 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
645 if(!anAttrSelectionList.get()) {
646 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
650 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
651 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
653 //GeomValidators_BodyShapes aBodyValidator;
654 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
658 GeomValidators_FeatureKind aFeatureKindValidator;
659 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
663 ResultPtr aContext = aSelectAttr->context();
664 ResultConstructionPtr aResultConstruction =
665 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
666 if(aResultConstruction.get()) {
667 theError = "Error: Only body shapes and construction planes are allowed for selection.";
671 ResultCompSolidPtr aResultCompsolid =
672 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
673 if(aResultCompsolid.get()) {
677 theError = "Error: Only body shapes and construction planes are allowed for selection.";
685 //==================================================================================================
686 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
687 const std::list<std::string>& theArguments,
688 Events_InfoMessage& theError) const
690 AttributeSelectionListPtr aSubShapesAttrList =
691 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
692 if(!aSubShapesAttrList.get()) {
694 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
698 static const std::string aBaseShapeID = "base_shape";
699 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
700 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
702 if(!aShapeAttrSelection.get()) {
703 theError = "Error: Could not get \"%1\" attribute.";
704 theError.arg(aBaseShapeID);
708 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
709 ResultPtr aContext = aShapeAttrSelection->context();
710 if(!aContext.get()) {
711 theError = "Error: Empty context.";
714 if(!aBaseShape.get()) {
715 aBaseShape = aContext->shape();
717 if(!aBaseShape.get()) {
718 theError = "Error: Empty base shape.";
722 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
723 bool isSameFound = false;
724 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
725 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
726 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
727 if(anIt.current()->isEqual(aShapeToAdd)) {
733 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
741 //==================================================================================================
742 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
743 const std::shared_ptr<ModelAPI_Feature>& theFeature,
744 const std::list<std::string>& theArguments,
745 Events_InfoMessage& theError) const
747 static const std::string aBaseShapeID = "base_shape";
748 static const std::string aSubShapesID = "subshapes";
750 if(theFeature->getKind() != "Remove_SubShapes") {
751 theError = "Error: Feature \"%1\" does not supported by this validator.";
752 theError.arg(theFeature->getKind());
756 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
757 if(!aShapeAttrSelection.get()) {
758 theError = "Error: Could not get \"%1\" attribute.";
759 theError.arg(aBaseShapeID);
763 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
764 if(!aSubShapesAttrList.get()) {
765 theError = "Error: Could not get \"%1\" attribute.";
766 theError.arg(aSubShapesID);
771 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
772 if(!aBaseShape.get()) {
773 theError = "Error: Base shape is empty.";
776 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
778 // Copy sub-shapes from list to new shape.
779 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
780 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
781 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
782 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
786 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
787 theError = "Error: Resulting shape is not valid.";
794 //==================================================================================================
795 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
796 std::string theAttribute)
801 //==================================================================================================
802 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
803 const std::list<std::string>& theArguments,
804 Events_InfoMessage& theError) const
806 AttributeSelectionListPtr aBaseObjectsAttrList =
807 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
808 if(!aBaseObjectsAttrList.get()) {
809 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
810 theError.arg(FeaturesPlugin_Union::ID());
814 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
815 bool isSameFound = false;
816 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
817 ResultCompSolidPtr aResult =
818 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
822 if(aResult->numberOfSubs() > 0) {
823 theError = "Error: Whole compsolids not allowed for selection.";
831 //==================================================================================================
832 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
833 const std::shared_ptr<ModelAPI_Feature>& theFeature,
834 const std::list<std::string>& theArguments,
835 Events_InfoMessage& theError) const
837 // Check feature kind.
838 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
839 theError = "Error: This validator supports only \"%1\" feature.";
840 theError.arg(FeaturesPlugin_Union::ID());
844 // Get base objects attribute list.
845 AttributeSelectionListPtr aBaseObejctsAttrList =
846 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
847 if(!aBaseObejctsAttrList.get()) {
848 theError = "Error: Could not get \"%1\" attribute.";
849 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
854 ListOfShape aBaseShapesList;
855 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
856 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
857 GeomShapePtr aShape = anAttrSelectionInList->value();
858 aBaseShapesList.push_back(aShape);
861 // Make componud and find connected.
862 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
863 ListOfShape aCombined, aFree;
864 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
866 if(aFree.size() > 0 || aCombined.size() > 1) {
867 theError = "Error: Not all shapes have shared topology.";
874 //==================================================================================================
875 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
876 std::string theAttribute)
881 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
882 const std::list<std::string>& theArguments,
883 Events_InfoMessage& theError) const
885 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
886 theError = "Error: The attribute with the %1 type is not processed";
887 theError.arg(theAttribute->attributeType());
891 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
893 ObjectPtr aRefObject = aRefAttribute->value();
894 if (!aRefObject.get()) {
895 theError = "Error: Empty feature.";
899 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
900 if (!aRefFeature.get()) {
901 theError = "Error: Empty feature.";
904 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
905 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
907 size_t aConcealedResults = aResults.size();
908 if (!aConcealedResults && !theArguments.empty()) {
909 // find if these results are touched by the feature in another attribute
910 std::list<std::string>::const_iterator anIt = theArguments.begin();
911 std::string aRecoveredList = *anIt;
912 if (!aRecoveredList.empty()) {
913 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
914 theAttribute->owner()->data()->reflist(aRecoveredList);
915 if (aParameterList.get())
916 aConcealedResults = aParameterList->size();
920 if (aConcealedResults == 0)
921 theError = "Error: No concealed results.";
923 return theError.empty();