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_BooleanCommon.h"
26 #include "FeaturesPlugin_BooleanSmash.h"
27 #include "FeaturesPlugin_Union.h"
29 #include <Events_InfoMessage.h>
31 #include <ModelAPI_Attribute.h>
32 #include <ModelAPI_AttributeInteger.h>
33 #include <ModelAPI_AttributeSelectionList.h>
34 #include <ModelAPI_AttributeString.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeRefList.h>
37 #include <ModelAPI_Feature.h>
38 #include <ModelAPI_ResultBody.h>
39 #include <ModelAPI_ResultConstruction.h>
40 #include <ModelAPI_Tools.h>
42 #include <GeomValidators_BodyShapes.h>
43 #include <GeomValidators_Face.h>
44 #include <GeomValidators_FeatureKind.h>
45 #include <GeomValidators_ShapeType.h>
47 #include <GeomAPI_DataMapOfShapeShape.h>
48 #include <GeomAPI_Lin.h>
49 #include <GeomAPI_PlanarEdges.h>
50 #include <GeomAPI_Pln.h>
51 #include <GeomAPI_ShapeExplorer.h>
52 #include <GeomAPI_ShapeIterator.h>
54 #include <GeomAlgoAPI_CompoundBuilder.h>
55 #include <GeomAlgoAPI_ShapeBuilder.h>
56 #include <GeomAlgoAPI_ShapeTools.h>
57 #include <GeomAlgoAPI_WireBuilder.h>
59 #define _USE_MATH_DEFINES
62 //==================================================================================================
63 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
64 const std::list<std::string>& theArguments,
65 Events_InfoMessage& theError) const
67 AttributeSelectionPtr aPathAttrSelection =
68 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
69 if(!aPathAttrSelection.get()) {
70 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
74 GeomShapePtr aPathShape = aPathAttrSelection->value();
75 ResultPtr aContext = aPathAttrSelection->context();
77 theError = "Error: Empty context.";
80 GeomShapePtr aContextShape = aContext->shape();
81 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
82 !aPathShape->isEqual(aContextShape)) {
83 theError = "Error: Local selection of wires not allowed.";
90 //==================================================================================================
91 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
92 const std::shared_ptr<ModelAPI_Feature>& theFeature,
93 const std::list<std::string>& theArguments,
94 Events_InfoMessage& theError) const
96 static const std::string aCreationMethodID = "creation_method";
97 static const std::string aBaseObjectsID = "base_objects";
98 static const std::string aLocationsID = "locations_objects";
100 if(theFeature->getKind() != "Pipe") {
101 theError = "Error: Feature \"%1\" does not supported by this validator.";
102 theError.arg(theFeature->getKind());
106 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
107 if(!aCreationMethodAttr.get()) {
108 theError = "Error: Could not get \"%1\" attribute.";
109 theError.arg(aCreationMethodID);
113 if(aCreationMethodAttr->value() != "locations") {
117 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
118 if(!aBaseObjectsSelectionList.get()) {
119 theError = "Error: Could not get \"%1\" attribute.";
120 theError.arg(aBaseObjectsID);
124 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
125 if(!aLocationsSelectionList.get()) {
126 theError = "Error: Could not get \"%1\" attribute.";
127 theError.arg(aBaseObjectsID);
131 if(aLocationsSelectionList->size() > 0 &&
132 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
133 theError = "Error: Number of locations should be the same as base objects.";
140 //==================================================================================================
141 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
142 const std::list<std::string>& theArguments,
143 Events_InfoMessage& theError) const
145 if(theArguments.empty()) {
146 theError = "Error: Validator parameters is empty.";
150 // Checking attribute.
151 if(!isValidAttribute(theAttribute, theArguments, theError)) {
152 if(theError.empty()) {
153 theError = "Error: Attribute contains unacceptable shape.";
158 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
159 std::string anAttributeType = theAttribute->attributeType();
160 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
161 AttributeSelectionListPtr aListAttr =
162 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
163 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
164 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
165 ResultPtr aContext = aSelectionAttr->context();
166 if(!aContext.get()) {
167 theError = "Error: Empty context.";
171 ResultConstructionPtr aResultConstruction =
172 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
173 if(!aResultConstruction.get()) {
174 // It is not a result construction.
175 // If shape is compound check that it contains only faces and edges.
176 GeomShapePtr aShape = aSelectionAttr->value();
178 aShape = aContext->shape();
181 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
182 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
183 GeomShapePtr aSubShape = anIt.current();
184 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
185 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
186 theError = "Error: Compound should contain only faces and edges.";
195 GeomShapePtr aShape = aSelectionAttr->value();
196 GeomShapePtr aContextShape = aResultConstruction->shape();
198 // Whole sketch selected.
201 // Object from sketch selected.
202 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
203 GeomShapePtr aWire = anExp.current();
204 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
205 theError = "Error: Wire with wrong orientation selected.";
209 if(aSelectedWiresFromObjects.isBound(aWire)) {
211 "Error: Objects with such wire already selected. Don't allow to select this object.";
215 aSelectedWiresFromObjects.bind(aWire, aWire);
224 //==================================================================================================
225 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
226 const std::shared_ptr<ModelAPI_Feature>& theFeature,
227 const std::list<std::string>& theArguments,
228 Events_InfoMessage& theError) const
230 const std::string aBaseObjectsID = theArguments.front();
232 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
233 if(!aListAttr.get()) {
234 theError = "Error: Could not get \"%1\" attribute.";
235 theError.arg(aBaseObjectsID);
239 std::set<ResultConstructionPtr> aSelectedSketches;
240 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
242 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
243 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
244 ResultPtr aContext = aSelectionAttr->context();
245 if(!aContext.get()) {
246 theError = "Error: Empty context.";
250 ResultConstructionPtr aResultConstruction =
251 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
252 if(!aResultConstruction.get()) {
253 // It is not a result construction.
257 GeomShapePtr aShape = aSelectionAttr->value();
258 GeomShapePtr aContextShape = aResultConstruction->shape();
260 // Whole sketch selected.
261 aSelectedSketches.insert(aResultConstruction);
263 // Object from sketch selected.
264 aSelectedSketchesFromObjects.insert(aResultConstruction);
269 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
270 anIt != aSelectedSketches.cend();
272 ResultConstructionPtr aResultConstruction = *anIt;
273 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
274 aSelectedSketchesFromObjects.cend()) {
275 theError = "Sketch and objects from it can not be selected at the same time.";
283 //==================================================================================================
284 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
285 const std::list<std::string>& theArguments,
286 Events_InfoMessage& theError) const
288 if(!theAttribute.get()) {
289 theError = "Error: Empty attribute.";
293 std::string anAttributeType = theAttribute->attributeType();
294 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
295 AttributeSelectionListPtr aListAttr =
296 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
297 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
298 // If at least one attribute is invalid, the result is false.
299 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
303 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
305 AttributeSelectionPtr anAttr =
306 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
307 ResultPtr aContext = anAttr->context();
308 if(!aContext.get()) {
309 theError = "Error: Attribute have empty context.";
313 GeomShapePtr aShape = anAttr->value();
314 GeomShapePtr aContextShape = aContext->shape();
316 aShape = aContextShape;
319 theError = "Error: Empty shape selected";
323 ResultConstructionPtr aConstruction =
324 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
325 if(aConstruction.get()) {
326 // Construciotn selected. Check that is is not infinite.
327 if(aConstruction->isInfinite()) {
328 theError = "Error: Infinite constructions is not allowed as base.";
332 if(aShape->isEqual(aContextShape)) {
333 // Whole construction selected. Check that it have faces.
334 if(aConstruction->facesNum() > 0) {
338 // Shape on construction selected. Check that it is a face or wire.
339 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
340 aShape->shapeType() == GeomAPI_Shape::FACE) {
348 if(!aShape->isEqual(aContextShape)) {
349 // Local selection on body does not allowed.
351 "Error: Selected shape is in the local selection. Only global selection is allowed.";
355 // Check that object is a shape with allowed type.
356 GeomValidators_ShapeType aShapeTypeValidator;
357 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
358 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
359 "wires on sketch, whole sketch(if it has at least one face), "
360 "and whole objects with shape types: %1";
361 std::string anArgumentString;
362 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
363 if (!anArgumentString.empty())
364 anArgumentString += ", ";
365 anArgumentString += *anIt;
367 theError.arg(anArgumentString);
372 theError = "Error: Attribute \"%1\" does not supported by this validator.";
373 theError.arg(anAttributeType);
380 //==================================================================================================
381 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
382 const std::list<std::string>& theArguments,
383 Events_InfoMessage& theError) const
385 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
386 theError = "Error: The attribute with the %1 type is not processed";
387 theError.arg(theAttribute->attributeType());
390 if (theArguments.size() != 2) {
391 theError = "Error: Wrong parameters in XML definition for %1 type";
392 theError.arg(theAttribute->attributeType());
395 // first argument is for the base attribute, second - for skipping feature kind
396 std::list<std::string>::const_iterator anIt = theArguments.begin();
397 std::string aBaseAttributeId = *anIt;
398 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
399 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
400 if (!aBaseAttribute.get()) {
401 theError = "Wrong parameters in XML definition for %1 type";
402 theError.arg(theAttribute->attributeType());
405 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
406 // this validator is not necessary anymore
410 std::string aFeatureAttributeKind = *anIt;
411 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
412 // check whether the selection is on the sketch
413 std::list<std::string> anArguments;
414 anArguments.push_back(aFeatureAttributeKind);
416 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
417 bool aPlanarFace = false;
418 // check if selection has Face selected
419 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
421 anArguments.push_back("face");
422 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
424 bool aValid = !aFeatureKind && aPlanarFace;
428 //==================================================================================================
429 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
430 const std::shared_ptr<ModelAPI_Feature>& theFeature,
431 const std::list<std::string>& theArguments,
432 Events_InfoMessage& theError) const
434 if(theArguments.size() != 2) {
435 theError = "Error: Validator should be used with 2 parameters for extrusion.";
439 std::list<std::string>::const_iterator
440 anArgsIt = theArguments.begin(), aLast = theArguments.end();
442 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
445 GeomShapePtr aDirShape;
446 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
448 aDirShape = aSelAttr->value();
449 if(!aDirShape.get()) {
450 ResultPtr aContext = aSelAttr->context();
452 aDirShape = aContext->shape();
457 if(!aDirShape.get()) {
458 // Check that dir can be empty.
459 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
460 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
461 "can not be used with default value. Select direction for extrusion.";
462 theError.arg(*anArgsIt);
469 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
471 // If faces selected check that direction not parallel with them.
472 AttributeSelectionListPtr aListAttr =
473 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
474 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
475 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
476 GeomShapePtr aShapeInList = anAttr->value();
477 if(!aShapeInList.get()) {
478 aShapeInList = anAttr->context()->shape();
480 bool isParallel = true;
481 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
482 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
483 for(GeomAPI_ShapeExplorer
484 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
485 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
486 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
491 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
492 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
493 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
494 if(aPlanarEdges.get()) {
495 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
496 if(aDirEdge->isLine()) {
497 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
498 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
510 "Error: Direction is parallel to one of the selected face or face on selected shell.";
518 //==================================================================================================
519 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
520 Events_InfoMessage& theError) const
522 if(!theAttribute.get()) {
526 std::string anAttributeType = theAttribute->attributeType();
527 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
528 AttributeSelectionListPtr aListAttr =
529 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
530 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
531 // If at least one attribute is invalid, the result is false.
532 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
536 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
538 AttributeSelectionPtr anAttr =
539 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
540 ResultPtr aContext = anAttr->context();
541 if(!aContext.get()) {
545 GeomShapePtr aShape = anAttr->value();
546 GeomShapePtr aContextShape = aContext->shape();
548 aShape = aContextShape;
554 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
555 aShape->shapeType() == GeomAPI_Shape::EDGE ||
556 !aShape->isPlanar()) {
566 //==================================================================================================
567 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
568 const std::list<std::string>& theArguments,
569 Events_InfoMessage& theError) const
571 AttributeSelectionListPtr anAttrSelectionList =
572 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
573 if(!anAttrSelectionList.get()) {
575 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
578 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
579 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
580 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
582 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
583 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
584 if(!anAttrSelection.get()) {
585 theError = "Error: Empty attribute selection.";
588 ResultPtr aContext = anAttrSelection->context();
589 if(!aContext.get()) {
590 FeaturePtr aContFeat = anAttrSelection->contextFeature();
591 if (!aContFeat.get() || !aContFeat->results().size()) {
592 theError = "Error: Empty selection context.";
596 ResultConstructionPtr aResultConstruction =
597 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
598 if(aResultConstruction.get()) {
599 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
600 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
601 theError = "Error: Result construction not allowed for selection.";
605 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
606 if(!aShape.get() && aContext.get()) {
607 GeomShapePtr aContextShape = aContext->shape();
608 aShape = aContextShape;
611 theError = "Error: Empty shape.";
614 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
615 theError = "Error: Local selection not allowed.";
619 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
620 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
621 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
622 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
623 anAllowedTypes.insert(GeomAPI_Shape::FACE);
624 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
625 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
626 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
627 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
628 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
630 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
631 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
632 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
633 anAllowedTypes.insert(GeomAPI_Shape::FACE);
634 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
635 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
636 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
637 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
639 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
640 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
641 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
644 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
645 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
646 theError = "Error: Selected shape has the wrong type.";
655 //==================================================================================================
656 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
657 const std::list<std::string>& theArguments,
658 Events_InfoMessage& theError) const
660 AttributeSelectionListPtr anAttrSelectionList =
661 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
662 if(!anAttrSelectionList.get()) {
664 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
668 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
669 // Check all selected entities are sub-shapes of single solid
670 GeomShapePtr aBaseSolid;
671 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
672 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
673 if(!anAttrSelection.get()) {
674 theError = "Error: Empty attribute selection.";
677 ResultPtr aContext = anAttrSelection->context();
678 if(!aContext.get()) {
679 FeaturePtr aContFeat = anAttrSelection->contextFeature();
680 if (!aContFeat.get() || !aContFeat->results().size() ||
681 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
682 theError = "Error: Empty selection context.";
685 if (aContFeat->results().size() == 1)
686 aContext = aContFeat->firstResult();
688 theError = "Error: Too many shapes selected.";
693 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
694 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
696 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
697 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
698 theError = "Error: Not all selected shapes are sub-shapes of solids.";
703 aBaseSolid = anOwner;
704 else if (!aBaseSolid->isEqual(anOwner)) {
705 theError = "Error: Sub-shapes of different solids have been selected.";
713 //==================================================================================================
714 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
715 const std::list<std::string>& theArguments,
716 Events_InfoMessage& theError) const
718 AttributeSelectionListPtr anAttrSelectionList =
719 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
720 if(!anAttrSelectionList.get()) {
721 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
725 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
726 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
728 //GeomValidators_BodyShapes aBodyValidator;
729 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
733 GeomValidators_FeatureKind aFeatureKindValidator;
734 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
738 ResultPtr aContext = aSelectAttr->context();
739 ResultConstructionPtr aResultConstruction =
740 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
741 if(aResultConstruction.get()) {
742 theError = "Error: Only body shapes and construction planes are allowed for selection.";
746 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
747 if(aResultBody.get()) {
750 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
751 if(aResultFeature.get()) {
753 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
754 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
755 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
756 if (aBody.get() && !aBody->isDisabled())
763 theError = "Error: Only body shapes and construction planes are allowed for selection.";
771 //==================================================================================================
772 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
773 const std::list<std::string>& theArguments,
774 Events_InfoMessage& theError) const
776 AttributeSelectionListPtr aSubShapesAttrList =
777 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
778 if(!aSubShapesAttrList.get()) {
780 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
784 static const std::string aBaseShapeID = "base_shape";
785 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
786 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
788 if(!aShapeAttrSelection.get()) {
789 theError = "Error: Could not get \"%1\" attribute.";
790 theError.arg(aBaseShapeID);
794 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
795 ResultPtr aContext = aShapeAttrSelection->context();
796 if(!aContext.get()) {
797 theError = "Error: Empty context.";
800 if(!aBaseShape.get()) {
801 aBaseShape = aContext->shape();
803 if(!aBaseShape.get()) {
804 theError = "Error: Empty base shape.";
808 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
809 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
810 bool isSameFound = false;
811 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
812 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
813 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt) {
814 if ((*anIt)->isEqual(aShapeToAdd)) {
820 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
828 //==================================================================================================
829 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
830 const std::shared_ptr<ModelAPI_Feature>& theFeature,
831 const std::list<std::string>& theArguments,
832 Events_InfoMessage& theError) const
834 static const std::string aBaseShapeID = "base_shape";
835 static const std::string aSubShapesID = "subshapes_to_keep";
837 if(theFeature->getKind() != "Remove_SubShapes") {
838 theError = "Error: Feature \"%1\" does not supported by this validator.";
839 theError.arg(theFeature->getKind());
843 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
844 if(!aShapeAttrSelection.get()) {
845 theError = "Error: Could not get \"%1\" attribute.";
846 theError.arg(aBaseShapeID);
850 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
851 if(!aSubShapesAttrList.get()) {
852 theError = "Error: Could not get \"%1\" attribute.";
853 theError.arg(aSubShapesID);
858 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
859 if(!aBaseShape.get()) {
860 theError = "Error: Base shape is empty.";
863 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
865 if (aSubShapesAttrList->size() == 0) {
866 theError = "Error: Resulting shape is not valid.";
870 // Copy sub-shapes from list to new shape.
871 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
872 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
873 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
874 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
878 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
879 theError = "Error: Resulting shape is not valid.";
886 //==================================================================================================
887 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
888 const std::list<std::string>& theArguments,
889 Events_InfoMessage& theError) const
891 AttributeSelectionListPtr aBaseObjectsAttrList =
892 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
893 if(!aBaseObjectsAttrList.get()) {
894 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
895 theError.arg(FeaturesPlugin_Union::ID());
899 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
900 bool isSameFound = false;
901 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
902 ResultPtr aContext = anAttrSelectionInList->context();
903 if (!aContext.get()) {
904 theError = "Error: selection is invalid.";
908 ResultConstructionPtr aConstruction =
909 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
910 if(aConstruction.get()) {
911 theError = "Error: Result construction not allowed for selection.";
915 GeomShapePtr aShape = anAttrSelectionInList->value();
916 GeomShapePtr aContextShape = aContext->shape();
917 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
918 theError = "Error: Local selection not allowed.";
922 ResultBodyPtr aResult =
923 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
928 if(aResult->numberOfSubs() > 0) {
929 theError = "Error: Whole compsolids not allowed for selection.";
937 //==================================================================================================
938 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
939 const std::shared_ptr<ModelAPI_Feature>& theFeature,
940 const std::list<std::string>& theArguments,
941 Events_InfoMessage& theError) const
943 // Check feature kind.
944 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
945 theError = "Error: This validator supports only \"%1\" feature.";
946 theError.arg(FeaturesPlugin_Union::ID());
950 // Get base objects attribute list.
951 AttributeSelectionListPtr aBaseObejctsAttrList =
952 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
953 if(!aBaseObejctsAttrList.get()) {
954 theError = "Error: Could not get \"%1\" attribute.";
955 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
960 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
961 ListOfShape aBaseShapesList;
962 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
963 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
964 GeomShapePtr aShape = anAttrSelectionInList->value();
968 aBaseShapesList.push_back(aShape);
969 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
970 GeomAPI_Shape::COMPSOLID;
973 // Make compound and find connected.
974 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
975 ListOfShape aCombined, aFree;
976 GeomAlgoAPI_ShapeTools::combineShapes(
982 if(aFree.size() > 0 || aCombined.size() > 1) {
983 theError = "Error: Not all shapes have shared topology.";
990 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
991 const std::list<std::string>& theArguments,
992 Events_InfoMessage& theError) const
994 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
995 theError = "Error: The attribute with the %1 type is not processed";
996 theError.arg(theAttribute->attributeType());
1000 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1002 ObjectPtr aRefObject = aRefAttribute->value();
1003 if (!aRefObject.get()) {
1004 theError = "Error: Empty feature.";
1008 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1009 if (!aRefFeature.get()) {
1010 theError = "Error: Empty feature.";
1013 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1014 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1016 size_t aConcealedResults = aResults.size();
1017 if (!aConcealedResults && !theArguments.empty()) {
1018 // find if these results are touched by the feature in another attribute
1019 std::list<std::string>::const_iterator anIt = theArguments.begin();
1020 std::string aRecoveredList = *anIt;
1021 if (!aRecoveredList.empty()) {
1022 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1023 theAttribute->owner()->data()->reflist(aRecoveredList);
1024 if (aParameterList.get())
1025 aConcealedResults = aParameterList->size();
1029 if (aConcealedResults == 0)
1030 theError = "Error: No concealed results.";
1032 return theError.empty();
1035 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1036 const std::list<std::string>& theArguments,
1037 Events_InfoMessage& theError) const
1039 static std::list<std::string> aEdgeArg(1, "circle");
1040 static std::list<std::string> aFaceArg(1, "cylinder");
1042 Events_InfoMessage aError;
1043 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1045 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1047 theError = "The shape neither circle nor cylinder";
1052 //=================================================================================================
1053 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1054 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1055 const std::list<std::string>& theArguments,
1056 Events_InfoMessage& theError) const
1058 if (theArguments.size() != 2)
1060 theError = "Wrong number of arguments (expected 2).";
1064 int anObjectsNb = 0, aToolsNb = 0;
1065 //int anOperationType = 0;
1067 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1069 bool isAllInSameCompSolid = true;
1070 ResultBodyPtr aCompSolid;
1072 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1075 anObjectsNb = anAttrSelList->size();
1076 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1078 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1079 ResultPtr aContext = anAttr->context();
1080 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1081 if (aResCompSolidPtr.get())
1083 if (aCompSolid.get())
1085 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1089 aCompSolid = aResCompSolidPtr;
1094 isAllInSameCompSolid = false;
1102 anAttrSelList = theFeature->selectionList(*anIt);
1105 aToolsNb = anAttrSelList->size();
1106 if (isAllInSameCompSolid)
1108 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1110 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1111 ResultPtr aContext = anAttr->context();
1112 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1113 if (aResCompSolidPtr.get())
1115 if (aCompSolid.get())
1117 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1121 aCompSolid = aResCompSolidPtr;
1126 isAllInSameCompSolid = false;
1134 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1135 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1136 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1138 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1141 if (anObjectsNb + aToolsNb < 2)
1143 theError = "Not enough arguments for Fuse operation.";
1146 else if (isAllInSameCompSolid)
1148 theError = "Operations only between sub-shapes of the same shape not allowed.";
1154 if (anObjectsNb < 1)
1156 theError = "Objects not selected.";
1161 theError = "Tools not selected.";
1164 if (isAllInSameCompSolid)
1166 theError = "Operations only between sub-shapes of the same shape not allowed.";
1174 //=================================================================================================
1175 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1176 std::string theAttribute)
1178 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1186 //==================================================================================================
1187 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1188 const AttributePtr& theAttribute,
1189 const std::list<std::string>& theArguments,
1190 Events_InfoMessage& theError) const
1192 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1193 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1195 AttributeSelectionListPtr anAttrSelectionList =
1196 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1197 if (!aFeature.get() || !anAttrSelectionList.get()) {
1199 "Error: Validator used in wrong feature or attribute";
1203 AttributeSelectionListPtr anOtherAttrSelectionList;
1204 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1205 anOtherAttrSelectionList =
1206 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1208 anOtherAttrSelectionList =
1209 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1212 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1213 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1214 GeomPlanePtr aFacesPln;
1216 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1217 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1219 if (anAttrSelection->contextFeature().get()) {
1220 theError = "Error: Features not allowed for selection.";
1224 ResultPtr aContext = anAttrSelection->context();
1225 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1226 GeomShapePtr aContextShape = aContext->shape();
1227 if (!aShape.get()) {
1228 aShape = aContextShape;
1231 if (aShape->isSolid() || aShape->isCompSolid()) {
1232 aSelectedShapesType = GeomAPI_Shape::SOLID;
1233 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1234 if (aResCompSolidPtr.get()) {
1235 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1236 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1239 aSelectedShapesType = GeomAPI_Shape::FACE;
1240 GeomAPI_Face aFace(aShape);
1241 aFacesPln = aFace.getPlane();
1246 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1247 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1248 if (!anAttrSelection.get()) {
1249 theError = "Error: Empty attribute selection.";
1253 if (anAttrSelection->contextFeature().get()) {
1254 theError = "Error: Features not allowed for selection.";
1258 ResultPtr aContext = anAttrSelection->context();
1259 if(!aContext.get()) {
1260 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1261 if (!aContFeat.get() || !aContFeat->results().size() ||
1262 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1263 theError = "Error: Empty selection context.";
1267 ResultConstructionPtr aResultConstruction =
1268 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1269 if (aResultConstruction.get()) {
1270 theError = "Error: Result construction not allowed for selection.";
1273 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1274 GeomShapePtr aContextShape = aContext->shape();
1275 if (!aShape.get()) {
1276 aShape = aContextShape;
1278 if (!aShape.get()) {
1279 theError = "Error: Empty shape.";
1282 if (!aShape->isEqual(aContextShape)) {
1283 theError = "Error: Local selection not allowed.";
1287 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1288 // Other list is empty.
1289 if (aShape->isSolid() || aShape->isCompSolid()) {
1290 aSelectedShapesType = GeomAPI_Shape::SOLID;
1292 aSelectedShapesType = GeomAPI_Shape::FACE;
1293 GeomAPI_Face aFace(aShape);
1294 aFacesPln = aFace.getPlane();
1296 if (!aFacesPln.get()) {
1297 theError = "Error: Only planar faces allowed.";
1303 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1304 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1305 theError = "Error: Selected shapes should have the same type.";
1309 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1310 if (aResCompSolidPtr.get()) {
1311 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1312 if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) {
1313 theError = "Error: Solids from compsolid in other list not allowed.";
1318 GeomAPI_Face aFace(aShape);
1319 GeomPlanePtr aPln = aFace.getPlane();
1322 theError = "Error: Only planar faces allowed.";
1326 if (!aFacesPln->isCoincident(aPln)) {
1327 theError = "Error: Only coincident faces allowed.";
1336 //==================================================================================================
1337 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1338 const std::list<std::string>& theArguments,
1339 Events_InfoMessage& theError) const
1341 if (!theAttribute.get()) {
1342 theError = "Error: empty selection.";
1345 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1346 AttributeSelectionListPtr anAttrSelectionList =
1347 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1348 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1349 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1350 if (!anAttrSelection.get()) {
1351 theError = "Error: empty attribute selection.";
1354 ResultPtr aContext = anAttrSelection->context();
1355 if(!aContext.get()) {
1356 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1357 if (!aContFeat.get() || !aContFeat->results().size() ||
1358 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1359 theError = "Error: Empty selection context.";
1363 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1364 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1365 if (!aFeature.get()) {
1366 theError = "Error: empty feature.";
1369 std::string aFeatureKind = aFeature->getKind();
1370 if (aFeatureKind == "Sketch" ||
1371 aFeatureKind == "Plane" ||
1372 aFeatureKind == "Axis") {
1373 theError = "Error: %1 shape is not allowed for selection.";
1374 theError.arg(aFeatureKind);
1377 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1378 if (!aShape.get()) {
1379 GeomShapePtr aContextShape = aContext->shape();
1380 aShape = aContextShape;
1382 if (!aShape.get()) {
1383 theError = "Error: empty shape.";
1386 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1387 theError = "Error: Local selection not allowed.";
1391 int aShapeType = aShape->shapeType();
1392 // Allow to select edges, faces and solids.
1393 if (aShapeType != GeomAPI_Shape::EDGE &&
1394 aShapeType != GeomAPI_Shape::FACE &&
1395 aShapeType != GeomAPI_Shape::SOLID &&
1396 aShapeType != GeomAPI_Shape::COMPSOLID &&
1397 aShapeType != GeomAPI_Shape::COMPOUND) {
1398 theError = "Error: selected shape has the wrong type.";
1406 //==================================================================================================
1407 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1408 const AttributePtr& theAttribute,
1409 const std::list<std::string>& theArguments,
1410 Events_InfoMessage& theError) const
1412 AttributeSelectionListPtr anAttrSelectionList =
1413 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1414 if (!anAttrSelectionList.get()) {
1416 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1420 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1421 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1422 if (!anAttrSelection.get()) {
1423 theError = "Error: Empty attribute selection.";
1426 ResultPtr aContext = anAttrSelection->context();
1427 if(!aContext.get()) {
1428 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1429 if (!aContFeat.get() || !aContFeat->results().size() ||
1430 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1431 theError = "Error: Empty selection context.";
1435 ResultConstructionPtr aResultConstruction =
1436 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1437 if (aResultConstruction.get()) {
1438 theError = "Error: Result construction not allowed for selection.";
1441 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1442 if (!aShape.get()) {
1443 GeomShapePtr aContextShape = aContext->shape();
1444 aShape = aContextShape;
1446 if (!aShape.get()) {
1447 theError = "Error: Empty shape.";
1450 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1451 theError = "Error: Local selection not allowed.";
1459 //=================================================================================================
1460 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1461 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1462 const std::list<std::string>& theArguments,
1463 Events_InfoMessage& theError) const
1465 if (theArguments.size() != 2) {
1466 theError = "Wrong number of arguments (expected 2).";
1470 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1471 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1473 int anObjectsNb = 0, aToolsNb = 0;
1475 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1477 bool isAllInSameCompSolid = true;
1478 ResultBodyPtr aCompSolid;
1480 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1481 if (anAttrSelList) {
1482 anObjectsNb = anAttrSelList->size();
1483 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1484 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1485 ResultPtr aContext = anAttr->context();
1486 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1487 if (aResCompSolidPtr.get()) {
1488 if (aCompSolid.get()) {
1489 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1491 aCompSolid = aResCompSolidPtr;
1494 isAllInSameCompSolid = false;
1501 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1502 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1503 anAttrSelList = theFeature->selectionList(*anIt);
1504 if (anAttrSelList) {
1505 aToolsNb = anAttrSelList->size();
1506 if (isAllInSameCompSolid) {
1507 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1508 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1509 ResultPtr aContext = anAttr->context();
1510 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1511 if (aResCompSolidPtr.get()) {
1512 if (aCompSolid.get()) {
1513 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1515 aCompSolid = aResCompSolidPtr;
1518 isAllInSameCompSolid = false;
1528 if (anObjectsNb + aToolsNb < 2) {
1529 theError = "Not enough arguments for Fuse operation.";
1531 } else if (isAllInSameCompSolid) {
1532 theError = "Operations only between sub-shapes of the same shape not allowed.";
1539 //=================================================================================================
1540 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1541 std::string theFeature,
1542 std::string theAttribute)
1544 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1551 //==================================================================================================
1552 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1553 const AttributePtr& theAttribute,
1554 const std::list<std::string>& theArguments,
1555 Events_InfoMessage& theError) const
1557 AttributeSelectionListPtr anAttrSelectionList =
1558 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1559 if (!anAttrSelectionList.get()) {
1561 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1565 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1566 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1567 if (!anAttrSelection.get()) {
1568 theError = "Error: Empty attribute selection.";
1571 ResultPtr aContext = anAttrSelection->context();
1572 if (!aContext.get()) {
1573 theError = "Error: Empty selection context.";
1576 ResultConstructionPtr aResultConstruction =
1577 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1578 if (aResultConstruction.get()) {
1579 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1580 theError = "Error: Result construction not allowed for selection.";
1584 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1585 GeomShapePtr aContextShape = aContext->shape();
1586 if (!aShape.get()) {
1587 aShape = aContextShape;
1589 if (!aShape.get()) {
1590 theError = "Error: Empty shape.";
1593 if (!aShape->isEqual(aContextShape)) {
1594 theError = "Error: Local selection not allowed.";
1598 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1599 theError = "Error: Result construction should be plane.";
1607 //=================================================================================================
1608 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1609 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1610 const std::list<std::string>& theArguments,
1611 Events_InfoMessage& theError) const
1613 if (theArguments.size() != 2) {
1614 theError = "Wrong number of arguments (expected 2).";
1618 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1619 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1621 int anObjectsNb = 0, aToolsNb = 0;
1623 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1625 bool isAllInSameCompSolid = true;
1626 ResultBodyPtr aCompSolid;
1628 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1629 if (anAttrSelList) {
1630 anObjectsNb = anAttrSelList->size();
1633 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1634 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1636 if (!isSimpleMode) {
1637 anAttrSelList = theFeature->selectionList(*anIt);
1638 if (anAttrSelList) {
1639 aToolsNb = anAttrSelList->size();
1643 if ((isSimpleMode && anObjectsNb < 2)
1644 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1645 theError = "Not enough arguments for Fuse operation.";
1650 //=================================================================================================
1651 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1652 std::string theFeature,
1653 std::string theAttribute)