1 // Copyright (C) 2014-2022 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_CompositeBoolean.h"
27 #include "FeaturesPlugin_Extrusion.h"
28 #include "FeaturesPlugin_Pipe.h"
29 #include "FeaturesPlugin_Union.h"
31 #include <Events_InfoMessage.h>
33 #include <ModelAPI_Attribute.h>
34 #include <ModelAPI_AttributeDouble.h>
35 #include <ModelAPI_AttributeInteger.h>
36 #include <ModelAPI_AttributeSelectionList.h>
37 #include <ModelAPI_AttributeString.h>
38 #include <ModelAPI_AttributeReference.h>
39 #include <ModelAPI_AttributeRefList.h>
40 #include <ModelAPI_Feature.h>
41 #include <ModelAPI_ResultBody.h>
42 #include <ModelAPI_ResultConstruction.h>
43 #include <ModelAPI_Tools.h>
45 #include <GeomValidators_BodyShapes.h>
46 #include <GeomValidators_Face.h>
47 #include <GeomValidators_FeatureKind.h>
48 #include <GeomValidators_ShapeType.h>
50 #include <GeomAPI_DataMapOfShapeShape.h>
51 #include <GeomAPI_Lin.h>
52 #include <GeomAPI_PlanarEdges.h>
53 #include <GeomAPI_Pln.h>
54 #include <GeomAPI_ShapeExplorer.h>
55 #include <GeomAPI_ShapeIterator.h>
57 #include <GeomAlgoAPI_CompoundBuilder.h>
58 #include <GeomAlgoAPI_MapShapesAndAncestors.h>
59 #include <GeomAlgoAPI_Prism.h>
60 #include <GeomAlgoAPI_ShapeBuilder.h>
61 #include <GeomAlgoAPI_ShapeTools.h>
62 #include <GeomAlgoAPI_WireBuilder.h>
66 #define _USE_MATH_DEFINES
70 #pragma warning(disable: 4100)
73 //==================================================================================================
74 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
75 const std::list<std::string>& theArguments,
76 Events_InfoMessage& theError) const
78 AttributeSelectionPtr aPathAttrSelection =
79 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
80 if(!aPathAttrSelection.get()) {
82 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
87 GeomShapePtr aPathShape = aPathAttrSelection->value();
88 ResultPtr aContext = aPathAttrSelection->context();
90 theError = "Error: Empty context.";
93 GeomShapePtr aContextShape = aContext->shape();
94 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
95 !aPathShape->isEqual(aContextShape)) {
96 theError = "Error: Local selection of wires not allowed.";
103 //==================================================================================================
104 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute,
105 const std::list<std::string>& theArguments,
106 Events_InfoMessage& theError) const
108 AttributeSelectionListPtr anAttrSelectionList =
109 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
110 if(!anAttrSelectionList.get()) {
113 "Error: This validator can only work with selection list attributes in \"Pipe\" feature.";
117 std::shared_ptr<FeaturesPlugin_Pipe> aFeature =
118 std::dynamic_pointer_cast<FeaturesPlugin_Pipe>(theAttribute->owner());
120 AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
121 if (!aPathSelection.get()) {
123 theError = "Error: Path not selected.";
128 GeomShapePtr aPathShape = aPathSelection->value();
129 if (!aPathShape.get()) {
130 ResultPtr aContext = aPathSelection->context();
131 if (!aContext.get()) {
132 FeaturePtr aContFeat = aPathSelection->contextFeature();
133 if (!aContFeat.get() || !aContFeat->results().size()) {
134 theError = "Error: Empty selection context.";
138 aPathShape = aContext->shape();
141 if (!aPathShape.get()) {
142 theError = "Error: Empty path shape.";
146 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
147 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
148 if (!anAttrSelection.get()) {
149 theError = "Error: Empty attribute selection.";
152 ResultPtr aContext = anAttrSelection->context();
153 if (!aContext.get()) {
154 FeaturePtr aContFeat = anAttrSelection->contextFeature();
155 if (!aContFeat.get() || !aContFeat->results().size()) {
156 theError = "Error: Empty selection context.";
160 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
161 if (!aShape.get() && aContext.get()) {
162 GeomShapePtr aContextShape = aContext->shape();
163 aShape = aContextShape;
166 theError = "Error: Empty shape.";
170 if (!aPathShape->isSubShape(aShape)) {
171 theError = "Error: Location should be a vertex subshape from path shape.";
179 //==================================================================================================
181 bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid(
182 const std::shared_ptr<ModelAPI_Feature>& theFeature,
183 const std::list<std::string>& theArguments,
184 Events_InfoMessage& theError) const
186 static const std::string aCreationMethodID = "creation_method";
187 static const std::string aBaseObjectsID = "base_objects";
188 static const std::string aLocationsID = "locations_objects";
190 if(theFeature->getKind() != "Pipe") {
191 theError = "Error: Feature \"%1\" does not supported by this validator.";
192 theError.arg(theFeature->getKind());
196 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
197 if(!aCreationMethodAttr.get()) {
198 theError = "Error: Could not get \"%1\" attribute.";
199 theError.arg(aCreationMethodID);
203 if(aCreationMethodAttr->value() != "locations") {
207 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
208 if(!aBaseObjectsSelectionList.get()) {
209 theError = "Error: Could not get \"%1\" attribute.";
210 theError.arg(aBaseObjectsID);
214 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
215 if(!aLocationsSelectionList.get()) {
216 theError = "Error: Could not get \"%1\" attribute.";
217 theError.arg(aBaseObjectsID);
221 if(aLocationsSelectionList->size() > 0 &&
222 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
223 theError = "Error: Number of locations should be the same as base objects.";
231 //==================================================================================================
232 bool FeaturesPlugin_ValidatorLoftSameTypeShape::isValid(
233 const std::shared_ptr<ModelAPI_Feature>& theFeature,
234 const std::list<std::string>& theArguments,
235 Events_InfoMessage& theError) const
237 static const std::string aFirstObjetcID = "first_object";
238 static const std::string aSecondObjetcID = "second_object";
240 if (theFeature->getKind() != "Loft") {
241 theError = "Error: Feature \"%1\" does not supported by this validator.";
242 theError.arg(theFeature->getKind());
246 AttributeSelectionPtr aFirstObjectsSelection = theFeature->selection(aFirstObjetcID);
247 if ( !aFirstObjectsSelection->isInitialized()) {
248 theError = "Error: Could not get \"%1\" attribute.";
249 theError.arg(aFirstObjetcID);
253 AttributeSelectionPtr aSecondObjectsSelection = theFeature->selection(aSecondObjetcID);
254 if (!aSecondObjectsSelection->isInitialized()) {
255 theError = "Error: Could not get \"%1\" attribute.";
256 theError.arg(aSecondObjetcID);
260 GeomShapePtr aFirstShape = aFirstObjectsSelection->value();
261 if (!aFirstShape.get()) {
262 aFirstShape = aFirstObjectsSelection->context()->shape();
264 GeomShapePtr aSecondShape = aSecondObjectsSelection->value();
265 if (!aSecondShape.get()) {
266 aSecondShape = aSecondObjectsSelection->context()->shape();
269 if (aFirstShape->isEqual(aSecondShape)) {
270 theError = "Error: the shapes are equal";
274 if (aFirstShape->shapeType()!=aSecondShape->shapeType()) {
275 theError = "Error: the shapes have different type";
282 //==================================================================================================
283 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
284 const std::list<std::string>& theArguments,
285 Events_InfoMessage& theError) const
288 if(theArguments.empty()) {
289 theError = "Error: Validator parameters is empty.";
294 // Checking attribute.
295 if(!isValidAttribute(theAttribute, theArguments, theError)) {
296 if(theError.empty()) {
297 theError = "Error: Attribute contains unacceptable shape.";
302 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
303 std::string anAttributeType = theAttribute->attributeType();
304 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
305 AttributeSelectionListPtr aListAttr =
306 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
307 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
308 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
309 ResultPtr aContext = aSelectionAttr->context();
310 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
311 theError = "Error: Empty context.";
315 ResultConstructionPtr aResultConstruction =
316 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
317 if(!aResultConstruction.get()) {
318 // It is not a result construction.
319 // If shape is compound check that it contains only faces, edges or vertices.
320 GeomShapePtr aShape = aSelectionAttr->value();
322 if (aContext.get()) {
323 aShape = aContext->shape();
325 theError = "Error: Empty context.";
330 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
331 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
332 GeomShapePtr aSubShape = anIt.current();
333 if (aSubShape->shapeType() > GeomAPI_Shape::VERTEX ||
334 aSubShape->shapeType() < GeomAPI_Shape::FACE) {
335 theError = "Error: Compound should contain only faces, edges or vertices.";
344 GeomShapePtr aShape = aSelectionAttr->value();
345 GeomShapePtr aContextShape = aResultConstruction->shape();
347 // Whole sketch selected.
350 // Object from sketch selected.
351 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
352 GeomShapePtr aWire = anExp.current();
353 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
354 theError = "Error: Wire with wrong orientation selected.";
358 if(aSelectedWiresFromObjects.isBound(aWire)) {
360 "Error: Objects with this wire already selected. Don't allow to select this object.";
364 aSelectedWiresFromObjects.bind(aWire, aWire);
373 //==================================================================================================
374 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
375 const std::shared_ptr<ModelAPI_Feature>& theFeature,
376 const std::list<std::string>& theArguments,
377 Events_InfoMessage& theError) const
379 const std::string aBaseObjectsID = theArguments.front();
381 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
382 if(!aListAttr.get()) {
384 theError = "Error: Could not get \"%1\" attribute.";
385 theError.arg(aBaseObjectsID);
390 std::set<ResultConstructionPtr> aSelectedSketches;
391 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
393 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
394 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
395 ResultPtr aContext = aSelectionAttr->context();
396 if(!aContext.get()) {
397 FeaturePtr aFeature = aSelectionAttr->contextFeature();
398 if (!aFeature.get() || aFeature->results().empty()) {
399 theError = "Error: Empty context.";
402 aContext = aFeature->firstResult();
406 ResultConstructionPtr aResultConstruction =
407 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
408 if(!aResultConstruction.get()) {
409 // It is not a result construction.
413 GeomShapePtr aShape = aSelectionAttr->value();
414 GeomShapePtr aContextShape = aResultConstruction->shape();
416 // Whole sketch selected.
417 aSelectedSketches.insert(aResultConstruction);
419 // Object from sketch selected.
420 aSelectedSketchesFromObjects.insert(aResultConstruction);
425 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
426 anIt != aSelectedSketches.cend();
428 ResultConstructionPtr aResultConstruction = *anIt;
429 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
430 aSelectedSketchesFromObjects.cend()) {
431 theError = "Sketch and objects from it can not be selected at the same time.";
439 //==================================================================================================
440 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
441 const std::list<std::string>& theArguments,
442 Events_InfoMessage& theError) const
444 if(!theAttribute.get()) {
446 theError = "Error: Empty attribute.";
451 std::string anAttributeType = theAttribute->attributeType();
452 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
453 AttributeSelectionListPtr aListAttr =
454 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
456 const std::string& aVersion = theAttribute->owner()->data()->version();
457 std::string aSelType;
458 if (!aVersion.empty())
459 aSelType = aListAttr->selectionType();
461 std::list<std::string> anApplicableTypes;
462 switch (GeomValidators_ShapeType::shapeType(aSelType)) {
463 case GeomValidators_ShapeType::Vertex:
464 anApplicableTypes.push_back("vertex");
466 case GeomValidators_ShapeType::Edge:
467 anApplicableTypes.push_back("edge");
468 anApplicableTypes.push_back("wire");
470 case GeomValidators_ShapeType::Face:
471 anApplicableTypes.push_back("face");
472 anApplicableTypes.push_back("shell");
473 // wire should not be the first in this list to be able to check
474 // the type of selection when evaluating shape by shape
475 anApplicableTypes.push_back("wire");
478 anApplicableTypes = theArguments;
482 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
483 // If at least one attribute is invalid, the result is false.
484 if(!isValidAttribute(aListAttr->value(anIndex), anApplicableTypes, theError)) {
488 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
490 AttributeSelectionPtr anAttr =
491 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
492 ResultPtr aContext = anAttr->context();
493 if(!aContext.get() && !anAttr->contextFeature().get()) {
494 theError = "Error: Attribute have empty context.";
498 GeomShapePtr aShape = anAttr->value();
499 GeomShapePtr aContextShape;
500 if(!aShape.get() && aContext.get()) {
501 aContextShape = aContext->shape();
502 aShape = aContextShape;
505 theError = "Error: Empty shape selected";
509 ResultConstructionPtr aConstruction;
510 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
511 aContext = anAttr->contextFeature()->firstResult();
514 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
515 if(aConstruction.get()) {
516 // Construction selected. Check that it is not infinite.
517 if(aConstruction->isInfinite() && !aConstruction->shape()->isVertex()) {
518 theError = "Error: Infinite constructions is not allowed as base.";
522 aContextShape = aContext->shape();
523 if(aShape->isEqual(aContextShape)) {
524 // Whole construction selected. Check that it has faces.
525 if((theArguments.front() == "face" && aConstruction->facesNum() > 0) ||
526 theArguments.front() == "edge") {
530 // CUT operation supports only FACE or WIRE as a tool base
531 std::shared_ptr<FeaturesPlugin_CompositeBoolean> aComposite =
532 std::dynamic_pointer_cast<FeaturesPlugin_CompositeBoolean>(
533 ModelAPI_Feature::feature(theAttribute->owner()));
535 aComposite->operationType() == FeaturesPlugin_CompositeBoolean::BOOL_CUT) {
536 return aShape->shapeType() == GeomAPI_Shape::WIRE ||
537 aShape->shapeType() == GeomAPI_Shape::FACE;
542 if(!aConstruction && aContextShape.get() && !aShape->isEqual(aContextShape)) {
543 // Local selection on body does not allowed.
545 "Error: Selected shape is in the local selection. Only global selection is allowed.";
549 // Check that object is a shape with allowed type.
550 GeomValidators_ShapeType aShapeTypeValidator;
551 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
552 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
553 "wires on sketch, whole sketch (if it has at least one face), "
554 "and whole objects with shape types: %1";
555 std::string anArgumentString;
556 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
557 if (!anArgumentString.empty())
558 anArgumentString += ", ";
559 anArgumentString += *anIt;
561 theError.arg(anArgumentString);
567 theError = "Error: Attribute \"%1\" does not supported by this validator.";
568 theError.arg(anAttributeType);
576 //==================================================================================================
578 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
579 const std::list<std::string>& theArguments,
580 Events_InfoMessage& theError) const
582 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
583 theError = "Error: The attribute with the %1 type is not processed";
584 theError.arg(theAttribute->attributeType());
587 if (theArguments.size() != 2) {
588 theError = "Error: Wrong parameters in XML definition for %1 type";
589 theError.arg(theAttribute->attributeType());
592 // first argument is for the base attribute, second - for skipping feature kind
593 std::list<std::string>::const_iterator anIt = theArguments.begin();
594 std::string aBaseAttributeId = *anIt;
595 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
596 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
597 if (!aBaseAttribute.get()) {
598 theError = "Wrong parameters in XML definition for %1 type";
599 theError.arg(theAttribute->attributeType());
602 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
603 // this validator is not necessary anymore
607 std::string aFeatureAttributeKind = *anIt;
608 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
609 // check whether the selection is on the sketch
610 std::list<std::string> anArguments;
611 anArguments.push_back(aFeatureAttributeKind);
613 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
614 bool aPlanarFace = false;
615 // check if selection has Face selected
616 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
618 anArguments.push_back("face");
619 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
621 bool aValid = !aFeatureKind && aPlanarFace;
626 //==================================================================================================
627 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
628 const std::shared_ptr<ModelAPI_Feature>& theFeature,
629 const std::list<std::string>& theArguments,
630 Events_InfoMessage& theError) const
632 if(theArguments.size() != 2) {
634 theError = "Error: Validator should be used with 2 parameters for extrusion.";
639 std::list<std::string>::const_iterator anArgsIt = theArguments.begin();
641 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
644 GeomShapePtr aDirShape;
645 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
647 aDirShape = aSelAttr->value();
648 if(!aDirShape.get()) {
649 ResultPtr aContext = aSelAttr->context();
650 if(!aContext.get()) {
651 FeaturePtr aFeature = aSelAttr->contextFeature();
652 if (aFeature.get() && !aFeature->results().empty()) {
653 aContext = aFeature->firstResult();
658 aDirShape = aContext->shape();
661 if (aDirShape.get() && aDirShape->isCompound()) {
662 GeomAPI_ShapeIterator anIt(aDirShape);
663 aDirShape = anIt.current();
668 if(!aDirShape.get() || aDirShape->isNull() ||
669 aDirShape->shapeType() != GeomAPI_Shape::EDGE) {
670 // Check that dir can be empty.
671 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
672 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
673 "can not be used with default value. Select direction for extrusion.";
674 theError.arg(*anArgsIt);
681 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
683 // If faces selected check that direction not parallel with them.
684 AttributeSelectionListPtr aListAttr =
685 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
686 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
687 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
688 GeomShapePtr aShapeInList = anAttr->value();
689 if(!aShapeInList.get()) {
690 aShapeInList = anAttr->context()->shape();
692 bool isParallel = true;
693 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
694 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
695 for(GeomAPI_ShapeExplorer
696 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
697 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
698 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
703 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
704 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
705 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
706 if(aPlanarEdges.get()) {
707 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
708 if(aDirEdge->isLine()) {
709 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
710 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
722 "Error: Direction is parallel to one of the selected face or face on selected shell.";
730 //==================================================================================================
731 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
732 Events_InfoMessage& theError) const
735 if(!theAttribute.get()) {
740 std::string anAttributeType = theAttribute->attributeType();
741 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
742 AttributeSelectionListPtr aListAttr =
743 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
744 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
745 // If at least one attribute is invalid, the result is false.
746 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
750 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
752 AttributeSelectionPtr anAttr =
753 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
754 ResultPtr aContext = anAttr->context();
755 if(!aContext.get() && !anAttr->contextFeature().get()) {
759 GeomShapePtr aShape = anAttr->value();
760 if(!aShape.get() && aContext.get()) {
761 GeomShapePtr aContextShape = aContext->shape();
762 aShape = aContextShape;
768 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
769 aShape->shapeType() == GeomAPI_Shape::EDGE ||
770 !aShape->isPlanar()) {
780 //==================================================================================================
781 bool FeaturesPlugin_ValidatorExtrusionBoundaryFace::isValid(
782 const AttributePtr& theAttribute,
783 const std::list<std::string>& theArguments,
784 Events_InfoMessage& theError) const
786 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
788 // Collect all necessary attributes and try to build prism
791 AttributeSelectionListPtr aBaseShapeAttr =
792 aFeature->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID());
793 ListOfShape aBaseShapeList;
795 if (!FeaturesPlugin_Tools::getShape(aBaseShapeAttr, true, aBaseShapeList, anError)) {
801 AttributeSelectionPtr aSelection =
802 aFeature->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID());
803 GeomShapePtr aShape = aSelection->value();
804 if (!aShape.get() && aSelection->context().get())
805 aShape = aSelection->context()->shape();
809 if (aShape->isEdge())
810 anEdge = aShape->edge();
811 else if (aShape->isCompound()) {
812 GeomAPI_ShapeIterator anIt(aShape);
813 anEdge = anIt.current()->edge();
817 std::shared_ptr<GeomAPI_Dir> aDir;
818 if (anEdge.get() && anEdge->isLine())
819 aDir = anEdge->line()->direction();
822 GeomShapePtr aFromShape, aToShape;
823 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID());
824 if (aSelection.get()) {
825 aToShape = aSelection->value();
826 if (!aToShape.get() && aSelection->context().get())
827 aToShape = aSelection->context()->shape();
828 if (aToShape.get() && aToShape->isCompound()) {
829 GeomAPI_ShapeIterator anIt(aToShape);
830 aToShape = anIt.current();
832 if (aToShape.get() && !aToShape->isFace()) {
833 theError = "\"To\" shape is not a face";
837 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID());
838 if (aSelection.get()) {
839 aFromShape = aSelection->value();
840 if (!aFromShape.get() && aSelection->context().get())
841 aFromShape = aSelection->context()->shape();
842 if (aFromShape.get() && aFromShape->isCompound()) {
843 GeomAPI_ShapeIterator anIt(aFromShape);
844 aFromShape = anIt.current();
846 if (aFromShape.get() && !aFromShape->isFace()) {
847 theError = "\"From\" shape is not a face";
852 double aToSize = aFeature->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID())->value();
853 double aFromSize = aFeature->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID())->value();
856 for (ListOfShape::iterator anIt = aBaseShapeList.begin(); anIt != aBaseShapeList.end(); anIt++) {
857 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIt;
859 std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo(
860 new GeomAlgoAPI_Prism(aBaseShape, aDir, aToShape, aToSize, aFromShape, aFromSize));
861 bool isFailed = GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPrismAlgo,
862 FeaturesPlugin_Extrusion::ID(),
873 //==================================================================================================
874 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
875 const std::list<std::string>& theArguments,
876 Events_InfoMessage& theError) const
878 AttributeSelectionListPtr anAttrSelectionList =
879 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
880 if(!anAttrSelectionList.get()) {
883 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
887 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
888 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
889 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
891 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
892 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
893 if(!anAttrSelection.get()) {
894 theError = "Error: Empty attribute selection.";
897 ResultPtr aContext = anAttrSelection->context();
898 if(!aContext.get()) {
899 FeaturePtr aContFeat = anAttrSelection->contextFeature();
900 if (!aContFeat.get() || !aContFeat->results().size()) {
901 theError = "Error: Empty selection context.";
905 ResultConstructionPtr aResultConstruction =
906 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
907 if(aResultConstruction.get()) {
908 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
909 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
910 theError = "Error: Result construction not allowed for selection.";
914 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
915 if(!aShape.get() && aContext.get()) {
916 GeomShapePtr aContextShape = aContext->shape();
917 aShape = aContextShape;
920 theError = "Error: Empty shape.";
923 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
924 theError = "Error: Local selection not allowed.";
928 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
929 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
930 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
931 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
932 anAllowedTypes.insert(GeomAPI_Shape::FACE);
933 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
934 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
935 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
936 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
937 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
939 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
940 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
941 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
942 anAllowedTypes.insert(GeomAPI_Shape::FACE);
943 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
944 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
945 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
946 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
948 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
949 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
950 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
953 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
954 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
955 theError = "Error: Selected shape has the wrong type.";
964 //==================================================================================================
965 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
966 const std::list<std::string>& theArguments,
967 Events_InfoMessage& theError) const
969 AttributeSelectionListPtr anAttrSelectionList =
970 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
971 if(!anAttrSelectionList.get()) {
974 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
979 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
980 // Check all selected entities are sub-shapes of single solid
981 GeomShapePtr aBaseSolid;
982 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
983 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
984 if(!anAttrSelection.get()) {
985 theError = "Error: Empty attribute selection.";
988 ResultPtr aContext = anAttrSelection->context();
989 if(!aContext.get()) {
990 FeaturePtr aContFeat = anAttrSelection->contextFeature();
991 if (!aContFeat.get() || !aContFeat->results().size() ||
992 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
993 theError = "Error: Empty selection context.";
996 if (aContFeat->results().size() == 1)
997 aContext = aContFeat->firstResult();
999 theError = "Error: Too many shapes selected.";
1004 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true);
1005 GeomShapePtr anOwner = aContext->shape();
1006 GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner;
1009 theError = "Error: wrong feature is selected.";
1013 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
1014 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
1015 theError = "Error: Not all selected shapes are sub-shapes of solids.";
1020 aBaseSolid = aTopLevelOwner;
1021 else if (!aBaseSolid->isEqual(aTopLevelOwner)) {
1022 theError = "Error: Sub-shapes of different solids have been selected.";
1031 //==================================================================================================
1032 bool FeaturesPlugin_ValidatorFillet1DSelection::isValid(const AttributePtr& theAttribute,
1033 const std::list<std::string>& theArguments,
1034 Events_InfoMessage& theError) const
1036 AttributeSelectionListPtr anAttrSelectionList =
1037 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1038 if (!anAttrSelectionList.get()) {
1041 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
1046 // Validate wires selection
1047 if (!theArguments.empty() &&
1048 theArguments.front() == "wire") {
1049 for (int ind = 0; ind < anAttrSelectionList->size(); ++ind) {
1050 AttributeSelectionPtr aCurSel = anAttrSelectionList->value(ind);
1051 //GeomShapePtr aContext = aCurSel->context()->shape();
1052 GeomShapePtr aWire = aCurSel->value();
1053 if (aWire->shapeType() != GeomAPI_Shape::WIRE) {
1054 theError = "Selected shape is not a wire";
1061 // check each selected vertex is a sharp corner between adjacent edges,
1062 // and these edges are in the same plane
1063 std::map<GeomShapePtr, MapShapeToShapes> aWireSubshapes;
1064 int aNbSel = anAttrSelectionList->size();
1065 for (int ind = 0; ind < aNbSel; ++ind) {
1066 AttributeSelectionPtr aCurSel = anAttrSelectionList->value(ind);
1067 GeomShapePtr aContext = aCurSel->context()->shape();
1068 GeomShapePtr aVertex = aCurSel->value();
1069 // check wire already processed, if not, store all vertices and edges, sharing them
1070 std::map<GeomShapePtr, MapShapeToShapes>::iterator aProcessed = aWireSubshapes.find(aContext);
1071 if (aProcessed == aWireSubshapes.end()) {
1072 if (aContext->shapeType() != GeomAPI_Shape::WIRE) {
1073 theError = "Selected vertex is not a wire corner";
1076 if (aVertex->shapeType() != GeomAPI_Shape::VERTEX) {
1077 theError = "Selected shape is not a vertex";
1081 GeomAlgoAPI_MapShapesAndAncestors aMapVE(aContext, GeomAPI_Shape::VERTEX,
1082 GeomAPI_Shape::EDGE);
1083 aWireSubshapes[aContext] = aMapVE.map();
1084 aProcessed = aWireSubshapes.find(aContext);
1088 MapShapeToShapes::iterator aFound = aProcessed->second.find(aVertex);
1089 if (aFound == aProcessed->second.end()) {
1090 theError = "Selected vertex does not exist in the wire";
1093 else if (aFound->second.size() != 2) {
1094 theError = "Vertex should be shared between 2 edges exactly";
1098 ListOfShape anEdges;
1099 anEdges.insert(anEdges.end(), aFound->second.begin(), aFound->second.end());
1100 GeomPlanePtr aPlane = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
1102 theError = "Error: Edges are not planar";
1106 GeomEdgePtr anEdge1(new GeomAPI_Edge(anEdges.front()));
1107 GeomEdgePtr anEdge2(new GeomAPI_Edge(anEdges.back()));
1108 GeomVertexPtr aSharedVertex(new GeomAPI_Vertex(aVertex));
1109 if (GeomAlgoAPI_ShapeTools::isTangent(anEdge1, anEdge2, aSharedVertex)) {
1110 theError = "Error: Edges are tangent";
1118 //==================================================================================================
1119 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
1120 const std::list<std::string>& theArguments,
1121 Events_InfoMessage& theError) const
1123 AttributeSelectionListPtr anAttrSelectionList =
1124 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1125 if(!anAttrSelectionList.get()) {
1127 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
1132 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1133 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
1135 //GeomValidators_BodyShapes aBodyValidator;
1136 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
1140 GeomValidators_FeatureKind aFeatureKindValidator;
1141 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
1145 ResultPtr aContext = aSelectAttr->context();
1146 ResultConstructionPtr aResultConstruction =
1147 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1148 if(aResultConstruction.get()) {
1149 theError = "Error: Only body shapes and construction planes are allowed for selection.";
1153 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1154 if(aResultBody.get()) {
1157 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
1158 if(aResultFeature.get()) {
1159 bool aOkRes = false;
1160 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
1161 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
1162 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
1163 if (aBody.get() && !aBody->isDisabled())
1170 theError = "Error: Only body shapes and construction planes are allowed for selection.";
1178 //==================================================================================================
1179 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
1180 const std::list<std::string>& theArguments,
1181 Events_InfoMessage& theError) const
1183 AttributeSelectionListPtr aSubShapesAttrList =
1184 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1185 if(!aSubShapesAttrList.get()) {
1188 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
1193 static const std::string aBaseShapeID = "base_shape";
1194 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1195 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
1197 if(!aShapeAttrSelection.get()) {
1199 theError = "Error: Could not get \"%1\" attribute.";
1200 theError.arg(aBaseShapeID);
1205 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1206 ResultPtr aContext = aShapeAttrSelection->context();
1207 if(!aContext.get()) {
1208 theError = "Error: Empty context.";
1211 if(!aBaseShape.get()) {
1212 aBaseShape = aContext->shape();
1214 if(!aBaseShape.get()) {
1215 theError = "Error: Empty base shape.";
1219 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
1220 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1221 bool isSameFound = false;
1222 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1223 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1224 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
1226 if ((*anIt)->isEqual(aShapeToAdd)) {
1232 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
1240 //==================================================================================================
1241 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
1242 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1243 const std::list<std::string>& theArguments,
1244 Events_InfoMessage& theError) const
1246 static const std::string aBaseShapeID = "base_shape";
1247 static const std::string aSubShapesID = "subshapes_to_keep";
1250 if(theFeature->getKind() != "Remove_SubShapes") {
1251 theError = "Error: Feature \"%1\" does not supported by this validator.";
1252 theError.arg(theFeature->getKind());
1256 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
1257 if(!aShapeAttrSelection.get()) {
1258 theError = "Error: Could not get \"%1\" attribute.";
1259 theError.arg(aBaseShapeID);
1263 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
1264 if(!aSubShapesAttrList.get()) {
1265 theError = "Error: Could not get \"%1\" attribute.";
1266 theError.arg(aSubShapesID);
1272 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1273 if(!aBaseShape.get()) {
1274 theError = "Error: Base shape is empty.";
1277 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
1279 if (aSubShapesAttrList->size() == 0) {
1280 theError = "Error: Resulting shape is not valid.";
1284 // Copy sub-shapes from list to new shape.
1285 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1286 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1287 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1288 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
1292 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
1293 theError = "Error: Resulting shape is not valid.";
1300 //==================================================================================================
1302 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
1303 const std::list<std::string>& theArguments,
1304 Events_InfoMessage& theError) const
1306 AttributeSelectionListPtr aBaseObjectsAttrList =
1307 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1308 if(!aBaseObjectsAttrList.get()) {
1309 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1310 theError.arg(FeaturesPlugin_Union::ID());
1314 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1315 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1316 ResultPtr aContext = anAttrSelectionInList->context();
1317 if (!aContext.get()) {
1318 theError = "Error: selection is invalid.";
1322 ResultConstructionPtr aConstruction =
1323 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1324 if(aConstruction.get()) {
1325 theError = "Error: Result construction not allowed for selection.";
1329 GeomShapePtr aShape = anAttrSelectionInList->value();
1330 GeomShapePtr aContextShape = aContext->shape();
1331 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1332 theError = "Error: Local selection not allowed.";
1336 ResultBodyPtr aResult =
1337 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1338 if(!aResult.get()) {
1342 if(aResult->numberOfSubs() > 0) {
1343 theError = "Error: Whole compsolids not allowed for selection.";
1352 //==================================================================================================
1353 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1354 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1355 const std::list<std::string>& theArguments,
1356 Events_InfoMessage& theError) const
1359 // Check feature kind.
1360 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1361 theError = "Error: This validator supports only \"%1\" feature.";
1362 theError.arg(FeaturesPlugin_Union::ID());
1366 // Get base objects attribute list.
1367 AttributeSelectionListPtr aBaseObejctsAttrList =
1368 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1369 if(!aBaseObejctsAttrList.get()) {
1370 theError = "Error: Could not get \"%1\" attribute.";
1371 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1377 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1378 ListOfShape aBaseShapesList;
1379 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1380 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1381 GeomShapePtr aShape = anAttrSelectionInList->value();
1382 if (!aShape.get()) {
1385 aBaseShapesList.push_back(aShape);
1386 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1387 GeomAPI_Shape::COMPSOLID;
1390 // Make compound and find connected.
1391 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1392 ListOfShape aResults;
1393 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults);
1395 if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) {
1396 theError = "Error: Not all shapes have shared topology.";
1403 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1404 const std::list<std::string>& theArguments,
1405 Events_InfoMessage& theError) const
1407 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1409 theError = "Error: The attribute with the %1 type is not processed";
1410 theError.arg(theAttribute->attributeType());
1415 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1417 ObjectPtr aRefObject = aRefAttribute->value();
1418 if (!aRefObject.get()) {
1419 theError = "Error: Empty feature.";
1423 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1424 if (!aRefFeature.get()) {
1425 theError = "Error: Empty feature.";
1428 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1429 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1431 size_t aConcealedResults = aResults.size();
1432 if (!aConcealedResults && !theArguments.empty()) {
1433 // find if these results are touched by the feature in another attribute
1434 std::list<std::string>::const_iterator anIt = theArguments.begin();
1435 std::string aRecoveredList = *anIt;
1436 if (!aRecoveredList.empty()) {
1437 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1438 theAttribute->owner()->data()->reflist(aRecoveredList);
1439 if (aParameterList.get())
1440 aConcealedResults = aParameterList->size();
1444 if (aConcealedResults == 0)
1445 theError = "Error: No concealed results.";
1447 return theError.empty();
1450 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1451 const std::list<std::string>& theArguments,
1452 Events_InfoMessage& theError) const
1454 static std::list<std::string> aEdgeArg(1, "circle");
1455 static std::list<std::string> aFaceArg(1, "cylinder");
1457 Events_InfoMessage aError;
1458 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1460 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1462 theError = "The shape neither circle nor cylinder";
1467 //=================================================================================================
1468 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1469 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1470 const std::list<std::string>& theArguments,
1471 Events_InfoMessage& theError) const
1474 if (theArguments.size() != 2)
1476 theError = "Wrong number of arguments (expected 2).";
1481 int anObjectsToolsNb[2] = { 0, 0 };
1483 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1485 bool isAllInSameCompSolid = true;
1486 ResultBodyPtr aCompSolid;
1488 for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
1489 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1492 *anArgNbIt = anAttrSelList->size();
1493 if (isAllInSameCompSolid) {
1494 for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
1496 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1497 ResultPtr aContext = anAttr->context();
1498 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1499 if (aResCompSolidPtr.get())
1501 if (aCompSolid.get())
1503 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1507 aCompSolid = aResCompSolidPtr;
1512 isAllInSameCompSolid = false;
1520 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1521 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1522 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1524 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1527 if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
1529 theError = "Not enough arguments for Fuse operation.";
1532 else if (isAllInSameCompSolid)
1534 theError = "Operations only between sub-shapes of the same shape not allowed.";
1540 if (anObjectsToolsNb[0] < 1) // check number of objects
1542 theError = "Objects not selected.";
1545 if (anObjectsToolsNb[1] < 1) // check number of tools
1547 theError = "Tools not selected.";
1550 if (isAllInSameCompSolid)
1552 theError = "Operations only between sub-shapes of the same shape not allowed.";
1560 //=================================================================================================
1562 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1563 std::string theAttribute)
1565 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1574 //==================================================================================================
1575 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1576 const AttributePtr& theAttribute,
1577 const std::list<std::string>& theArguments,
1578 Events_InfoMessage& theError) const
1580 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1581 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1583 AttributeSelectionListPtr anAttrSelectionList =
1584 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1585 if (!aFeature.get() || !anAttrSelectionList.get()) {
1588 "Error: Validator used in wrong feature or attribute";
1593 AttributeSelectionListPtr anOtherAttrSelectionList;
1594 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1595 anOtherAttrSelectionList =
1596 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1598 anOtherAttrSelectionList =
1599 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1602 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1603 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1604 GeomPlanePtr aFacesPln;
1606 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1607 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1609 if (anAttrSelection->contextFeature().get()) {
1610 theError = "Error: Features not allowed for selection.";
1614 ResultPtr aContext = anAttrSelection->context();
1615 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1616 if (!aShape.get()) {
1617 if (!aContext.get()) {
1618 theError = "Error: Empty selection.";
1621 aShape = aContext->shape();
1624 if (aShape->isSolid() || aShape->isCompSolid()) {
1625 aSelectedShapesType = GeomAPI_Shape::SOLID;
1626 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1627 if (aResCompSolidPtr.get()) {
1628 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1629 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1632 aSelectedShapesType = GeomAPI_Shape::FACE;
1633 GeomAPI_Face aFace(aShape);
1634 aFacesPln = aFace.getPlane();
1639 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1640 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1641 if (!anAttrSelection.get()) {
1642 theError = "Error: Empty attribute selection.";
1646 if (anAttrSelection->contextFeature().get()) {
1647 theError = "Error: Features not allowed for selection.";
1651 ResultPtr aContext = anAttrSelection->context();
1652 if(!aContext.get()) {
1653 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1654 if (!aContFeat.get() || !aContFeat->results().size() ||
1655 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1656 theError = "Error: Empty selection context.";
1660 ResultConstructionPtr aResultConstruction =
1661 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1662 if (aResultConstruction.get()) {
1663 theError = "Error: Result construction not allowed for selection.";
1666 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1667 GeomShapePtr aContextShape = aContext->shape();
1668 if (!aShape.get()) {
1669 aShape = aContextShape;
1671 if (!aShape.get()) {
1672 theError = "Error: Empty shape.";
1675 if (!aShape->isEqual(aContextShape)) {
1676 theError = "Error: Local selection not allowed.";
1680 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1681 // Other list is empty.
1682 if (aShape->isSolid() || aShape->isCompSolid()) {
1683 aSelectedShapesType = GeomAPI_Shape::SOLID;
1685 aSelectedShapesType = GeomAPI_Shape::FACE;
1686 GeomAPI_Face aFace(aShape);
1687 aFacesPln = aFace.getPlane();
1689 if (!aFacesPln.get()) {
1690 theError = "Error: Only planar faces allowed.";
1696 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1697 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1698 theError = "Error: Selected shapes should have the same type.";
1702 GeomAPI_Face aFace(aShape);
1703 GeomPlanePtr aPln = aFace.getPlane();
1706 theError = "Error: Only planar faces allowed.";
1710 if (!aFacesPln->isCoincident(aPln)) {
1711 theError = "Error: Only coincident faces allowed.";
1720 //==================================================================================================
1722 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1723 const std::list<std::string>& theArguments,
1724 Events_InfoMessage& theError) const
1726 if (!theAttribute.get()) {
1727 theError = "Error: empty selection.";
1730 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1731 AttributeSelectionListPtr anAttrSelectionList =
1732 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1733 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1734 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1735 if (!anAttrSelection.get()) {
1736 theError = "Error: empty attribute selection.";
1739 ResultPtr aContext = anAttrSelection->context();
1740 if (aContext.get()) {
1741 aFeature = ModelAPI_Feature::feature(aContext);
1743 aFeature = anAttrSelection->contextFeature();
1744 if (!aFeature.get() || !aFeature->results().size() ||
1745 aFeature->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1746 theError = "Error: Empty selection context.";
1750 if (!aFeature.get()) {
1751 theError = "Error: empty feature.";
1754 std::string aFeatureKind = aFeature->getKind();
1755 if (aFeatureKind == "Sketch" ||
1756 aFeatureKind == "Plane" ||
1757 aFeatureKind == "Axis") {
1758 theError = "Error: %1 shape is not allowed for selection.";
1759 theError.arg(aFeatureKind);
1762 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1763 if (!aShape.get()) {
1764 GeomShapePtr aContextShape = aContext->shape();
1765 aShape = aContextShape;
1767 if (!aShape.get()) {
1768 theError = "Error: empty shape.";
1771 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1772 theError = "Error: Local selection not allowed.";
1776 int aShapeType = aShape->shapeType();
1777 // Allow to select edges, faces and solids.
1778 if (aShapeType != GeomAPI_Shape::EDGE &&
1779 aShapeType != GeomAPI_Shape::FACE &&
1780 aShapeType != GeomAPI_Shape::SOLID &&
1781 aShapeType != GeomAPI_Shape::COMPSOLID &&
1782 aShapeType != GeomAPI_Shape::COMPOUND) {
1783 theError = "Error: selected shape has the wrong type.";
1792 //==================================================================================================
1794 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1795 const AttributePtr& theAttribute,
1796 const std::list<std::string>& theArguments,
1797 Events_InfoMessage& theError) const
1799 AttributeSelectionListPtr anAttrSelectionList =
1800 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1801 if (!anAttrSelectionList.get()) {
1803 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1807 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1808 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1809 if (!anAttrSelection.get()) {
1810 theError = "Error: Empty attribute selection.";
1813 ResultPtr aContext = anAttrSelection->context();
1814 if(!aContext.get()) {
1815 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1816 if (!aContFeat.get() || !aContFeat->results().size() ||
1817 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1818 theError = "Error: Empty selection context.";
1822 ResultConstructionPtr aResultConstruction =
1823 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1824 if (aResultConstruction.get()) {
1825 theError = "Error: Result construction not allowed for selection.";
1828 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1829 if (!aShape.get()) {
1830 GeomShapePtr aContextShape = aContext->shape();
1831 aShape = aContextShape;
1833 if (!aShape.get()) {
1834 theError = "Error: Empty shape.";
1837 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1838 theError = "Error: Local selection not allowed.";
1847 //=================================================================================================
1848 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1849 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1850 const std::list<std::string>& theArguments,
1851 Events_InfoMessage& theError) const
1854 if (theArguments.size() != 2) {
1855 theError = "Wrong number of arguments (expected 2).";
1860 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1861 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1863 int anObjectsNb = 0, aToolsNb = 0;
1865 std::list<std::string>::const_iterator anIt = theArguments.begin();
1867 bool isAllInSameCompSolid = true;
1868 ResultBodyPtr aCompSolid;
1870 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1871 if (anAttrSelList) {
1872 anObjectsNb = anAttrSelList->size();
1873 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1874 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1875 ResultPtr aContext = anAttr->context();
1876 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1877 if (aResCompSolidPtr.get()) {
1878 if (aCompSolid.get()) {
1879 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1881 aCompSolid = aResCompSolidPtr;
1884 isAllInSameCompSolid = false;
1891 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1892 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1893 anAttrSelList = theFeature->selectionList(*anIt);
1894 if (anAttrSelList) {
1895 aToolsNb = anAttrSelList->size();
1896 if (isAllInSameCompSolid) {
1897 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1898 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1899 ResultPtr aContext = anAttr->context();
1900 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1901 if (aResCompSolidPtr.get()) {
1902 if (aCompSolid.get()) {
1903 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1905 aCompSolid = aResCompSolidPtr;
1908 isAllInSameCompSolid = false;
1916 if (anObjectsNb + aToolsNb < 2) {
1917 theError = "Not enough arguments for Fuse operation.";
1924 //=================================================================================================
1926 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1927 std::string theFeature,
1928 std::string theAttribute)
1930 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1938 //==================================================================================================
1940 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1941 const AttributePtr& theAttribute,
1942 const std::list<std::string>& theArguments,
1943 Events_InfoMessage& theError) const
1945 AttributeSelectionListPtr anAttrSelectionList =
1946 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1947 if (!anAttrSelectionList.get()) {
1949 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1953 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1954 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1955 if (!anAttrSelection.get()) {
1956 theError = "Error: Empty attribute selection.";
1959 ResultPtr aContext = anAttrSelection->context();
1960 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1961 theError = "Error: Empty selection context.";
1964 ResultConstructionPtr aResultConstruction =
1965 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1966 if (aResultConstruction.get()) {
1967 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1968 theError = "Error: Result construction not allowed for selection.";
1972 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1973 GeomShapePtr aContextShape;
1974 if (aContext.get()) {
1975 aContextShape = aContext->shape();
1977 if (!aShape.get()) {
1978 aShape = aContextShape;
1980 if (!aShape.get()) {
1981 theError = "Error: Empty shape.";
1984 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1985 theError = "Error: Local selection not allowed.";
1989 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1990 theError = "Error: Result construction should be plane.";
1999 //=================================================================================================
2000 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
2001 const std::shared_ptr<ModelAPI_Feature>& theFeature,
2002 const std::list<std::string>& theArguments,
2003 Events_InfoMessage& theError) const
2005 if (theArguments.size() != 2) {
2007 theError = "Wrong number of arguments (expected 2).";
2012 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
2013 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
2015 int anObjectsNb = 0, aToolsNb = 0;
2017 std::list<std::string>::const_iterator anIt = theArguments.begin();
2019 ResultBodyPtr aCompSolid;
2021 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
2022 if (anAttrSelList) {
2023 anObjectsNb = anAttrSelList->size();
2026 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
2027 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
2029 if (!isSimpleMode) {
2030 anAttrSelList = theFeature->selectionList(*anIt);
2031 if (anAttrSelList) {
2032 aToolsNb = anAttrSelList->size();
2036 if ((isSimpleMode && anObjectsNb < 2)
2037 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
2038 theError = "Not enough arguments for Common operation.";
2044 //=================================================================================================
2046 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
2047 std::string theFeature,
2048 std::string theAttribute)
2054 //==================================================================================================
2055 bool FeaturesPlugin_ValidatorDefeaturingSelection::isValid(
2056 const AttributePtr& theAttribute,
2057 const std::list<std::string>& theArguments,
2058 Events_InfoMessage& theError) const
2060 AttributeSelectionListPtr anAttrSelectionList =
2061 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
2062 if (!anAttrSelectionList.get()) {
2064 theError = "Error: This validator can only work with selection list attributes.";
2069 // Check selected entities are sub-shapes of solid or compsolid
2070 GeomShapePtr aBaseSolid;
2071 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
2072 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
2073 if (!anAttrSelection.get()) {
2074 theError = "Error: Empty attribute selection.";
2077 ResultPtr aContext = anAttrSelection->context();
2078 if (!aContext.get()) {
2079 theError = "Error: Empty selection context.";
2083 GeomShapePtr aContextShape = aContext->shape();
2084 if (aContextShape->shapeType() != GeomAPI_Shape::SOLID) {
2085 theError = "Error: Not all selected shapes are sub-shapes of solids.";
2089 ResultBodyPtr aResRootPtr = ModelAPI_Tools::bodyOwner(aContext, true);
2090 if (aResRootPtr.get() && aResRootPtr->shape().get()) {
2091 if (!aResRootPtr->shape()->isCollectionOfSolids()) {
2092 theError = "Error: The main shape should be a collection of solids";
2101 //==================================================================================================
2102 bool FeaturesPlugin_ValidatorSewingSelection::isValid(const AttributePtr& theAttribute,
2103 const std::list<std::string>& theArguments,
2104 Events_InfoMessage& theError) const
2106 AttributeSelectionListPtr anAttrSelectionList =
2107 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
2108 if (!anAttrSelectionList.get()) {
2109 theError = "Error: This validator can only work with selection list attributes.";
2113 // Check selected entities are of valid types
2114 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
2115 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
2116 if (!anAttrSelection.get()) {
2117 theError = "Error: Empty attribute selection.";
2120 ResultPtr aContext = anAttrSelection->context();
2121 if (!aContext.get()) {
2122 theError = "Error: Empty selection context.";
2125 if (aContext->groupName() != ModelAPI_ResultBody::group()) {
2126 theError = "Error: Not a result body.";
2130 GeomShapePtr aContextShape = aContext->shape();
2131 if (!aContextShape.get()) {
2132 theError = "Error: Empty shape.";
2136 GeomAPI_Shape::ShapeType aShapeType = aContextShape->shapeType();
2137 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
2138 anAllowedTypes.insert(GeomAPI_Shape::FACE);
2139 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
2140 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
2141 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
2142 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
2143 if (anAllowedTypes.find(aShapeType) == anAllowedTypes.end()) {
2144 theError = "Error: Selected shape has the wrong type.";
2153 //==================================================================================================
2154 bool FeaturesPlugin_ValidatorGlueFacesSelection::isValid(const AttributePtr& theAttribute,
2155 const std::list<std::string>& theArguments,
2156 Events_InfoMessage& theError) const
2158 AttributeSelectionListPtr anAttrSelectionList =
2159 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
2160 if (!anAttrSelectionList.get()) {
2161 theError = "Error: This validator can only work with selection list attributes.";
2165 // Check selected entities are of valid types
2166 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
2167 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
2168 if (!anAttrSelection.get()) {
2169 theError = "Error: Empty attribute selection.";
2172 ResultPtr aContext = anAttrSelection->context();
2173 if (!aContext.get()) {
2174 theError = "Error: Empty selection context.";
2177 if (aContext->groupName() != ModelAPI_ResultBody::group()) {
2178 theError = "Error: Not a result body.";
2182 GeomShapePtr aContextShape = aContext->shape();
2183 if (!aContextShape.get()) {
2184 theError = "Error: Empty shape.";
2188 GeomAPI_Shape::ShapeType aShapeType = aContextShape->shapeType();
2189 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
2190 anAllowedTypes.insert(GeomAPI_Shape::FACE);
2191 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
2192 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
2193 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
2194 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
2195 if (anAllowedTypes.find(aShapeType) == anAllowedTypes.end()) {
2196 theError = "Error: Selected shape has the wrong type.";