1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Validators.h"
23 #include "FeaturesPlugin_Boolean.h"
24 #include "FeaturesPlugin_BooleanFuse.h"
25 #include "FeaturesPlugin_BooleanCommon.h"
26 #include "FeaturesPlugin_BooleanSmash.h"
27 #include "FeaturesPlugin_Union.h"
29 #include <Events_InfoMessage.h>
31 #include <ModelAPI_Attribute.h>
32 #include <ModelAPI_AttributeInteger.h>
33 #include <ModelAPI_AttributeSelectionList.h>
34 #include <ModelAPI_AttributeString.h>
35 #include <ModelAPI_AttributeReference.h>
36 #include <ModelAPI_AttributeRefList.h>
37 #include <ModelAPI_Feature.h>
38 #include <ModelAPI_ResultBody.h>
39 #include <ModelAPI_ResultConstruction.h>
40 #include <ModelAPI_Tools.h>
42 #include <GeomValidators_BodyShapes.h>
43 #include <GeomValidators_Face.h>
44 #include <GeomValidators_FeatureKind.h>
45 #include <GeomValidators_ShapeType.h>
47 #include <GeomAPI_DataMapOfShapeShape.h>
48 #include <GeomAPI_Lin.h>
49 #include <GeomAPI_PlanarEdges.h>
50 #include <GeomAPI_Pln.h>
51 #include <GeomAPI_ShapeExplorer.h>
52 #include <GeomAPI_ShapeIterator.h>
54 #include <GeomAlgoAPI_CompoundBuilder.h>
55 #include <GeomAlgoAPI_ShapeBuilder.h>
56 #include <GeomAlgoAPI_ShapeTools.h>
57 #include <GeomAlgoAPI_WireBuilder.h>
59 #define _USE_MATH_DEFINES
62 //==================================================================================================
63 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
64 const std::list<std::string>& theArguments,
65 Events_InfoMessage& theError) const
67 AttributeSelectionPtr aPathAttrSelection =
68 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
69 if(!aPathAttrSelection.get()) {
70 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
74 GeomShapePtr aPathShape = aPathAttrSelection->value();
75 ResultPtr aContext = aPathAttrSelection->context();
77 theError = "Error: Empty context.";
80 GeomShapePtr aContextShape = aContext->shape();
81 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
82 !aPathShape->isEqual(aContextShape)) {
83 theError = "Error: Local selection of wires not allowed.";
90 //==================================================================================================
91 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
92 const std::shared_ptr<ModelAPI_Feature>& theFeature,
93 const std::list<std::string>& theArguments,
94 Events_InfoMessage& theError) const
96 static const std::string aCreationMethodID = "creation_method";
97 static const std::string aBaseObjectsID = "base_objects";
98 static const std::string aLocationsID = "locations_objects";
100 if(theFeature->getKind() != "Pipe") {
101 theError = "Error: Feature \"%1\" does not supported by this validator.";
102 theError.arg(theFeature->getKind());
106 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
107 if(!aCreationMethodAttr.get()) {
108 theError = "Error: Could not get \"%1\" attribute.";
109 theError.arg(aCreationMethodID);
113 if(aCreationMethodAttr->value() != "locations") {
117 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
118 if(!aBaseObjectsSelectionList.get()) {
119 theError = "Error: Could not get \"%1\" attribute.";
120 theError.arg(aBaseObjectsID);
124 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
125 if(!aLocationsSelectionList.get()) {
126 theError = "Error: Could not get \"%1\" attribute.";
127 theError.arg(aBaseObjectsID);
131 if(aLocationsSelectionList->size() > 0 &&
132 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
133 theError = "Error: Number of locations should be the same as base objects.";
140 //==================================================================================================
141 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
142 const std::list<std::string>& theArguments,
143 Events_InfoMessage& theError) const
145 if(theArguments.empty()) {
146 theError = "Error: Validator parameters is empty.";
150 // Checking attribute.
151 if(!isValidAttribute(theAttribute, theArguments, theError)) {
152 if(theError.empty()) {
153 theError = "Error: Attribute contains unacceptable shape.";
158 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
159 std::string anAttributeType = theAttribute->attributeType();
160 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
161 AttributeSelectionListPtr aListAttr =
162 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
163 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
164 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
165 ResultPtr aContext = aSelectionAttr->context();
166 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
167 theError = "Error: Empty context.";
171 ResultConstructionPtr aResultConstruction =
172 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
173 if(!aResultConstruction.get()) {
174 // It is not a result construction.
175 // If shape is compound check that it contains only faces and edges.
176 GeomShapePtr aShape = aSelectionAttr->value();
178 if (aContext.get()) {
179 aShape = aContext->shape();
181 theError = "Error: Empty context.";
186 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
187 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
188 GeomShapePtr aSubShape = anIt.current();
189 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
190 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
191 theError = "Error: Compound should contain only faces and edges.";
200 GeomShapePtr aShape = aSelectionAttr->value();
201 GeomShapePtr aContextShape = aResultConstruction->shape();
203 // Whole sketch selected.
206 // Object from sketch selected.
207 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
208 GeomShapePtr aWire = anExp.current();
209 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
210 theError = "Error: Wire with wrong orientation selected.";
214 if(aSelectedWiresFromObjects.isBound(aWire)) {
216 "Error: Objects with such wire already selected. Don't allow to select this object.";
220 aSelectedWiresFromObjects.bind(aWire, aWire);
229 //==================================================================================================
230 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
231 const std::shared_ptr<ModelAPI_Feature>& theFeature,
232 const std::list<std::string>& theArguments,
233 Events_InfoMessage& theError) const
235 const std::string aBaseObjectsID = theArguments.front();
237 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
238 if(!aListAttr.get()) {
239 theError = "Error: Could not get \"%1\" attribute.";
240 theError.arg(aBaseObjectsID);
244 std::set<ResultConstructionPtr> aSelectedSketches;
245 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
247 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
248 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
249 ResultPtr aContext = aSelectionAttr->context();
250 if(!aContext.get()) {
251 FeaturePtr aFeature = aSelectionAttr->contextFeature();
252 if (!aFeature.get() || aFeature->results().empty()) {
253 theError = "Error: Empty context.";
256 aContext = aFeature->firstResult();
260 ResultConstructionPtr aResultConstruction =
261 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
262 if(!aResultConstruction.get()) {
263 // It is not a result construction.
267 GeomShapePtr aShape = aSelectionAttr->value();
268 GeomShapePtr aContextShape = aResultConstruction->shape();
270 // Whole sketch selected.
271 aSelectedSketches.insert(aResultConstruction);
273 // Object from sketch selected.
274 aSelectedSketchesFromObjects.insert(aResultConstruction);
279 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
280 anIt != aSelectedSketches.cend();
282 ResultConstructionPtr aResultConstruction = *anIt;
283 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
284 aSelectedSketchesFromObjects.cend()) {
285 theError = "Sketch and objects from it can not be selected at the same time.";
293 //==================================================================================================
294 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
295 const std::list<std::string>& theArguments,
296 Events_InfoMessage& theError) const
298 if(!theAttribute.get()) {
299 theError = "Error: Empty attribute.";
303 std::string anAttributeType = theAttribute->attributeType();
304 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
305 AttributeSelectionListPtr aListAttr =
306 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
307 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
308 // If at least one attribute is invalid, the result is false.
309 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
313 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
315 AttributeSelectionPtr anAttr =
316 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
317 ResultPtr aContext = anAttr->context();
318 if(!aContext.get() && !anAttr->contextFeature().get()) {
319 theError = "Error: Attribute have empty context.";
323 GeomShapePtr aShape = anAttr->value();
324 GeomShapePtr aContextShape;
325 if(!aShape.get() && aContext.get()) {
326 aContextShape = aContext->shape();
327 aShape = aContextShape;
330 theError = "Error: Empty shape selected";
334 ResultConstructionPtr aConstruction;
335 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
336 aContext = anAttr->contextFeature()->firstResult();
339 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
340 if(aConstruction.get()) {
341 // Construciotn selected. Check that is is not infinite.
342 if(aConstruction->isInfinite()) {
343 theError = "Error: Infinite constructions is not allowed as base.";
347 GeomShapePtr aContextShape = aContext->shape();
348 if(aShape->isEqual(aContextShape)) {
349 // Whole construction selected. Check that it have faces.
350 if(aConstruction->facesNum() > 0) {
354 // Shape on construction selected. Check that it is a face or wire.
355 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
356 aShape->shapeType() == GeomAPI_Shape::FACE) {
364 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
365 // Local selection on body does not allowed.
367 "Error: Selected shape is in the local selection. Only global selection is allowed.";
371 // Check that object is a shape with allowed type.
372 GeomValidators_ShapeType aShapeTypeValidator;
373 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
374 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
375 "wires on sketch, whole sketch(if it has at least one face), "
376 "and whole objects with shape types: %1";
377 std::string anArgumentString;
378 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
379 if (!anArgumentString.empty())
380 anArgumentString += ", ";
381 anArgumentString += *anIt;
383 theError.arg(anArgumentString);
388 theError = "Error: Attribute \"%1\" does not supported by this validator.";
389 theError.arg(anAttributeType);
396 //==================================================================================================
397 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
398 const std::list<std::string>& theArguments,
399 Events_InfoMessage& theError) const
401 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
402 theError = "Error: The attribute with the %1 type is not processed";
403 theError.arg(theAttribute->attributeType());
406 if (theArguments.size() != 2) {
407 theError = "Error: Wrong parameters in XML definition for %1 type";
408 theError.arg(theAttribute->attributeType());
411 // first argument is for the base attribute, second - for skipping feature kind
412 std::list<std::string>::const_iterator anIt = theArguments.begin();
413 std::string aBaseAttributeId = *anIt;
414 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
415 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
416 if (!aBaseAttribute.get()) {
417 theError = "Wrong parameters in XML definition for %1 type";
418 theError.arg(theAttribute->attributeType());
421 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
422 // this validator is not necessary anymore
426 std::string aFeatureAttributeKind = *anIt;
427 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
428 // check whether the selection is on the sketch
429 std::list<std::string> anArguments;
430 anArguments.push_back(aFeatureAttributeKind);
432 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
433 bool aPlanarFace = false;
434 // check if selection has Face selected
435 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
437 anArguments.push_back("face");
438 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
440 bool aValid = !aFeatureKind && aPlanarFace;
444 //==================================================================================================
445 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
446 const std::shared_ptr<ModelAPI_Feature>& theFeature,
447 const std::list<std::string>& theArguments,
448 Events_InfoMessage& theError) const
450 if(theArguments.size() != 2) {
451 theError = "Error: Validator should be used with 2 parameters for extrusion.";
455 std::list<std::string>::const_iterator
456 anArgsIt = theArguments.begin(), aLast = theArguments.end();
458 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
461 GeomShapePtr aDirShape;
462 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
464 aDirShape = aSelAttr->value();
465 if(!aDirShape.get()) {
466 ResultPtr aContext = aSelAttr->context();
467 if(!aContext.get()) {
468 FeaturePtr aFeature = aSelAttr->contextFeature();
469 if (aFeature.get() && !aFeature->results().empty()) {
470 aContext = aFeature->firstResult();
475 aDirShape = aContext->shape();
478 if (aDirShape.get() && aDirShape->isCompound()) {
479 GeomAPI_ShapeIterator anIt(aDirShape);
480 aDirShape = anIt.current();
485 if(!aDirShape.get()) {
486 // Check that dir can be empty.
487 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
488 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
489 "can not be used with default value. Select direction for extrusion.";
490 theError.arg(*anArgsIt);
497 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
499 // If faces selected check that direction not parallel with them.
500 AttributeSelectionListPtr aListAttr =
501 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
502 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
503 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
504 GeomShapePtr aShapeInList = anAttr->value();
505 if(!aShapeInList.get()) {
506 aShapeInList = anAttr->context()->shape();
508 bool isParallel = true;
509 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
510 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
511 for(GeomAPI_ShapeExplorer
512 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
513 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
514 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
519 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
520 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
521 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
522 if(aPlanarEdges.get()) {
523 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
524 if(aDirEdge->isLine()) {
525 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
526 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
538 "Error: Direction is parallel to one of the selected face or face on selected shell.";
546 //==================================================================================================
547 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
548 Events_InfoMessage& theError) const
550 if(!theAttribute.get()) {
554 std::string anAttributeType = theAttribute->attributeType();
555 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
556 AttributeSelectionListPtr aListAttr =
557 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
558 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
559 // If at least one attribute is invalid, the result is false.
560 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
564 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
566 AttributeSelectionPtr anAttr =
567 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
568 ResultPtr aContext = anAttr->context();
569 if(!aContext.get() && !anAttr->contextFeature().get()) {
573 GeomShapePtr aShape = anAttr->value();
574 if(!aShape.get() && aContext.get()) {
575 GeomShapePtr aContextShape = aContext->shape();
576 aShape = aContextShape;
582 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
583 aShape->shapeType() == GeomAPI_Shape::EDGE ||
584 !aShape->isPlanar()) {
594 //==================================================================================================
595 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
596 const std::list<std::string>& theArguments,
597 Events_InfoMessage& theError) const
599 AttributeSelectionListPtr anAttrSelectionList =
600 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
601 if(!anAttrSelectionList.get()) {
603 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
606 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
607 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
608 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
610 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
611 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
612 if(!anAttrSelection.get()) {
613 theError = "Error: Empty attribute selection.";
616 ResultPtr aContext = anAttrSelection->context();
617 if(!aContext.get()) {
618 FeaturePtr aContFeat = anAttrSelection->contextFeature();
619 if (!aContFeat.get() || !aContFeat->results().size()) {
620 theError = "Error: Empty selection context.";
624 ResultConstructionPtr aResultConstruction =
625 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
626 if(aResultConstruction.get()) {
627 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
628 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
629 theError = "Error: Result construction not allowed for selection.";
633 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
634 if(!aShape.get() && aContext.get()) {
635 GeomShapePtr aContextShape = aContext->shape();
636 aShape = aContextShape;
639 theError = "Error: Empty shape.";
642 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
643 theError = "Error: Local selection not allowed.";
647 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
648 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
649 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
650 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
651 anAllowedTypes.insert(GeomAPI_Shape::FACE);
652 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
653 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
654 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
655 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
656 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
658 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
659 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
660 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
661 anAllowedTypes.insert(GeomAPI_Shape::FACE);
662 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
663 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
664 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
665 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
667 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
668 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
669 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
672 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
673 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
674 theError = "Error: Selected shape has the wrong type.";
683 //==================================================================================================
684 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
685 const std::list<std::string>& theArguments,
686 Events_InfoMessage& theError) const
688 AttributeSelectionListPtr anAttrSelectionList =
689 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
690 if(!anAttrSelectionList.get()) {
692 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
696 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
697 // Check all selected entities are sub-shapes of single solid
698 GeomShapePtr aBaseSolid;
699 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
700 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
701 if(!anAttrSelection.get()) {
702 theError = "Error: Empty attribute selection.";
705 ResultPtr aContext = anAttrSelection->context();
706 if(!aContext.get()) {
707 FeaturePtr aContFeat = anAttrSelection->contextFeature();
708 if (!aContFeat.get() || !aContFeat->results().size() ||
709 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
710 theError = "Error: Empty selection context.";
713 if (aContFeat->results().size() == 1)
714 aContext = aContFeat->firstResult();
716 theError = "Error: Too many shapes selected.";
721 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
722 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
725 theError = "Error: wrong feature is selected.";
729 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
730 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
731 theError = "Error: Not all selected shapes are sub-shapes of solids.";
736 aBaseSolid = anOwner;
737 else if (!aBaseSolid->isEqual(anOwner)) {
738 theError = "Error: Sub-shapes of different solids have been selected.";
746 //==================================================================================================
747 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
748 const std::list<std::string>& theArguments,
749 Events_InfoMessage& theError) const
751 AttributeSelectionListPtr anAttrSelectionList =
752 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
753 if(!anAttrSelectionList.get()) {
754 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
758 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
759 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
761 //GeomValidators_BodyShapes aBodyValidator;
762 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
766 GeomValidators_FeatureKind aFeatureKindValidator;
767 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
771 ResultPtr aContext = aSelectAttr->context();
772 ResultConstructionPtr aResultConstruction =
773 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
774 if(aResultConstruction.get()) {
775 theError = "Error: Only body shapes and construction planes are allowed for selection.";
779 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
780 if(aResultBody.get()) {
783 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
784 if(aResultFeature.get()) {
786 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
787 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
788 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
789 if (aBody.get() && !aBody->isDisabled())
796 theError = "Error: Only body shapes and construction planes are allowed for selection.";
804 //==================================================================================================
805 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
806 const std::list<std::string>& theArguments,
807 Events_InfoMessage& theError) const
809 AttributeSelectionListPtr aSubShapesAttrList =
810 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
811 if(!aSubShapesAttrList.get()) {
813 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
817 static const std::string aBaseShapeID = "base_shape";
818 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
819 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
821 if(!aShapeAttrSelection.get()) {
822 theError = "Error: Could not get \"%1\" attribute.";
823 theError.arg(aBaseShapeID);
827 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
828 ResultPtr aContext = aShapeAttrSelection->context();
829 if(!aContext.get()) {
830 theError = "Error: Empty context.";
833 if(!aBaseShape.get()) {
834 aBaseShape = aContext->shape();
836 if(!aBaseShape.get()) {
837 theError = "Error: Empty base shape.";
841 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
842 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
843 bool isSameFound = false;
844 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
845 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
846 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt) {
847 if ((*anIt)->isEqual(aShapeToAdd)) {
853 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
861 //==================================================================================================
862 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
863 const std::shared_ptr<ModelAPI_Feature>& theFeature,
864 const std::list<std::string>& theArguments,
865 Events_InfoMessage& theError) const
867 static const std::string aBaseShapeID = "base_shape";
868 static const std::string aSubShapesID = "subshapes_to_keep";
870 if(theFeature->getKind() != "Remove_SubShapes") {
871 theError = "Error: Feature \"%1\" does not supported by this validator.";
872 theError.arg(theFeature->getKind());
876 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
877 if(!aShapeAttrSelection.get()) {
878 theError = "Error: Could not get \"%1\" attribute.";
879 theError.arg(aBaseShapeID);
883 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
884 if(!aSubShapesAttrList.get()) {
885 theError = "Error: Could not get \"%1\" attribute.";
886 theError.arg(aSubShapesID);
891 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
892 if(!aBaseShape.get()) {
893 theError = "Error: Base shape is empty.";
896 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
898 if (aSubShapesAttrList->size() == 0) {
899 theError = "Error: Resulting shape is not valid.";
903 // Copy sub-shapes from list to new shape.
904 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
905 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
906 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
907 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
911 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
912 theError = "Error: Resulting shape is not valid.";
919 //==================================================================================================
920 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
921 const std::list<std::string>& theArguments,
922 Events_InfoMessage& theError) const
924 AttributeSelectionListPtr aBaseObjectsAttrList =
925 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
926 if(!aBaseObjectsAttrList.get()) {
927 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
928 theError.arg(FeaturesPlugin_Union::ID());
932 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
933 bool isSameFound = false;
934 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
935 ResultPtr aContext = anAttrSelectionInList->context();
936 if (!aContext.get()) {
937 theError = "Error: selection is invalid.";
941 ResultConstructionPtr aConstruction =
942 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
943 if(aConstruction.get()) {
944 theError = "Error: Result construction not allowed for selection.";
948 GeomShapePtr aShape = anAttrSelectionInList->value();
949 GeomShapePtr aContextShape = aContext->shape();
950 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
951 theError = "Error: Local selection not allowed.";
955 ResultBodyPtr aResult =
956 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
961 if(aResult->numberOfSubs() > 0) {
962 theError = "Error: Whole compsolids not allowed for selection.";
970 //==================================================================================================
971 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
972 const std::shared_ptr<ModelAPI_Feature>& theFeature,
973 const std::list<std::string>& theArguments,
974 Events_InfoMessage& theError) const
976 // Check feature kind.
977 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
978 theError = "Error: This validator supports only \"%1\" feature.";
979 theError.arg(FeaturesPlugin_Union::ID());
983 // Get base objects attribute list.
984 AttributeSelectionListPtr aBaseObejctsAttrList =
985 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
986 if(!aBaseObejctsAttrList.get()) {
987 theError = "Error: Could not get \"%1\" attribute.";
988 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
993 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
994 ListOfShape aBaseShapesList;
995 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
996 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
997 GeomShapePtr aShape = anAttrSelectionInList->value();
1001 aBaseShapesList.push_back(aShape);
1002 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1003 GeomAPI_Shape::COMPSOLID;
1006 // Make compound and find connected.
1007 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1008 ListOfShape aCombined, aFree;
1009 GeomAlgoAPI_ShapeTools::combineShapes(
1015 if(aFree.size() > 0 || aCombined.size() > 1) {
1016 theError = "Error: Not all shapes have shared topology.";
1023 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1024 const std::list<std::string>& theArguments,
1025 Events_InfoMessage& theError) const
1027 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1028 theError = "Error: The attribute with the %1 type is not processed";
1029 theError.arg(theAttribute->attributeType());
1033 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1035 ObjectPtr aRefObject = aRefAttribute->value();
1036 if (!aRefObject.get()) {
1037 theError = "Error: Empty feature.";
1041 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1042 if (!aRefFeature.get()) {
1043 theError = "Error: Empty feature.";
1046 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1047 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1049 size_t aConcealedResults = aResults.size();
1050 if (!aConcealedResults && !theArguments.empty()) {
1051 // find if these results are touched by the feature in another attribute
1052 std::list<std::string>::const_iterator anIt = theArguments.begin();
1053 std::string aRecoveredList = *anIt;
1054 if (!aRecoveredList.empty()) {
1055 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1056 theAttribute->owner()->data()->reflist(aRecoveredList);
1057 if (aParameterList.get())
1058 aConcealedResults = aParameterList->size();
1062 if (aConcealedResults == 0)
1063 theError = "Error: No concealed results.";
1065 return theError.empty();
1068 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1069 const std::list<std::string>& theArguments,
1070 Events_InfoMessage& theError) const
1072 static std::list<std::string> aEdgeArg(1, "circle");
1073 static std::list<std::string> aFaceArg(1, "cylinder");
1075 Events_InfoMessage aError;
1076 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1078 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1080 theError = "The shape neither circle nor cylinder";
1085 //=================================================================================================
1086 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1087 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1088 const std::list<std::string>& theArguments,
1089 Events_InfoMessage& theError) const
1091 if (theArguments.size() != 2)
1093 theError = "Wrong number of arguments (expected 2).";
1097 int anObjectsNb = 0, aToolsNb = 0;
1098 //int anOperationType = 0;
1100 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1102 bool isAllInSameCompSolid = true;
1103 ResultBodyPtr aCompSolid;
1105 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1108 anObjectsNb = anAttrSelList->size();
1109 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1111 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1112 ResultPtr aContext = anAttr->context();
1113 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1114 if (aResCompSolidPtr.get())
1116 if (aCompSolid.get())
1118 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1122 aCompSolid = aResCompSolidPtr;
1127 isAllInSameCompSolid = false;
1135 anAttrSelList = theFeature->selectionList(*anIt);
1138 aToolsNb = anAttrSelList->size();
1139 if (isAllInSameCompSolid)
1141 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1143 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1144 ResultPtr aContext = anAttr->context();
1145 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1146 if (aResCompSolidPtr.get())
1148 if (aCompSolid.get())
1150 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1154 aCompSolid = aResCompSolidPtr;
1159 isAllInSameCompSolid = false;
1167 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1168 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1169 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1171 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1174 if (anObjectsNb + aToolsNb < 2)
1176 theError = "Not enough arguments for Fuse operation.";
1179 else if (isAllInSameCompSolid)
1181 theError = "Operations only between sub-shapes of the same shape not allowed.";
1187 if (anObjectsNb < 1)
1189 theError = "Objects not selected.";
1194 theError = "Tools not selected.";
1197 if (isAllInSameCompSolid)
1199 theError = "Operations only between sub-shapes of the same shape not allowed.";
1207 //=================================================================================================
1208 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1209 std::string theAttribute)
1211 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1219 //==================================================================================================
1220 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1221 const AttributePtr& theAttribute,
1222 const std::list<std::string>& theArguments,
1223 Events_InfoMessage& theError) const
1225 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1226 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1228 AttributeSelectionListPtr anAttrSelectionList =
1229 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1230 if (!aFeature.get() || !anAttrSelectionList.get()) {
1232 "Error: Validator used in wrong feature or attribute";
1236 AttributeSelectionListPtr anOtherAttrSelectionList;
1237 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1238 anOtherAttrSelectionList =
1239 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1241 anOtherAttrSelectionList =
1242 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1245 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1246 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1247 GeomPlanePtr aFacesPln;
1249 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1250 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1252 if (anAttrSelection->contextFeature().get()) {
1253 theError = "Error: Features not allowed for selection.";
1257 ResultPtr aContext = anAttrSelection->context();
1258 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1259 GeomShapePtr aContextShape = aContext->shape();
1260 if (!aShape.get()) {
1261 aShape = aContextShape;
1264 if (aShape->isSolid() || aShape->isCompSolid()) {
1265 aSelectedShapesType = GeomAPI_Shape::SOLID;
1266 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1267 if (aResCompSolidPtr.get()) {
1268 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1269 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1272 aSelectedShapesType = GeomAPI_Shape::FACE;
1273 GeomAPI_Face aFace(aShape);
1274 aFacesPln = aFace.getPlane();
1279 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1280 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1281 if (!anAttrSelection.get()) {
1282 theError = "Error: Empty attribute selection.";
1286 if (anAttrSelection->contextFeature().get()) {
1287 theError = "Error: Features not allowed for selection.";
1291 ResultPtr aContext = anAttrSelection->context();
1292 if(!aContext.get()) {
1293 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1294 if (!aContFeat.get() || !aContFeat->results().size() ||
1295 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1296 theError = "Error: Empty selection context.";
1300 ResultConstructionPtr aResultConstruction =
1301 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1302 if (aResultConstruction.get()) {
1303 theError = "Error: Result construction not allowed for selection.";
1306 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1307 GeomShapePtr aContextShape = aContext->shape();
1308 if (!aShape.get()) {
1309 aShape = aContextShape;
1311 if (!aShape.get()) {
1312 theError = "Error: Empty shape.";
1315 if (!aShape->isEqual(aContextShape)) {
1316 theError = "Error: Local selection not allowed.";
1320 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1321 // Other list is empty.
1322 if (aShape->isSolid() || aShape->isCompSolid()) {
1323 aSelectedShapesType = GeomAPI_Shape::SOLID;
1325 aSelectedShapesType = GeomAPI_Shape::FACE;
1326 GeomAPI_Face aFace(aShape);
1327 aFacesPln = aFace.getPlane();
1329 if (!aFacesPln.get()) {
1330 theError = "Error: Only planar faces allowed.";
1336 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1337 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1338 theError = "Error: Selected shapes should have the same type.";
1342 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1343 if (aResCompSolidPtr.get()) {
1344 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1345 if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) {
1346 theError = "Error: Solids from compsolid in other list not allowed.";
1351 GeomAPI_Face aFace(aShape);
1352 GeomPlanePtr aPln = aFace.getPlane();
1355 theError = "Error: Only planar faces allowed.";
1359 if (!aFacesPln->isCoincident(aPln)) {
1360 theError = "Error: Only coincident faces allowed.";
1369 //==================================================================================================
1370 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1371 const std::list<std::string>& theArguments,
1372 Events_InfoMessage& theError) const
1374 if (!theAttribute.get()) {
1375 theError = "Error: empty selection.";
1378 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1379 AttributeSelectionListPtr anAttrSelectionList =
1380 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1381 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1382 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1383 if (!anAttrSelection.get()) {
1384 theError = "Error: empty attribute selection.";
1387 ResultPtr aContext = anAttrSelection->context();
1388 if(!aContext.get()) {
1389 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1390 if (!aContFeat.get() || !aContFeat->results().size() ||
1391 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1392 theError = "Error: Empty selection context.";
1396 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1397 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1398 if (!aFeature.get()) {
1399 theError = "Error: empty feature.";
1402 std::string aFeatureKind = aFeature->getKind();
1403 if (aFeatureKind == "Sketch" ||
1404 aFeatureKind == "Plane" ||
1405 aFeatureKind == "Axis") {
1406 theError = "Error: %1 shape is not allowed for selection.";
1407 theError.arg(aFeatureKind);
1410 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1411 if (!aShape.get()) {
1412 GeomShapePtr aContextShape = aContext->shape();
1413 aShape = aContextShape;
1415 if (!aShape.get()) {
1416 theError = "Error: empty shape.";
1419 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1420 theError = "Error: Local selection not allowed.";
1424 int aShapeType = aShape->shapeType();
1425 // Allow to select edges, faces and solids.
1426 if (aShapeType != GeomAPI_Shape::EDGE &&
1427 aShapeType != GeomAPI_Shape::FACE &&
1428 aShapeType != GeomAPI_Shape::SOLID &&
1429 aShapeType != GeomAPI_Shape::COMPSOLID &&
1430 aShapeType != GeomAPI_Shape::COMPOUND) {
1431 theError = "Error: selected shape has the wrong type.";
1439 //==================================================================================================
1440 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1441 const AttributePtr& theAttribute,
1442 const std::list<std::string>& theArguments,
1443 Events_InfoMessage& theError) const
1445 AttributeSelectionListPtr anAttrSelectionList =
1446 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1447 if (!anAttrSelectionList.get()) {
1449 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1453 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1454 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1455 if (!anAttrSelection.get()) {
1456 theError = "Error: Empty attribute selection.";
1459 ResultPtr aContext = anAttrSelection->context();
1460 if(!aContext.get()) {
1461 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1462 if (!aContFeat.get() || !aContFeat->results().size() ||
1463 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1464 theError = "Error: Empty selection context.";
1468 ResultConstructionPtr aResultConstruction =
1469 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1470 if (aResultConstruction.get()) {
1471 theError = "Error: Result construction not allowed for selection.";
1474 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1475 if (!aShape.get()) {
1476 GeomShapePtr aContextShape = aContext->shape();
1477 aShape = aContextShape;
1479 if (!aShape.get()) {
1480 theError = "Error: Empty shape.";
1483 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1484 theError = "Error: Local selection not allowed.";
1492 //=================================================================================================
1493 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1494 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1495 const std::list<std::string>& theArguments,
1496 Events_InfoMessage& theError) const
1498 if (theArguments.size() != 2) {
1499 theError = "Wrong number of arguments (expected 2).";
1503 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1504 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1506 int anObjectsNb = 0, aToolsNb = 0;
1508 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1510 bool isAllInSameCompSolid = true;
1511 ResultBodyPtr aCompSolid;
1513 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1514 if (anAttrSelList) {
1515 anObjectsNb = anAttrSelList->size();
1516 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1517 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1518 ResultPtr aContext = anAttr->context();
1519 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1520 if (aResCompSolidPtr.get()) {
1521 if (aCompSolid.get()) {
1522 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1524 aCompSolid = aResCompSolidPtr;
1527 isAllInSameCompSolid = false;
1534 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1535 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1536 anAttrSelList = theFeature->selectionList(*anIt);
1537 if (anAttrSelList) {
1538 aToolsNb = anAttrSelList->size();
1539 if (isAllInSameCompSolid) {
1540 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1541 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1542 ResultPtr aContext = anAttr->context();
1543 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1544 if (aResCompSolidPtr.get()) {
1545 if (aCompSolid.get()) {
1546 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1548 aCompSolid = aResCompSolidPtr;
1551 isAllInSameCompSolid = false;
1561 if (anObjectsNb + aToolsNb < 2) {
1562 theError = "Not enough arguments for Fuse operation.";
1564 } else if (isAllInSameCompSolid) {
1565 theError = "Operations only between sub-shapes of the same shape not allowed.";
1572 //=================================================================================================
1573 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1574 std::string theFeature,
1575 std::string theAttribute)
1577 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1584 //==================================================================================================
1585 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1586 const AttributePtr& theAttribute,
1587 const std::list<std::string>& theArguments,
1588 Events_InfoMessage& theError) const
1590 AttributeSelectionListPtr anAttrSelectionList =
1591 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1592 if (!anAttrSelectionList.get()) {
1594 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1598 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1599 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1600 if (!anAttrSelection.get()) {
1601 theError = "Error: Empty attribute selection.";
1604 ResultPtr aContext = anAttrSelection->context();
1605 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1606 theError = "Error: Empty selection context.";
1609 ResultConstructionPtr aResultConstruction =
1610 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1611 if (aResultConstruction.get()) {
1612 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1613 theError = "Error: Result construction not allowed for selection.";
1617 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1618 GeomShapePtr aContextShape;
1619 if (!aShape.get() && aContext.get()) {
1620 aContextShape = aContext->shape();
1621 aShape = aContextShape;
1623 if (!aShape.get()) {
1624 theError = "Error: Empty shape.";
1627 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1628 theError = "Error: Local selection not allowed.";
1632 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1633 theError = "Error: Result construction should be plane.";
1641 //=================================================================================================
1642 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1643 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1644 const std::list<std::string>& theArguments,
1645 Events_InfoMessage& theError) const
1647 if (theArguments.size() != 2) {
1648 theError = "Wrong number of arguments (expected 2).";
1652 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1653 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1655 int anObjectsNb = 0, aToolsNb = 0;
1657 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1659 bool isAllInSameCompSolid = true;
1660 ResultBodyPtr aCompSolid;
1662 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1663 if (anAttrSelList) {
1664 anObjectsNb = anAttrSelList->size();
1667 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1668 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1670 if (!isSimpleMode) {
1671 anAttrSelList = theFeature->selectionList(*anIt);
1672 if (anAttrSelList) {
1673 aToolsNb = anAttrSelList->size();
1677 if ((isSimpleMode && anObjectsNb < 2)
1678 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1679 theError = "Not enough arguments for Fuse operation.";
1685 //=================================================================================================
1686 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1687 std::string theFeature,
1688 std::string theAttribute)