1 // Copyright (C) 2014-2019 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 email : webmaster.salome@opencascade.com
20 #include "FeaturesPlugin_Validators.h"
22 #include "FeaturesPlugin_Boolean.h"
23 #include "FeaturesPlugin_BooleanFuse.h"
24 #include "FeaturesPlugin_BooleanCommon.h"
25 #include "FeaturesPlugin_BooleanSmash.h"
26 #include "FeaturesPlugin_Pipe.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()) {
71 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
76 GeomShapePtr aPathShape = aPathAttrSelection->value();
77 ResultPtr aContext = aPathAttrSelection->context();
79 theError = "Error: Empty context.";
82 GeomShapePtr aContextShape = aContext->shape();
83 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
84 !aPathShape->isEqual(aContextShape)) {
85 theError = "Error: Local selection of wires not allowed.";
92 //==================================================================================================
93 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute,
94 const std::list<std::string>& theArguments,
95 Events_InfoMessage& theError) const
97 AttributeSelectionListPtr anAttrSelectionList =
98 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
99 if(!anAttrSelectionList.get()) {
102 "Error: This validator can only work with selection list attributes in \"Pipe\" feature.";
106 std::shared_ptr<FeaturesPlugin_Pipe> aFeature =
107 std::dynamic_pointer_cast<FeaturesPlugin_Pipe>(theAttribute->owner());
109 AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
110 if (!aPathSelection.get()) {
112 theError = "Error: Path not selected.";
117 GeomShapePtr aPathShape = aPathSelection->value();
118 if (!aPathShape.get()) {
119 ResultPtr aContext = aPathSelection->context();
120 if (!aContext.get()) {
121 FeaturePtr aContFeat = aPathSelection->contextFeature();
122 if (!aContFeat.get() || !aContFeat->results().size()) {
123 theError = "Error: Empty selection context.";
127 aPathShape = aContext->shape();
130 if (!aPathShape.get()) {
131 theError = "Error: Empty path shape.";
135 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
136 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
137 if (!anAttrSelection.get()) {
138 theError = "Error: Empty attribute selection.";
141 ResultPtr aContext = anAttrSelection->context();
142 if (!aContext.get()) {
143 FeaturePtr aContFeat = anAttrSelection->contextFeature();
144 if (!aContFeat.get() || !aContFeat->results().size()) {
145 theError = "Error: Empty selection context.";
149 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
150 if (!aShape.get() && aContext.get()) {
151 GeomShapePtr aContextShape = aContext->shape();
152 aShape = aContextShape;
155 theError = "Error: Empty shape.";
159 if (!aPathShape->isSubShape(aShape)) {
160 theError = "Error: Location should be a vertex subshape from path shape.";
168 //==================================================================================================
170 bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid(
171 const std::shared_ptr<ModelAPI_Feature>& theFeature,
172 const std::list<std::string>& theArguments,
173 Events_InfoMessage& theError) const
175 static const std::string aCreationMethodID = "creation_method";
176 static const std::string aBaseObjectsID = "base_objects";
177 static const std::string aLocationsID = "locations_objects";
179 if(theFeature->getKind() != "Pipe") {
180 theError = "Error: Feature \"%1\" does not supported by this validator.";
181 theError.arg(theFeature->getKind());
185 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
186 if(!aCreationMethodAttr.get()) {
187 theError = "Error: Could not get \"%1\" attribute.";
188 theError.arg(aCreationMethodID);
192 if(aCreationMethodAttr->value() != "locations") {
196 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
197 if(!aBaseObjectsSelectionList.get()) {
198 theError = "Error: Could not get \"%1\" attribute.";
199 theError.arg(aBaseObjectsID);
203 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
204 if(!aLocationsSelectionList.get()) {
205 theError = "Error: Could not get \"%1\" attribute.";
206 theError.arg(aBaseObjectsID);
210 if(aLocationsSelectionList->size() > 0 &&
211 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
212 theError = "Error: Number of locations should be the same as base objects.";
220 //==================================================================================================
221 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
222 const std::list<std::string>& theArguments,
223 Events_InfoMessage& theError) const
226 if(theArguments.empty()) {
227 theError = "Error: Validator parameters is empty.";
232 // Checking attribute.
233 if(!isValidAttribute(theAttribute, theArguments, theError)) {
234 if(theError.empty()) {
235 theError = "Error: Attribute contains unacceptable shape.";
240 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
241 std::string anAttributeType = theAttribute->attributeType();
242 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
243 AttributeSelectionListPtr aListAttr =
244 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
245 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
246 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
247 ResultPtr aContext = aSelectionAttr->context();
248 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
249 theError = "Error: Empty context.";
253 ResultConstructionPtr aResultConstruction =
254 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
255 if(!aResultConstruction.get()) {
256 // It is not a result construction.
257 // If shape is compound check that it contains only faces, edges or vertices.
258 GeomShapePtr aShape = aSelectionAttr->value();
260 if (aContext.get()) {
261 aShape = aContext->shape();
263 theError = "Error: Empty context.";
268 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
269 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
270 GeomShapePtr aSubShape = anIt.current();
271 if(aSubShape->shapeType() != GeomAPI_Shape::VERTEX
272 && aSubShape->shapeType() != GeomAPI_Shape::EDGE
273 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
274 theError = "Error: Compound should contain only faces, edges or vertices.";
283 GeomShapePtr aShape = aSelectionAttr->value();
284 GeomShapePtr aContextShape = aResultConstruction->shape();
286 // Whole sketch selected.
289 // Object from sketch selected.
290 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
291 GeomShapePtr aWire = anExp.current();
292 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
293 theError = "Error: Wire with wrong orientation selected.";
297 if(aSelectedWiresFromObjects.isBound(aWire)) {
299 "Error: Objects with such wire already selected. Don't allow to select this object.";
303 aSelectedWiresFromObjects.bind(aWire, aWire);
312 //==================================================================================================
313 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
314 const std::shared_ptr<ModelAPI_Feature>& theFeature,
315 const std::list<std::string>& theArguments,
316 Events_InfoMessage& theError) const
318 const std::string aBaseObjectsID = theArguments.front();
320 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
321 if(!aListAttr.get()) {
323 theError = "Error: Could not get \"%1\" attribute.";
324 theError.arg(aBaseObjectsID);
329 std::set<ResultConstructionPtr> aSelectedSketches;
330 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
332 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
333 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
334 ResultPtr aContext = aSelectionAttr->context();
335 if(!aContext.get()) {
336 FeaturePtr aFeature = aSelectionAttr->contextFeature();
337 if (!aFeature.get() || aFeature->results().empty()) {
338 theError = "Error: Empty context.";
341 aContext = aFeature->firstResult();
345 ResultConstructionPtr aResultConstruction =
346 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
347 if(!aResultConstruction.get()) {
348 // It is not a result construction.
352 GeomShapePtr aShape = aSelectionAttr->value();
353 GeomShapePtr aContextShape = aResultConstruction->shape();
355 // Whole sketch selected.
356 aSelectedSketches.insert(aResultConstruction);
358 // Object from sketch selected.
359 aSelectedSketchesFromObjects.insert(aResultConstruction);
364 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
365 anIt != aSelectedSketches.cend();
367 ResultConstructionPtr aResultConstruction = *anIt;
368 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
369 aSelectedSketchesFromObjects.cend()) {
370 theError = "Sketch and objects from it can not be selected at the same time.";
378 //==================================================================================================
379 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
380 const std::list<std::string>& theArguments,
381 Events_InfoMessage& theError) const
383 if(!theAttribute.get()) {
385 theError = "Error: Empty attribute.";
390 std::string anAttributeType = theAttribute->attributeType();
391 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
392 AttributeSelectionListPtr aListAttr =
393 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
394 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
395 // If at least one attribute is invalid, the result is false.
396 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
400 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
402 AttributeSelectionPtr anAttr =
403 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
404 ResultPtr aContext = anAttr->context();
405 if(!aContext.get() && !anAttr->contextFeature().get()) {
406 theError = "Error: Attribute have empty context.";
410 GeomShapePtr aShape = anAttr->value();
411 GeomShapePtr aContextShape;
412 if(!aShape.get() && aContext.get()) {
413 aContextShape = aContext->shape();
414 aShape = aContextShape;
417 theError = "Error: Empty shape selected";
421 ResultConstructionPtr aConstruction;
422 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
423 aContext = anAttr->contextFeature()->firstResult();
426 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
427 if(aConstruction.get()) {
428 // Construction selected. Check that it is not infinite.
429 if(aConstruction->isInfinite()) {
430 theError = "Error: Infinite constructions is not allowed as base.";
434 GeomShapePtr aContextShape = aContext->shape();
435 if(aShape->isEqual(aContextShape)) {
436 // Whole construction selected. Check that it have faces.
437 if(aConstruction->facesNum() > 0) {
441 // Shape on construction selected. Check that it is a face or wire.
442 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
443 aShape->shapeType() == GeomAPI_Shape::FACE) {
450 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
451 // Local selection on body does not allowed.
453 "Error: Selected shape is in the local selection. Only global selection is allowed.";
457 // Check that object is a shape with allowed type.
458 GeomValidators_ShapeType aShapeTypeValidator;
459 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
460 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
461 "wires on sketch, whole sketch(if it has at least one face), "
462 "and whole objects with shape types: %1";
463 std::string anArgumentString;
464 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
465 if (!anArgumentString.empty())
466 anArgumentString += ", ";
467 anArgumentString += *anIt;
469 theError.arg(anArgumentString);
475 theError = "Error: Attribute \"%1\" does not supported by this validator.";
476 theError.arg(anAttributeType);
484 //==================================================================================================
486 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
487 const std::list<std::string>& theArguments,
488 Events_InfoMessage& theError) const
490 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
491 theError = "Error: The attribute with the %1 type is not processed";
492 theError.arg(theAttribute->attributeType());
495 if (theArguments.size() != 2) {
496 theError = "Error: Wrong parameters in XML definition for %1 type";
497 theError.arg(theAttribute->attributeType());
500 // first argument is for the base attribute, second - for skipping feature kind
501 std::list<std::string>::const_iterator anIt = theArguments.begin();
502 std::string aBaseAttributeId = *anIt;
503 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
504 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
505 if (!aBaseAttribute.get()) {
506 theError = "Wrong parameters in XML definition for %1 type";
507 theError.arg(theAttribute->attributeType());
510 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
511 // this validator is not necessary anymore
515 std::string aFeatureAttributeKind = *anIt;
516 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
517 // check whether the selection is on the sketch
518 std::list<std::string> anArguments;
519 anArguments.push_back(aFeatureAttributeKind);
521 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
522 bool aPlanarFace = false;
523 // check if selection has Face selected
524 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
526 anArguments.push_back("face");
527 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
529 bool aValid = !aFeatureKind && aPlanarFace;
534 //==================================================================================================
535 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
536 const std::shared_ptr<ModelAPI_Feature>& theFeature,
537 const std::list<std::string>& theArguments,
538 Events_InfoMessage& theError) const
540 if(theArguments.size() != 2) {
542 theError = "Error: Validator should be used with 2 parameters for extrusion.";
547 std::list<std::string>::const_iterator
548 anArgsIt = theArguments.begin(), aLast = theArguments.end();
550 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
553 GeomShapePtr aDirShape;
554 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
556 aDirShape = aSelAttr->value();
557 if(!aDirShape.get()) {
558 ResultPtr aContext = aSelAttr->context();
559 if(!aContext.get()) {
560 FeaturePtr aFeature = aSelAttr->contextFeature();
561 if (aFeature.get() && !aFeature->results().empty()) {
562 aContext = aFeature->firstResult();
567 aDirShape = aContext->shape();
570 if (aDirShape.get() && aDirShape->isCompound()) {
571 GeomAPI_ShapeIterator anIt(aDirShape);
572 aDirShape = anIt.current();
577 if(!aDirShape.get() || aDirShape->isNull() ||
578 aDirShape->shapeType() != GeomAPI_Shape::EDGE) {
579 // Check that dir can be empty.
580 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
581 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
582 "can not be used with default value. Select direction for extrusion.";
583 theError.arg(*anArgsIt);
590 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
592 // If faces selected check that direction not parallel with them.
593 AttributeSelectionListPtr aListAttr =
594 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
595 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
596 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
597 GeomShapePtr aShapeInList = anAttr->value();
598 if(!aShapeInList.get()) {
599 aShapeInList = anAttr->context()->shape();
601 bool isParallel = true;
602 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
603 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
604 for(GeomAPI_ShapeExplorer
605 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
606 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
607 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
612 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
613 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
614 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
615 if(aPlanarEdges.get()) {
616 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
617 if(aDirEdge->isLine()) {
618 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
619 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
631 "Error: Direction is parallel to one of the selected face or face on selected shell.";
639 //==================================================================================================
640 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
641 Events_InfoMessage& theError) const
644 if(!theAttribute.get()) {
649 std::string anAttributeType = theAttribute->attributeType();
650 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
651 AttributeSelectionListPtr aListAttr =
652 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
653 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
654 // If at least one attribute is invalid, the result is false.
655 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
659 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
661 AttributeSelectionPtr anAttr =
662 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
663 ResultPtr aContext = anAttr->context();
664 if(!aContext.get() && !anAttr->contextFeature().get()) {
668 GeomShapePtr aShape = anAttr->value();
669 if(!aShape.get() && aContext.get()) {
670 GeomShapePtr aContextShape = aContext->shape();
671 aShape = aContextShape;
677 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
678 aShape->shapeType() == GeomAPI_Shape::EDGE ||
679 !aShape->isPlanar()) {
689 //==================================================================================================
690 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
691 const std::list<std::string>& theArguments,
692 Events_InfoMessage& theError) const
694 AttributeSelectionListPtr anAttrSelectionList =
695 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
696 if(!anAttrSelectionList.get()) {
699 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
703 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
704 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
705 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
707 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
708 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
709 if(!anAttrSelection.get()) {
710 theError = "Error: Empty attribute selection.";
713 ResultPtr aContext = anAttrSelection->context();
714 if(!aContext.get()) {
715 FeaturePtr aContFeat = anAttrSelection->contextFeature();
716 if (!aContFeat.get() || !aContFeat->results().size()) {
717 theError = "Error: Empty selection context.";
721 ResultConstructionPtr aResultConstruction =
722 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
723 if(aResultConstruction.get()) {
724 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
725 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
726 theError = "Error: Result construction not allowed for selection.";
730 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
731 if(!aShape.get() && aContext.get()) {
732 GeomShapePtr aContextShape = aContext->shape();
733 aShape = aContextShape;
736 theError = "Error: Empty shape.";
739 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
740 theError = "Error: Local selection not allowed.";
744 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
745 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
746 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
747 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
748 anAllowedTypes.insert(GeomAPI_Shape::FACE);
749 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
750 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
751 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
752 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
753 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
755 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
756 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
757 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
758 anAllowedTypes.insert(GeomAPI_Shape::FACE);
759 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
760 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
761 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
762 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
764 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
765 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
766 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
769 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
770 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
771 theError = "Error: Selected shape has the wrong type.";
780 //==================================================================================================
781 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
782 const std::list<std::string>& theArguments,
783 Events_InfoMessage& theError) const
785 AttributeSelectionListPtr anAttrSelectionList =
786 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
787 if(!anAttrSelectionList.get()) {
790 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
795 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
796 // Check all selected entities are sub-shapes of single solid
797 GeomShapePtr aBaseSolid;
798 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
799 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
800 if(!anAttrSelection.get()) {
801 theError = "Error: Empty attribute selection.";
804 ResultPtr aContext = anAttrSelection->context();
805 if(!aContext.get()) {
806 FeaturePtr aContFeat = anAttrSelection->contextFeature();
807 if (!aContFeat.get() || !aContFeat->results().size() ||
808 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
809 theError = "Error: Empty selection context.";
812 if (aContFeat->results().size() == 1)
813 aContext = aContFeat->firstResult();
815 theError = "Error: Too many shapes selected.";
820 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
821 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
824 theError = "Error: wrong feature is selected.";
828 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
829 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
830 theError = "Error: Not all selected shapes are sub-shapes of solids.";
835 aBaseSolid = anOwner;
836 else if (!aBaseSolid->isEqual(anOwner)) {
837 theError = "Error: Sub-shapes of different solids have been selected.";
845 //==================================================================================================
846 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
847 const std::list<std::string>& theArguments,
848 Events_InfoMessage& theError) const
850 AttributeSelectionListPtr anAttrSelectionList =
851 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
852 if(!anAttrSelectionList.get()) {
854 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
859 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
860 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
862 //GeomValidators_BodyShapes aBodyValidator;
863 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
867 GeomValidators_FeatureKind aFeatureKindValidator;
868 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
872 ResultPtr aContext = aSelectAttr->context();
873 ResultConstructionPtr aResultConstruction =
874 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
875 if(aResultConstruction.get()) {
876 theError = "Error: Only body shapes and construction planes are allowed for selection.";
880 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
881 if(aResultBody.get()) {
884 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
885 if(aResultFeature.get()) {
887 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
888 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
889 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
890 if (aBody.get() && !aBody->isDisabled())
897 theError = "Error: Only body shapes and construction planes are allowed for selection.";
905 //==================================================================================================
906 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
907 const std::list<std::string>& theArguments,
908 Events_InfoMessage& theError) const
910 AttributeSelectionListPtr aSubShapesAttrList =
911 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
912 if(!aSubShapesAttrList.get()) {
915 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
920 static const std::string aBaseShapeID = "base_shape";
921 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
922 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
924 if(!aShapeAttrSelection.get()) {
926 theError = "Error: Could not get \"%1\" attribute.";
927 theError.arg(aBaseShapeID);
932 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
933 ResultPtr aContext = aShapeAttrSelection->context();
934 if(!aContext.get()) {
935 theError = "Error: Empty context.";
938 if(!aBaseShape.get()) {
939 aBaseShape = aContext->shape();
941 if(!aBaseShape.get()) {
942 theError = "Error: Empty base shape.";
946 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
947 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
948 bool isSameFound = false;
949 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
950 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
951 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
953 if ((*anIt)->isEqual(aShapeToAdd)) {
959 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
967 //==================================================================================================
968 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
969 const std::shared_ptr<ModelAPI_Feature>& theFeature,
970 const std::list<std::string>& theArguments,
971 Events_InfoMessage& theError) const
973 static const std::string aBaseShapeID = "base_shape";
974 static const std::string aSubShapesID = "subshapes_to_keep";
977 if(theFeature->getKind() != "Remove_SubShapes") {
978 theError = "Error: Feature \"%1\" does not supported by this validator.";
979 theError.arg(theFeature->getKind());
983 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
984 if(!aShapeAttrSelection.get()) {
985 theError = "Error: Could not get \"%1\" attribute.";
986 theError.arg(aBaseShapeID);
990 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
991 if(!aSubShapesAttrList.get()) {
992 theError = "Error: Could not get \"%1\" attribute.";
993 theError.arg(aSubShapesID);
999 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1000 if(!aBaseShape.get()) {
1001 theError = "Error: Base shape is empty.";
1004 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
1006 if (aSubShapesAttrList->size() == 0) {
1007 theError = "Error: Resulting shape is not valid.";
1011 // Copy sub-shapes from list to new shape.
1012 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1013 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1014 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1015 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
1019 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
1020 theError = "Error: Resulting shape is not valid.";
1027 //==================================================================================================
1029 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
1030 const std::list<std::string>& theArguments,
1031 Events_InfoMessage& theError) const
1033 AttributeSelectionListPtr aBaseObjectsAttrList =
1034 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1035 if(!aBaseObjectsAttrList.get()) {
1036 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1037 theError.arg(FeaturesPlugin_Union::ID());
1041 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1042 bool isSameFound = false;
1043 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1044 ResultPtr aContext = anAttrSelectionInList->context();
1045 if (!aContext.get()) {
1046 theError = "Error: selection is invalid.";
1050 ResultConstructionPtr aConstruction =
1051 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1052 if(aConstruction.get()) {
1053 theError = "Error: Result construction not allowed for selection.";
1057 GeomShapePtr aShape = anAttrSelectionInList->value();
1058 GeomShapePtr aContextShape = aContext->shape();
1059 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1060 theError = "Error: Local selection not allowed.";
1064 ResultBodyPtr aResult =
1065 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1066 if(!aResult.get()) {
1070 if(aResult->numberOfSubs() > 0) {
1071 theError = "Error: Whole compsolids not allowed for selection.";
1080 //==================================================================================================
1081 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1082 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1083 const std::list<std::string>& theArguments,
1084 Events_InfoMessage& theError) const
1087 // Check feature kind.
1088 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1089 theError = "Error: This validator supports only \"%1\" feature.";
1090 theError.arg(FeaturesPlugin_Union::ID());
1094 // Get base objects attribute list.
1095 AttributeSelectionListPtr aBaseObejctsAttrList =
1096 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1097 if(!aBaseObejctsAttrList.get()) {
1098 theError = "Error: Could not get \"%1\" attribute.";
1099 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1105 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1106 ListOfShape aBaseShapesList;
1107 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1108 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1109 GeomShapePtr aShape = anAttrSelectionInList->value();
1110 if (!aShape.get()) {
1113 aBaseShapesList.push_back(aShape);
1114 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1115 GeomAPI_Shape::COMPSOLID;
1118 // Make compound and find connected.
1119 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1120 ListOfShape aResults;
1121 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults);
1123 if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) {
1124 theError = "Error: Not all shapes have shared topology.";
1131 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1132 const std::list<std::string>& theArguments,
1133 Events_InfoMessage& theError) const
1135 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1137 theError = "Error: The attribute with the %1 type is not processed";
1138 theError.arg(theAttribute->attributeType());
1143 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1145 ObjectPtr aRefObject = aRefAttribute->value();
1146 if (!aRefObject.get()) {
1147 theError = "Error: Empty feature.";
1151 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1152 if (!aRefFeature.get()) {
1153 theError = "Error: Empty feature.";
1156 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1157 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1159 size_t aConcealedResults = aResults.size();
1160 if (!aConcealedResults && !theArguments.empty()) {
1161 // find if these results are touched by the feature in another attribute
1162 std::list<std::string>::const_iterator anIt = theArguments.begin();
1163 std::string aRecoveredList = *anIt;
1164 if (!aRecoveredList.empty()) {
1165 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1166 theAttribute->owner()->data()->reflist(aRecoveredList);
1167 if (aParameterList.get())
1168 aConcealedResults = aParameterList->size();
1172 if (aConcealedResults == 0)
1173 theError = "Error: No concealed results.";
1175 return theError.empty();
1178 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1179 const std::list<std::string>& theArguments,
1180 Events_InfoMessage& theError) const
1182 static std::list<std::string> aEdgeArg(1, "circle");
1183 static std::list<std::string> aFaceArg(1, "cylinder");
1185 Events_InfoMessage aError;
1186 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1188 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1190 theError = "The shape neither circle nor cylinder";
1195 //=================================================================================================
1196 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1197 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1198 const std::list<std::string>& theArguments,
1199 Events_InfoMessage& theError) const
1202 if (theArguments.size() != 2)
1204 theError = "Wrong number of arguments (expected 2).";
1209 int anObjectsToolsNb[2] = { 0, 0 };
1211 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1213 bool isAllInSameCompSolid = true;
1214 ResultBodyPtr aCompSolid;
1216 for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
1217 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1220 *anArgNbIt = anAttrSelList->size();
1221 if (isAllInSameCompSolid) {
1222 for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
1224 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1225 ResultPtr aContext = anAttr->context();
1226 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1227 if (aResCompSolidPtr.get())
1229 if (aCompSolid.get())
1231 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1235 aCompSolid = aResCompSolidPtr;
1240 isAllInSameCompSolid = false;
1248 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1249 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1250 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1252 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1255 if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
1257 theError = "Not enough arguments for Fuse operation.";
1260 else if (isAllInSameCompSolid)
1262 theError = "Operations only between sub-shapes of the same shape not allowed.";
1268 if (anObjectsToolsNb[0] < 1) // check number of objects
1270 theError = "Objects not selected.";
1273 if (anObjectsToolsNb[1] < 1) // check number of tools
1275 theError = "Tools not selected.";
1278 if (isAllInSameCompSolid)
1280 theError = "Operations only between sub-shapes of the same shape not allowed.";
1288 //=================================================================================================
1290 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1291 std::string theAttribute)
1293 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1302 //==================================================================================================
1303 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1304 const AttributePtr& theAttribute,
1305 const std::list<std::string>& theArguments,
1306 Events_InfoMessage& theError) const
1308 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1309 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1311 AttributeSelectionListPtr anAttrSelectionList =
1312 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1313 if (!aFeature.get() || !anAttrSelectionList.get()) {
1316 "Error: Validator used in wrong feature or attribute";
1321 AttributeSelectionListPtr anOtherAttrSelectionList;
1322 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1323 anOtherAttrSelectionList =
1324 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1326 anOtherAttrSelectionList =
1327 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1330 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1331 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1332 GeomPlanePtr aFacesPln;
1334 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1335 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1337 if (anAttrSelection->contextFeature().get()) {
1338 theError = "Error: Features not allowed for selection.";
1342 ResultPtr aContext = anAttrSelection->context();
1343 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1344 if (!aShape.get()) {
1345 if (!aContext.get()) {
1346 theError = "Error: Empty selection.";
1349 aShape = aContext->shape();
1352 if (aShape->isSolid() || aShape->isCompSolid()) {
1353 aSelectedShapesType = GeomAPI_Shape::SOLID;
1354 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1355 if (aResCompSolidPtr.get()) {
1356 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1357 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1360 aSelectedShapesType = GeomAPI_Shape::FACE;
1361 GeomAPI_Face aFace(aShape);
1362 aFacesPln = aFace.getPlane();
1367 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1368 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1369 if (!anAttrSelection.get()) {
1370 theError = "Error: Empty attribute selection.";
1374 if (anAttrSelection->contextFeature().get()) {
1375 theError = "Error: Features not allowed for selection.";
1379 ResultPtr aContext = anAttrSelection->context();
1380 if(!aContext.get()) {
1381 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1382 if (!aContFeat.get() || !aContFeat->results().size() ||
1383 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1384 theError = "Error: Empty selection context.";
1388 ResultConstructionPtr aResultConstruction =
1389 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1390 if (aResultConstruction.get()) {
1391 theError = "Error: Result construction not allowed for selection.";
1394 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1395 GeomShapePtr aContextShape = aContext->shape();
1396 if (!aShape.get()) {
1397 aShape = aContextShape;
1399 if (!aShape.get()) {
1400 theError = "Error: Empty shape.";
1403 if (!aShape->isEqual(aContextShape)) {
1404 theError = "Error: Local selection not allowed.";
1408 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1409 // Other list is empty.
1410 if (aShape->isSolid() || aShape->isCompSolid()) {
1411 aSelectedShapesType = GeomAPI_Shape::SOLID;
1413 aSelectedShapesType = GeomAPI_Shape::FACE;
1414 GeomAPI_Face aFace(aShape);
1415 aFacesPln = aFace.getPlane();
1417 if (!aFacesPln.get()) {
1418 theError = "Error: Only planar faces allowed.";
1424 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1425 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1426 theError = "Error: Selected shapes should have the same type.";
1430 GeomAPI_Face aFace(aShape);
1431 GeomPlanePtr aPln = aFace.getPlane();
1434 theError = "Error: Only planar faces allowed.";
1438 if (!aFacesPln->isCoincident(aPln)) {
1439 theError = "Error: Only coincident faces allowed.";
1448 //==================================================================================================
1450 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1451 const std::list<std::string>& theArguments,
1452 Events_InfoMessage& theError) const
1454 if (!theAttribute.get()) {
1455 theError = "Error: empty selection.";
1458 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1459 AttributeSelectionListPtr anAttrSelectionList =
1460 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1461 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1462 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1463 if (!anAttrSelection.get()) {
1464 theError = "Error: empty attribute selection.";
1467 ResultPtr aContext = anAttrSelection->context();
1468 if(!aContext.get()) {
1469 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1470 if (!aContFeat.get() || !aContFeat->results().size() ||
1471 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1472 theError = "Error: Empty selection context.";
1476 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1477 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1478 if (!aFeature.get()) {
1479 theError = "Error: empty feature.";
1482 std::string aFeatureKind = aFeature->getKind();
1483 if (aFeatureKind == "Sketch" ||
1484 aFeatureKind == "Plane" ||
1485 aFeatureKind == "Axis") {
1486 theError = "Error: %1 shape is not allowed for selection.";
1487 theError.arg(aFeatureKind);
1490 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1491 if (!aShape.get()) {
1492 GeomShapePtr aContextShape = aContext->shape();
1493 aShape = aContextShape;
1495 if (!aShape.get()) {
1496 theError = "Error: empty shape.";
1499 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1500 theError = "Error: Local selection not allowed.";
1504 int aShapeType = aShape->shapeType();
1505 // Allow to select edges, faces and solids.
1506 if (aShapeType != GeomAPI_Shape::EDGE &&
1507 aShapeType != GeomAPI_Shape::FACE &&
1508 aShapeType != GeomAPI_Shape::SOLID &&
1509 aShapeType != GeomAPI_Shape::COMPSOLID &&
1510 aShapeType != GeomAPI_Shape::COMPOUND) {
1511 theError = "Error: selected shape has the wrong type.";
1520 //==================================================================================================
1522 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1523 const AttributePtr& theAttribute,
1524 const std::list<std::string>& theArguments,
1525 Events_InfoMessage& theError) const
1527 AttributeSelectionListPtr anAttrSelectionList =
1528 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1529 if (!anAttrSelectionList.get()) {
1531 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1535 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1536 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1537 if (!anAttrSelection.get()) {
1538 theError = "Error: Empty attribute selection.";
1541 ResultPtr aContext = anAttrSelection->context();
1542 if(!aContext.get()) {
1543 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1544 if (!aContFeat.get() || !aContFeat->results().size() ||
1545 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1546 theError = "Error: Empty selection context.";
1550 ResultConstructionPtr aResultConstruction =
1551 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1552 if (aResultConstruction.get()) {
1553 theError = "Error: Result construction not allowed for selection.";
1556 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1557 if (!aShape.get()) {
1558 GeomShapePtr aContextShape = aContext->shape();
1559 aShape = aContextShape;
1561 if (!aShape.get()) {
1562 theError = "Error: Empty shape.";
1565 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1566 theError = "Error: Local selection not allowed.";
1575 //=================================================================================================
1576 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1577 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1578 const std::list<std::string>& theArguments,
1579 Events_InfoMessage& theError) const
1582 if (theArguments.size() != 2) {
1583 theError = "Wrong number of arguments (expected 2).";
1588 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1589 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1591 int anObjectsNb = 0, aToolsNb = 0;
1593 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1595 bool isAllInSameCompSolid = true;
1596 ResultBodyPtr aCompSolid;
1598 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1599 if (anAttrSelList) {
1600 anObjectsNb = anAttrSelList->size();
1601 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1602 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1603 ResultPtr aContext = anAttr->context();
1604 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1605 if (aResCompSolidPtr.get()) {
1606 if (aCompSolid.get()) {
1607 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1609 aCompSolid = aResCompSolidPtr;
1612 isAllInSameCompSolid = false;
1619 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1620 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1621 anAttrSelList = theFeature->selectionList(*anIt);
1622 if (anAttrSelList) {
1623 aToolsNb = anAttrSelList->size();
1624 if (isAllInSameCompSolid) {
1625 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1626 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1627 ResultPtr aContext = anAttr->context();
1628 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1629 if (aResCompSolidPtr.get()) {
1630 if (aCompSolid.get()) {
1631 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1633 aCompSolid = aResCompSolidPtr;
1636 isAllInSameCompSolid = false;
1646 if (anObjectsNb + aToolsNb < 2) {
1647 theError = "Not enough arguments for Fuse operation.";
1649 } else if (isAllInSameCompSolid) {
1650 theError = "Operations only between sub-shapes of the same shape not allowed.";
1657 //=================================================================================================
1659 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1660 std::string theFeature,
1661 std::string theAttribute)
1663 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1671 //==================================================================================================
1673 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1674 const AttributePtr& theAttribute,
1675 const std::list<std::string>& theArguments,
1676 Events_InfoMessage& theError) const
1678 AttributeSelectionListPtr anAttrSelectionList =
1679 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1680 if (!anAttrSelectionList.get()) {
1682 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1686 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1687 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1688 if (!anAttrSelection.get()) {
1689 theError = "Error: Empty attribute selection.";
1692 ResultPtr aContext = anAttrSelection->context();
1693 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1694 theError = "Error: Empty selection context.";
1697 ResultConstructionPtr aResultConstruction =
1698 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1699 if (aResultConstruction.get()) {
1700 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1701 theError = "Error: Result construction not allowed for selection.";
1705 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1706 GeomShapePtr aContextShape;
1707 if (aContext.get()) {
1708 aContextShape = aContext->shape();
1710 if (!aShape.get()) {
1711 aShape = aContextShape;
1713 if (!aShape.get()) {
1714 theError = "Error: Empty shape.";
1717 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1718 theError = "Error: Local selection not allowed.";
1722 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1723 theError = "Error: Result construction should be plane.";
1732 //=================================================================================================
1733 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1734 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1735 const std::list<std::string>& theArguments,
1736 Events_InfoMessage& theError) const
1738 if (theArguments.size() != 2) {
1740 theError = "Wrong number of arguments (expected 2).";
1745 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1746 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1748 int anObjectsNb = 0, aToolsNb = 0;
1750 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1752 bool isAllInSameCompSolid = true;
1753 ResultBodyPtr aCompSolid;
1755 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1756 if (anAttrSelList) {
1757 anObjectsNb = anAttrSelList->size();
1760 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1761 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1763 if (!isSimpleMode) {
1764 anAttrSelList = theFeature->selectionList(*anIt);
1765 if (anAttrSelList) {
1766 aToolsNb = anAttrSelList->size();
1770 if ((isSimpleMode && anObjectsNb < 2)
1771 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1772 theError = "Not enough arguments for Fuse operation.";
1778 //=================================================================================================
1780 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1781 std::string theFeature,
1782 std::string theAttribute)