1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Validators.h"
23 #include "FeaturesPlugin_Boolean.h"
24 #include "FeaturesPlugin_BooleanFuse.h"
25 #include "FeaturesPlugin_BooleanSmash.h"
26 #include "FeaturesPlugin_Union.h"
28 #include <Events_InfoMessage.h>
30 #include <ModelAPI_Attribute.h>
31 #include <ModelAPI_AttributeInteger.h>
32 #include <ModelAPI_AttributeSelectionList.h>
33 #include <ModelAPI_AttributeString.h>
34 #include <ModelAPI_AttributeReference.h>
35 #include <ModelAPI_AttributeRefList.h>
36 #include <ModelAPI_Feature.h>
37 #include <ModelAPI_ResultBody.h>
38 #include <ModelAPI_ResultConstruction.h>
39 #include <ModelAPI_Tools.h>
41 #include <GeomValidators_BodyShapes.h>
42 #include <GeomValidators_Face.h>
43 #include <GeomValidators_FeatureKind.h>
44 #include <GeomValidators_ShapeType.h>
46 #include <GeomAPI_DataMapOfShapeShape.h>
47 #include <GeomAPI_Lin.h>
48 #include <GeomAPI_PlanarEdges.h>
49 #include <GeomAPI_Pln.h>
50 #include <GeomAPI_ShapeExplorer.h>
51 #include <GeomAPI_ShapeIterator.h>
53 #include <GeomAlgoAPI_CompoundBuilder.h>
54 #include <GeomAlgoAPI_ShapeBuilder.h>
55 #include <GeomAlgoAPI_ShapeTools.h>
56 #include <GeomAlgoAPI_WireBuilder.h>
58 #define _USE_MATH_DEFINES
61 //==================================================================================================
62 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
63 const std::list<std::string>& theArguments,
64 Events_InfoMessage& theError) const
66 AttributeSelectionPtr aPathAttrSelection =
67 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
68 if(!aPathAttrSelection.get()) {
69 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
73 GeomShapePtr aPathShape = aPathAttrSelection->value();
74 ResultPtr aContext = aPathAttrSelection->context();
76 theError = "Error: Empty context.";
79 GeomShapePtr aContextShape = aContext->shape();
80 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
81 !aPathShape->isEqual(aContextShape)) {
82 theError = "Error: Local selection of wires not allowed.";
89 //==================================================================================================
90 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
91 const std::shared_ptr<ModelAPI_Feature>& theFeature,
92 const std::list<std::string>& theArguments,
93 Events_InfoMessage& theError) const
95 static const std::string aCreationMethodID = "creation_method";
96 static const std::string aBaseObjectsID = "base_objects";
97 static const std::string aLocationsID = "locations_objects";
99 if(theFeature->getKind() != "Pipe") {
100 theError = "Error: Feature \"%1\" does not supported by this validator.";
101 theError.arg(theFeature->getKind());
105 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
106 if(!aCreationMethodAttr.get()) {
107 theError = "Error: Could not get \"%1\" attribute.";
108 theError.arg(aCreationMethodID);
112 if(aCreationMethodAttr->value() != "locations") {
116 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
117 if(!aBaseObjectsSelectionList.get()) {
118 theError = "Error: Could not get \"%1\" attribute.";
119 theError.arg(aBaseObjectsID);
123 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
124 if(!aLocationsSelectionList.get()) {
125 theError = "Error: Could not get \"%1\" attribute.";
126 theError.arg(aBaseObjectsID);
130 if(aLocationsSelectionList->size() > 0 &&
131 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
132 theError = "Error: Number of locations should be the same as base objects.";
139 //==================================================================================================
140 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
141 const std::list<std::string>& theArguments,
142 Events_InfoMessage& theError) const
144 if(theArguments.empty()) {
145 theError = "Error: Validator parameters is empty.";
149 // Checking attribute.
150 if(!isValidAttribute(theAttribute, theArguments, theError)) {
151 if(theError.empty()) {
152 theError = "Error: Attribute contains unacceptable shape.";
157 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
158 std::string anAttributeType = theAttribute->attributeType();
159 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
160 AttributeSelectionListPtr aListAttr =
161 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
162 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
163 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
164 ResultPtr aContext = aSelectionAttr->context();
165 if(!aContext.get()) {
166 theError = "Error: Empty context.";
170 ResultConstructionPtr aResultConstruction =
171 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
172 if(!aResultConstruction.get()) {
173 // It is not a result construction.
174 // If shape is compound check that it contains only faces and edges.
175 GeomShapePtr aShape = aSelectionAttr->value();
177 aShape = aContext->shape();
180 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
181 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
182 GeomShapePtr aSubShape = anIt.current();
183 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
184 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
185 theError = "Error: Compound should contain only faces and edges.";
194 GeomShapePtr aShape = aSelectionAttr->value();
195 GeomShapePtr aContextShape = aResultConstruction->shape();
197 // Whole sketch selected.
200 // Object from sketch selected.
201 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
202 GeomShapePtr aWire = anExp.current();
203 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
204 theError = "Error: Wire with wrong orientation selected.";
208 if(aSelectedWiresFromObjects.isBound(aWire)) {
210 "Error: Objects with such wire already selected. Don't allow to select this object.";
214 aSelectedWiresFromObjects.bind(aWire, aWire);
223 //==================================================================================================
224 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
225 const std::shared_ptr<ModelAPI_Feature>& theFeature,
226 const std::list<std::string>& theArguments,
227 Events_InfoMessage& theError) const
229 const std::string aBaseObjectsID = theArguments.front();
231 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
232 if(!aListAttr.get()) {
233 theError = "Error: Could not get \"%1\" attribute.";
234 theError.arg(aBaseObjectsID);
238 std::set<ResultConstructionPtr> aSelectedSketches;
239 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
241 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
242 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
243 ResultPtr aContext = aSelectionAttr->context();
244 if(!aContext.get()) {
245 theError = "Error: Empty context.";
249 ResultConstructionPtr aResultConstruction =
250 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
251 if(!aResultConstruction.get()) {
252 // It is not a result construction.
256 GeomShapePtr aShape = aSelectionAttr->value();
257 GeomShapePtr aContextShape = aResultConstruction->shape();
259 // Whole sketch selected.
260 aSelectedSketches.insert(aResultConstruction);
262 // Object from sketch selected.
263 aSelectedSketchesFromObjects.insert(aResultConstruction);
268 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
269 anIt != aSelectedSketches.cend();
271 ResultConstructionPtr aResultConstruction = *anIt;
272 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
273 aSelectedSketchesFromObjects.cend()) {
274 theError = "Sketch and objects from it can not be selected at the same time.";
282 //==================================================================================================
283 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
284 const std::list<std::string>& theArguments,
285 Events_InfoMessage& theError) const
287 if(!theAttribute.get()) {
288 theError = "Error: Empty attribute.";
292 std::string anAttributeType = theAttribute->attributeType();
293 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
294 AttributeSelectionListPtr aListAttr =
295 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
296 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
297 // If at least one attribute is invalid, the result is false.
298 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
302 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
304 AttributeSelectionPtr anAttr =
305 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
306 ResultPtr aContext = anAttr->context();
307 if(!aContext.get()) {
308 theError = "Error: Attribute have empty context.";
312 GeomShapePtr aShape = anAttr->value();
313 GeomShapePtr aContextShape = aContext->shape();
315 aShape = aContextShape;
318 theError = "Error: Empty shape selected";
322 ResultConstructionPtr aConstruction =
323 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
324 if(aConstruction.get()) {
325 // Construciotn selected. Check that is is not infinite.
326 if(aConstruction->isInfinite()) {
327 theError = "Error: Infinite constructions is not allowed as base.";
331 if(aShape->isEqual(aContextShape)) {
332 // Whole construction selected. Check that it have faces.
333 if(aConstruction->facesNum() > 0) {
337 // Shape on construction selected. Check that it is a face or wire.
338 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
339 aShape->shapeType() == GeomAPI_Shape::FACE) {
347 if(!aShape->isEqual(aContextShape)) {
348 // Local selection on body does not allowed.
350 "Error: Selected shape is in the local selection. Only global selection is allowed.";
354 // Check that object is a shape with allowed type.
355 GeomValidators_ShapeType aShapeTypeValidator;
356 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
357 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
358 "wires on sketch, whole sketch(if it has at least one face), "
359 "and whole objects with shape types: %1";
360 std::string anArgumentString;
361 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
362 if (!anArgumentString.empty())
363 anArgumentString += ", ";
364 anArgumentString += *anIt;
366 theError.arg(anArgumentString);
371 theError = "Error: Attribute \"%1\" does not supported by this validator.";
372 theError.arg(anAttributeType);
379 //==================================================================================================
380 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
381 const std::list<std::string>& theArguments,
382 Events_InfoMessage& theError) const
384 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
385 theError = "Error: The attribute with the %1 type is not processed";
386 theError.arg(theAttribute->attributeType());
389 if (theArguments.size() != 2) {
390 theError = "Error: Wrong parameters in XML definition for %1 type";
391 theError.arg(theAttribute->attributeType());
394 // first argument is for the base attribute, second - for skipping feature kind
395 std::list<std::string>::const_iterator anIt = theArguments.begin();
396 std::string aBaseAttributeId = *anIt;
397 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
398 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
399 if (!aBaseAttribute.get()) {
400 theError = "Wrong parameters in XML definition for %1 type";
401 theError.arg(theAttribute->attributeType());
404 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
405 // this validator is not necessary anymore
409 std::string aFeatureAttributeKind = *anIt;
410 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
411 // check whether the selection is on the sketch
412 std::list<std::string> anArguments;
413 anArguments.push_back(aFeatureAttributeKind);
415 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
416 bool aPlanarFace = false;
417 // check if selection has Face selected
418 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
420 anArguments.push_back("face");
421 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
423 bool aValid = !aFeatureKind && aPlanarFace;
427 //==================================================================================================
428 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
429 const std::shared_ptr<ModelAPI_Feature>& theFeature,
430 const std::list<std::string>& theArguments,
431 Events_InfoMessage& theError) const
433 if(theArguments.size() != 2) {
434 theError = "Error: Validator should be used with 2 parameters for extrusion.";
438 std::list<std::string>::const_iterator
439 anArgsIt = theArguments.begin(), aLast = theArguments.end();
441 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
444 GeomShapePtr aDirShape;
445 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
447 aDirShape = aSelAttr->value();
448 if(!aDirShape.get()) {
449 ResultPtr aContext = aSelAttr->context();
451 aDirShape = aContext->shape();
456 if(!aDirShape.get()) {
457 // Check that dir can be empty.
458 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
459 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
460 "can not be used with default value. Select direction for extrusion.";
461 theError.arg(*anArgsIt);
468 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
470 // If faces selected check that direction not parallel with them.
471 AttributeSelectionListPtr aListAttr =
472 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
473 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
474 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
475 GeomShapePtr aShapeInList = anAttr->value();
476 if(!aShapeInList.get()) {
477 aShapeInList = anAttr->context()->shape();
479 bool isParallel = true;
480 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
481 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
482 for(GeomAPI_ShapeExplorer
483 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
484 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
485 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
490 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
491 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
492 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
493 if(aPlanarEdges.get()) {
494 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
495 if(aDirEdge->isLine()) {
496 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
497 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
509 "Error: Direction is parallel to one of the selected face or face on selected shell.";
517 //==================================================================================================
518 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
519 Events_InfoMessage& theError) const
521 if(!theAttribute.get()) {
525 std::string anAttributeType = theAttribute->attributeType();
526 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
527 AttributeSelectionListPtr aListAttr =
528 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
529 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
530 // If at least one attribute is invalid, the result is false.
531 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
535 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
537 AttributeSelectionPtr anAttr =
538 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
539 ResultPtr aContext = anAttr->context();
540 if(!aContext.get()) {
544 GeomShapePtr aShape = anAttr->value();
545 GeomShapePtr aContextShape = aContext->shape();
547 aShape = aContextShape;
553 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
554 aShape->shapeType() == GeomAPI_Shape::EDGE ||
555 !aShape->isPlanar()) {
565 //==================================================================================================
566 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
567 const std::list<std::string>& theArguments,
568 Events_InfoMessage& theError) const
570 AttributeSelectionListPtr anAttrSelectionList =
571 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
572 if(!anAttrSelectionList.get()) {
574 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
577 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
578 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
579 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
581 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
582 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
583 if(!anAttrSelection.get()) {
584 theError = "Error: Empty attribute selection.";
587 ResultPtr aContext = anAttrSelection->context();
588 if(!aContext.get()) {
589 FeaturePtr aContFeat = anAttrSelection->contextFeature();
590 if (!aContFeat.get()) {
591 theError = "Error: Empty selection context.";
595 ResultConstructionPtr aResultConstruction =
596 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
597 if(aResultConstruction.get()) {
598 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
599 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
600 theError = "Error: Result construction not allowed for selection.";
604 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
606 GeomShapePtr aContextShape = aContext->shape();
607 aShape = aContextShape;
610 theError = "Error: Empty shape.";
613 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
614 theError = "Error: Local selection not allowed.";
618 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
619 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
620 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
621 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
622 anAllowedTypes.insert(GeomAPI_Shape::FACE);
623 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
624 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
625 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
626 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
627 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
629 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
630 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
631 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
632 anAllowedTypes.insert(GeomAPI_Shape::FACE);
633 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
634 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
635 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
636 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
638 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
639 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
640 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
643 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
644 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
645 theError = "Error: Selected shape has the wrong type.";
654 //==================================================================================================
655 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
656 const std::list<std::string>& theArguments,
657 Events_InfoMessage& theError) const
659 AttributeSelectionListPtr anAttrSelectionList =
660 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
661 if(!anAttrSelectionList.get()) {
663 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
667 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
668 // Check all selected entities are sub-shapes of single solid
669 GeomShapePtr aBaseSolid;
670 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
671 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
672 if(!anAttrSelection.get()) {
673 theError = "Error: Empty attribute selection.";
676 ResultPtr aContext = anAttrSelection->context();
677 if(!aContext.get()) {
678 theError = "Error: Empty selection context.";
682 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
683 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
685 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
686 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
687 theError = "Error: Not all selected shapes are sub-shapes of solids";
692 aBaseSolid = anOwner;
693 else if (!aBaseSolid->isEqual(anOwner)) {
694 theError = "Error: Sub-shapes of different solids have been selected.";
702 //==================================================================================================
703 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
704 const std::list<std::string>& theArguments,
705 Events_InfoMessage& theError) const
707 AttributeSelectionListPtr anAttrSelectionList =
708 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
709 if(!anAttrSelectionList.get()) {
710 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
714 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
715 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
717 //GeomValidators_BodyShapes aBodyValidator;
718 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
722 GeomValidators_FeatureKind aFeatureKindValidator;
723 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
727 ResultPtr aContext = aSelectAttr->context();
728 ResultConstructionPtr aResultConstruction =
729 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
730 if(aResultConstruction.get()) {
731 theError = "Error: Only body shapes and construction planes are allowed for selection.";
735 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
736 if(aResultBody.get()) {
739 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
740 if(aResultFeature.get()) {
742 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
743 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
744 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
745 if (aBody.get() && !aBody->isDisabled())
752 theError = "Error: Only body shapes and construction planes are allowed for selection.";
760 //==================================================================================================
761 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
762 const std::list<std::string>& theArguments,
763 Events_InfoMessage& theError) const
765 AttributeSelectionListPtr aSubShapesAttrList =
766 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
767 if(!aSubShapesAttrList.get()) {
769 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
773 static const std::string aBaseShapeID = "base_shape";
774 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
775 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
777 if(!aShapeAttrSelection.get()) {
778 theError = "Error: Could not get \"%1\" attribute.";
779 theError.arg(aBaseShapeID);
783 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
784 ResultPtr aContext = aShapeAttrSelection->context();
785 if(!aContext.get()) {
786 theError = "Error: Empty context.";
789 if(!aBaseShape.get()) {
790 aBaseShape = aContext->shape();
792 if(!aBaseShape.get()) {
793 theError = "Error: Empty base shape.";
797 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
798 bool isSameFound = false;
799 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
800 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
801 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
802 if(anIt.current()->isEqual(aShapeToAdd)) {
808 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
816 //==================================================================================================
817 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
818 const std::shared_ptr<ModelAPI_Feature>& theFeature,
819 const std::list<std::string>& theArguments,
820 Events_InfoMessage& theError) const
822 static const std::string aBaseShapeID = "base_shape";
823 static const std::string aSubShapesID = "subshapes_to_keep";
825 if(theFeature->getKind() != "Remove_SubShapes") {
826 theError = "Error: Feature \"%1\" does not supported by this validator.";
827 theError.arg(theFeature->getKind());
831 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
832 if(!aShapeAttrSelection.get()) {
833 theError = "Error: Could not get \"%1\" attribute.";
834 theError.arg(aBaseShapeID);
838 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
839 if(!aSubShapesAttrList.get()) {
840 theError = "Error: Could not get \"%1\" attribute.";
841 theError.arg(aSubShapesID);
846 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
847 if(!aBaseShape.get()) {
848 theError = "Error: Base shape is empty.";
851 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
853 if (aSubShapesAttrList->size() == 0) {
854 theError = "Error: Resulting shape is not valid.";
858 // Copy sub-shapes from list to new shape.
859 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
860 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
861 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
862 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
866 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
867 theError = "Error: Resulting shape is not valid.";
874 //==================================================================================================
875 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
876 const std::list<std::string>& theArguments,
877 Events_InfoMessage& theError) const
879 AttributeSelectionListPtr aBaseObjectsAttrList =
880 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
881 if(!aBaseObjectsAttrList.get()) {
882 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
883 theError.arg(FeaturesPlugin_Union::ID());
887 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
888 bool isSameFound = false;
889 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
890 ResultPtr aContext = anAttrSelectionInList->context();
891 if (!aContext.get()) {
892 theError = "Error: selection is invalid.";
896 ResultConstructionPtr aConstruction =
897 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
898 if(aConstruction.get()) {
899 theError = "Error: Result construction not allowed for selection.";
903 GeomShapePtr aShape = anAttrSelectionInList->value();
904 GeomShapePtr aContextShape = aContext->shape();
905 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
906 theError = "Error: Local selection not allowed.";
910 ResultBodyPtr aResult =
911 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
916 if(aResult->numberOfSubs() > 0) {
917 theError = "Error: Whole compsolids not allowed for selection.";
925 //==================================================================================================
926 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
927 const std::shared_ptr<ModelAPI_Feature>& theFeature,
928 const std::list<std::string>& theArguments,
929 Events_InfoMessage& theError) const
931 // Check feature kind.
932 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
933 theError = "Error: This validator supports only \"%1\" feature.";
934 theError.arg(FeaturesPlugin_Union::ID());
938 // Get base objects attribute list.
939 AttributeSelectionListPtr aBaseObejctsAttrList =
940 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
941 if(!aBaseObejctsAttrList.get()) {
942 theError = "Error: Could not get \"%1\" attribute.";
943 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
948 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
949 ListOfShape aBaseShapesList;
950 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
951 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
952 GeomShapePtr aShape = anAttrSelectionInList->value();
956 aBaseShapesList.push_back(aShape);
957 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
958 GeomAPI_Shape::COMPSOLID;
961 // Make compound and find connected.
962 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
963 ListOfShape aCombined, aFree;
964 GeomAlgoAPI_ShapeTools::combineShapes(
970 if(aFree.size() > 0 || aCombined.size() > 1) {
971 theError = "Error: Not all shapes have shared topology.";
978 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
979 const std::list<std::string>& theArguments,
980 Events_InfoMessage& theError) const
982 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
983 theError = "Error: The attribute with the %1 type is not processed";
984 theError.arg(theAttribute->attributeType());
988 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
990 ObjectPtr aRefObject = aRefAttribute->value();
991 if (!aRefObject.get()) {
992 theError = "Error: Empty feature.";
996 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
997 if (!aRefFeature.get()) {
998 theError = "Error: Empty feature.";
1001 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1002 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1004 size_t aConcealedResults = aResults.size();
1005 if (!aConcealedResults && !theArguments.empty()) {
1006 // find if these results are touched by the feature in another attribute
1007 std::list<std::string>::const_iterator anIt = theArguments.begin();
1008 std::string aRecoveredList = *anIt;
1009 if (!aRecoveredList.empty()) {
1010 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1011 theAttribute->owner()->data()->reflist(aRecoveredList);
1012 if (aParameterList.get())
1013 aConcealedResults = aParameterList->size();
1017 if (aConcealedResults == 0)
1018 theError = "Error: No concealed results.";
1020 return theError.empty();
1023 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1024 const std::list<std::string>& theArguments,
1025 Events_InfoMessage& theError) const
1027 static std::list<std::string> aEdgeArg(1, "circle");
1028 static std::list<std::string> aFaceArg(1, "cylinder");
1030 Events_InfoMessage aError;
1031 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1033 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1035 theError = "The shape neither circle nor cylinder";
1040 //=================================================================================================
1041 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1042 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1043 const std::list<std::string>& theArguments,
1044 Events_InfoMessage& theError) const
1046 if (theArguments.size() != 2)
1048 theError = "Wrong number of arguments (expected 2).";
1052 int anObjectsNb = 0, aToolsNb = 0;
1053 //int anOperationType = 0;
1055 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1057 bool isAllInSameCompSolid = true;
1058 ResultBodyPtr aCompSolid;
1060 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1063 anObjectsNb = anAttrSelList->size();
1064 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1066 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1067 ResultPtr aContext = anAttr->context();
1068 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1069 if (aResCompSolidPtr.get())
1071 if (aCompSolid.get())
1073 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1077 aCompSolid = aResCompSolidPtr;
1082 isAllInSameCompSolid = false;
1090 anAttrSelList = theFeature->selectionList(*anIt);
1093 aToolsNb = anAttrSelList->size();
1094 if (isAllInSameCompSolid)
1096 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1098 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1099 ResultPtr aContext = anAttr->context();
1100 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1101 if (aResCompSolidPtr.get())
1103 if (aCompSolid.get())
1105 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1109 aCompSolid = aResCompSolidPtr;
1114 isAllInSameCompSolid = false;
1122 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1123 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1124 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1126 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1129 if (anObjectsNb + aToolsNb < 2)
1131 theError = "Not enough arguments for Fuse operation.";
1134 else if (isAllInSameCompSolid)
1136 theError = "Operations only between sub-shapes of the same shape not allowed.";
1142 if (anObjectsNb < 1)
1144 theError = "Objects not selected.";
1149 theError = "Tools not selected.";
1152 if (isAllInSameCompSolid)
1154 theError = "Operations only between sub-shapes of the same shape not allowed.";
1162 //=================================================================================================
1163 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1164 std::string theAttribute)
1166 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1174 //==================================================================================================
1175 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1176 const AttributePtr& theAttribute,
1177 const std::list<std::string>& theArguments,
1178 Events_InfoMessage& theError) const
1180 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1181 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1183 AttributeSelectionListPtr anAttrSelectionList =
1184 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1185 if (!aFeature.get() || !anAttrSelectionList.get()) {
1187 "Error: Validator used in wrong feature or attribute";
1191 AttributeSelectionListPtr anOtherAttrSelectionList;
1192 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1193 anOtherAttrSelectionList =
1194 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1196 anOtherAttrSelectionList =
1197 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1200 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1201 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1202 GeomPlanePtr aFacesPln;
1204 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1205 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1206 ResultPtr aContext = anAttrSelection->context();
1207 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1208 GeomShapePtr aContextShape = aContext->shape();
1209 if (!aShape.get()) {
1210 aShape = aContextShape;
1213 if (aShape->isSolid() || aShape->isCompSolid()) {
1214 aSelectedShapesType = GeomAPI_Shape::SOLID;
1215 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1216 if (aResCompSolidPtr.get()) {
1217 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1218 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1221 aSelectedShapesType = GeomAPI_Shape::FACE;
1222 GeomAPI_Face aFace(aShape);
1223 aFacesPln = aFace.getPlane();
1228 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1229 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1230 if (!anAttrSelection.get()) {
1231 theError = "Error: Empty attribute selection.";
1234 ResultPtr aContext = anAttrSelection->context();
1235 if (!aContext.get()) {
1236 theError = "Error: Empty selection context.";
1239 ResultConstructionPtr aResultConstruction =
1240 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1241 if (aResultConstruction.get()) {
1242 theError = "Error: Result construction not allowed for selection.";
1245 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1246 GeomShapePtr aContextShape = aContext->shape();
1247 if (!aShape.get()) {
1248 aShape = aContextShape;
1250 if (!aShape.get()) {
1251 theError = "Error: Empty shape.";
1254 if (!aShape->isEqual(aContextShape)) {
1255 theError = "Error: Local selection not allowed.";
1259 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1260 // Other list is empty.
1261 if (aShape->isSolid() || aShape->isCompSolid()) {
1262 aSelectedShapesType = GeomAPI_Shape::SOLID;
1264 aSelectedShapesType = GeomAPI_Shape::FACE;
1265 GeomAPI_Face aFace(aShape);
1266 aFacesPln = aFace.getPlane();
1268 if (!aFacesPln.get()) {
1269 theError = "Error: Only planar faces allowed.";
1275 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1276 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1277 theError = "Error: Selected shapes should have the same type.";
1281 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1282 if (aResCompSolidPtr.get()) {
1283 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1284 if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) {
1285 theError = "Error: Solids from compsolid in other list not allowed.";
1290 GeomAPI_Face aFace(aShape);
1291 GeomPlanePtr aPln = aFace.getPlane();
1294 theError = "Error: Only planar faces allowed.";
1298 if (!aFacesPln->isCoincident(aPln)) {
1299 theError = "Error: Only coincident faces allowed.";
1308 //==================================================================================================
1309 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1310 const std::list<std::string>& theArguments,
1311 Events_InfoMessage& theError) const
1313 if (!theAttribute.get()) {
1314 theError = "Error: empty selection.";
1317 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1318 AttributeSelectionListPtr anAttrSelectionList =
1319 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1320 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1321 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1322 if (!anAttrSelection.get()) {
1323 theError = "Error: empty attribute selection.";
1326 ResultPtr aContext = anAttrSelection->context();
1327 if (!aContext.get()) {
1328 theError = "Error: empty selection context.";
1331 FeaturePtr aFeature = ModelAPI_Feature::feature(aContext);
1332 if (!aFeature.get()) {
1333 theError = "Error: empty feature.";
1336 std::string aFeatureKind = aFeature->getKind();
1337 if (aFeatureKind == "Sketch" ||
1338 aFeatureKind == "Plane" ||
1339 aFeatureKind == "Axis") {
1340 theError = "Error: %1 shape is not allowed for selection.";
1341 theError.arg(aFeatureKind);
1344 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1345 GeomShapePtr aContextShape = aContext->shape();
1346 if (!aShape.get()) {
1347 aShape = aContextShape;
1349 if (!aShape.get()) {
1350 theError = "Error: empty shape.";
1353 if (!aShape->isEqual(aContextShape)) {
1354 theError = "Error: Local selection not allowed.";
1358 int aShapeType = aShape->shapeType();
1359 // Allow to select edges, faces and solids.
1360 if (aShapeType != GeomAPI_Shape::EDGE &&
1361 aShapeType != GeomAPI_Shape::FACE &&
1362 aShapeType != GeomAPI_Shape::SOLID &&
1363 aShapeType != GeomAPI_Shape::COMPSOLID &&
1364 aShapeType != GeomAPI_Shape::COMPOUND) {
1365 theError = "Error: selected shape has the wrong type.";
1373 //==================================================================================================
1374 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1375 const AttributePtr& theAttribute,
1376 const std::list<std::string>& theArguments,
1377 Events_InfoMessage& theError) const
1379 AttributeSelectionListPtr anAttrSelectionList =
1380 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1381 if (!anAttrSelectionList.get()) {
1383 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1387 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1388 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1389 if (!anAttrSelection.get()) {
1390 theError = "Error: Empty attribute selection.";
1393 ResultPtr aContext = anAttrSelection->context();
1394 if (!aContext.get()) {
1395 theError = "Error: Empty selection context.";
1398 ResultConstructionPtr aResultConstruction =
1399 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1400 if (aResultConstruction.get()) {
1401 theError = "Error: Result construction not allowed for selection.";
1404 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1405 GeomShapePtr aContextShape = aContext->shape();
1406 if (!aShape.get()) {
1407 aShape = aContextShape;
1409 if (!aShape.get()) {
1410 theError = "Error: Empty shape.";
1413 if (!aShape->isEqual(aContextShape)) {
1414 theError = "Error: Local selection not allowed.";
1422 //=================================================================================================
1423 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1424 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1425 const std::list<std::string>& theArguments,
1426 Events_InfoMessage& theError) const
1428 if (theArguments.size() != 2) {
1429 theError = "Wrong number of arguments (expected 2).";
1433 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1434 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1436 int anObjectsNb = 0, aToolsNb = 0;
1438 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1440 bool isAllInSameCompSolid = true;
1441 ResultBodyPtr aCompSolid;
1443 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1444 if (anAttrSelList) {
1445 anObjectsNb = anAttrSelList->size();
1446 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1447 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1448 ResultPtr aContext = anAttr->context();
1449 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1450 if (aResCompSolidPtr.get()) {
1451 if (aCompSolid.get()) {
1452 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1454 aCompSolid = aResCompSolidPtr;
1457 isAllInSameCompSolid = false;
1464 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1465 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1466 anAttrSelList = theFeature->selectionList(*anIt);
1467 if (anAttrSelList) {
1468 aToolsNb = anAttrSelList->size();
1469 if (isAllInSameCompSolid) {
1470 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1471 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1472 ResultPtr aContext = anAttr->context();
1473 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1474 if (aResCompSolidPtr.get()) {
1475 if (aCompSolid.get()) {
1476 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1478 aCompSolid = aResCompSolidPtr;
1481 isAllInSameCompSolid = false;
1491 if (anObjectsNb + aToolsNb < 2) {
1492 theError = "Not enough arguments for Fuse operation.";
1494 } else if (isAllInSameCompSolid) {
1495 theError = "Operations only between sub-shapes of the same shape not allowed.";
1502 //=================================================================================================
1503 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1504 std::string theFeature,
1505 std::string theAttribute)
1507 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {