1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Validators.h"
23 #include "FeaturesPlugin_Boolean.h"
24 #include "FeaturesPlugin_BooleanFuse.h"
25 #include "FeaturesPlugin_BooleanCommon.h"
26 #include "FeaturesPlugin_BooleanSmash.h"
27 #include "FeaturesPlugin_Pipe.h"
28 #include "FeaturesPlugin_Union.h"
30 #include <Events_InfoMessage.h>
32 #include <ModelAPI_Attribute.h>
33 #include <ModelAPI_AttributeInteger.h>
34 #include <ModelAPI_AttributeSelectionList.h>
35 #include <ModelAPI_AttributeString.h>
36 #include <ModelAPI_AttributeReference.h>
37 #include <ModelAPI_AttributeRefList.h>
38 #include <ModelAPI_Feature.h>
39 #include <ModelAPI_ResultBody.h>
40 #include <ModelAPI_ResultConstruction.h>
41 #include <ModelAPI_Tools.h>
43 #include <GeomValidators_BodyShapes.h>
44 #include <GeomValidators_Face.h>
45 #include <GeomValidators_FeatureKind.h>
46 #include <GeomValidators_ShapeType.h>
48 #include <GeomAPI_DataMapOfShapeShape.h>
49 #include <GeomAPI_Lin.h>
50 #include <GeomAPI_PlanarEdges.h>
51 #include <GeomAPI_Pln.h>
52 #include <GeomAPI_ShapeExplorer.h>
53 #include <GeomAPI_ShapeIterator.h>
55 #include <GeomAlgoAPI_CompoundBuilder.h>
56 #include <GeomAlgoAPI_ShapeBuilder.h>
57 #include <GeomAlgoAPI_ShapeTools.h>
58 #include <GeomAlgoAPI_WireBuilder.h>
60 #define _USE_MATH_DEFINES
63 //==================================================================================================
64 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
65 const std::list<std::string>& theArguments,
66 Events_InfoMessage& theError) const
68 AttributeSelectionPtr aPathAttrSelection =
69 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
70 if(!aPathAttrSelection.get()) {
71 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
75 GeomShapePtr aPathShape = aPathAttrSelection->value();
76 ResultPtr aContext = aPathAttrSelection->context();
78 theError = "Error: Empty context.";
81 GeomShapePtr aContextShape = aContext->shape();
82 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
83 !aPathShape->isEqual(aContextShape)) {
84 theError = "Error: Local selection of wires not allowed.";
91 //==================================================================================================
92 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute,
93 const std::list<std::string>& theArguments,
94 Events_InfoMessage& theError) const
96 AttributeSelectionListPtr anAttrSelectionList =
97 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
98 if(!anAttrSelectionList.get()) {
100 "Error: This validator can only work with selection list attributes in \"Pipe\" feature.";
103 std::shared_ptr<FeaturesPlugin_Pipe> aFeature =
104 std::dynamic_pointer_cast<FeaturesPlugin_Pipe>(theAttribute->owner());
106 AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
107 if (!aPathSelection.get()) {
108 theError = "Error: Path not selected.";
112 GeomShapePtr aPathShape = aPathSelection->value();
113 if (!aPathShape.get()) {
114 ResultPtr aContext = aPathSelection->context();
115 if (!aContext.get()) {
116 FeaturePtr aContFeat = aPathSelection->contextFeature();
117 if (!aContFeat.get() || !aContFeat->results().size()) {
118 theError = "Error: Empty selection context.";
122 aPathShape = aContext->shape();
125 if (!aPathShape.get()) {
126 theError = "Error: Empty path shape.";
130 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
131 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
132 if (!anAttrSelection.get()) {
133 theError = "Error: Empty attribute selection.";
136 ResultPtr aContext = anAttrSelection->context();
137 if (!aContext.get()) {
138 FeaturePtr aContFeat = anAttrSelection->contextFeature();
139 if (!aContFeat.get() || !aContFeat->results().size()) {
140 theError = "Error: Empty selection context.";
144 ResultConstructionPtr aResultConstruction =
145 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
146 if (aResultConstruction.get()) {
147 theError = "Error: Result construction not allowed for selection.";
150 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
151 if (!aShape.get() && aContext.get()) {
152 GeomShapePtr aContextShape = aContext->shape();
153 aShape = aContextShape;
156 theError = "Error: Empty shape.";
160 if (!aPathShape->isSubShape(aShape)) {
161 theError = "Error: Location should be a vertex subshape from path shape.";
169 //==================================================================================================
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.";
219 //==================================================================================================
220 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
221 const std::list<std::string>& theArguments,
222 Events_InfoMessage& theError) const
224 if(theArguments.empty()) {
225 theError = "Error: Validator parameters is empty.";
229 // Checking attribute.
230 if(!isValidAttribute(theAttribute, theArguments, theError)) {
231 if(theError.empty()) {
232 theError = "Error: Attribute contains unacceptable shape.";
237 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
238 std::string anAttributeType = theAttribute->attributeType();
239 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
240 AttributeSelectionListPtr aListAttr =
241 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
242 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
243 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
244 ResultPtr aContext = aSelectionAttr->context();
245 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
246 theError = "Error: Empty context.";
250 ResultConstructionPtr aResultConstruction =
251 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
252 if(!aResultConstruction.get()) {
253 // It is not a result construction.
254 // If shape is compound check that it contains only faces and edges.
255 GeomShapePtr aShape = aSelectionAttr->value();
257 if (aContext.get()) {
258 aShape = aContext->shape();
260 theError = "Error: Empty context.";
265 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
266 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
267 GeomShapePtr aSubShape = anIt.current();
268 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
269 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
270 theError = "Error: Compound should contain only faces and edges.";
279 GeomShapePtr aShape = aSelectionAttr->value();
280 GeomShapePtr aContextShape = aResultConstruction->shape();
282 // Whole sketch selected.
285 // Object from sketch selected.
286 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
287 GeomShapePtr aWire = anExp.current();
288 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
289 theError = "Error: Wire with wrong orientation selected.";
293 if(aSelectedWiresFromObjects.isBound(aWire)) {
295 "Error: Objects with such wire already selected. Don't allow to select this object.";
299 aSelectedWiresFromObjects.bind(aWire, aWire);
308 //==================================================================================================
309 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
310 const std::shared_ptr<ModelAPI_Feature>& theFeature,
311 const std::list<std::string>& theArguments,
312 Events_InfoMessage& theError) const
314 const std::string aBaseObjectsID = theArguments.front();
316 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
317 if(!aListAttr.get()) {
318 theError = "Error: Could not get \"%1\" attribute.";
319 theError.arg(aBaseObjectsID);
323 std::set<ResultConstructionPtr> aSelectedSketches;
324 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
326 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
327 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
328 ResultPtr aContext = aSelectionAttr->context();
329 if(!aContext.get()) {
330 FeaturePtr aFeature = aSelectionAttr->contextFeature();
331 if (!aFeature.get() || aFeature->results().empty()) {
332 theError = "Error: Empty context.";
335 aContext = aFeature->firstResult();
339 ResultConstructionPtr aResultConstruction =
340 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
341 if(!aResultConstruction.get()) {
342 // It is not a result construction.
346 GeomShapePtr aShape = aSelectionAttr->value();
347 GeomShapePtr aContextShape = aResultConstruction->shape();
349 // Whole sketch selected.
350 aSelectedSketches.insert(aResultConstruction);
352 // Object from sketch selected.
353 aSelectedSketchesFromObjects.insert(aResultConstruction);
358 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
359 anIt != aSelectedSketches.cend();
361 ResultConstructionPtr aResultConstruction = *anIt;
362 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
363 aSelectedSketchesFromObjects.cend()) {
364 theError = "Sketch and objects from it can not be selected at the same time.";
372 //==================================================================================================
373 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
374 const std::list<std::string>& theArguments,
375 Events_InfoMessage& theError) const
377 if(!theAttribute.get()) {
378 theError = "Error: Empty attribute.";
382 std::string anAttributeType = theAttribute->attributeType();
383 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
384 AttributeSelectionListPtr aListAttr =
385 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
386 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
387 // If at least one attribute is invalid, the result is false.
388 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
392 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
394 AttributeSelectionPtr anAttr =
395 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
396 ResultPtr aContext = anAttr->context();
397 if(!aContext.get() && !anAttr->contextFeature().get()) {
398 theError = "Error: Attribute have empty context.";
402 GeomShapePtr aShape = anAttr->value();
403 GeomShapePtr aContextShape;
404 if(!aShape.get() && aContext.get()) {
405 aContextShape = aContext->shape();
406 aShape = aContextShape;
409 theError = "Error: Empty shape selected";
413 ResultConstructionPtr aConstruction;
414 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
415 aContext = anAttr->contextFeature()->firstResult();
418 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
419 if(aConstruction.get()) {
420 // Construciotn selected. Check that is is not infinite.
421 if(aConstruction->isInfinite()) {
422 theError = "Error: Infinite constructions is not allowed as base.";
426 GeomShapePtr aContextShape = aContext->shape();
427 if(aShape->isEqual(aContextShape)) {
428 // Whole construction selected. Check that it have faces.
429 if(aConstruction->facesNum() > 0) {
433 // Shape on construction selected. Check that it is a face or wire.
434 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
435 aShape->shapeType() == GeomAPI_Shape::FACE) {
443 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
444 // Local selection on body does not allowed.
446 "Error: Selected shape is in the local selection. Only global selection is allowed.";
450 // Check that object is a shape with allowed type.
451 GeomValidators_ShapeType aShapeTypeValidator;
452 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
453 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
454 "wires on sketch, whole sketch(if it has at least one face), "
455 "and whole objects with shape types: %1";
456 std::string anArgumentString;
457 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
458 if (!anArgumentString.empty())
459 anArgumentString += ", ";
460 anArgumentString += *anIt;
462 theError.arg(anArgumentString);
467 theError = "Error: Attribute \"%1\" does not supported by this validator.";
468 theError.arg(anAttributeType);
475 //==================================================================================================
476 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
477 const std::list<std::string>& theArguments,
478 Events_InfoMessage& theError) const
480 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
481 theError = "Error: The attribute with the %1 type is not processed";
482 theError.arg(theAttribute->attributeType());
485 if (theArguments.size() != 2) {
486 theError = "Error: Wrong parameters in XML definition for %1 type";
487 theError.arg(theAttribute->attributeType());
490 // first argument is for the base attribute, second - for skipping feature kind
491 std::list<std::string>::const_iterator anIt = theArguments.begin();
492 std::string aBaseAttributeId = *anIt;
493 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
494 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
495 if (!aBaseAttribute.get()) {
496 theError = "Wrong parameters in XML definition for %1 type";
497 theError.arg(theAttribute->attributeType());
500 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
501 // this validator is not necessary anymore
505 std::string aFeatureAttributeKind = *anIt;
506 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
507 // check whether the selection is on the sketch
508 std::list<std::string> anArguments;
509 anArguments.push_back(aFeatureAttributeKind);
511 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
512 bool aPlanarFace = false;
513 // check if selection has Face selected
514 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
516 anArguments.push_back("face");
517 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
519 bool aValid = !aFeatureKind && aPlanarFace;
523 //==================================================================================================
524 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
525 const std::shared_ptr<ModelAPI_Feature>& theFeature,
526 const std::list<std::string>& theArguments,
527 Events_InfoMessage& theError) const
529 if(theArguments.size() != 2) {
530 theError = "Error: Validator should be used with 2 parameters for extrusion.";
534 std::list<std::string>::const_iterator
535 anArgsIt = theArguments.begin(), aLast = theArguments.end();
537 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
540 GeomShapePtr aDirShape;
541 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
543 aDirShape = aSelAttr->value();
544 if(!aDirShape.get()) {
545 ResultPtr aContext = aSelAttr->context();
546 if(!aContext.get()) {
547 FeaturePtr aFeature = aSelAttr->contextFeature();
548 if (aFeature.get() && !aFeature->results().empty()) {
549 aContext = aFeature->firstResult();
554 aDirShape = aContext->shape();
559 if(!aDirShape.get()) {
560 // Check that dir can be empty.
561 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
562 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
563 "can not be used with default value. Select direction for extrusion.";
564 theError.arg(*anArgsIt);
571 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
573 // If faces selected check that direction not parallel with them.
574 AttributeSelectionListPtr aListAttr =
575 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
576 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
577 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
578 GeomShapePtr aShapeInList = anAttr->value();
579 if(!aShapeInList.get()) {
580 aShapeInList = anAttr->context()->shape();
582 bool isParallel = true;
583 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
584 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
585 for(GeomAPI_ShapeExplorer
586 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
587 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
588 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
593 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
594 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
595 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
596 if(aPlanarEdges.get()) {
597 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
598 if(aDirEdge->isLine()) {
599 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
600 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
612 "Error: Direction is parallel to one of the selected face or face on selected shell.";
620 //==================================================================================================
621 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
622 Events_InfoMessage& theError) const
624 if(!theAttribute.get()) {
628 std::string anAttributeType = theAttribute->attributeType();
629 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
630 AttributeSelectionListPtr aListAttr =
631 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
632 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
633 // If at least one attribute is invalid, the result is false.
634 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
638 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
640 AttributeSelectionPtr anAttr =
641 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
642 ResultPtr aContext = anAttr->context();
643 if(!aContext.get() && !anAttr->contextFeature().get()) {
647 GeomShapePtr aShape = anAttr->value();
648 if(!aShape.get() && aContext.get()) {
649 GeomShapePtr aContextShape = aContext->shape();
650 aShape = aContextShape;
656 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
657 aShape->shapeType() == GeomAPI_Shape::EDGE ||
658 !aShape->isPlanar()) {
668 //==================================================================================================
669 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
670 const std::list<std::string>& theArguments,
671 Events_InfoMessage& theError) const
673 AttributeSelectionListPtr anAttrSelectionList =
674 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
675 if(!anAttrSelectionList.get()) {
677 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
680 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
681 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
682 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
684 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
685 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
686 if(!anAttrSelection.get()) {
687 theError = "Error: Empty attribute selection.";
690 ResultPtr aContext = anAttrSelection->context();
691 if(!aContext.get()) {
692 FeaturePtr aContFeat = anAttrSelection->contextFeature();
693 if (!aContFeat.get() || !aContFeat->results().size()) {
694 theError = "Error: Empty selection context.";
698 ResultConstructionPtr aResultConstruction =
699 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
700 if(aResultConstruction.get()) {
701 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
702 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
703 theError = "Error: Result construction not allowed for selection.";
707 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
708 if(!aShape.get() && aContext.get()) {
709 GeomShapePtr aContextShape = aContext->shape();
710 aShape = aContextShape;
713 theError = "Error: Empty shape.";
716 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
717 theError = "Error: Local selection not allowed.";
721 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
722 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
723 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
724 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
725 anAllowedTypes.insert(GeomAPI_Shape::FACE);
726 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
727 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
728 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
729 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
730 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
732 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
733 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
734 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
735 anAllowedTypes.insert(GeomAPI_Shape::FACE);
736 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
737 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
738 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
739 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
741 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
742 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
743 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
746 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
747 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
748 theError = "Error: Selected shape has the wrong type.";
757 //==================================================================================================
758 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
759 const std::list<std::string>& theArguments,
760 Events_InfoMessage& theError) const
762 AttributeSelectionListPtr anAttrSelectionList =
763 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
764 if(!anAttrSelectionList.get()) {
766 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
770 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
771 // Check all selected entities are sub-shapes of single solid
772 GeomShapePtr aBaseSolid;
773 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
774 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
775 if(!anAttrSelection.get()) {
776 theError = "Error: Empty attribute selection.";
779 ResultPtr aContext = anAttrSelection->context();
780 if(!aContext.get()) {
781 FeaturePtr aContFeat = anAttrSelection->contextFeature();
782 if (!aContFeat.get() || !aContFeat->results().size() ||
783 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
784 theError = "Error: Empty selection context.";
787 if (aContFeat->results().size() == 1)
788 aContext = aContFeat->firstResult();
790 theError = "Error: Too many shapes selected.";
795 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
796 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
799 theError = "Error: wrong feature is selected.";
803 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
804 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
805 theError = "Error: Not all selected shapes are sub-shapes of solids.";
810 aBaseSolid = anOwner;
811 else if (!aBaseSolid->isEqual(anOwner)) {
812 theError = "Error: Sub-shapes of different solids have been selected.";
820 //==================================================================================================
821 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
822 const std::list<std::string>& theArguments,
823 Events_InfoMessage& theError) const
825 AttributeSelectionListPtr anAttrSelectionList =
826 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
827 if(!anAttrSelectionList.get()) {
828 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
832 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
833 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
835 //GeomValidators_BodyShapes aBodyValidator;
836 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
840 GeomValidators_FeatureKind aFeatureKindValidator;
841 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
845 ResultPtr aContext = aSelectAttr->context();
846 ResultConstructionPtr aResultConstruction =
847 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
848 if(aResultConstruction.get()) {
849 theError = "Error: Only body shapes and construction planes are allowed for selection.";
853 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
854 if(aResultBody.get()) {
857 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
858 if(aResultFeature.get()) {
860 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
861 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
862 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
863 if (aBody.get() && !aBody->isDisabled())
870 theError = "Error: Only body shapes and construction planes are allowed for selection.";
878 //==================================================================================================
879 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
880 const std::list<std::string>& theArguments,
881 Events_InfoMessage& theError) const
883 AttributeSelectionListPtr aSubShapesAttrList =
884 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
885 if(!aSubShapesAttrList.get()) {
887 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
891 static const std::string aBaseShapeID = "base_shape";
892 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
893 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
895 if(!aShapeAttrSelection.get()) {
896 theError = "Error: Could not get \"%1\" attribute.";
897 theError.arg(aBaseShapeID);
901 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
902 ResultPtr aContext = aShapeAttrSelection->context();
903 if(!aContext.get()) {
904 theError = "Error: Empty context.";
907 if(!aBaseShape.get()) {
908 aBaseShape = aContext->shape();
910 if(!aBaseShape.get()) {
911 theError = "Error: Empty base shape.";
915 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
916 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
917 bool isSameFound = false;
918 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
919 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
920 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
922 if ((*anIt)->isEqual(aShapeToAdd)) {
928 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
936 //==================================================================================================
937 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
938 const std::shared_ptr<ModelAPI_Feature>& theFeature,
939 const std::list<std::string>& theArguments,
940 Events_InfoMessage& theError) const
942 static const std::string aBaseShapeID = "base_shape";
943 static const std::string aSubShapesID = "subshapes_to_keep";
945 if(theFeature->getKind() != "Remove_SubShapes") {
946 theError = "Error: Feature \"%1\" does not supported by this validator.";
947 theError.arg(theFeature->getKind());
951 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
952 if(!aShapeAttrSelection.get()) {
953 theError = "Error: Could not get \"%1\" attribute.";
954 theError.arg(aBaseShapeID);
958 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
959 if(!aSubShapesAttrList.get()) {
960 theError = "Error: Could not get \"%1\" attribute.";
961 theError.arg(aSubShapesID);
966 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
967 if(!aBaseShape.get()) {
968 theError = "Error: Base shape is empty.";
971 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
973 if (aSubShapesAttrList->size() == 0) {
974 theError = "Error: Resulting shape is not valid.";
978 // Copy sub-shapes from list to new shape.
979 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
980 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
981 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
982 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
986 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
987 theError = "Error: Resulting shape is not valid.";
994 //==================================================================================================
995 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
996 const std::list<std::string>& theArguments,
997 Events_InfoMessage& theError) const
999 AttributeSelectionListPtr aBaseObjectsAttrList =
1000 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1001 if(!aBaseObjectsAttrList.get()) {
1002 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1003 theError.arg(FeaturesPlugin_Union::ID());
1007 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1008 bool isSameFound = false;
1009 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1010 ResultPtr aContext = anAttrSelectionInList->context();
1011 if (!aContext.get()) {
1012 theError = "Error: selection is invalid.";
1016 ResultConstructionPtr aConstruction =
1017 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1018 if(aConstruction.get()) {
1019 theError = "Error: Result construction not allowed for selection.";
1023 GeomShapePtr aShape = anAttrSelectionInList->value();
1024 GeomShapePtr aContextShape = aContext->shape();
1025 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1026 theError = "Error: Local selection not allowed.";
1030 ResultBodyPtr aResult =
1031 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1032 if(!aResult.get()) {
1036 if(aResult->numberOfSubs() > 0) {
1037 theError = "Error: Whole compsolids not allowed for selection.";
1045 //==================================================================================================
1046 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1047 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1048 const std::list<std::string>& theArguments,
1049 Events_InfoMessage& theError) const
1051 // Check feature kind.
1052 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1053 theError = "Error: This validator supports only \"%1\" feature.";
1054 theError.arg(FeaturesPlugin_Union::ID());
1058 // Get base objects attribute list.
1059 AttributeSelectionListPtr aBaseObejctsAttrList =
1060 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1061 if(!aBaseObejctsAttrList.get()) {
1062 theError = "Error: Could not get \"%1\" attribute.";
1063 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1068 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1069 ListOfShape aBaseShapesList;
1070 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1071 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1072 GeomShapePtr aShape = anAttrSelectionInList->value();
1073 if (!aShape.get()) {
1076 aBaseShapesList.push_back(aShape);
1077 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1078 GeomAPI_Shape::COMPSOLID;
1081 // Make compound and find connected.
1082 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1083 ListOfShape aCombined, aFree;
1084 GeomAlgoAPI_ShapeTools::combineShapes(
1090 if(aFree.size() > 0 || aCombined.size() > 1) {
1091 theError = "Error: Not all shapes have shared topology.";
1098 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1099 const std::list<std::string>& theArguments,
1100 Events_InfoMessage& theError) const
1102 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1103 theError = "Error: The attribute with the %1 type is not processed";
1104 theError.arg(theAttribute->attributeType());
1108 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1110 ObjectPtr aRefObject = aRefAttribute->value();
1111 if (!aRefObject.get()) {
1112 theError = "Error: Empty feature.";
1116 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1117 if (!aRefFeature.get()) {
1118 theError = "Error: Empty feature.";
1121 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1122 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1124 size_t aConcealedResults = aResults.size();
1125 if (!aConcealedResults && !theArguments.empty()) {
1126 // find if these results are touched by the feature in another attribute
1127 std::list<std::string>::const_iterator anIt = theArguments.begin();
1128 std::string aRecoveredList = *anIt;
1129 if (!aRecoveredList.empty()) {
1130 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1131 theAttribute->owner()->data()->reflist(aRecoveredList);
1132 if (aParameterList.get())
1133 aConcealedResults = aParameterList->size();
1137 if (aConcealedResults == 0)
1138 theError = "Error: No concealed results.";
1140 return theError.empty();
1143 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1144 const std::list<std::string>& theArguments,
1145 Events_InfoMessage& theError) const
1147 static std::list<std::string> aEdgeArg(1, "circle");
1148 static std::list<std::string> aFaceArg(1, "cylinder");
1150 Events_InfoMessage aError;
1151 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1153 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1155 theError = "The shape neither circle nor cylinder";
1160 //=================================================================================================
1161 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1162 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1163 const std::list<std::string>& theArguments,
1164 Events_InfoMessage& theError) const
1166 if (theArguments.size() != 2)
1168 theError = "Wrong number of arguments (expected 2).";
1172 int anObjectsNb = 0, aToolsNb = 0;
1173 //int anOperationType = 0;
1175 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1177 bool isAllInSameCompSolid = true;
1178 ResultBodyPtr aCompSolid;
1180 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1183 anObjectsNb = anAttrSelList->size();
1184 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1186 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1187 ResultPtr aContext = anAttr->context();
1188 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1189 if (aResCompSolidPtr.get())
1191 if (aCompSolid.get())
1193 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1197 aCompSolid = aResCompSolidPtr;
1202 isAllInSameCompSolid = false;
1210 anAttrSelList = theFeature->selectionList(*anIt);
1213 aToolsNb = anAttrSelList->size();
1214 if (isAllInSameCompSolid)
1216 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1218 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1219 ResultPtr aContext = anAttr->context();
1220 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1221 if (aResCompSolidPtr.get())
1223 if (aCompSolid.get())
1225 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1229 aCompSolid = aResCompSolidPtr;
1234 isAllInSameCompSolid = false;
1242 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1243 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1244 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1246 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1249 if (anObjectsNb + aToolsNb < 2)
1251 theError = "Not enough arguments for Fuse operation.";
1254 else if (isAllInSameCompSolid)
1256 theError = "Operations only between sub-shapes of the same shape not allowed.";
1262 if (anObjectsNb < 1)
1264 theError = "Objects not selected.";
1269 theError = "Tools not selected.";
1272 if (isAllInSameCompSolid)
1274 theError = "Operations only between sub-shapes of the same shape not allowed.";
1282 //=================================================================================================
1283 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1284 std::string theAttribute)
1286 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1294 //==================================================================================================
1295 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1296 const AttributePtr& theAttribute,
1297 const std::list<std::string>& theArguments,
1298 Events_InfoMessage& theError) const
1300 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1301 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1303 AttributeSelectionListPtr anAttrSelectionList =
1304 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1305 if (!aFeature.get() || !anAttrSelectionList.get()) {
1307 "Error: Validator used in wrong feature or attribute";
1311 AttributeSelectionListPtr anOtherAttrSelectionList;
1312 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1313 anOtherAttrSelectionList =
1314 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1316 anOtherAttrSelectionList =
1317 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1320 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1321 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1322 GeomPlanePtr aFacesPln;
1324 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1325 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1327 if (anAttrSelection->contextFeature().get()) {
1328 theError = "Error: Features not allowed for selection.";
1332 ResultPtr aContext = anAttrSelection->context();
1333 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1334 GeomShapePtr aContextShape = aContext->shape();
1335 if (!aShape.get()) {
1336 aShape = aContextShape;
1339 if (aShape->isSolid() || aShape->isCompSolid()) {
1340 aSelectedShapesType = GeomAPI_Shape::SOLID;
1341 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1342 if (aResCompSolidPtr.get()) {
1343 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1344 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1347 aSelectedShapesType = GeomAPI_Shape::FACE;
1348 GeomAPI_Face aFace(aShape);
1349 aFacesPln = aFace.getPlane();
1354 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1355 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1356 if (!anAttrSelection.get()) {
1357 theError = "Error: Empty attribute selection.";
1361 if (anAttrSelection->contextFeature().get()) {
1362 theError = "Error: Features not allowed for selection.";
1366 ResultPtr aContext = anAttrSelection->context();
1367 if(!aContext.get()) {
1368 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1369 if (!aContFeat.get() || !aContFeat->results().size() ||
1370 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1371 theError = "Error: Empty selection context.";
1375 ResultConstructionPtr aResultConstruction =
1376 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1377 if (aResultConstruction.get()) {
1378 theError = "Error: Result construction not allowed for selection.";
1381 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1382 GeomShapePtr aContextShape = aContext->shape();
1383 if (!aShape.get()) {
1384 aShape = aContextShape;
1386 if (!aShape.get()) {
1387 theError = "Error: Empty shape.";
1390 if (!aShape->isEqual(aContextShape)) {
1391 theError = "Error: Local selection not allowed.";
1395 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1396 // Other list is empty.
1397 if (aShape->isSolid() || aShape->isCompSolid()) {
1398 aSelectedShapesType = GeomAPI_Shape::SOLID;
1400 aSelectedShapesType = GeomAPI_Shape::FACE;
1401 GeomAPI_Face aFace(aShape);
1402 aFacesPln = aFace.getPlane();
1404 if (!aFacesPln.get()) {
1405 theError = "Error: Only planar faces allowed.";
1411 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1412 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1413 theError = "Error: Selected shapes should have the same type.";
1417 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1418 if (aResCompSolidPtr.get()) {
1419 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1420 if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) {
1421 theError = "Error: Solids from compsolid in other list not allowed.";
1426 GeomAPI_Face aFace(aShape);
1427 GeomPlanePtr aPln = aFace.getPlane();
1430 theError = "Error: Only planar faces allowed.";
1434 if (!aFacesPln->isCoincident(aPln)) {
1435 theError = "Error: Only coincident faces allowed.";
1444 //==================================================================================================
1445 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1446 const std::list<std::string>& theArguments,
1447 Events_InfoMessage& theError) const
1449 if (!theAttribute.get()) {
1450 theError = "Error: empty selection.";
1453 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1454 AttributeSelectionListPtr anAttrSelectionList =
1455 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1456 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1457 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1458 if (!anAttrSelection.get()) {
1459 theError = "Error: empty attribute selection.";
1462 ResultPtr aContext = anAttrSelection->context();
1463 if(!aContext.get()) {
1464 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1465 if (!aContFeat.get() || !aContFeat->results().size() ||
1466 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1467 theError = "Error: Empty selection context.";
1471 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1472 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1473 if (!aFeature.get()) {
1474 theError = "Error: empty feature.";
1477 std::string aFeatureKind = aFeature->getKind();
1478 if (aFeatureKind == "Sketch" ||
1479 aFeatureKind == "Plane" ||
1480 aFeatureKind == "Axis") {
1481 theError = "Error: %1 shape is not allowed for selection.";
1482 theError.arg(aFeatureKind);
1485 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1486 if (!aShape.get()) {
1487 GeomShapePtr aContextShape = aContext->shape();
1488 aShape = aContextShape;
1490 if (!aShape.get()) {
1491 theError = "Error: empty shape.";
1494 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1495 theError = "Error: Local selection not allowed.";
1499 int aShapeType = aShape->shapeType();
1500 // Allow to select edges, faces and solids.
1501 if (aShapeType != GeomAPI_Shape::EDGE &&
1502 aShapeType != GeomAPI_Shape::FACE &&
1503 aShapeType != GeomAPI_Shape::SOLID &&
1504 aShapeType != GeomAPI_Shape::COMPSOLID &&
1505 aShapeType != GeomAPI_Shape::COMPOUND) {
1506 theError = "Error: selected shape has the wrong type.";
1514 //==================================================================================================
1515 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1516 const AttributePtr& theAttribute,
1517 const std::list<std::string>& theArguments,
1518 Events_InfoMessage& theError) const
1520 AttributeSelectionListPtr anAttrSelectionList =
1521 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1522 if (!anAttrSelectionList.get()) {
1524 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1528 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1529 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1530 if (!anAttrSelection.get()) {
1531 theError = "Error: Empty attribute selection.";
1534 ResultPtr aContext = anAttrSelection->context();
1535 if(!aContext.get()) {
1536 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1537 if (!aContFeat.get() || !aContFeat->results().size() ||
1538 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1539 theError = "Error: Empty selection context.";
1543 ResultConstructionPtr aResultConstruction =
1544 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1545 if (aResultConstruction.get()) {
1546 theError = "Error: Result construction not allowed for selection.";
1549 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1550 if (!aShape.get()) {
1551 GeomShapePtr aContextShape = aContext->shape();
1552 aShape = aContextShape;
1554 if (!aShape.get()) {
1555 theError = "Error: Empty shape.";
1558 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1559 theError = "Error: Local selection not allowed.";
1567 //=================================================================================================
1568 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1569 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1570 const std::list<std::string>& theArguments,
1571 Events_InfoMessage& theError) const
1573 if (theArguments.size() != 2) {
1574 theError = "Wrong number of arguments (expected 2).";
1578 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1579 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1581 int anObjectsNb = 0, aToolsNb = 0;
1583 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1585 bool isAllInSameCompSolid = true;
1586 ResultBodyPtr aCompSolid;
1588 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1589 if (anAttrSelList) {
1590 anObjectsNb = anAttrSelList->size();
1591 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1592 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1593 ResultPtr aContext = anAttr->context();
1594 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1595 if (aResCompSolidPtr.get()) {
1596 if (aCompSolid.get()) {
1597 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1599 aCompSolid = aResCompSolidPtr;
1602 isAllInSameCompSolid = false;
1609 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1610 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1611 anAttrSelList = theFeature->selectionList(*anIt);
1612 if (anAttrSelList) {
1613 aToolsNb = anAttrSelList->size();
1614 if (isAllInSameCompSolid) {
1615 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1616 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1617 ResultPtr aContext = anAttr->context();
1618 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1619 if (aResCompSolidPtr.get()) {
1620 if (aCompSolid.get()) {
1621 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1623 aCompSolid = aResCompSolidPtr;
1626 isAllInSameCompSolid = false;
1636 if (anObjectsNb + aToolsNb < 2) {
1637 theError = "Not enough arguments for Fuse operation.";
1639 } else if (isAllInSameCompSolid) {
1640 theError = "Operations only between sub-shapes of the same shape not allowed.";
1647 //=================================================================================================
1648 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1649 std::string theFeature,
1650 std::string theAttribute)
1652 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1659 //==================================================================================================
1660 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1661 const AttributePtr& theAttribute,
1662 const std::list<std::string>& theArguments,
1663 Events_InfoMessage& theError) const
1665 AttributeSelectionListPtr anAttrSelectionList =
1666 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1667 if (!anAttrSelectionList.get()) {
1669 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1673 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1674 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1675 if (!anAttrSelection.get()) {
1676 theError = "Error: Empty attribute selection.";
1679 ResultPtr aContext = anAttrSelection->context();
1680 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1681 theError = "Error: Empty selection context.";
1684 ResultConstructionPtr aResultConstruction =
1685 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1686 if (aResultConstruction.get()) {
1687 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1688 theError = "Error: Result construction not allowed for selection.";
1692 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1693 GeomShapePtr aContextShape;
1694 if (!aShape.get() && aContext.get()) {
1695 aContextShape = aContext->shape();
1696 aShape = aContextShape;
1698 if (!aShape.get()) {
1699 theError = "Error: Empty shape.";
1702 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1703 theError = "Error: Local selection not allowed.";
1707 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1708 theError = "Error: Result construction should be plane.";
1716 //=================================================================================================
1717 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1718 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1719 const std::list<std::string>& theArguments,
1720 Events_InfoMessage& theError) const
1722 if (theArguments.size() != 2) {
1723 theError = "Wrong number of arguments (expected 2).";
1727 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1728 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1730 int anObjectsNb = 0, aToolsNb = 0;
1732 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1734 bool isAllInSameCompSolid = true;
1735 ResultBodyPtr aCompSolid;
1737 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1738 if (anAttrSelList) {
1739 anObjectsNb = anAttrSelList->size();
1742 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1743 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1745 if (!isSimpleMode) {
1746 anAttrSelList = theFeature->selectionList(*anIt);
1747 if (anAttrSelList) {
1748 aToolsNb = anAttrSelList->size();
1752 if ((isSimpleMode && anObjectsNb < 2)
1753 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1754 theError = "Not enough arguments for Fuse operation.";
1760 //=================================================================================================
1761 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1762 std::string theFeature,
1763 std::string theAttribute)