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_Feature.h>
19 #include <ModelAPI_ResultCompSolid.h>
20 #include <ModelAPI_ResultConstruction.h>
22 #include <GeomValidators_BodyShapes.h>
23 #include <GeomValidators_FeatureKind.h>
24 #include <GeomValidators_ShapeType.h>
26 #include <GeomAPI_DataMapOfShapeShape.h>
27 #include <GeomAPI_Lin.h>
28 #include <GeomAPI_PlanarEdges.h>
29 #include <GeomAPI_ShapeExplorer.h>
30 #include <GeomAPI_ShapeIterator.h>
32 #include <GeomAlgoAPI_CompoundBuilder.h>
33 #include <GeomAlgoAPI_ShapeBuilder.h>
34 #include <GeomAlgoAPI_ShapeTools.h>
35 #include <GeomAlgoAPI_WireBuilder.h>
37 #define _USE_MATH_DEFINES
40 //==================================================================================================
41 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
42 const std::list<std::string>& theArguments,
43 Events_InfoMessage& theError) const
45 AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
46 if(!aPathAttrSelection.get()) {
47 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
51 GeomShapePtr aPathShape = aPathAttrSelection->value();
52 ResultPtr aContext = aPathAttrSelection->context();
54 theError = "Error: Empty context.";
57 GeomShapePtr aContextShape = aContext->shape();
58 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE && !aPathShape->isEqual(aContextShape)) {
59 theError = "Error: Local selection of wires not allowed.";
66 //==================================================================================================
67 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
68 const std::list<std::string>& theArguments,
69 Events_InfoMessage& theError) const
71 static const std::string aCreationMethodID = "creation_method";
72 static const std::string aBaseObjectsID = "base_objects";
73 static const std::string aLocationsID = "locations_objects";
75 if(theFeature->getKind() != "Pipe") {
76 theError = "Error: Feature \"%1\" does not supported by this validator.";
77 theError.arg(theFeature->getKind());
81 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
82 if(!aCreationMethodAttr.get()) {
83 theError = "Error: Could not get \"%1\" attribute.";
84 theError.arg(aCreationMethodID);
88 if(aCreationMethodAttr->value() != "locations") {
92 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
93 if(!aBaseObjectsSelectionList.get()) {
94 theError = "Error: Could not get \"%1\" attribute.";
95 theError.arg(aBaseObjectsID);
99 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
100 if(!aLocationsSelectionList.get()) {
101 theError = "Error: Could not get \"%1\" attribute.";
102 theError.arg(aBaseObjectsID);
106 if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
107 theError = "Error: Number of locations should be the same as base objects.";
114 //==================================================================================================
115 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
120 //==================================================================================================
121 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
122 const std::list<std::string>& theArguments,
123 Events_InfoMessage& theError) const
125 if(theArguments.empty()) {
126 theError = "Error: Validator parameters is empty.";
130 // Checking attribute.
131 if(!isValidAttribute(theAttribute, theArguments, theError)) {
132 if(theError.empty()) {
133 theError = "Error: Attribute contains unacceptable shape.";
138 std::set<ResultConstructionPtr> aSelectedSketches;
139 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
140 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
141 std::string anAttributeType = theAttribute->attributeType();
142 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
143 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
144 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
145 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
146 ResultPtr aContext = aSelectionAttr->context();
147 if(!aContext.get()) {
148 theError = "Error: Empty context.";
152 ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
153 if(!aResultConstruction.get()) {
154 // It is not a result construction. If shape is compound check that it contains only faces and edges.
155 GeomShapePtr aShape = aSelectionAttr->value();
157 aShape = aContext->shape();
160 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
161 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
162 GeomShapePtr aSubShape = anIt.current();
163 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
164 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
165 theError = "Error: Compound should contain only faces and edges.";
174 GeomShapePtr aShape = aSelectionAttr->value();
175 GeomShapePtr aContextShape = aResultConstruction->shape();
177 // Whole sketch selected.
178 if(aSelectedSketchesFromObjects.find(aResultConstruction) != aSelectedSketchesFromObjects.cend()) {
179 theError = "Error: Object from this sketch is already selected. Sketch is not allowed for selection.";
183 aSelectedSketches.insert(aResultConstruction);
185 // Object from sketch selected.
186 if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {
187 theError = "Error: Whole sketch with this object is already selected. Don't allow to select this object.";
191 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
192 GeomShapePtr aWire = anExp.current();
193 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
194 theError = "Error: Wire with wrong orientation selected.";
198 if(aSelectedWiresFromObjects.isBound(aWire)) {
199 theError = "Error: Objects with such wire already selected. Don't allow to select this object.";
203 aSelectedWiresFromObjects.bind(aWire, aWire);
204 aSelectedSketchesFromObjects.insert(aResultConstruction);
213 //==================================================================================================
214 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
215 const std::list<std::string>& theArguments,
216 Events_InfoMessage& theError) const
218 if(!theAttribute.get()) {
219 theError = "Error: Empty attribute.";
223 std::string anAttributeType = theAttribute->attributeType();
224 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
225 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
226 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
227 // If at least one attribute is invalid, the result is false.
228 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
232 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
234 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
235 ResultPtr aContext = anAttr->context();
236 if(!aContext.get()) {
237 theError = "Error: Attribute have empty context.";
241 GeomShapePtr aShape = anAttr->value();
242 GeomShapePtr aContextShape = aContext->shape();
244 aShape = aContextShape;
247 theError = "Error: Empty shape selected";
251 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
252 if(aConstruction.get()) {
253 // Construciotn selected. Check that is is not infinite.
254 if(aConstruction->isInfinite()) {
255 theError = "Error: Infinite constructions is not allowed as base.";
259 if(aShape->isEqual(aContextShape)) {
260 // Whole construction selected. Check that it have faces.
261 if(aConstruction->facesNum() > 0) {
265 // Shape on construction selected. Check that it is a face or wire.
266 if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
274 if(!aShape->isEqual(aContextShape)) {
275 // Local selection on body does not allowed.
276 theError = "Error: Selected shape is in the local selection. Only global selection is allowed.";
280 // Check that object is a shape with allowed type.
281 GeomValidators_ShapeType aShapeTypeValidator;
282 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
283 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, whole sketch(if it has at least one face), and whole objects with shape types: %1";
284 std::string anArgumentString;
285 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
286 if (!anArgumentString.empty())
287 anArgumentString += ", ";
288 anArgumentString += *anIt;
290 theError.arg(anArgumentString);
295 theError = "Error: Attribute \"%1\" does not supported by this validator.";
296 theError.arg(anAttributeType);
303 //==================================================================================================
304 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
305 const std::list<std::string>& theArguments,
306 Events_InfoMessage& theError) const
308 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
309 theError = "Error: The attribute with the %1 type is not processed";
310 theError.arg(theAttribute->attributeType());
313 if (theArguments.size() != 2) {
314 theError = "Error: Wrong parameters in XML definition for %1 type";
315 theError.arg(theAttribute->attributeType());
318 // first argument is for the base attribute, second - for skipping feature kind
319 std::list<std::string>::const_iterator anIt = theArguments.begin();
320 std::string aBaseAttributeId = *anIt;
321 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
322 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
323 if (!aBaseAttribute.get()) {
324 theError = "Wrong parameters in XML definition for %1 type";
325 theError.arg(theAttribute->attributeType());
328 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
329 // this validator is not necessary anymore
333 std::string aFeatureAttributeKind = *anIt;
334 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
335 // check whether the selection is on the sketch
336 std::list<std::string> anArguments;
337 anArguments.push_back(aFeatureAttributeKind);
339 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
340 bool aPlanarFace = false;
341 // check if selection has Face selected
342 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
344 anArguments.push_back("face");
345 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
347 bool aValid = !aFeatureKind && aPlanarFace;
351 //==================================================================================================
352 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
353 const std::list<std::string>& theArguments,
354 Events_InfoMessage& theError) const
356 if(theArguments.size() != 2) {
357 theError = "Error: Validator should be used with 2 parameters for extrusion.";
361 std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
363 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
366 GeomShapePtr aDirShape;
367 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
369 aDirShape = aSelAttr->value();
370 if(!aDirShape.get()) {
371 ResultPtr aContext = aSelAttr->context();
373 aDirShape = aContext->shape();
378 if(!aDirShape.get()) {
379 // Check that dir can be empty.
380 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
381 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" can not be used with default value. Select direction for extrusion.";
382 theError.arg(*anArgsIt);
389 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
391 // If faces selected check that direction not parallel with them.
392 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
393 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
394 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
395 GeomShapePtr aShapeInList = anAttr->value();
396 if(!aShapeInList.get()) {
397 aShapeInList = anAttr->context()->shape();
399 bool isParallel = true;
400 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE || aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
401 for(GeomAPI_ShapeExplorer anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
402 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
403 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
408 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
409 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
410 if(aPlanarEdges.get()) {
411 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
412 if(aDirEdge->isLine()) {
413 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
414 isParallel = abs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
425 theError = "Error: Direction is parallel to one of the selected face or face on selected shell.";
433 //==================================================================================================
434 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature, std::string theAttribute)
439 //==================================================================================================
440 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
441 Events_InfoMessage& theError) const
443 if(!theAttribute.get()) {
447 std::string anAttributeType = theAttribute->attributeType();
448 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
449 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
450 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
451 // If at least one attribute is invalid, the result is false.
452 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
456 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
458 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
459 ResultPtr aContext = anAttr->context();
460 if(!aContext.get()) {
464 GeomShapePtr aShape = anAttr->value();
465 GeomShapePtr aContextShape = aContext->shape();
467 aShape = aContextShape;
473 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
474 aShape->shapeType() == GeomAPI_Shape::EDGE ||
475 !aShape->isPlanar()) {
485 //==================================================================================================
486 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
487 const std::list<std::string>& theArguments,
488 Events_InfoMessage& theError) const
490 AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
491 if(!anAttrSelectionList.get()) {
492 theError = "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
495 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
496 int anOperationType = aFeature->integer("bool_type")->value();
498 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
499 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
500 if(!anAttrSelection.get()) {
501 theError = "Error: Empty attribute selection.";
504 ResultPtr aContext = anAttrSelection->context();
505 if(!aContext.get()) {
506 theError = "Error: Empty selection context.";
509 ResultConstructionPtr aResultConstruction =
510 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
511 if(aResultConstruction.get()) {
512 theError = "Error: Result construction not allowed for selection.";
515 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
516 GeomShapePtr aContextShape = aContext->shape();
518 aShape = aContextShape;
521 theError = "Error: Empty shape.";
524 if(!aShape->isEqual(aContextShape)) {
525 theError = "Error: Local selection not allowed.";
529 int aShapeType = aShape->shapeType();
530 if(anOperationType == 1) {
531 // Fuse operation. Allow to select edges, faces and solids.
532 if(aShapeType != GeomAPI_Shape::EDGE &&
533 aShapeType != GeomAPI_Shape::FACE &&
534 aShapeType != GeomAPI_Shape::SOLID &&
535 aShapeType != GeomAPI_Shape::COMPSOLID &&
536 aShapeType != GeomAPI_Shape::COMPOUND) {
537 theError = "Error: Selected shape has the wrong type.";
541 if(aShapeType != GeomAPI_Shape::SOLID &&
542 aShapeType != GeomAPI_Shape::COMPSOLID &&
543 aShapeType != GeomAPI_Shape::COMPOUND) {
544 theError = "Error: Selected shape has the wrong type.";
553 //==================================================================================================
554 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
555 const std::list<std::string>& theArguments,
556 Events_InfoMessage& theError) const
558 AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
559 if(!anAttrSelectionList.get()) {
560 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
564 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
565 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
567 //GeomValidators_BodyShapes aBodyValidator;
568 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
572 GeomValidators_FeatureKind aFeatureKindValidator;
573 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
577 ResultPtr aContext = aSelectAttr->context();
578 ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
579 if(aResultConstruction.get()) {
580 theError = "Error: Only body shapes and construction planes are allowed for selection.";
584 ResultCompSolidPtr aResultCompsolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
585 if(aResultCompsolid.get()) {
589 theError = "Error: Only body shapes and construction planes are allowed for selection.";
597 //==================================================================================================
598 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
599 const std::list<std::string>& theArguments,
600 Events_InfoMessage& theError) const
602 AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
603 if(!aSubShapesAttrList.get()) {
604 theError = "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
608 static const std::string aBaseShapeID = "base_shape";
609 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
610 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
612 if(!aShapeAttrSelection.get()) {
613 theError = "Error: Could not get \"%1\" attribute.";
614 theError.arg(aBaseShapeID);
618 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
619 ResultPtr aContext = aShapeAttrSelection->context();
620 if(!aContext.get()) {
621 theError = "Error: Empty context.";
624 if(!aBaseShape.get()) {
625 aBaseShape = aContext->shape();
627 if(!aBaseShape.get()) {
628 theError = "Error: Empty base shape.";
632 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
633 bool isSameFound = false;
634 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
635 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
636 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
637 if(anIt.current()->isEqual(aShapeToAdd)) {
643 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
651 //==================================================================================================
652 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
653 const std::list<std::string>& theArguments,
654 Events_InfoMessage& theError) const
656 static const std::string aBaseShapeID = "base_shape";
657 static const std::string aSubShapesID = "subshapes";
659 if(theFeature->getKind() != "Remove_SubShapes") {
660 theError = "Error: Feature \"%1\" does not supported by this validator.";
661 theError.arg(theFeature->getKind());
665 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
666 if(!aShapeAttrSelection.get()) {
667 theError = "Error: Could not get \"%1\" attribute.";
668 theError.arg(aBaseShapeID);
672 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
673 if(!aSubShapesAttrList.get()) {
674 theError = "Error: Could not get \"%1\" attribute.";
675 theError.arg(aSubShapesID);
680 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
681 if(!aBaseShape.get()) {
682 theError = "Error: Base shape is empty.";
685 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
687 // Copy sub-shapes from list to new shape.
688 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
689 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
690 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
691 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
695 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
696 theError = "Error: Resulting shape is not valid.";
703 //==================================================================================================
704 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
705 std::string theAttribute)
710 //==================================================================================================
711 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
712 const std::list<std::string>& theArguments,
713 Events_InfoMessage& theError) const
715 AttributeSelectionListPtr aBaseObjectsAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
716 if(!aBaseObjectsAttrList.get()) {
717 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
718 theError.arg(FeaturesPlugin_Union::ID());
722 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
723 bool isSameFound = false;
724 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
725 ResultCompSolidPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
729 if(aResult->numberOfSubs() > 0) {
730 theError = "Error: Whole compsolids not allowed for selection.";
738 //==================================================================================================
739 bool FeaturesPlugin_ValidatorUnionArguments::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
740 const std::list<std::string>& theArguments,
741 Events_InfoMessage& theError) const
743 // Check feature kind.
744 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
745 theError = "Error: This validator supports only \"%1\" feature.";
746 theError.arg(FeaturesPlugin_Union::ID());
750 // Get base objects attribute list.
751 AttributeSelectionListPtr aBaseObejctsAttrList = theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
752 if(!aBaseObejctsAttrList.get()) {
753 theError = "Error: Could not get \"%1\" attribute.";
754 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
759 ListOfShape aBaseShapesList;
760 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
761 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
762 GeomShapePtr aShape = anAttrSelectionInList->value();
763 aBaseShapesList.push_back(aShape);
766 // Make componud and find connected.
767 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
768 ListOfShape aCombined, aFree;
769 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
771 if(aFree.size() > 0 || aCombined.size() > 1) {
772 theError = "Error: Not all shapes have shared topology.";
779 //==================================================================================================
780 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
781 std::string theAttribute)