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 <ModelAPI_Attribute.h>
12 #include <ModelAPI_AttributeInteger.h>
13 #include <ModelAPI_AttributeSelectionList.h>
14 #include <ModelAPI_AttributeString.h>
15 #include <ModelAPI_AttributeReference.h>
16 #include <ModelAPI_Feature.h>
17 #include <ModelAPI_ResultCompSolid.h>
18 #include <ModelAPI_ResultConstruction.h>
20 #include <GeomValidators_BodyShapes.h>
21 #include <GeomValidators_FeatureKind.h>
22 #include <GeomValidators_ShapeType.h>
24 #include <GeomAPI_DataMapOfShapeShape.h>
25 #include <GeomAPI_PlanarEdges.h>
26 #include <GeomAPI_ShapeExplorer.h>
27 #include <GeomAPI_ShapeIterator.h>
29 #include <GeomAlgoAPI_CompoundBuilder.h>
30 #include <GeomAlgoAPI_ShapeBuilder.h>
31 #include <GeomAlgoAPI_ShapeTools.h>
32 #include <GeomAlgoAPI_WireBuilder.h>
34 //==================================================================================================
35 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
36 const std::list<std::string>& theArguments,
37 std::string& theError) const
39 AttributeSelectionPtr aPathAttrSelection = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
40 if(!aPathAttrSelection.get()) {
41 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
45 GeomShapePtr aPathShape = aPathAttrSelection->value();
46 ResultPtr aContext = aPathAttrSelection->context();
48 theError = "Error: Empty context.";
51 GeomShapePtr aContextShape = aContext->shape();
52 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE && !aPathShape->isEqual(aContextShape)) {
53 theError = "Error: Local selection of wires not allowed.";
60 //==================================================================================================
61 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
62 const std::list<std::string>& theArguments,
63 std::string& theError) const
65 static const std::string aCreationMethodID = "creation_method";
66 static const std::string aBaseObjectsID = "base_objects";
67 static const std::string aLocationsID = "locations_objects";
69 if(theFeature->getKind() != "Pipe") {
70 theError = "Error: Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
74 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
75 if(!aCreationMethodAttr.get()) {
76 theError = "Error: Could not get \"" + aCreationMethodID + "\" attribute.";
80 if(aCreationMethodAttr->value() != "locations") {
84 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
85 if(!aBaseObjectsSelectionList.get()) {
86 theError = "Error: Could not get \"" + aBaseObjectsID + "\" attribute.";
90 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
91 if(!aLocationsSelectionList.get()) {
92 theError = "Error: Could not get \"" + aBaseObjectsID + "\" attribute.";
96 if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
97 theError = "Error: Number of locations should be the same as base objects.";
104 //==================================================================================================
105 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
110 //==================================================================================================
111 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
112 const std::list<std::string>& theArguments,
113 std::string& theError) const
115 if(theArguments.empty()) {
116 theError = "Error: Validator parameters is empty.";
120 // Checking attribute.
121 if(!isValidAttribute(theAttribute, theArguments, theError)) {
122 if(theError.empty()) {
123 theError = "Error: Attribute contains unacceptable shape.";
128 std::set<ResultConstructionPtr> aSelectedSketches;
129 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
130 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
131 std::string anAttributeType = theAttribute->attributeType();
132 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
133 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
134 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
135 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
136 ResultPtr aContext = aSelectionAttr->context();
137 if(!aContext.get()) {
138 theError = "Error: Empty context.";
142 ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
143 if(!aResultConstruction.get()) {
144 // It is not a result construction. If shape is compound check that it contains only faces and edges.
145 GeomShapePtr aShape = aSelectionAttr->value();
147 aShape = aContext->shape();
150 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
151 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
152 GeomShapePtr aSubShape = anIt.current();
153 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
154 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
155 theError = "Error: Compound should contain only faces and edges.";
164 GeomShapePtr aShape = aSelectionAttr->value();
165 GeomShapePtr aContextShape = aResultConstruction->shape();
167 // Whole sketch selected.
168 if(aSelectedSketchesFromObjects.find(aResultConstruction) != aSelectedSketchesFromObjects.cend()) {
169 theError = "Error: Object from this sketch is already selected. Sketch is not allowed for selection.";
173 aSelectedSketches.insert(aResultConstruction);
175 // Object from sketch selected.
176 if(aSelectedSketches.find(aResultConstruction) != aSelectedSketches.cend()) {
177 theError = "Error: Whole sketch with this object is already selected. Don't allow to select this object.";
181 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
182 GeomShapePtr aWire = anExp.current();
183 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
184 theError = "Error: Wire with wrong orientation selected.";
188 if(aSelectedWiresFromObjects.isBound(aWire)) {
189 theError = "Error: Objects with such wire already selected. Don't allow to select this object.";
193 aSelectedWiresFromObjects.bind(aWire, aWire);
194 aSelectedSketchesFromObjects.insert(aResultConstruction);
203 //==================================================================================================
204 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
205 const std::list<std::string>& theArguments,
206 std::string& theError) const
208 if(!theAttribute.get()) {
209 theError = "Error: Empty attribute.";
213 std::string anAttributeType = theAttribute->attributeType();
214 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
215 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
216 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
217 // If at least one attribute is invalid, the result is false.
218 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
222 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
224 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
225 ResultPtr aContext = anAttr->context();
226 if(!aContext.get()) {
227 theError = "Error: Attribute have empty context.";
231 GeomShapePtr aShape = anAttr->value();
232 GeomShapePtr aContextShape = aContext->shape();
234 aShape = aContextShape;
237 theError = "Error: Empty shape selected";
241 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
242 if(aConstruction.get()) {
243 // Construciotn selected. Check that is is not infinite.
244 if(aConstruction->isInfinite()) {
245 theError = "Error: Infinite constructions is not allowed as base.";
249 if(aShape->isEqual(aContextShape)) {
250 // Whole construction selected. Check that it have faces.
251 if(aConstruction->facesNum() > 0) {
255 // Shape on construction selected. Check that it is a face or wire.
256 if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
264 if(!aShape->isEqual(aContextShape)) {
265 // Local selection on body does not allowed.
266 theError = "Error: Selected shape is in the local selection. Only global selection is allowed.";
270 // Check that object is a shape with allowed type.
271 GeomValidators_ShapeType aShapeTypeValidator;
272 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
273 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, "
274 "whole sketch(if it has at least one face), and whole objects with shape types: ";
275 std::list<std::string>::const_iterator anIt = theArguments.cbegin();
277 for(++anIt; anIt != theArguments.cend(); ++anIt) {
278 theError += ", " + *anIt;
284 theError = "Error: Attribute \"" + anAttributeType + "\" does not supported by this validator.";
291 //==================================================================================================
292 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
293 const std::list<std::string>& theArguments,
294 std::string& theError) const
296 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
297 theError = "Error: The attribute with the " + theAttribute->attributeType() + " type is not processed";
300 if (theArguments.size() != 2) {
301 theError = "Error: Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
304 // first argument is for the base attribute, second - for skipping feature kind
305 std::list<std::string>::const_iterator anIt = theArguments.begin();
306 std::string aBaseAttributeId = *anIt;
307 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
308 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
309 if (!aBaseAttribute.get()) {
310 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
313 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
314 // this validator is not necessary anymore
318 std::string aFeatureAttributeKind = *anIt;
319 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
320 // check whether the selection is on the sketch
321 std::list<std::string> anArguments;
322 anArguments.push_back(aFeatureAttributeKind);
324 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
325 bool aPlanarFace = false;
326 // check if selection has Face selected
327 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
329 anArguments.push_back("face");
330 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
332 bool aValid = !aFeatureKind && aPlanarFace;
336 //==================================================================================================
337 bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
338 const std::list<std::string>& theArguments,
339 std::string& theError) const
341 if(theArguments.size() != 2) {
342 theError = "Error: Validator should be used with 2 parameters for extrusion.";
346 std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
348 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
351 if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
355 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
356 if(!aSelAttr.get()) {
357 theError = "Error: Could not get selection attribute \"" + *anArgsIt + "\".";
361 GeomShapePtr aShape = aSelAttr->value();
363 ResultPtr aContext = aSelAttr->context();
364 if(!aContext.get()) {
365 theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
366 + "\" can not be used with default value. Select direction for extrusion.";
370 aShape = aContext->shape();
374 theError = "Error: Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
375 + "\" can not be used with default value. Select direction for extrusion.";
382 //==================================================================================================
383 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
388 //==================================================================================================
389 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
390 std::string& theError) const
392 if(!theAttribute.get()) {
396 std::string anAttributeType = theAttribute->attributeType();
397 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
398 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
399 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
400 // If at least one attribute is invalid, the result is false.
401 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
405 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
407 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
408 ResultPtr aContext = anAttr->context();
409 if(!aContext.get()) {
413 GeomShapePtr aShape = anAttr->value();
414 GeomShapePtr aContextShape = aContext->shape();
416 aShape = aContextShape;
422 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
423 aShape->shapeType() == GeomAPI_Shape::EDGE ||
424 !aShape->isPlanar()) {
434 //==================================================================================================
435 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
436 const std::list<std::string>& theArguments,
437 std::string& theError) const
439 AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
440 if(!anAttrSelectionList.get()) {
441 theError = "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
444 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
445 int anOperationType = aFeature->integer("bool_type")->value();
447 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
448 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
449 if(!anAttrSelection.get()) {
450 theError = "Error: Empty attribute selection.";
453 ResultPtr aContext = anAttrSelection->context();
454 if(!aContext.get()) {
455 theError = "Error: Empty selection context.";
458 ResultConstructionPtr aResultConstruction =
459 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
460 if(aResultConstruction.get()) {
461 theError = "Error: Result construction not allowed for selection.";
464 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
466 aShape = aContext->shape();
469 theError = "Error: Empty shape.";
472 int aShapeType = aShape->shapeType();
473 if(anOperationType == 1) {
474 // Fuse operation. Allow to select edges, faces and solids.
475 if(aShapeType != GeomAPI_Shape::EDGE &&
476 aShapeType != GeomAPI_Shape::FACE &&
477 aShapeType != GeomAPI_Shape::SOLID &&
478 aShapeType != GeomAPI_Shape::COMPSOLID &&
479 aShapeType != GeomAPI_Shape::COMPOUND) {
480 theError = "Error: Selected shape has the wrong type.";
484 if(aShapeType != GeomAPI_Shape::SOLID &&
485 aShapeType != GeomAPI_Shape::COMPSOLID &&
486 aShapeType != GeomAPI_Shape::COMPOUND) {
487 theError = "Error: Selected shape has the wrong type.";
496 //==================================================================================================
497 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
498 const std::list<std::string>& theArguments,
499 std::string& theError) const
501 AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
502 if(!anAttrSelectionList.get()) {
503 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
507 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
508 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
510 //GeomValidators_BodyShapes aBodyValidator;
511 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
515 GeomValidators_FeatureKind aFeatureKindValidator;
516 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
520 ResultPtr aContext = aSelectAttr->context();
521 ResultConstructionPtr aResultConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
522 if(aResultConstruction.get()) {
523 theError = "Error: Only body shapes and construction planes are allowed for selection.";
527 ResultCompSolidPtr aResultCompsolid = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
528 if(aResultCompsolid.get()) {
532 theError = "Error: Only body shapes and construction planes are allowed for selection.";
540 //==================================================================================================
541 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
542 const std::list<std::string>& theArguments,
543 std::string& theError) const
545 AttributeSelectionListPtr aSubShapesAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
546 if(!aSubShapesAttrList.get()) {
547 theError = "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
551 static const std::string aBaseShapeID = "base_shape";
552 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
553 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
555 if(!aShapeAttrSelection.get()) {
556 theError = "Error: Could not get \"" + aBaseShapeID + "\" attribute.";
560 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
561 ResultPtr aContext = aShapeAttrSelection->context();
562 if(!aContext.get()) {
563 theError = "Error: Empty context.";
566 if(!aBaseShape.get()) {
567 aBaseShape = aContext->shape();
569 if(!aBaseShape.get()) {
570 theError = "Error: Empty base shape.";
574 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
575 bool isSameFound = false;
576 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
577 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
578 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
579 if(anIt.current()->isEqual(aShapeToAdd)) {
585 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
593 //==================================================================================================
594 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
595 const std::list<std::string>& theArguments,
596 std::string& theError) const
598 static const std::string aBaseShapeID = "base_shape";
599 static const std::string aSubShapesID = "subshapes";
601 if(theFeature->getKind() != "Remove_SubShapes") {
602 theError = "Error: Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
606 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
607 if(!aShapeAttrSelection.get()) {
608 theError = "Error: Could not get \"" + aBaseShapeID + "\" attribute.";
612 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
613 if(!aSubShapesAttrList.get()) {
614 theError = "Error: Could not get \"" + aSubShapesID + "\" attribute.";
619 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
620 if(!aBaseShape.get()) {
621 theError = "Error: Base shape is empty.";
624 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
626 // Copy sub-shapes from list to new shape.
627 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
628 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
629 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
630 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
634 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
635 theError = "Error: Resulting shape is not valid.";
642 //==================================================================================================
643 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
644 std::string theAttribute)
649 //==================================================================================================
650 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
651 const std::list<std::string>& theArguments,
652 std::string& theError) const
654 AttributeSelectionListPtr aBaseObjectsAttrList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
655 if(!aBaseObjectsAttrList.get()) {
656 theError = "Error: This validator can only work with selection list in \"" + FeaturesPlugin_Union::ID() + "\" feature.";
660 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
661 bool isSameFound = false;
662 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
663 ResultCompSolidPtr aResult = std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
667 if(aResult->numberOfSubs() > 0) {
668 theError = "Error: Whole compsolids not allowed for selection.";
676 //==================================================================================================
677 bool FeaturesPlugin_ValidatorUnionArguments::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
678 const std::list<std::string>& theArguments,
679 std::string& theError) const
681 // Check feature kind.
682 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
683 theError = "Error: This validator supports only \"" + FeaturesPlugin_Union::ID() + "\" feature.";
687 // Get base objects attribute list.
688 AttributeSelectionListPtr aBaseObejctsAttrList = theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
689 if(!aBaseObejctsAttrList.get()) {
690 theError = "Error: Could not get \"" + FeaturesPlugin_Union::BASE_OBJECTS_ID() + "\" attribute.";
695 ListOfShape aBaseShapesList;
696 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
697 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
698 GeomShapePtr aShape = anAttrSelectionInList->value();
699 aBaseShapesList.push_back(aShape);
702 // Make componud and find connected.
703 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
704 ListOfShape aCombined, aFree;
705 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
707 if(aFree.size() > 0 || aCombined.size() > 1) {
708 theError = "Error: Not all shapes have shared topology.";
715 //==================================================================================================
716 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
717 std::string theAttribute)