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 // For possibility to select whole sketch from ObjectBrowser when
188 // Extrusion already has sub-element of this sketch, the next check
190 // Whole sketch selected.
191 /*if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
192 aSelectedSketchesFromObjects.cend()) {
193 theError = "Error: Object from this sketch is already selected. "
194 "Sketch is not allowed for selection.";
198 aSelectedSketches.insert(aResultConstruction);
200 // Object from sketch selected.
201 if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {
202 theError = "Error: Whole sketch with this object is already selected. "
203 "Don't allow to select this object.";
207 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
208 GeomShapePtr aWire = anExp.current();
209 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
210 theError = "Error: Wire with wrong orientation selected.";
214 if(aSelectedWiresFromObjects.isBound(aWire)) {
216 "Error: Objects with such wire already selected. Don't allow to select this object.";
220 aSelectedWiresFromObjects.bind(aWire, aWire);
221 aSelectedSketchesFromObjects.insert(aResultConstruction);
230 //==================================================================================================
231 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
232 const std::list<std::string>& theArguments,
233 Events_InfoMessage& theError) const
235 if(!theAttribute.get()) {
236 theError = "Error: Empty attribute.";
240 std::string anAttributeType = theAttribute->attributeType();
241 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
242 AttributeSelectionListPtr aListAttr =
243 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
244 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
245 // If at least one attribute is invalid, the result is false.
246 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
250 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
252 AttributeSelectionPtr anAttr =
253 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
254 ResultPtr aContext = anAttr->context();
255 if(!aContext.get()) {
256 theError = "Error: Attribute have empty context.";
260 GeomShapePtr aShape = anAttr->value();
261 GeomShapePtr aContextShape = aContext->shape();
263 aShape = aContextShape;
266 theError = "Error: Empty shape selected";
270 ResultConstructionPtr aConstruction =
271 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
272 if(aConstruction.get()) {
273 // Construciotn selected. Check that is is not infinite.
274 if(aConstruction->isInfinite()) {
275 theError = "Error: Infinite constructions is not allowed as base.";
279 if(aShape->isEqual(aContextShape)) {
280 // Whole construction selected. Check that it have faces.
281 if(aConstruction->facesNum() > 0) {
285 // Shape on construction selected. Check that it is a face or wire.
286 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
287 aShape->shapeType() == GeomAPI_Shape::FACE) {
295 if(!aShape->isEqual(aContextShape)) {
296 // Local selection on body does not allowed.
298 "Error: Selected shape is in the local selection. Only global selection is allowed.";
302 // Check that object is a shape with allowed type.
303 GeomValidators_ShapeType aShapeTypeValidator;
304 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
305 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
306 "wires on sketch, whole sketch(if it has at least one face), "
307 "and whole objects with shape types: %1";
308 std::string anArgumentString;
309 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
310 if (!anArgumentString.empty())
311 anArgumentString += ", ";
312 anArgumentString += *anIt;
314 theError.arg(anArgumentString);
319 theError = "Error: Attribute \"%1\" does not supported by this validator.";
320 theError.arg(anAttributeType);
327 //==================================================================================================
328 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
329 const std::list<std::string>& theArguments,
330 Events_InfoMessage& theError) const
332 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
333 theError = "Error: The attribute with the %1 type is not processed";
334 theError.arg(theAttribute->attributeType());
337 if (theArguments.size() != 2) {
338 theError = "Error: Wrong parameters in XML definition for %1 type";
339 theError.arg(theAttribute->attributeType());
342 // first argument is for the base attribute, second - for skipping feature kind
343 std::list<std::string>::const_iterator anIt = theArguments.begin();
344 std::string aBaseAttributeId = *anIt;
345 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
346 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
347 if (!aBaseAttribute.get()) {
348 theError = "Wrong parameters in XML definition for %1 type";
349 theError.arg(theAttribute->attributeType());
352 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
353 // this validator is not necessary anymore
357 std::string aFeatureAttributeKind = *anIt;
358 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
359 // check whether the selection is on the sketch
360 std::list<std::string> anArguments;
361 anArguments.push_back(aFeatureAttributeKind);
363 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
364 bool aPlanarFace = false;
365 // check if selection has Face selected
366 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
368 anArguments.push_back("face");
369 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
371 bool aValid = !aFeatureKind && aPlanarFace;
375 //==================================================================================================
376 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
377 const std::shared_ptr<ModelAPI_Feature>& theFeature,
378 const std::list<std::string>& theArguments,
379 Events_InfoMessage& theError) const
381 if(theArguments.size() != 2) {
382 theError = "Error: Validator should be used with 2 parameters for extrusion.";
386 std::list<std::string>::const_iterator
387 anArgsIt = theArguments.begin(), aLast = theArguments.end();
389 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
392 GeomShapePtr aDirShape;
393 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
395 aDirShape = aSelAttr->value();
396 if(!aDirShape.get()) {
397 ResultPtr aContext = aSelAttr->context();
399 aDirShape = aContext->shape();
404 if(!aDirShape.get()) {
405 // Check that dir can be empty.
406 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
407 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
408 "can not be used with default value. Select direction for extrusion.";
409 theError.arg(*anArgsIt);
416 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
418 // If faces selected check that direction not parallel with them.
419 AttributeSelectionListPtr aListAttr =
420 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
421 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
422 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
423 GeomShapePtr aShapeInList = anAttr->value();
424 if(!aShapeInList.get()) {
425 aShapeInList = anAttr->context()->shape();
427 bool isParallel = true;
428 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
429 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
430 for(GeomAPI_ShapeExplorer
431 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
432 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
433 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
438 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
439 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
440 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
441 if(aPlanarEdges.get()) {
442 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
443 if(aDirEdge->isLine()) {
444 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
445 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
457 "Error: Direction is parallel to one of the selected face or face on selected shell.";
465 //==================================================================================================
466 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
467 std::string theAttribute)
472 //==================================================================================================
473 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
474 Events_InfoMessage& theError) const
476 if(!theAttribute.get()) {
480 std::string anAttributeType = theAttribute->attributeType();
481 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
482 AttributeSelectionListPtr aListAttr =
483 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
484 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
485 // If at least one attribute is invalid, the result is false.
486 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
490 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
492 AttributeSelectionPtr anAttr =
493 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
494 ResultPtr aContext = anAttr->context();
495 if(!aContext.get()) {
499 GeomShapePtr aShape = anAttr->value();
500 GeomShapePtr aContextShape = aContext->shape();
502 aShape = aContextShape;
508 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
509 aShape->shapeType() == GeomAPI_Shape::EDGE ||
510 !aShape->isPlanar()) {
520 //==================================================================================================
521 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
522 const std::list<std::string>& theArguments,
523 Events_InfoMessage& theError) const
525 AttributeSelectionListPtr anAttrSelectionList =
526 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
527 if(!anAttrSelectionList.get()) {
529 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
532 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
533 int anOperationType = aFeature->integer("bool_type")->value();
535 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
536 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
537 if(!anAttrSelection.get()) {
538 theError = "Error: Empty attribute selection.";
541 ResultPtr aContext = anAttrSelection->context();
542 if(!aContext.get()) {
543 theError = "Error: Empty selection context.";
546 ResultConstructionPtr aResultConstruction =
547 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
548 if(aResultConstruction.get()) {
549 theError = "Error: Result construction not allowed for selection.";
552 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
553 GeomShapePtr aContextShape = aContext->shape();
555 aShape = aContextShape;
558 theError = "Error: Empty shape.";
561 if(!aShape->isEqual(aContextShape)) {
562 theError = "Error: Local selection not allowed.";
566 int aShapeType = aShape->shapeType();
567 if(anOperationType == 1) {
568 // Fuse operation. Allow to select edges, faces and solids.
569 if(aShapeType != GeomAPI_Shape::EDGE &&
570 aShapeType != GeomAPI_Shape::FACE &&
571 aShapeType != GeomAPI_Shape::SOLID &&
572 aShapeType != GeomAPI_Shape::COMPSOLID &&
573 aShapeType != GeomAPI_Shape::COMPOUND) {
574 theError = "Error: Selected shape has the wrong type.";
578 if(aShapeType != GeomAPI_Shape::SOLID &&
579 aShapeType != GeomAPI_Shape::COMPSOLID &&
580 aShapeType != GeomAPI_Shape::COMPOUND) {
581 theError = "Error: Selected shape has the wrong type.";
590 //==================================================================================================
591 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
592 const std::list<std::string>& theArguments,
593 Events_InfoMessage& theError) const
595 AttributeSelectionListPtr anAttrSelectionList =
596 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
597 if(!anAttrSelectionList.get()) {
598 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
602 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
603 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
605 //GeomValidators_BodyShapes aBodyValidator;
606 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
610 GeomValidators_FeatureKind aFeatureKindValidator;
611 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
615 ResultPtr aContext = aSelectAttr->context();
616 ResultConstructionPtr aResultConstruction =
617 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
618 if(aResultConstruction.get()) {
619 theError = "Error: Only body shapes and construction planes are allowed for selection.";
623 ResultCompSolidPtr aResultCompsolid =
624 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
625 if(aResultCompsolid.get()) {
629 theError = "Error: Only body shapes and construction planes are allowed for selection.";
637 //==================================================================================================
638 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
639 const std::list<std::string>& theArguments,
640 Events_InfoMessage& theError) const
642 AttributeSelectionListPtr aSubShapesAttrList =
643 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
644 if(!aSubShapesAttrList.get()) {
646 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
650 static const std::string aBaseShapeID = "base_shape";
651 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
652 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
654 if(!aShapeAttrSelection.get()) {
655 theError = "Error: Could not get \"%1\" attribute.";
656 theError.arg(aBaseShapeID);
660 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
661 ResultPtr aContext = aShapeAttrSelection->context();
662 if(!aContext.get()) {
663 theError = "Error: Empty context.";
666 if(!aBaseShape.get()) {
667 aBaseShape = aContext->shape();
669 if(!aBaseShape.get()) {
670 theError = "Error: Empty base shape.";
674 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
675 bool isSameFound = false;
676 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
677 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
678 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
679 if(anIt.current()->isEqual(aShapeToAdd)) {
685 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
693 //==================================================================================================
694 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
695 const std::shared_ptr<ModelAPI_Feature>& theFeature,
696 const std::list<std::string>& theArguments,
697 Events_InfoMessage& theError) const
699 static const std::string aBaseShapeID = "base_shape";
700 static const std::string aSubShapesID = "subshapes";
702 if(theFeature->getKind() != "Remove_SubShapes") {
703 theError = "Error: Feature \"%1\" does not supported by this validator.";
704 theError.arg(theFeature->getKind());
708 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
709 if(!aShapeAttrSelection.get()) {
710 theError = "Error: Could not get \"%1\" attribute.";
711 theError.arg(aBaseShapeID);
715 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
716 if(!aSubShapesAttrList.get()) {
717 theError = "Error: Could not get \"%1\" attribute.";
718 theError.arg(aSubShapesID);
723 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
724 if(!aBaseShape.get()) {
725 theError = "Error: Base shape is empty.";
728 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
730 // Copy sub-shapes from list to new shape.
731 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
732 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
733 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
734 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
738 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
739 theError = "Error: Resulting shape is not valid.";
746 //==================================================================================================
747 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
748 std::string theAttribute)
753 //==================================================================================================
754 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
755 const std::list<std::string>& theArguments,
756 Events_InfoMessage& theError) const
758 AttributeSelectionListPtr aBaseObjectsAttrList =
759 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
760 if(!aBaseObjectsAttrList.get()) {
761 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
762 theError.arg(FeaturesPlugin_Union::ID());
766 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
767 bool isSameFound = false;
768 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
769 ResultCompSolidPtr aResult =
770 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
774 if(aResult->numberOfSubs() > 0) {
775 theError = "Error: Whole compsolids not allowed for selection.";
783 //==================================================================================================
784 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
785 const std::shared_ptr<ModelAPI_Feature>& theFeature,
786 const std::list<std::string>& theArguments,
787 Events_InfoMessage& theError) const
789 // Check feature kind.
790 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
791 theError = "Error: This validator supports only \"%1\" feature.";
792 theError.arg(FeaturesPlugin_Union::ID());
796 // Get base objects attribute list.
797 AttributeSelectionListPtr aBaseObejctsAttrList =
798 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
799 if(!aBaseObejctsAttrList.get()) {
800 theError = "Error: Could not get \"%1\" attribute.";
801 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
806 ListOfShape aBaseShapesList;
807 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
808 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
809 GeomShapePtr aShape = anAttrSelectionInList->value();
810 aBaseShapesList.push_back(aShape);
813 // Make componud and find connected.
814 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
815 ListOfShape aCombined, aFree;
816 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
818 if(aFree.size() > 0 || aCombined.size() > 1) {
819 theError = "Error: Not all shapes have shared topology.";
826 //==================================================================================================
827 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
828 std::string theAttribute)
833 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
834 const std::list<std::string>& theArguments,
835 Events_InfoMessage& theError) const
837 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
838 theError = "Error: The attribute with the %1 type is not processed";
839 theError.arg(theAttribute->attributeType());
843 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
845 ObjectPtr aRefObject = aRefAttribute->value();
846 if (!aRefObject.get()) {
847 theError = "Error: Empty feature.";
851 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
852 if (!aRefFeature.get()) {
853 theError = "Error: Empty feature.";
856 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
857 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
859 size_t aConcealedResults = aResults.size();
860 if (!aConcealedResults && !theArguments.empty()) {
861 // find if these results are touched by the feature in another attribute
862 std::list<std::string>::const_iterator anIt = theArguments.begin();
863 std::string aRecoveredList = *anIt;
864 if (!aRecoveredList.empty()) {
865 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
866 theAttribute->owner()->data()->reflist(aRecoveredList);
867 if (aParameterList.get())
868 aConcealedResults = aParameterList->size();
872 if (aConcealedResults == 0)
873 theError = "Error: No concealed results.";
875 return theError.empty();