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 and edges.
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::EDGE
272 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
273 theError = "Error: Compound should contain only faces and edges.";
282 GeomShapePtr aShape = aSelectionAttr->value();
283 GeomShapePtr aContextShape = aResultConstruction->shape();
285 // Whole sketch selected.
288 // Object from sketch selected.
289 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
290 GeomShapePtr aWire = anExp.current();
291 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
292 theError = "Error: Wire with wrong orientation selected.";
296 if(aSelectedWiresFromObjects.isBound(aWire)) {
298 "Error: Objects with such wire already selected. Don't allow to select this object.";
302 aSelectedWiresFromObjects.bind(aWire, aWire);
311 //==================================================================================================
312 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
313 const std::shared_ptr<ModelAPI_Feature>& theFeature,
314 const std::list<std::string>& theArguments,
315 Events_InfoMessage& theError) const
317 const std::string aBaseObjectsID = theArguments.front();
319 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
320 if(!aListAttr.get()) {
322 theError = "Error: Could not get \"%1\" attribute.";
323 theError.arg(aBaseObjectsID);
328 std::set<ResultConstructionPtr> aSelectedSketches;
329 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
331 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
332 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
333 ResultPtr aContext = aSelectionAttr->context();
334 if(!aContext.get()) {
335 FeaturePtr aFeature = aSelectionAttr->contextFeature();
336 if (!aFeature.get() || aFeature->results().empty()) {
337 theError = "Error: Empty context.";
340 aContext = aFeature->firstResult();
344 ResultConstructionPtr aResultConstruction =
345 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
346 if(!aResultConstruction.get()) {
347 // It is not a result construction.
351 GeomShapePtr aShape = aSelectionAttr->value();
352 GeomShapePtr aContextShape = aResultConstruction->shape();
354 // Whole sketch selected.
355 aSelectedSketches.insert(aResultConstruction);
357 // Object from sketch selected.
358 aSelectedSketchesFromObjects.insert(aResultConstruction);
363 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
364 anIt != aSelectedSketches.cend();
366 ResultConstructionPtr aResultConstruction = *anIt;
367 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
368 aSelectedSketchesFromObjects.cend()) {
369 theError = "Sketch and objects from it can not be selected at the same time.";
377 //==================================================================================================
378 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
379 const std::list<std::string>& theArguments,
380 Events_InfoMessage& theError) const
382 if(!theAttribute.get()) {
384 theError = "Error: Empty attribute.";
389 std::string anAttributeType = theAttribute->attributeType();
390 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
391 AttributeSelectionListPtr aListAttr =
392 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
393 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
394 // If at least one attribute is invalid, the result is false.
395 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
399 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
401 AttributeSelectionPtr anAttr =
402 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
403 ResultPtr aContext = anAttr->context();
404 if(!aContext.get() && !anAttr->contextFeature().get()) {
405 theError = "Error: Attribute have empty context.";
409 GeomShapePtr aShape = anAttr->value();
410 GeomShapePtr aContextShape;
411 if(!aShape.get() && aContext.get()) {
412 aContextShape = aContext->shape();
413 aShape = aContextShape;
416 theError = "Error: Empty shape selected";
420 ResultConstructionPtr aConstruction;
421 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
422 aContext = anAttr->contextFeature()->firstResult();
425 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
426 if(aConstruction.get()) {
427 // Construction selected. Check that it is not infinite.
428 if(aConstruction->isInfinite()) {
429 theError = "Error: Infinite constructions is not allowed as base.";
433 GeomShapePtr aContextShape = aContext->shape();
434 if(aShape->isEqual(aContextShape)) {
435 // Whole construction selected. Check that it have faces.
436 if(aConstruction->facesNum() > 0) {
440 // Shape on construction selected. Check that it is a face or wire.
441 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
442 aShape->shapeType() == GeomAPI_Shape::FACE) {
449 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
450 // Local selection on body does not allowed.
452 "Error: Selected shape is in the local selection. Only global selection is allowed.";
456 // Check that object is a shape with allowed type.
457 GeomValidators_ShapeType aShapeTypeValidator;
458 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
459 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
460 "wires on sketch, whole sketch(if it has at least one face), "
461 "and whole objects with shape types: %1";
462 std::string anArgumentString;
463 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
464 if (!anArgumentString.empty())
465 anArgumentString += ", ";
466 anArgumentString += *anIt;
468 theError.arg(anArgumentString);
474 theError = "Error: Attribute \"%1\" does not supported by this validator.";
475 theError.arg(anAttributeType);
483 //==================================================================================================
485 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
486 const std::list<std::string>& theArguments,
487 Events_InfoMessage& theError) const
489 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
490 theError = "Error: The attribute with the %1 type is not processed";
491 theError.arg(theAttribute->attributeType());
494 if (theArguments.size() != 2) {
495 theError = "Error: Wrong parameters in XML definition for %1 type";
496 theError.arg(theAttribute->attributeType());
499 // first argument is for the base attribute, second - for skipping feature kind
500 std::list<std::string>::const_iterator anIt = theArguments.begin();
501 std::string aBaseAttributeId = *anIt;
502 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
503 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
504 if (!aBaseAttribute.get()) {
505 theError = "Wrong parameters in XML definition for %1 type";
506 theError.arg(theAttribute->attributeType());
509 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
510 // this validator is not necessary anymore
514 std::string aFeatureAttributeKind = *anIt;
515 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
516 // check whether the selection is on the sketch
517 std::list<std::string> anArguments;
518 anArguments.push_back(aFeatureAttributeKind);
520 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
521 bool aPlanarFace = false;
522 // check if selection has Face selected
523 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
525 anArguments.push_back("face");
526 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
528 bool aValid = !aFeatureKind && aPlanarFace;
533 //==================================================================================================
534 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
535 const std::shared_ptr<ModelAPI_Feature>& theFeature,
536 const std::list<std::string>& theArguments,
537 Events_InfoMessage& theError) const
539 if(theArguments.size() != 2) {
541 theError = "Error: Validator should be used with 2 parameters for extrusion.";
546 std::list<std::string>::const_iterator
547 anArgsIt = theArguments.begin(), aLast = theArguments.end();
549 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
552 GeomShapePtr aDirShape;
553 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
555 aDirShape = aSelAttr->value();
556 if(!aDirShape.get()) {
557 ResultPtr aContext = aSelAttr->context();
558 if(!aContext.get()) {
559 FeaturePtr aFeature = aSelAttr->contextFeature();
560 if (aFeature.get() && !aFeature->results().empty()) {
561 aContext = aFeature->firstResult();
566 aDirShape = aContext->shape();
569 if (aDirShape.get() && aDirShape->isCompound()) {
570 GeomAPI_ShapeIterator anIt(aDirShape);
571 aDirShape = anIt.current();
576 if(!aDirShape.get() || aDirShape->isNull() ||
577 aDirShape->shapeType() != GeomAPI_Shape::EDGE) {
578 // Check that dir can be empty.
579 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
580 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
581 "can not be used with default value. Select direction for extrusion.";
582 theError.arg(*anArgsIt);
589 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
591 // If faces selected check that direction not parallel with them.
592 AttributeSelectionListPtr aListAttr =
593 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
594 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
595 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
596 GeomShapePtr aShapeInList = anAttr->value();
597 if(!aShapeInList.get()) {
598 aShapeInList = anAttr->context()->shape();
600 bool isParallel = true;
601 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
602 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
603 for(GeomAPI_ShapeExplorer
604 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
605 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
606 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
611 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
612 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
613 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
614 if(aPlanarEdges.get()) {
615 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
616 if(aDirEdge->isLine()) {
617 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
618 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
630 "Error: Direction is parallel to one of the selected face or face on selected shell.";
638 //==================================================================================================
639 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
640 Events_InfoMessage& theError) const
643 if(!theAttribute.get()) {
648 std::string anAttributeType = theAttribute->attributeType();
649 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
650 AttributeSelectionListPtr aListAttr =
651 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
652 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
653 // If at least one attribute is invalid, the result is false.
654 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
658 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
660 AttributeSelectionPtr anAttr =
661 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
662 ResultPtr aContext = anAttr->context();
663 if(!aContext.get() && !anAttr->contextFeature().get()) {
667 GeomShapePtr aShape = anAttr->value();
668 if(!aShape.get() && aContext.get()) {
669 GeomShapePtr aContextShape = aContext->shape();
670 aShape = aContextShape;
676 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
677 aShape->shapeType() == GeomAPI_Shape::EDGE ||
678 !aShape->isPlanar()) {
688 //==================================================================================================
689 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
690 const std::list<std::string>& theArguments,
691 Events_InfoMessage& theError) const
693 AttributeSelectionListPtr anAttrSelectionList =
694 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
695 if(!anAttrSelectionList.get()) {
698 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
702 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
703 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
704 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
706 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
707 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
708 if(!anAttrSelection.get()) {
709 theError = "Error: Empty attribute selection.";
712 ResultPtr aContext = anAttrSelection->context();
713 if(!aContext.get()) {
714 FeaturePtr aContFeat = anAttrSelection->contextFeature();
715 if (!aContFeat.get() || !aContFeat->results().size()) {
716 theError = "Error: Empty selection context.";
720 ResultConstructionPtr aResultConstruction =
721 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
722 if(aResultConstruction.get()) {
723 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
724 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
725 theError = "Error: Result construction not allowed for selection.";
729 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
730 if(!aShape.get() && aContext.get()) {
731 GeomShapePtr aContextShape = aContext->shape();
732 aShape = aContextShape;
735 theError = "Error: Empty shape.";
738 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
739 theError = "Error: Local selection not allowed.";
743 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
744 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
745 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
746 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
747 anAllowedTypes.insert(GeomAPI_Shape::FACE);
748 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
749 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
750 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
751 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
752 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
754 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
755 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
756 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
757 anAllowedTypes.insert(GeomAPI_Shape::FACE);
758 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
759 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
760 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
761 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
763 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
764 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
765 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
768 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
769 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
770 theError = "Error: Selected shape has the wrong type.";
779 //==================================================================================================
780 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
781 const std::list<std::string>& theArguments,
782 Events_InfoMessage& theError) const
784 AttributeSelectionListPtr anAttrSelectionList =
785 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
786 if(!anAttrSelectionList.get()) {
789 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
794 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
795 // Check all selected entities are sub-shapes of single solid
796 GeomShapePtr aBaseSolid;
797 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
798 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
799 if(!anAttrSelection.get()) {
800 theError = "Error: Empty attribute selection.";
803 ResultPtr aContext = anAttrSelection->context();
804 if(!aContext.get()) {
805 FeaturePtr aContFeat = anAttrSelection->contextFeature();
806 if (!aContFeat.get() || !aContFeat->results().size() ||
807 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
808 theError = "Error: Empty selection context.";
811 if (aContFeat->results().size() == 1)
812 aContext = aContFeat->firstResult();
814 theError = "Error: Too many shapes selected.";
819 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
820 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
823 theError = "Error: wrong feature is selected.";
827 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
828 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
829 theError = "Error: Not all selected shapes are sub-shapes of solids.";
834 aBaseSolid = anOwner;
835 else if (!aBaseSolid->isEqual(anOwner)) {
836 theError = "Error: Sub-shapes of different solids have been selected.";
844 //==================================================================================================
845 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
846 const std::list<std::string>& theArguments,
847 Events_InfoMessage& theError) const
849 AttributeSelectionListPtr anAttrSelectionList =
850 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
851 if(!anAttrSelectionList.get()) {
853 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
858 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
859 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
861 //GeomValidators_BodyShapes aBodyValidator;
862 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
866 GeomValidators_FeatureKind aFeatureKindValidator;
867 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
871 ResultPtr aContext = aSelectAttr->context();
872 ResultConstructionPtr aResultConstruction =
873 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
874 if(aResultConstruction.get()) {
875 theError = "Error: Only body shapes and construction planes are allowed for selection.";
879 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
880 if(aResultBody.get()) {
883 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
884 if(aResultFeature.get()) {
886 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
887 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
888 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
889 if (aBody.get() && !aBody->isDisabled())
896 theError = "Error: Only body shapes and construction planes are allowed for selection.";
904 //==================================================================================================
905 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
906 const std::list<std::string>& theArguments,
907 Events_InfoMessage& theError) const
909 AttributeSelectionListPtr aSubShapesAttrList =
910 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
911 if(!aSubShapesAttrList.get()) {
914 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
919 static const std::string aBaseShapeID = "base_shape";
920 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
921 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
923 if(!aShapeAttrSelection.get()) {
925 theError = "Error: Could not get \"%1\" attribute.";
926 theError.arg(aBaseShapeID);
931 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
932 ResultPtr aContext = aShapeAttrSelection->context();
933 if(!aContext.get()) {
934 theError = "Error: Empty context.";
937 if(!aBaseShape.get()) {
938 aBaseShape = aContext->shape();
940 if(!aBaseShape.get()) {
941 theError = "Error: Empty base shape.";
945 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
946 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
947 bool isSameFound = false;
948 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
949 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
950 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
952 if ((*anIt)->isEqual(aShapeToAdd)) {
958 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
966 //==================================================================================================
967 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
968 const std::shared_ptr<ModelAPI_Feature>& theFeature,
969 const std::list<std::string>& theArguments,
970 Events_InfoMessage& theError) const
972 static const std::string aBaseShapeID = "base_shape";
973 static const std::string aSubShapesID = "subshapes_to_keep";
976 if(theFeature->getKind() != "Remove_SubShapes") {
977 theError = "Error: Feature \"%1\" does not supported by this validator.";
978 theError.arg(theFeature->getKind());
982 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
983 if(!aShapeAttrSelection.get()) {
984 theError = "Error: Could not get \"%1\" attribute.";
985 theError.arg(aBaseShapeID);
989 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
990 if(!aSubShapesAttrList.get()) {
991 theError = "Error: Could not get \"%1\" attribute.";
992 theError.arg(aSubShapesID);
998 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
999 if(!aBaseShape.get()) {
1000 theError = "Error: Base shape is empty.";
1003 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
1005 if (aSubShapesAttrList->size() == 0) {
1006 theError = "Error: Resulting shape is not valid.";
1010 // Copy sub-shapes from list to new shape.
1011 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1012 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1013 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1014 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
1018 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
1019 theError = "Error: Resulting shape is not valid.";
1026 //==================================================================================================
1028 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
1029 const std::list<std::string>& theArguments,
1030 Events_InfoMessage& theError) const
1032 AttributeSelectionListPtr aBaseObjectsAttrList =
1033 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1034 if(!aBaseObjectsAttrList.get()) {
1035 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1036 theError.arg(FeaturesPlugin_Union::ID());
1040 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1041 bool isSameFound = false;
1042 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1043 ResultPtr aContext = anAttrSelectionInList->context();
1044 if (!aContext.get()) {
1045 theError = "Error: selection is invalid.";
1049 ResultConstructionPtr aConstruction =
1050 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1051 if(aConstruction.get()) {
1052 theError = "Error: Result construction not allowed for selection.";
1056 GeomShapePtr aShape = anAttrSelectionInList->value();
1057 GeomShapePtr aContextShape = aContext->shape();
1058 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1059 theError = "Error: Local selection not allowed.";
1063 ResultBodyPtr aResult =
1064 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1065 if(!aResult.get()) {
1069 if(aResult->numberOfSubs() > 0) {
1070 theError = "Error: Whole compsolids not allowed for selection.";
1079 //==================================================================================================
1080 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1081 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1082 const std::list<std::string>& theArguments,
1083 Events_InfoMessage& theError) const
1086 // Check feature kind.
1087 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1088 theError = "Error: This validator supports only \"%1\" feature.";
1089 theError.arg(FeaturesPlugin_Union::ID());
1093 // Get base objects attribute list.
1094 AttributeSelectionListPtr aBaseObejctsAttrList =
1095 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1096 if(!aBaseObejctsAttrList.get()) {
1097 theError = "Error: Could not get \"%1\" attribute.";
1098 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1104 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1105 ListOfShape aBaseShapesList;
1106 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1107 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1108 GeomShapePtr aShape = anAttrSelectionInList->value();
1109 if (!aShape.get()) {
1112 aBaseShapesList.push_back(aShape);
1113 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1114 GeomAPI_Shape::COMPSOLID;
1117 // Make compound and find connected.
1118 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1119 ListOfShape aResults;
1120 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults);
1122 if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) {
1123 theError = "Error: Not all shapes have shared topology.";
1130 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1131 const std::list<std::string>& theArguments,
1132 Events_InfoMessage& theError) const
1134 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1136 theError = "Error: The attribute with the %1 type is not processed";
1137 theError.arg(theAttribute->attributeType());
1142 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1144 ObjectPtr aRefObject = aRefAttribute->value();
1145 if (!aRefObject.get()) {
1146 theError = "Error: Empty feature.";
1150 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1151 if (!aRefFeature.get()) {
1152 theError = "Error: Empty feature.";
1155 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1156 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1158 size_t aConcealedResults = aResults.size();
1159 if (!aConcealedResults && !theArguments.empty()) {
1160 // find if these results are touched by the feature in another attribute
1161 std::list<std::string>::const_iterator anIt = theArguments.begin();
1162 std::string aRecoveredList = *anIt;
1163 if (!aRecoveredList.empty()) {
1164 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1165 theAttribute->owner()->data()->reflist(aRecoveredList);
1166 if (aParameterList.get())
1167 aConcealedResults = aParameterList->size();
1171 if (aConcealedResults == 0)
1172 theError = "Error: No concealed results.";
1174 return theError.empty();
1177 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1178 const std::list<std::string>& theArguments,
1179 Events_InfoMessage& theError) const
1181 static std::list<std::string> aEdgeArg(1, "circle");
1182 static std::list<std::string> aFaceArg(1, "cylinder");
1184 Events_InfoMessage aError;
1185 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1187 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1189 theError = "The shape neither circle nor cylinder";
1194 //=================================================================================================
1195 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1196 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1197 const std::list<std::string>& theArguments,
1198 Events_InfoMessage& theError) const
1201 if (theArguments.size() != 2)
1203 theError = "Wrong number of arguments (expected 2).";
1208 int anObjectsToolsNb[2] = { 0, 0 };
1210 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1212 bool isAllInSameCompSolid = true;
1213 ResultBodyPtr aCompSolid;
1215 for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
1216 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1219 *anArgNbIt = anAttrSelList->size();
1220 if (isAllInSameCompSolid) {
1221 for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
1223 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1224 ResultPtr aContext = anAttr->context();
1225 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1226 if (aResCompSolidPtr.get())
1228 if (aCompSolid.get())
1230 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1234 aCompSolid = aResCompSolidPtr;
1239 isAllInSameCompSolid = false;
1247 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1248 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1249 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1251 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1254 if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
1256 theError = "Not enough arguments for Fuse operation.";
1259 else if (isAllInSameCompSolid)
1261 theError = "Operations only between sub-shapes of the same shape not allowed.";
1267 if (anObjectsToolsNb[0] < 1) // check number of objects
1269 theError = "Objects not selected.";
1272 if (anObjectsToolsNb[1] < 1) // check number of tools
1274 theError = "Tools not selected.";
1277 if (isAllInSameCompSolid)
1279 theError = "Operations only between sub-shapes of the same shape not allowed.";
1287 //=================================================================================================
1289 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1290 std::string theAttribute)
1292 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1301 //==================================================================================================
1302 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1303 const AttributePtr& theAttribute,
1304 const std::list<std::string>& theArguments,
1305 Events_InfoMessage& theError) const
1307 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1308 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1310 AttributeSelectionListPtr anAttrSelectionList =
1311 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1312 if (!aFeature.get() || !anAttrSelectionList.get()) {
1315 "Error: Validator used in wrong feature or attribute";
1320 AttributeSelectionListPtr anOtherAttrSelectionList;
1321 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1322 anOtherAttrSelectionList =
1323 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1325 anOtherAttrSelectionList =
1326 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1329 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1330 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1331 GeomPlanePtr aFacesPln;
1333 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1334 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1336 if (anAttrSelection->contextFeature().get()) {
1337 theError = "Error: Features not allowed for selection.";
1341 ResultPtr aContext = anAttrSelection->context();
1342 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1343 if (!aShape.get()) {
1344 if (!aContext.get()) {
1345 theError = "Error: Empty selection.";
1348 aShape = aContext->shape();
1351 if (aShape->isSolid() || aShape->isCompSolid()) {
1352 aSelectedShapesType = GeomAPI_Shape::SOLID;
1353 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1354 if (aResCompSolidPtr.get()) {
1355 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1356 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1359 aSelectedShapesType = GeomAPI_Shape::FACE;
1360 GeomAPI_Face aFace(aShape);
1361 aFacesPln = aFace.getPlane();
1366 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1367 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1368 if (!anAttrSelection.get()) {
1369 theError = "Error: Empty attribute selection.";
1373 if (anAttrSelection->contextFeature().get()) {
1374 theError = "Error: Features not allowed for selection.";
1378 ResultPtr aContext = anAttrSelection->context();
1379 if(!aContext.get()) {
1380 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1381 if (!aContFeat.get() || !aContFeat->results().size() ||
1382 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1383 theError = "Error: Empty selection context.";
1387 ResultConstructionPtr aResultConstruction =
1388 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1389 if (aResultConstruction.get()) {
1390 theError = "Error: Result construction not allowed for selection.";
1393 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1394 GeomShapePtr aContextShape = aContext->shape();
1395 if (!aShape.get()) {
1396 aShape = aContextShape;
1398 if (!aShape.get()) {
1399 theError = "Error: Empty shape.";
1402 if (!aShape->isEqual(aContextShape)) {
1403 theError = "Error: Local selection not allowed.";
1407 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1408 // Other list is empty.
1409 if (aShape->isSolid() || aShape->isCompSolid()) {
1410 aSelectedShapesType = GeomAPI_Shape::SOLID;
1412 aSelectedShapesType = GeomAPI_Shape::FACE;
1413 GeomAPI_Face aFace(aShape);
1414 aFacesPln = aFace.getPlane();
1416 if (!aFacesPln.get()) {
1417 theError = "Error: Only planar faces allowed.";
1423 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1424 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1425 theError = "Error: Selected shapes should have the same type.";
1429 GeomAPI_Face aFace(aShape);
1430 GeomPlanePtr aPln = aFace.getPlane();
1433 theError = "Error: Only planar faces allowed.";
1437 if (!aFacesPln->isCoincident(aPln)) {
1438 theError = "Error: Only coincident faces allowed.";
1447 //==================================================================================================
1449 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1450 const std::list<std::string>& theArguments,
1451 Events_InfoMessage& theError) const
1453 if (!theAttribute.get()) {
1454 theError = "Error: empty selection.";
1457 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1458 AttributeSelectionListPtr anAttrSelectionList =
1459 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1460 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1461 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1462 if (!anAttrSelection.get()) {
1463 theError = "Error: empty attribute selection.";
1466 ResultPtr aContext = anAttrSelection->context();
1467 if(!aContext.get()) {
1468 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1469 if (!aContFeat.get() || !aContFeat->results().size() ||
1470 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1471 theError = "Error: Empty selection context.";
1475 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1476 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1477 if (!aFeature.get()) {
1478 theError = "Error: empty feature.";
1481 std::string aFeatureKind = aFeature->getKind();
1482 if (aFeatureKind == "Sketch" ||
1483 aFeatureKind == "Plane" ||
1484 aFeatureKind == "Axis") {
1485 theError = "Error: %1 shape is not allowed for selection.";
1486 theError.arg(aFeatureKind);
1489 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1490 if (!aShape.get()) {
1491 GeomShapePtr aContextShape = aContext->shape();
1492 aShape = aContextShape;
1494 if (!aShape.get()) {
1495 theError = "Error: empty shape.";
1498 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1499 theError = "Error: Local selection not allowed.";
1503 int aShapeType = aShape->shapeType();
1504 // Allow to select edges, faces and solids.
1505 if (aShapeType != GeomAPI_Shape::EDGE &&
1506 aShapeType != GeomAPI_Shape::FACE &&
1507 aShapeType != GeomAPI_Shape::SOLID &&
1508 aShapeType != GeomAPI_Shape::COMPSOLID &&
1509 aShapeType != GeomAPI_Shape::COMPOUND) {
1510 theError = "Error: selected shape has the wrong type.";
1519 //==================================================================================================
1521 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1522 const AttributePtr& theAttribute,
1523 const std::list<std::string>& theArguments,
1524 Events_InfoMessage& theError) const
1526 AttributeSelectionListPtr anAttrSelectionList =
1527 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1528 if (!anAttrSelectionList.get()) {
1530 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1534 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1535 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1536 if (!anAttrSelection.get()) {
1537 theError = "Error: Empty attribute selection.";
1540 ResultPtr aContext = anAttrSelection->context();
1541 if(!aContext.get()) {
1542 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1543 if (!aContFeat.get() || !aContFeat->results().size() ||
1544 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1545 theError = "Error: Empty selection context.";
1549 ResultConstructionPtr aResultConstruction =
1550 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1551 if (aResultConstruction.get()) {
1552 theError = "Error: Result construction not allowed for selection.";
1555 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1556 if (!aShape.get()) {
1557 GeomShapePtr aContextShape = aContext->shape();
1558 aShape = aContextShape;
1560 if (!aShape.get()) {
1561 theError = "Error: Empty shape.";
1564 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1565 theError = "Error: Local selection not allowed.";
1574 //=================================================================================================
1575 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1576 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1577 const std::list<std::string>& theArguments,
1578 Events_InfoMessage& theError) const
1581 if (theArguments.size() != 2) {
1582 theError = "Wrong number of arguments (expected 2).";
1587 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1588 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1590 int anObjectsNb = 0, aToolsNb = 0;
1592 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1594 bool isAllInSameCompSolid = true;
1595 ResultBodyPtr aCompSolid;
1597 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1598 if (anAttrSelList) {
1599 anObjectsNb = anAttrSelList->size();
1600 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1601 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1602 ResultPtr aContext = anAttr->context();
1603 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1604 if (aResCompSolidPtr.get()) {
1605 if (aCompSolid.get()) {
1606 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1608 aCompSolid = aResCompSolidPtr;
1611 isAllInSameCompSolid = false;
1618 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1619 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1620 anAttrSelList = theFeature->selectionList(*anIt);
1621 if (anAttrSelList) {
1622 aToolsNb = anAttrSelList->size();
1623 if (isAllInSameCompSolid) {
1624 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1625 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1626 ResultPtr aContext = anAttr->context();
1627 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1628 if (aResCompSolidPtr.get()) {
1629 if (aCompSolid.get()) {
1630 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1632 aCompSolid = aResCompSolidPtr;
1635 isAllInSameCompSolid = false;
1645 if (anObjectsNb + aToolsNb < 2) {
1646 theError = "Not enough arguments for Fuse operation.";
1648 } else if (isAllInSameCompSolid) {
1649 theError = "Operations only between sub-shapes of the same shape not allowed.";
1656 //=================================================================================================
1658 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1659 std::string theFeature,
1660 std::string theAttribute)
1662 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1670 //==================================================================================================
1672 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1673 const AttributePtr& theAttribute,
1674 const std::list<std::string>& theArguments,
1675 Events_InfoMessage& theError) const
1677 AttributeSelectionListPtr anAttrSelectionList =
1678 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1679 if (!anAttrSelectionList.get()) {
1681 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1685 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1686 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1687 if (!anAttrSelection.get()) {
1688 theError = "Error: Empty attribute selection.";
1691 ResultPtr aContext = anAttrSelection->context();
1692 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1693 theError = "Error: Empty selection context.";
1696 ResultConstructionPtr aResultConstruction =
1697 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1698 if (aResultConstruction.get()) {
1699 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1700 theError = "Error: Result construction not allowed for selection.";
1704 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1705 GeomShapePtr aContextShape;
1706 if (aContext.get()) {
1707 aContextShape = aContext->shape();
1709 if (!aShape.get()) {
1710 aShape = aContextShape;
1712 if (!aShape.get()) {
1713 theError = "Error: Empty shape.";
1716 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1717 theError = "Error: Local selection not allowed.";
1721 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1722 theError = "Error: Result construction should be plane.";
1731 //=================================================================================================
1732 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1733 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1734 const std::list<std::string>& theArguments,
1735 Events_InfoMessage& theError) const
1737 if (theArguments.size() != 2) {
1739 theError = "Wrong number of arguments (expected 2).";
1744 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1745 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1747 int anObjectsNb = 0, aToolsNb = 0;
1749 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1751 bool isAllInSameCompSolid = true;
1752 ResultBodyPtr aCompSolid;
1754 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1755 if (anAttrSelList) {
1756 anObjectsNb = anAttrSelList->size();
1759 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1760 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1762 if (!isSimpleMode) {
1763 anAttrSelList = theFeature->selectionList(*anIt);
1764 if (anAttrSelList) {
1765 aToolsNb = anAttrSelList->size();
1769 if ((isSimpleMode && anObjectsNb < 2)
1770 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1771 theError = "Not enough arguments for Fuse operation.";
1777 //=================================================================================================
1779 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1780 std::string theFeature,
1781 std::string theAttribute)