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 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
145 if (!aShape.get() && aContext.get()) {
146 GeomShapePtr aContextShape = aContext->shape();
147 aShape = aContextShape;
150 theError = "Error: Empty shape.";
154 if (!aPathShape->isSubShape(aShape)) {
155 theError = "Error: Location should be a vertex subshape from path shape.";
163 //==================================================================================================
164 bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid(
165 const std::shared_ptr<ModelAPI_Feature>& theFeature,
166 const std::list<std::string>& theArguments,
167 Events_InfoMessage& theError) const
169 static const std::string aCreationMethodID = "creation_method";
170 static const std::string aBaseObjectsID = "base_objects";
171 static const std::string aLocationsID = "locations_objects";
173 if(theFeature->getKind() != "Pipe") {
174 theError = "Error: Feature \"%1\" does not supported by this validator.";
175 theError.arg(theFeature->getKind());
179 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
180 if(!aCreationMethodAttr.get()) {
181 theError = "Error: Could not get \"%1\" attribute.";
182 theError.arg(aCreationMethodID);
186 if(aCreationMethodAttr->value() != "locations") {
190 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
191 if(!aBaseObjectsSelectionList.get()) {
192 theError = "Error: Could not get \"%1\" attribute.";
193 theError.arg(aBaseObjectsID);
197 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
198 if(!aLocationsSelectionList.get()) {
199 theError = "Error: Could not get \"%1\" attribute.";
200 theError.arg(aBaseObjectsID);
204 if(aLocationsSelectionList->size() > 0 &&
205 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
206 theError = "Error: Number of locations should be the same as base objects.";
213 //==================================================================================================
214 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
215 const std::list<std::string>& theArguments,
216 Events_InfoMessage& theError) const
218 if(theArguments.empty()) {
219 theError = "Error: Validator parameters is empty.";
223 // Checking attribute.
224 if(!isValidAttribute(theAttribute, theArguments, theError)) {
225 if(theError.empty()) {
226 theError = "Error: Attribute contains unacceptable shape.";
231 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
232 std::string anAttributeType = theAttribute->attributeType();
233 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
234 AttributeSelectionListPtr aListAttr =
235 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
236 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
237 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
238 ResultPtr aContext = aSelectionAttr->context();
239 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
240 theError = "Error: Empty context.";
244 ResultConstructionPtr aResultConstruction =
245 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
246 if(!aResultConstruction.get()) {
247 // It is not a result construction.
248 // If shape is compound check that it contains only faces and edges.
249 GeomShapePtr aShape = aSelectionAttr->value();
251 if (aContext.get()) {
252 aShape = aContext->shape();
254 theError = "Error: Empty context.";
259 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
260 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
261 GeomShapePtr aSubShape = anIt.current();
262 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
263 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
264 theError = "Error: Compound should contain only faces and edges.";
273 GeomShapePtr aShape = aSelectionAttr->value();
274 GeomShapePtr aContextShape = aResultConstruction->shape();
276 // Whole sketch selected.
279 // Object from sketch selected.
280 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
281 GeomShapePtr aWire = anExp.current();
282 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
283 theError = "Error: Wire with wrong orientation selected.";
287 if(aSelectedWiresFromObjects.isBound(aWire)) {
289 "Error: Objects with such wire already selected. Don't allow to select this object.";
293 aSelectedWiresFromObjects.bind(aWire, aWire);
302 //==================================================================================================
303 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
304 const std::shared_ptr<ModelAPI_Feature>& theFeature,
305 const std::list<std::string>& theArguments,
306 Events_InfoMessage& theError) const
308 const std::string aBaseObjectsID = theArguments.front();
310 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
311 if(!aListAttr.get()) {
312 theError = "Error: Could not get \"%1\" attribute.";
313 theError.arg(aBaseObjectsID);
317 std::set<ResultConstructionPtr> aSelectedSketches;
318 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
320 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
321 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
322 ResultPtr aContext = aSelectionAttr->context();
323 if(!aContext.get()) {
324 FeaturePtr aFeature = aSelectionAttr->contextFeature();
325 if (!aFeature.get() || aFeature->results().empty()) {
326 theError = "Error: Empty context.";
329 aContext = aFeature->firstResult();
333 ResultConstructionPtr aResultConstruction =
334 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
335 if(!aResultConstruction.get()) {
336 // It is not a result construction.
340 GeomShapePtr aShape = aSelectionAttr->value();
341 GeomShapePtr aContextShape = aResultConstruction->shape();
343 // Whole sketch selected.
344 aSelectedSketches.insert(aResultConstruction);
346 // Object from sketch selected.
347 aSelectedSketchesFromObjects.insert(aResultConstruction);
352 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
353 anIt != aSelectedSketches.cend();
355 ResultConstructionPtr aResultConstruction = *anIt;
356 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
357 aSelectedSketchesFromObjects.cend()) {
358 theError = "Sketch and objects from it can not be selected at the same time.";
366 //==================================================================================================
367 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
368 const std::list<std::string>& theArguments,
369 Events_InfoMessage& theError) const
371 if(!theAttribute.get()) {
372 theError = "Error: Empty attribute.";
376 std::string anAttributeType = theAttribute->attributeType();
377 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
378 AttributeSelectionListPtr aListAttr =
379 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
380 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
381 // If at least one attribute is invalid, the result is false.
382 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
386 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
388 AttributeSelectionPtr anAttr =
389 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
390 ResultPtr aContext = anAttr->context();
391 if(!aContext.get() && !anAttr->contextFeature().get()) {
392 theError = "Error: Attribute have empty context.";
396 GeomShapePtr aShape = anAttr->value();
397 GeomShapePtr aContextShape;
398 if(!aShape.get() && aContext.get()) {
399 aContextShape = aContext->shape();
400 aShape = aContextShape;
403 theError = "Error: Empty shape selected";
407 ResultConstructionPtr aConstruction;
408 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
409 aContext = anAttr->contextFeature()->firstResult();
412 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
413 if(aConstruction.get()) {
414 // Construciotn selected. Check that is is not infinite.
415 if(aConstruction->isInfinite()) {
416 theError = "Error: Infinite constructions is not allowed as base.";
420 GeomShapePtr aContextShape = aContext->shape();
421 if(aShape->isEqual(aContextShape)) {
422 // Whole construction selected. Check that it have faces.
423 if(aConstruction->facesNum() > 0) {
427 // Shape on construction selected. Check that it is a face or wire.
428 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
429 aShape->shapeType() == GeomAPI_Shape::FACE) {
437 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
438 // Local selection on body does not allowed.
440 "Error: Selected shape is in the local selection. Only global selection is allowed.";
444 // Check that object is a shape with allowed type.
445 GeomValidators_ShapeType aShapeTypeValidator;
446 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
447 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
448 "wires on sketch, whole sketch(if it has at least one face), "
449 "and whole objects with shape types: %1";
450 std::string anArgumentString;
451 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
452 if (!anArgumentString.empty())
453 anArgumentString += ", ";
454 anArgumentString += *anIt;
456 theError.arg(anArgumentString);
461 theError = "Error: Attribute \"%1\" does not supported by this validator.";
462 theError.arg(anAttributeType);
469 //==================================================================================================
470 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
471 const std::list<std::string>& theArguments,
472 Events_InfoMessage& theError) const
474 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
475 theError = "Error: The attribute with the %1 type is not processed";
476 theError.arg(theAttribute->attributeType());
479 if (theArguments.size() != 2) {
480 theError = "Error: Wrong parameters in XML definition for %1 type";
481 theError.arg(theAttribute->attributeType());
484 // first argument is for the base attribute, second - for skipping feature kind
485 std::list<std::string>::const_iterator anIt = theArguments.begin();
486 std::string aBaseAttributeId = *anIt;
487 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
488 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
489 if (!aBaseAttribute.get()) {
490 theError = "Wrong parameters in XML definition for %1 type";
491 theError.arg(theAttribute->attributeType());
494 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
495 // this validator is not necessary anymore
499 std::string aFeatureAttributeKind = *anIt;
500 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
501 // check whether the selection is on the sketch
502 std::list<std::string> anArguments;
503 anArguments.push_back(aFeatureAttributeKind);
505 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
506 bool aPlanarFace = false;
507 // check if selection has Face selected
508 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
510 anArguments.push_back("face");
511 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
513 bool aValid = !aFeatureKind && aPlanarFace;
517 //==================================================================================================
518 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
519 const std::shared_ptr<ModelAPI_Feature>& theFeature,
520 const std::list<std::string>& theArguments,
521 Events_InfoMessage& theError) const
523 if(theArguments.size() != 2) {
524 theError = "Error: Validator should be used with 2 parameters for extrusion.";
528 std::list<std::string>::const_iterator
529 anArgsIt = theArguments.begin(), aLast = theArguments.end();
531 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
534 GeomShapePtr aDirShape;
535 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
537 aDirShape = aSelAttr->value();
538 if(!aDirShape.get()) {
539 ResultPtr aContext = aSelAttr->context();
540 if(!aContext.get()) {
541 FeaturePtr aFeature = aSelAttr->contextFeature();
542 if (aFeature.get() && !aFeature->results().empty()) {
543 aContext = aFeature->firstResult();
548 aDirShape = aContext->shape();
553 if(!aDirShape.get()) {
554 // Check that dir can be empty.
555 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
556 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
557 "can not be used with default value. Select direction for extrusion.";
558 theError.arg(*anArgsIt);
565 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
567 // If faces selected check that direction not parallel with them.
568 AttributeSelectionListPtr aListAttr =
569 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
570 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
571 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
572 GeomShapePtr aShapeInList = anAttr->value();
573 if(!aShapeInList.get()) {
574 aShapeInList = anAttr->context()->shape();
576 bool isParallel = true;
577 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
578 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
579 for(GeomAPI_ShapeExplorer
580 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
581 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
582 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
587 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
588 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
589 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
590 if(aPlanarEdges.get()) {
591 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
592 if(aDirEdge->isLine()) {
593 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
594 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
606 "Error: Direction is parallel to one of the selected face or face on selected shell.";
614 //==================================================================================================
615 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
616 Events_InfoMessage& theError) const
618 if(!theAttribute.get()) {
622 std::string anAttributeType = theAttribute->attributeType();
623 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
624 AttributeSelectionListPtr aListAttr =
625 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
626 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
627 // If at least one attribute is invalid, the result is false.
628 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
632 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
634 AttributeSelectionPtr anAttr =
635 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
636 ResultPtr aContext = anAttr->context();
637 if(!aContext.get() && !anAttr->contextFeature().get()) {
641 GeomShapePtr aShape = anAttr->value();
642 if(!aShape.get() && aContext.get()) {
643 GeomShapePtr aContextShape = aContext->shape();
644 aShape = aContextShape;
650 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
651 aShape->shapeType() == GeomAPI_Shape::EDGE ||
652 !aShape->isPlanar()) {
662 //==================================================================================================
663 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
664 const std::list<std::string>& theArguments,
665 Events_InfoMessage& theError) const
667 AttributeSelectionListPtr anAttrSelectionList =
668 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
669 if(!anAttrSelectionList.get()) {
671 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
674 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
675 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
676 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
678 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
679 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
680 if(!anAttrSelection.get()) {
681 theError = "Error: Empty attribute selection.";
684 ResultPtr aContext = anAttrSelection->context();
685 if(!aContext.get()) {
686 FeaturePtr aContFeat = anAttrSelection->contextFeature();
687 if (!aContFeat.get() || !aContFeat->results().size()) {
688 theError = "Error: Empty selection context.";
692 ResultConstructionPtr aResultConstruction =
693 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
694 if(aResultConstruction.get()) {
695 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
696 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
697 theError = "Error: Result construction not allowed for selection.";
701 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
702 if(!aShape.get() && aContext.get()) {
703 GeomShapePtr aContextShape = aContext->shape();
704 aShape = aContextShape;
707 theError = "Error: Empty shape.";
710 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
711 theError = "Error: Local selection not allowed.";
715 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
716 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
717 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
718 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
719 anAllowedTypes.insert(GeomAPI_Shape::FACE);
720 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
721 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
722 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
723 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
724 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
726 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
727 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
728 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
729 anAllowedTypes.insert(GeomAPI_Shape::FACE);
730 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
731 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
732 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
733 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
735 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
736 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
737 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
740 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
741 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
742 theError = "Error: Selected shape has the wrong type.";
751 //==================================================================================================
752 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
753 const std::list<std::string>& theArguments,
754 Events_InfoMessage& theError) const
756 AttributeSelectionListPtr anAttrSelectionList =
757 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
758 if(!anAttrSelectionList.get()) {
760 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
764 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
765 // Check all selected entities are sub-shapes of single solid
766 GeomShapePtr aBaseSolid;
767 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
768 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
769 if(!anAttrSelection.get()) {
770 theError = "Error: Empty attribute selection.";
773 ResultPtr aContext = anAttrSelection->context();
774 if(!aContext.get()) {
775 FeaturePtr aContFeat = anAttrSelection->contextFeature();
776 if (!aContFeat.get() || !aContFeat->results().size() ||
777 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
778 theError = "Error: Empty selection context.";
781 if (aContFeat->results().size() == 1)
782 aContext = aContFeat->firstResult();
784 theError = "Error: Too many shapes selected.";
789 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext);
790 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
793 theError = "Error: wrong feature is selected.";
797 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
798 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
799 theError = "Error: Not all selected shapes are sub-shapes of solids.";
804 aBaseSolid = anOwner;
805 else if (!aBaseSolid->isEqual(anOwner)) {
806 theError = "Error: Sub-shapes of different solids have been selected.";
814 //==================================================================================================
815 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
816 const std::list<std::string>& theArguments,
817 Events_InfoMessage& theError) const
819 AttributeSelectionListPtr anAttrSelectionList =
820 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
821 if(!anAttrSelectionList.get()) {
822 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
826 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
827 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
829 //GeomValidators_BodyShapes aBodyValidator;
830 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
834 GeomValidators_FeatureKind aFeatureKindValidator;
835 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
839 ResultPtr aContext = aSelectAttr->context();
840 ResultConstructionPtr aResultConstruction =
841 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
842 if(aResultConstruction.get()) {
843 theError = "Error: Only body shapes and construction planes are allowed for selection.";
847 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
848 if(aResultBody.get()) {
851 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
852 if(aResultFeature.get()) {
854 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
855 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
856 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
857 if (aBody.get() && !aBody->isDisabled())
864 theError = "Error: Only body shapes and construction planes are allowed for selection.";
872 //==================================================================================================
873 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
874 const std::list<std::string>& theArguments,
875 Events_InfoMessage& theError) const
877 AttributeSelectionListPtr aSubShapesAttrList =
878 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
879 if(!aSubShapesAttrList.get()) {
881 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
885 static const std::string aBaseShapeID = "base_shape";
886 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
887 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
889 if(!aShapeAttrSelection.get()) {
890 theError = "Error: Could not get \"%1\" attribute.";
891 theError.arg(aBaseShapeID);
895 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
896 ResultPtr aContext = aShapeAttrSelection->context();
897 if(!aContext.get()) {
898 theError = "Error: Empty context.";
901 if(!aBaseShape.get()) {
902 aBaseShape = aContext->shape();
904 if(!aBaseShape.get()) {
905 theError = "Error: Empty base shape.";
909 ListOfShape aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
910 // add to the list all sub-shapes of the compound due to they can be selected as a shapes to keep
911 for (GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next())
912 aSubShapes.push_back(anIt.current());
913 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
914 bool isSameFound = false;
915 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
916 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
917 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
919 if ((*anIt)->isEqual(aShapeToAdd)) {
925 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
933 //==================================================================================================
934 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
935 const std::shared_ptr<ModelAPI_Feature>& theFeature,
936 const std::list<std::string>& theArguments,
937 Events_InfoMessage& theError) const
939 static const std::string aBaseShapeID = "base_shape";
940 static const std::string aSubShapesID = "subshapes_to_keep";
942 if(theFeature->getKind() != "Remove_SubShapes") {
943 theError = "Error: Feature \"%1\" does not supported by this validator.";
944 theError.arg(theFeature->getKind());
948 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
949 if(!aShapeAttrSelection.get()) {
950 theError = "Error: Could not get \"%1\" attribute.";
951 theError.arg(aBaseShapeID);
955 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
956 if(!aSubShapesAttrList.get()) {
957 theError = "Error: Could not get \"%1\" attribute.";
958 theError.arg(aSubShapesID);
963 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
964 if(!aBaseShape.get()) {
965 theError = "Error: Base shape is empty.";
968 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
970 if (aSubShapesAttrList->size() == 0) {
971 theError = "Error: Resulting shape is not valid.";
975 // Copy sub-shapes from list to new shape.
976 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
977 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
978 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
979 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
983 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
984 theError = "Error: Resulting shape is not valid.";
991 //==================================================================================================
992 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
993 const std::list<std::string>& theArguments,
994 Events_InfoMessage& theError) const
996 AttributeSelectionListPtr aBaseObjectsAttrList =
997 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
998 if(!aBaseObjectsAttrList.get()) {
999 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1000 theError.arg(FeaturesPlugin_Union::ID());
1004 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1005 bool isSameFound = false;
1006 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1007 ResultPtr aContext = anAttrSelectionInList->context();
1008 if (!aContext.get()) {
1009 theError = "Error: selection is invalid.";
1013 ResultConstructionPtr aConstruction =
1014 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1015 if(aConstruction.get()) {
1016 theError = "Error: Result construction not allowed for selection.";
1020 GeomShapePtr aShape = anAttrSelectionInList->value();
1021 GeomShapePtr aContextShape = aContext->shape();
1022 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1023 theError = "Error: Local selection not allowed.";
1027 ResultBodyPtr aResult =
1028 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1029 if(!aResult.get()) {
1033 if(aResult->numberOfSubs() > 0) {
1034 theError = "Error: Whole compsolids not allowed for selection.";
1042 //==================================================================================================
1043 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1044 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1045 const std::list<std::string>& theArguments,
1046 Events_InfoMessage& theError) const
1048 // Check feature kind.
1049 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1050 theError = "Error: This validator supports only \"%1\" feature.";
1051 theError.arg(FeaturesPlugin_Union::ID());
1055 // Get base objects attribute list.
1056 AttributeSelectionListPtr aBaseObejctsAttrList =
1057 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1058 if(!aBaseObejctsAttrList.get()) {
1059 theError = "Error: Could not get \"%1\" attribute.";
1060 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1065 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1066 ListOfShape aBaseShapesList;
1067 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1068 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1069 GeomShapePtr aShape = anAttrSelectionInList->value();
1070 if (!aShape.get()) {
1073 aBaseShapesList.push_back(aShape);
1074 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1075 GeomAPI_Shape::COMPSOLID;
1078 // Make compound and find connected.
1079 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1080 ListOfShape aCombined, aFree;
1081 GeomAlgoAPI_ShapeTools::combineShapes(
1087 if(aFree.size() > 0 || aCombined.size() > 1) {
1088 theError = "Error: Not all shapes have shared topology.";
1095 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1096 const std::list<std::string>& theArguments,
1097 Events_InfoMessage& theError) const
1099 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1100 theError = "Error: The attribute with the %1 type is not processed";
1101 theError.arg(theAttribute->attributeType());
1105 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1107 ObjectPtr aRefObject = aRefAttribute->value();
1108 if (!aRefObject.get()) {
1109 theError = "Error: Empty feature.";
1113 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1114 if (!aRefFeature.get()) {
1115 theError = "Error: Empty feature.";
1118 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1119 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1121 size_t aConcealedResults = aResults.size();
1122 if (!aConcealedResults && !theArguments.empty()) {
1123 // find if these results are touched by the feature in another attribute
1124 std::list<std::string>::const_iterator anIt = theArguments.begin();
1125 std::string aRecoveredList = *anIt;
1126 if (!aRecoveredList.empty()) {
1127 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1128 theAttribute->owner()->data()->reflist(aRecoveredList);
1129 if (aParameterList.get())
1130 aConcealedResults = aParameterList->size();
1134 if (aConcealedResults == 0)
1135 theError = "Error: No concealed results.";
1137 return theError.empty();
1140 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1141 const std::list<std::string>& theArguments,
1142 Events_InfoMessage& theError) const
1144 static std::list<std::string> aEdgeArg(1, "circle");
1145 static std::list<std::string> aFaceArg(1, "cylinder");
1147 Events_InfoMessage aError;
1148 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1150 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1152 theError = "The shape neither circle nor cylinder";
1157 //=================================================================================================
1158 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1159 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1160 const std::list<std::string>& theArguments,
1161 Events_InfoMessage& theError) const
1163 if (theArguments.size() != 2)
1165 theError = "Wrong number of arguments (expected 2).";
1169 int anObjectsNb = 0, aToolsNb = 0;
1170 //int anOperationType = 0;
1172 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1174 bool isAllInSameCompSolid = true;
1175 ResultBodyPtr aCompSolid;
1177 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1180 anObjectsNb = anAttrSelList->size();
1181 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1183 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1184 ResultPtr aContext = anAttr->context();
1185 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1186 if (aResCompSolidPtr.get())
1188 if (aCompSolid.get())
1190 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1194 aCompSolid = aResCompSolidPtr;
1199 isAllInSameCompSolid = false;
1207 anAttrSelList = theFeature->selectionList(*anIt);
1210 aToolsNb = anAttrSelList->size();
1211 if (isAllInSameCompSolid)
1213 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1215 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1216 ResultPtr aContext = anAttr->context();
1217 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1218 if (aResCompSolidPtr.get())
1220 if (aCompSolid.get())
1222 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1226 aCompSolid = aResCompSolidPtr;
1231 isAllInSameCompSolid = false;
1239 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1240 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1241 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1243 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1246 if (anObjectsNb + aToolsNb < 2)
1248 theError = "Not enough arguments for Fuse operation.";
1251 else if (isAllInSameCompSolid)
1253 theError = "Operations only between sub-shapes of the same shape not allowed.";
1259 if (anObjectsNb < 1)
1261 theError = "Objects not selected.";
1266 theError = "Tools not selected.";
1269 if (isAllInSameCompSolid)
1271 theError = "Operations only between sub-shapes of the same shape not allowed.";
1279 //=================================================================================================
1280 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1281 std::string theAttribute)
1283 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1291 //==================================================================================================
1292 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1293 const AttributePtr& theAttribute,
1294 const std::list<std::string>& theArguments,
1295 Events_InfoMessage& theError) const
1297 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1298 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1300 AttributeSelectionListPtr anAttrSelectionList =
1301 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1302 if (!aFeature.get() || !anAttrSelectionList.get()) {
1304 "Error: Validator used in wrong feature or attribute";
1308 AttributeSelectionListPtr anOtherAttrSelectionList;
1309 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1310 anOtherAttrSelectionList =
1311 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1313 anOtherAttrSelectionList =
1314 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1317 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1318 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1319 GeomPlanePtr aFacesPln;
1321 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1322 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1324 if (anAttrSelection->contextFeature().get()) {
1325 theError = "Error: Features not allowed for selection.";
1329 ResultPtr aContext = anAttrSelection->context();
1330 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1331 GeomShapePtr aContextShape = aContext->shape();
1332 if (!aShape.get()) {
1333 aShape = aContextShape;
1336 if (aShape->isSolid() || aShape->isCompSolid()) {
1337 aSelectedShapesType = GeomAPI_Shape::SOLID;
1338 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1339 if (aResCompSolidPtr.get()) {
1340 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1341 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1344 aSelectedShapesType = GeomAPI_Shape::FACE;
1345 GeomAPI_Face aFace(aShape);
1346 aFacesPln = aFace.getPlane();
1351 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1352 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1353 if (!anAttrSelection.get()) {
1354 theError = "Error: Empty attribute selection.";
1358 if (anAttrSelection->contextFeature().get()) {
1359 theError = "Error: Features not allowed for selection.";
1363 ResultPtr aContext = anAttrSelection->context();
1364 if(!aContext.get()) {
1365 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1366 if (!aContFeat.get() || !aContFeat->results().size() ||
1367 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1368 theError = "Error: Empty selection context.";
1372 ResultConstructionPtr aResultConstruction =
1373 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1374 if (aResultConstruction.get()) {
1375 theError = "Error: Result construction not allowed for selection.";
1378 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1379 GeomShapePtr aContextShape = aContext->shape();
1380 if (!aShape.get()) {
1381 aShape = aContextShape;
1383 if (!aShape.get()) {
1384 theError = "Error: Empty shape.";
1387 if (!aShape->isEqual(aContextShape)) {
1388 theError = "Error: Local selection not allowed.";
1392 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1393 // Other list is empty.
1394 if (aShape->isSolid() || aShape->isCompSolid()) {
1395 aSelectedShapesType = GeomAPI_Shape::SOLID;
1397 aSelectedShapesType = GeomAPI_Shape::FACE;
1398 GeomAPI_Face aFace(aShape);
1399 aFacesPln = aFace.getPlane();
1401 if (!aFacesPln.get()) {
1402 theError = "Error: Only planar faces allowed.";
1408 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1409 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1410 theError = "Error: Selected shapes should have the same type.";
1414 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1415 if (aResCompSolidPtr.get()) {
1416 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1417 if (aSelectedCompSolidsInOtherList.isBound(aCompSolidShape)) {
1418 theError = "Error: Solids from compsolid in other list not allowed.";
1423 GeomAPI_Face aFace(aShape);
1424 GeomPlanePtr aPln = aFace.getPlane();
1427 theError = "Error: Only planar faces allowed.";
1431 if (!aFacesPln->isCoincident(aPln)) {
1432 theError = "Error: Only coincident faces allowed.";
1441 //==================================================================================================
1442 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1443 const std::list<std::string>& theArguments,
1444 Events_InfoMessage& theError) const
1446 if (!theAttribute.get()) {
1447 theError = "Error: empty selection.";
1450 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1451 AttributeSelectionListPtr anAttrSelectionList =
1452 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
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 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1469 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1470 if (!aFeature.get()) {
1471 theError = "Error: empty feature.";
1474 std::string aFeatureKind = aFeature->getKind();
1475 if (aFeatureKind == "Sketch" ||
1476 aFeatureKind == "Plane" ||
1477 aFeatureKind == "Axis") {
1478 theError = "Error: %1 shape is not allowed for selection.";
1479 theError.arg(aFeatureKind);
1482 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1483 if (!aShape.get()) {
1484 GeomShapePtr aContextShape = aContext->shape();
1485 aShape = aContextShape;
1487 if (!aShape.get()) {
1488 theError = "Error: empty shape.";
1491 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1492 theError = "Error: Local selection not allowed.";
1496 int aShapeType = aShape->shapeType();
1497 // Allow to select edges, faces and solids.
1498 if (aShapeType != GeomAPI_Shape::EDGE &&
1499 aShapeType != GeomAPI_Shape::FACE &&
1500 aShapeType != GeomAPI_Shape::SOLID &&
1501 aShapeType != GeomAPI_Shape::COMPSOLID &&
1502 aShapeType != GeomAPI_Shape::COMPOUND) {
1503 theError = "Error: selected shape has the wrong type.";
1511 //==================================================================================================
1512 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1513 const AttributePtr& theAttribute,
1514 const std::list<std::string>& theArguments,
1515 Events_InfoMessage& theError) const
1517 AttributeSelectionListPtr anAttrSelectionList =
1518 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1519 if (!anAttrSelectionList.get()) {
1521 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1525 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1526 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1527 if (!anAttrSelection.get()) {
1528 theError = "Error: Empty attribute selection.";
1531 ResultPtr aContext = anAttrSelection->context();
1532 if(!aContext.get()) {
1533 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1534 if (!aContFeat.get() || !aContFeat->results().size() ||
1535 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1536 theError = "Error: Empty selection context.";
1540 ResultConstructionPtr aResultConstruction =
1541 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1542 if (aResultConstruction.get()) {
1543 theError = "Error: Result construction not allowed for selection.";
1546 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1547 if (!aShape.get()) {
1548 GeomShapePtr aContextShape = aContext->shape();
1549 aShape = aContextShape;
1551 if (!aShape.get()) {
1552 theError = "Error: Empty shape.";
1555 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1556 theError = "Error: Local selection not allowed.";
1564 //=================================================================================================
1565 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1566 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1567 const std::list<std::string>& theArguments,
1568 Events_InfoMessage& theError) const
1570 if (theArguments.size() != 2) {
1571 theError = "Wrong number of arguments (expected 2).";
1575 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1576 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1578 int anObjectsNb = 0, aToolsNb = 0;
1580 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1582 bool isAllInSameCompSolid = true;
1583 ResultBodyPtr aCompSolid;
1585 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1586 if (anAttrSelList) {
1587 anObjectsNb = anAttrSelList->size();
1588 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1589 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1590 ResultPtr aContext = anAttr->context();
1591 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1592 if (aResCompSolidPtr.get()) {
1593 if (aCompSolid.get()) {
1594 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1596 aCompSolid = aResCompSolidPtr;
1599 isAllInSameCompSolid = false;
1606 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1607 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1608 anAttrSelList = theFeature->selectionList(*anIt);
1609 if (anAttrSelList) {
1610 aToolsNb = anAttrSelList->size();
1611 if (isAllInSameCompSolid) {
1612 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1613 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1614 ResultPtr aContext = anAttr->context();
1615 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1616 if (aResCompSolidPtr.get()) {
1617 if (aCompSolid.get()) {
1618 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1620 aCompSolid = aResCompSolidPtr;
1623 isAllInSameCompSolid = false;
1633 if (anObjectsNb + aToolsNb < 2) {
1634 theError = "Not enough arguments for Fuse operation.";
1636 } else if (isAllInSameCompSolid) {
1637 theError = "Operations only between sub-shapes of the same shape not allowed.";
1644 //=================================================================================================
1645 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1646 std::string theFeature,
1647 std::string theAttribute)
1649 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1656 //==================================================================================================
1657 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1658 const AttributePtr& theAttribute,
1659 const std::list<std::string>& theArguments,
1660 Events_InfoMessage& theError) const
1662 AttributeSelectionListPtr anAttrSelectionList =
1663 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1664 if (!anAttrSelectionList.get()) {
1666 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1670 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1671 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1672 if (!anAttrSelection.get()) {
1673 theError = "Error: Empty attribute selection.";
1676 ResultPtr aContext = anAttrSelection->context();
1677 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1678 theError = "Error: Empty selection context.";
1681 ResultConstructionPtr aResultConstruction =
1682 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1683 if (aResultConstruction.get()) {
1684 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1685 theError = "Error: Result construction not allowed for selection.";
1689 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1690 GeomShapePtr aContextShape;
1691 if (!aShape.get() && aContext.get()) {
1692 aContextShape = aContext->shape();
1693 aShape = aContextShape;
1695 if (!aShape.get()) {
1696 theError = "Error: Empty shape.";
1699 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1700 theError = "Error: Local selection not allowed.";
1704 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1705 theError = "Error: Result construction should be plane.";
1713 //=================================================================================================
1714 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1715 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1716 const std::list<std::string>& theArguments,
1717 Events_InfoMessage& theError) const
1719 if (theArguments.size() != 2) {
1720 theError = "Wrong number of arguments (expected 2).";
1724 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1725 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1727 int anObjectsNb = 0, aToolsNb = 0;
1729 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1731 bool isAllInSameCompSolid = true;
1732 ResultBodyPtr aCompSolid;
1734 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1735 if (anAttrSelList) {
1736 anObjectsNb = anAttrSelList->size();
1739 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1740 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1742 if (!isSimpleMode) {
1743 anAttrSelList = theFeature->selectionList(*anIt);
1744 if (anAttrSelList) {
1745 aToolsNb = anAttrSelList->size();
1749 if ((isSimpleMode && anObjectsNb < 2)
1750 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1751 theError = "Not enough arguments for Fuse operation.";
1757 //=================================================================================================
1758 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1759 std::string theFeature,
1760 std::string theAttribute)