1 // Copyright (C) 2014-2020 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com
20 #include "FeaturesPlugin_Validators.h"
22 #include "FeaturesPlugin_Boolean.h"
23 #include "FeaturesPlugin_BooleanFuse.h"
24 #include "FeaturesPlugin_BooleanCommon.h"
25 #include "FeaturesPlugin_BooleanSmash.h"
26 #include "FeaturesPlugin_Extrusion.h"
27 #include "FeaturesPlugin_Pipe.h"
28 #include "FeaturesPlugin_Union.h"
30 #include <Events_InfoMessage.h>
32 #include <ModelAPI_Attribute.h>
33 #include <ModelAPI_AttributeDouble.h>
34 #include <ModelAPI_AttributeInteger.h>
35 #include <ModelAPI_AttributeSelectionList.h>
36 #include <ModelAPI_AttributeString.h>
37 #include <ModelAPI_AttributeReference.h>
38 #include <ModelAPI_AttributeRefList.h>
39 #include <ModelAPI_Feature.h>
40 #include <ModelAPI_ResultBody.h>
41 #include <ModelAPI_ResultConstruction.h>
42 #include <ModelAPI_Tools.h>
44 #include <GeomValidators_BodyShapes.h>
45 #include <GeomValidators_Face.h>
46 #include <GeomValidators_FeatureKind.h>
47 #include <GeomValidators_ShapeType.h>
49 #include <GeomAPI_DataMapOfShapeShape.h>
50 #include <GeomAPI_Lin.h>
51 #include <GeomAPI_PlanarEdges.h>
52 #include <GeomAPI_Pln.h>
53 #include <GeomAPI_ShapeExplorer.h>
54 #include <GeomAPI_ShapeIterator.h>
56 #include <GeomAlgoAPI_CompoundBuilder.h>
57 #include <GeomAlgoAPI_Prism.h>
58 #include <GeomAlgoAPI_ShapeBuilder.h>
59 #include <GeomAlgoAPI_ShapeTools.h>
60 #include <GeomAlgoAPI_WireBuilder.h>
62 #define _USE_MATH_DEFINES
65 //==================================================================================================
66 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
67 const std::list<std::string>& theArguments,
68 Events_InfoMessage& theError) const
70 AttributeSelectionPtr aPathAttrSelection =
71 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
72 if(!aPathAttrSelection.get()) {
74 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
79 GeomShapePtr aPathShape = aPathAttrSelection->value();
80 ResultPtr aContext = aPathAttrSelection->context();
82 theError = "Error: Empty context.";
85 GeomShapePtr aContextShape = aContext->shape();
86 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
87 !aPathShape->isEqual(aContextShape)) {
88 theError = "Error: Local selection of wires not allowed.";
95 //==================================================================================================
96 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute,
97 const std::list<std::string>& theArguments,
98 Events_InfoMessage& theError) const
100 AttributeSelectionListPtr anAttrSelectionList =
101 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
102 if(!anAttrSelectionList.get()) {
105 "Error: This validator can only work with selection list attributes in \"Pipe\" feature.";
109 std::shared_ptr<FeaturesPlugin_Pipe> aFeature =
110 std::dynamic_pointer_cast<FeaturesPlugin_Pipe>(theAttribute->owner());
112 AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
113 if (!aPathSelection.get()) {
115 theError = "Error: Path not selected.";
120 GeomShapePtr aPathShape = aPathSelection->value();
121 if (!aPathShape.get()) {
122 ResultPtr aContext = aPathSelection->context();
123 if (!aContext.get()) {
124 FeaturePtr aContFeat = aPathSelection->contextFeature();
125 if (!aContFeat.get() || !aContFeat->results().size()) {
126 theError = "Error: Empty selection context.";
130 aPathShape = aContext->shape();
133 if (!aPathShape.get()) {
134 theError = "Error: Empty path shape.";
138 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
139 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
140 if (!anAttrSelection.get()) {
141 theError = "Error: Empty attribute selection.";
144 ResultPtr aContext = anAttrSelection->context();
145 if (!aContext.get()) {
146 FeaturePtr aContFeat = anAttrSelection->contextFeature();
147 if (!aContFeat.get() || !aContFeat->results().size()) {
148 theError = "Error: Empty selection context.";
152 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
153 if (!aShape.get() && aContext.get()) {
154 GeomShapePtr aContextShape = aContext->shape();
155 aShape = aContextShape;
158 theError = "Error: Empty shape.";
162 if (!aPathShape->isSubShape(aShape)) {
163 theError = "Error: Location should be a vertex subshape from path shape.";
171 //==================================================================================================
173 bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid(
174 const std::shared_ptr<ModelAPI_Feature>& theFeature,
175 const std::list<std::string>& theArguments,
176 Events_InfoMessage& theError) const
178 static const std::string aCreationMethodID = "creation_method";
179 static const std::string aBaseObjectsID = "base_objects";
180 static const std::string aLocationsID = "locations_objects";
182 if(theFeature->getKind() != "Pipe") {
183 theError = "Error: Feature \"%1\" does not supported by this validator.";
184 theError.arg(theFeature->getKind());
188 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
189 if(!aCreationMethodAttr.get()) {
190 theError = "Error: Could not get \"%1\" attribute.";
191 theError.arg(aCreationMethodID);
195 if(aCreationMethodAttr->value() != "locations") {
199 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
200 if(!aBaseObjectsSelectionList.get()) {
201 theError = "Error: Could not get \"%1\" attribute.";
202 theError.arg(aBaseObjectsID);
206 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
207 if(!aLocationsSelectionList.get()) {
208 theError = "Error: Could not get \"%1\" attribute.";
209 theError.arg(aBaseObjectsID);
213 if(aLocationsSelectionList->size() > 0 &&
214 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
215 theError = "Error: Number of locations should be the same as base objects.";
223 //==================================================================================================
224 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
225 const std::list<std::string>& theArguments,
226 Events_InfoMessage& theError) const
229 if(theArguments.empty()) {
230 theError = "Error: Validator parameters is empty.";
235 // Checking attribute.
236 if(!isValidAttribute(theAttribute, theArguments, theError)) {
237 if(theError.empty()) {
238 theError = "Error: Attribute contains unacceptable shape.";
243 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
244 std::string anAttributeType = theAttribute->attributeType();
245 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
246 AttributeSelectionListPtr aListAttr =
247 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
248 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
249 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
250 ResultPtr aContext = aSelectionAttr->context();
251 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
252 theError = "Error: Empty context.";
256 ResultConstructionPtr aResultConstruction =
257 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
258 if(!aResultConstruction.get()) {
259 // It is not a result construction.
260 // If shape is compound check that it contains only faces, edges or vertices.
261 GeomShapePtr aShape = aSelectionAttr->value();
263 if (aContext.get()) {
264 aShape = aContext->shape();
266 theError = "Error: Empty context.";
271 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
272 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
273 GeomShapePtr aSubShape = anIt.current();
274 if (aSubShape->shapeType() > GeomAPI_Shape::VERTEX ||
275 aSubShape->shapeType() < GeomAPI_Shape::FACE) {
276 theError = "Error: Compound should contain only faces, edges or vertices.";
285 GeomShapePtr aShape = aSelectionAttr->value();
286 GeomShapePtr aContextShape = aResultConstruction->shape();
288 // Whole sketch selected.
291 // Object from sketch selected.
292 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
293 GeomShapePtr aWire = anExp.current();
294 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
295 theError = "Error: Wire with wrong orientation selected.";
299 if(aSelectedWiresFromObjects.isBound(aWire)) {
301 "Error: Objects with this wire already selected. Don't allow to select this object.";
305 aSelectedWiresFromObjects.bind(aWire, aWire);
314 //==================================================================================================
315 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
316 const std::shared_ptr<ModelAPI_Feature>& theFeature,
317 const std::list<std::string>& theArguments,
318 Events_InfoMessage& theError) const
320 const std::string aBaseObjectsID = theArguments.front();
322 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
323 if(!aListAttr.get()) {
325 theError = "Error: Could not get \"%1\" attribute.";
326 theError.arg(aBaseObjectsID);
331 std::set<ResultConstructionPtr> aSelectedSketches;
332 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
334 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
335 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
336 ResultPtr aContext = aSelectionAttr->context();
337 if(!aContext.get()) {
338 FeaturePtr aFeature = aSelectionAttr->contextFeature();
339 if (!aFeature.get() || aFeature->results().empty()) {
340 theError = "Error: Empty context.";
343 aContext = aFeature->firstResult();
347 ResultConstructionPtr aResultConstruction =
348 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
349 if(!aResultConstruction.get()) {
350 // It is not a result construction.
354 GeomShapePtr aShape = aSelectionAttr->value();
355 GeomShapePtr aContextShape = aResultConstruction->shape();
357 // Whole sketch selected.
358 aSelectedSketches.insert(aResultConstruction);
360 // Object from sketch selected.
361 aSelectedSketchesFromObjects.insert(aResultConstruction);
366 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
367 anIt != aSelectedSketches.cend();
369 ResultConstructionPtr aResultConstruction = *anIt;
370 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
371 aSelectedSketchesFromObjects.cend()) {
372 theError = "Sketch and objects from it can not be selected at the same time.";
380 //==================================================================================================
381 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
382 const std::list<std::string>& theArguments,
383 Events_InfoMessage& theError) const
385 if(!theAttribute.get()) {
387 theError = "Error: Empty attribute.";
392 std::string anAttributeType = theAttribute->attributeType();
393 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
394 AttributeSelectionListPtr aListAttr =
395 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
396 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
397 // If at least one attribute is invalid, the result is false.
398 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
402 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
404 AttributeSelectionPtr anAttr =
405 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
406 ResultPtr aContext = anAttr->context();
407 if(!aContext.get() && !anAttr->contextFeature().get()) {
408 theError = "Error: Attribute have empty context.";
412 GeomShapePtr aShape = anAttr->value();
413 GeomShapePtr aContextShape;
414 if(!aShape.get() && aContext.get()) {
415 aContextShape = aContext->shape();
416 aShape = aContextShape;
419 theError = "Error: Empty shape selected";
423 ResultConstructionPtr aConstruction;
424 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
425 aContext = anAttr->contextFeature()->firstResult();
428 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
429 if(aConstruction.get()) {
430 // Construction selected. Check that it is not infinite.
431 if(aConstruction->isInfinite()) {
432 theError = "Error: Infinite constructions is not allowed as base.";
436 GeomShapePtr aContextShape = aContext->shape();
437 if(aShape->isEqual(aContextShape)) {
438 // Whole construction selected. Check that it have faces.
439 if(aConstruction->facesNum() > 0) {
443 // Shape on construction selected. Check that it is a face or wire.
444 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
445 aShape->shapeType() == GeomAPI_Shape::FACE) {
452 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
453 // Local selection on body does not allowed.
455 "Error: Selected shape is in the local selection. Only global selection is allowed.";
459 // Check that object is a shape with allowed type.
460 GeomValidators_ShapeType aShapeTypeValidator;
461 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
462 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
463 "wires on sketch, whole sketch (if it has at least one face), "
464 "and whole objects with shape types: %1";
465 std::string anArgumentString;
466 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
467 if (!anArgumentString.empty())
468 anArgumentString += ", ";
469 anArgumentString += *anIt;
471 theError.arg(anArgumentString);
477 theError = "Error: Attribute \"%1\" does not supported by this validator.";
478 theError.arg(anAttributeType);
486 //==================================================================================================
488 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
489 const std::list<std::string>& theArguments,
490 Events_InfoMessage& theError) const
492 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
493 theError = "Error: The attribute with the %1 type is not processed";
494 theError.arg(theAttribute->attributeType());
497 if (theArguments.size() != 2) {
498 theError = "Error: Wrong parameters in XML definition for %1 type";
499 theError.arg(theAttribute->attributeType());
502 // first argument is for the base attribute, second - for skipping feature kind
503 std::list<std::string>::const_iterator anIt = theArguments.begin();
504 std::string aBaseAttributeId = *anIt;
505 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
506 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
507 if (!aBaseAttribute.get()) {
508 theError = "Wrong parameters in XML definition for %1 type";
509 theError.arg(theAttribute->attributeType());
512 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
513 // this validator is not necessary anymore
517 std::string aFeatureAttributeKind = *anIt;
518 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
519 // check whether the selection is on the sketch
520 std::list<std::string> anArguments;
521 anArguments.push_back(aFeatureAttributeKind);
523 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
524 bool aPlanarFace = false;
525 // check if selection has Face selected
526 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
528 anArguments.push_back("face");
529 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
531 bool aValid = !aFeatureKind && aPlanarFace;
536 //==================================================================================================
537 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
538 const std::shared_ptr<ModelAPI_Feature>& theFeature,
539 const std::list<std::string>& theArguments,
540 Events_InfoMessage& theError) const
542 if(theArguments.size() != 2) {
544 theError = "Error: Validator should be used with 2 parameters for extrusion.";
549 std::list<std::string>::const_iterator anArgsIt = theArguments.begin();
551 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
554 GeomShapePtr aDirShape;
555 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
557 aDirShape = aSelAttr->value();
558 if(!aDirShape.get()) {
559 ResultPtr aContext = aSelAttr->context();
560 if(!aContext.get()) {
561 FeaturePtr aFeature = aSelAttr->contextFeature();
562 if (aFeature.get() && !aFeature->results().empty()) {
563 aContext = aFeature->firstResult();
568 aDirShape = aContext->shape();
571 if (aDirShape.get() && aDirShape->isCompound()) {
572 GeomAPI_ShapeIterator anIt(aDirShape);
573 aDirShape = anIt.current();
578 if(!aDirShape.get() || aDirShape->isNull() ||
579 aDirShape->shapeType() != GeomAPI_Shape::EDGE) {
580 // Check that dir can be empty.
581 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
582 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
583 "can not be used with default value. Select direction for extrusion.";
584 theError.arg(*anArgsIt);
591 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
593 // If faces selected check that direction not parallel with them.
594 AttributeSelectionListPtr aListAttr =
595 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
596 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
597 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
598 GeomShapePtr aShapeInList = anAttr->value();
599 if(!aShapeInList.get()) {
600 aShapeInList = anAttr->context()->shape();
602 bool isParallel = true;
603 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
604 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
605 for(GeomAPI_ShapeExplorer
606 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
607 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
608 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
613 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
614 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
615 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
616 if(aPlanarEdges.get()) {
617 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
618 if(aDirEdge->isLine()) {
619 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
620 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
632 "Error: Direction is parallel to one of the selected face or face on selected shell.";
640 //==================================================================================================
641 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
642 Events_InfoMessage& theError) const
645 if(!theAttribute.get()) {
650 std::string anAttributeType = theAttribute->attributeType();
651 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
652 AttributeSelectionListPtr aListAttr =
653 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
654 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
655 // If at least one attribute is invalid, the result is false.
656 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
660 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
662 AttributeSelectionPtr anAttr =
663 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
664 ResultPtr aContext = anAttr->context();
665 if(!aContext.get() && !anAttr->contextFeature().get()) {
669 GeomShapePtr aShape = anAttr->value();
670 if(!aShape.get() && aContext.get()) {
671 GeomShapePtr aContextShape = aContext->shape();
672 aShape = aContextShape;
678 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
679 aShape->shapeType() == GeomAPI_Shape::EDGE ||
680 !aShape->isPlanar()) {
690 //==================================================================================================
691 bool FeaturesPlugin_ValidatorExtrusionBoundaryFace::isValid(
692 const AttributePtr& theAttribute,
693 const std::list<std::string>& theArguments,
694 Events_InfoMessage& theError) const
696 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
698 // Collect all necessary attributes and try to build prism
701 AttributeSelectionListPtr aBaseShapeAttr =
702 aFeature->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID());
703 ListOfShape aBaseShapeList;
705 if (!FeaturesPlugin_Tools::getShape(aBaseShapeAttr, true, aBaseShapeList, anError)) {
711 AttributeSelectionPtr aSelection =
712 aFeature->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID());
713 GeomShapePtr aShape = aSelection->value();
714 if (!aShape.get() && aSelection->context().get())
715 aShape = aSelection->context()->shape();
719 if (aShape->isEdge())
720 anEdge = aShape->edge();
721 else if (aShape->isCompound()) {
722 GeomAPI_ShapeIterator anIt(aShape);
723 anEdge = anIt.current()->edge();
727 std::shared_ptr<GeomAPI_Dir> aDir;
728 if (anEdge.get() && anEdge->isLine())
729 aDir = anEdge->line()->direction();
732 GeomShapePtr aFromShape, aToShape;
733 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID());
734 if (aSelection.get()) {
735 aToShape = aSelection->value();
736 if (!aToShape.get() && aSelection->context().get())
737 aToShape = aSelection->context()->shape();
738 if (aToShape.get() && aToShape->isCompound()) {
739 GeomAPI_ShapeIterator anIt(aToShape);
740 aToShape = anIt.current();
742 if (aToShape.get() && !aToShape->isFace()) {
743 theError = "\"To\" shape is not a face";
747 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID());
748 if (aSelection.get()) {
749 aFromShape = aSelection->value();
750 if (!aFromShape.get() && aSelection->context().get())
751 aFromShape = aSelection->context()->shape();
752 if (aFromShape.get() && aFromShape->isCompound()) {
753 GeomAPI_ShapeIterator anIt(aFromShape);
754 aFromShape = anIt.current();
756 if (aFromShape.get() && !aFromShape->isFace()) {
757 theError = "\"From\" shape is not a face";
762 double aToSize = aFeature->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID())->value();
763 double aFromSize = aFeature->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID())->value();
766 for (ListOfShape::iterator anIt = aBaseShapeList.begin(); anIt != aBaseShapeList.end(); anIt++) {
767 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIt;
769 std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo(
770 new GeomAlgoAPI_Prism(aBaseShape, aDir, aToShape, aToSize, aFromShape, aFromSize));
771 bool isFailed = GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPrismAlgo,
772 FeaturesPlugin_Extrusion::ID(),
783 //==================================================================================================
784 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
785 const std::list<std::string>& theArguments,
786 Events_InfoMessage& theError) const
788 AttributeSelectionListPtr anAttrSelectionList =
789 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
790 if(!anAttrSelectionList.get()) {
793 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
797 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
798 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
799 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
801 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
802 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
803 if(!anAttrSelection.get()) {
804 theError = "Error: Empty attribute selection.";
807 ResultPtr aContext = anAttrSelection->context();
808 if(!aContext.get()) {
809 FeaturePtr aContFeat = anAttrSelection->contextFeature();
810 if (!aContFeat.get() || !aContFeat->results().size()) {
811 theError = "Error: Empty selection context.";
815 ResultConstructionPtr aResultConstruction =
816 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
817 if(aResultConstruction.get()) {
818 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
819 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
820 theError = "Error: Result construction not allowed for selection.";
824 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
825 if(!aShape.get() && aContext.get()) {
826 GeomShapePtr aContextShape = aContext->shape();
827 aShape = aContextShape;
830 theError = "Error: Empty shape.";
833 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
834 theError = "Error: Local selection not allowed.";
838 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
839 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
840 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
841 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
842 anAllowedTypes.insert(GeomAPI_Shape::FACE);
843 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
844 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
845 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
846 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
847 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
849 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
850 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
851 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
852 anAllowedTypes.insert(GeomAPI_Shape::FACE);
853 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
854 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
855 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
856 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
858 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
859 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
860 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
863 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
864 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
865 theError = "Error: Selected shape has the wrong type.";
874 //==================================================================================================
875 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
876 const std::list<std::string>& theArguments,
877 Events_InfoMessage& theError) const
879 AttributeSelectionListPtr anAttrSelectionList =
880 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
881 if(!anAttrSelectionList.get()) {
884 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
889 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
890 // Check all selected entities are sub-shapes of single solid
891 GeomShapePtr aBaseSolid;
892 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
893 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
894 if(!anAttrSelection.get()) {
895 theError = "Error: Empty attribute selection.";
898 ResultPtr aContext = anAttrSelection->context();
899 if(!aContext.get()) {
900 FeaturePtr aContFeat = anAttrSelection->contextFeature();
901 if (!aContFeat.get() || !aContFeat->results().size() ||
902 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
903 theError = "Error: Empty selection context.";
906 if (aContFeat->results().size() == 1)
907 aContext = aContFeat->firstResult();
909 theError = "Error: Too many shapes selected.";
914 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true);
915 GeomShapePtr anOwner = aContext->shape();
916 GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner;
919 theError = "Error: wrong feature is selected.";
923 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
924 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
925 theError = "Error: Not all selected shapes are sub-shapes of solids.";
930 aBaseSolid = aTopLevelOwner;
931 else if (!aBaseSolid->isEqual(aTopLevelOwner)) {
932 theError = "Error: Sub-shapes of different solids have been selected.";
940 //==================================================================================================
941 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
942 const std::list<std::string>& theArguments,
943 Events_InfoMessage& theError) const
945 AttributeSelectionListPtr anAttrSelectionList =
946 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
947 if(!anAttrSelectionList.get()) {
949 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
954 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
955 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
957 //GeomValidators_BodyShapes aBodyValidator;
958 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
962 GeomValidators_FeatureKind aFeatureKindValidator;
963 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
967 ResultPtr aContext = aSelectAttr->context();
968 ResultConstructionPtr aResultConstruction =
969 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
970 if(aResultConstruction.get()) {
971 theError = "Error: Only body shapes and construction planes are allowed for selection.";
975 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
976 if(aResultBody.get()) {
979 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
980 if(aResultFeature.get()) {
982 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
983 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
984 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
985 if (aBody.get() && !aBody->isDisabled())
992 theError = "Error: Only body shapes and construction planes are allowed for selection.";
1000 //==================================================================================================
1001 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
1002 const std::list<std::string>& theArguments,
1003 Events_InfoMessage& theError) const
1005 AttributeSelectionListPtr aSubShapesAttrList =
1006 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1007 if(!aSubShapesAttrList.get()) {
1010 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
1015 static const std::string aBaseShapeID = "base_shape";
1016 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1017 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
1019 if(!aShapeAttrSelection.get()) {
1021 theError = "Error: Could not get \"%1\" attribute.";
1022 theError.arg(aBaseShapeID);
1027 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1028 ResultPtr aContext = aShapeAttrSelection->context();
1029 if(!aContext.get()) {
1030 theError = "Error: Empty context.";
1033 if(!aBaseShape.get()) {
1034 aBaseShape = aContext->shape();
1036 if(!aBaseShape.get()) {
1037 theError = "Error: Empty base shape.";
1041 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
1042 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1043 bool isSameFound = false;
1044 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1045 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1046 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
1048 if ((*anIt)->isEqual(aShapeToAdd)) {
1054 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
1062 //==================================================================================================
1063 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
1064 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1065 const std::list<std::string>& theArguments,
1066 Events_InfoMessage& theError) const
1068 static const std::string aBaseShapeID = "base_shape";
1069 static const std::string aSubShapesID = "subshapes_to_keep";
1072 if(theFeature->getKind() != "Remove_SubShapes") {
1073 theError = "Error: Feature \"%1\" does not supported by this validator.";
1074 theError.arg(theFeature->getKind());
1078 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
1079 if(!aShapeAttrSelection.get()) {
1080 theError = "Error: Could not get \"%1\" attribute.";
1081 theError.arg(aBaseShapeID);
1085 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
1086 if(!aSubShapesAttrList.get()) {
1087 theError = "Error: Could not get \"%1\" attribute.";
1088 theError.arg(aSubShapesID);
1094 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1095 if(!aBaseShape.get()) {
1096 theError = "Error: Base shape is empty.";
1099 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
1101 if (aSubShapesAttrList->size() == 0) {
1102 theError = "Error: Resulting shape is not valid.";
1106 // Copy sub-shapes from list to new shape.
1107 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1108 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1109 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1110 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
1114 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
1115 theError = "Error: Resulting shape is not valid.";
1122 //==================================================================================================
1124 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
1125 const std::list<std::string>& theArguments,
1126 Events_InfoMessage& theError) const
1128 AttributeSelectionListPtr aBaseObjectsAttrList =
1129 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1130 if(!aBaseObjectsAttrList.get()) {
1131 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1132 theError.arg(FeaturesPlugin_Union::ID());
1136 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1137 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1138 ResultPtr aContext = anAttrSelectionInList->context();
1139 if (!aContext.get()) {
1140 theError = "Error: selection is invalid.";
1144 ResultConstructionPtr aConstruction =
1145 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1146 if(aConstruction.get()) {
1147 theError = "Error: Result construction not allowed for selection.";
1151 GeomShapePtr aShape = anAttrSelectionInList->value();
1152 GeomShapePtr aContextShape = aContext->shape();
1153 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1154 theError = "Error: Local selection not allowed.";
1158 ResultBodyPtr aResult =
1159 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1160 if(!aResult.get()) {
1164 if(aResult->numberOfSubs() > 0) {
1165 theError = "Error: Whole compsolids not allowed for selection.";
1174 //==================================================================================================
1175 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1176 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1177 const std::list<std::string>& theArguments,
1178 Events_InfoMessage& theError) const
1181 // Check feature kind.
1182 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1183 theError = "Error: This validator supports only \"%1\" feature.";
1184 theError.arg(FeaturesPlugin_Union::ID());
1188 // Get base objects attribute list.
1189 AttributeSelectionListPtr aBaseObejctsAttrList =
1190 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1191 if(!aBaseObejctsAttrList.get()) {
1192 theError = "Error: Could not get \"%1\" attribute.";
1193 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1199 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1200 ListOfShape aBaseShapesList;
1201 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1202 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1203 GeomShapePtr aShape = anAttrSelectionInList->value();
1204 if (!aShape.get()) {
1207 aBaseShapesList.push_back(aShape);
1208 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1209 GeomAPI_Shape::COMPSOLID;
1212 // Make compound and find connected.
1213 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1214 ListOfShape aResults;
1215 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults);
1217 if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) {
1218 theError = "Error: Not all shapes have shared topology.";
1225 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1226 const std::list<std::string>& theArguments,
1227 Events_InfoMessage& theError) const
1229 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1231 theError = "Error: The attribute with the %1 type is not processed";
1232 theError.arg(theAttribute->attributeType());
1237 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1239 ObjectPtr aRefObject = aRefAttribute->value();
1240 if (!aRefObject.get()) {
1241 theError = "Error: Empty feature.";
1245 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1246 if (!aRefFeature.get()) {
1247 theError = "Error: Empty feature.";
1250 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1251 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1253 size_t aConcealedResults = aResults.size();
1254 if (!aConcealedResults && !theArguments.empty()) {
1255 // find if these results are touched by the feature in another attribute
1256 std::list<std::string>::const_iterator anIt = theArguments.begin();
1257 std::string aRecoveredList = *anIt;
1258 if (!aRecoveredList.empty()) {
1259 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1260 theAttribute->owner()->data()->reflist(aRecoveredList);
1261 if (aParameterList.get())
1262 aConcealedResults = aParameterList->size();
1266 if (aConcealedResults == 0)
1267 theError = "Error: No concealed results.";
1269 return theError.empty();
1272 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1273 const std::list<std::string>& theArguments,
1274 Events_InfoMessage& theError) const
1276 static std::list<std::string> aEdgeArg(1, "circle");
1277 static std::list<std::string> aFaceArg(1, "cylinder");
1279 Events_InfoMessage aError;
1280 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1282 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1284 theError = "The shape neither circle nor cylinder";
1289 //=================================================================================================
1290 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1291 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1292 const std::list<std::string>& theArguments,
1293 Events_InfoMessage& theError) const
1296 if (theArguments.size() != 2)
1298 theError = "Wrong number of arguments (expected 2).";
1303 int anObjectsToolsNb[2] = { 0, 0 };
1305 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1307 bool isAllInSameCompSolid = true;
1308 ResultBodyPtr aCompSolid;
1310 for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
1311 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1314 *anArgNbIt = anAttrSelList->size();
1315 if (isAllInSameCompSolid) {
1316 for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
1318 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1319 ResultPtr aContext = anAttr->context();
1320 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1321 if (aResCompSolidPtr.get())
1323 if (aCompSolid.get())
1325 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1329 aCompSolid = aResCompSolidPtr;
1334 isAllInSameCompSolid = false;
1342 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1343 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1344 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1346 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1349 if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
1351 theError = "Not enough arguments for Fuse operation.";
1354 else if (isAllInSameCompSolid)
1356 theError = "Operations only between sub-shapes of the same shape not allowed.";
1362 if (anObjectsToolsNb[0] < 1) // check number of objects
1364 theError = "Objects not selected.";
1367 if (anObjectsToolsNb[1] < 1) // check number of tools
1369 theError = "Tools not selected.";
1372 if (isAllInSameCompSolid)
1374 theError = "Operations only between sub-shapes of the same shape not allowed.";
1382 //=================================================================================================
1384 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1385 std::string theAttribute)
1387 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1396 //==================================================================================================
1397 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1398 const AttributePtr& theAttribute,
1399 const std::list<std::string>& theArguments,
1400 Events_InfoMessage& theError) const
1402 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1403 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1405 AttributeSelectionListPtr anAttrSelectionList =
1406 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1407 if (!aFeature.get() || !anAttrSelectionList.get()) {
1410 "Error: Validator used in wrong feature or attribute";
1415 AttributeSelectionListPtr anOtherAttrSelectionList;
1416 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1417 anOtherAttrSelectionList =
1418 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1420 anOtherAttrSelectionList =
1421 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1424 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1425 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1426 GeomPlanePtr aFacesPln;
1428 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1429 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1431 if (anAttrSelection->contextFeature().get()) {
1432 theError = "Error: Features not allowed for selection.";
1436 ResultPtr aContext = anAttrSelection->context();
1437 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1438 if (!aShape.get()) {
1439 if (!aContext.get()) {
1440 theError = "Error: Empty selection.";
1443 aShape = aContext->shape();
1446 if (aShape->isSolid() || aShape->isCompSolid()) {
1447 aSelectedShapesType = GeomAPI_Shape::SOLID;
1448 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1449 if (aResCompSolidPtr.get()) {
1450 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1451 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1454 aSelectedShapesType = GeomAPI_Shape::FACE;
1455 GeomAPI_Face aFace(aShape);
1456 aFacesPln = aFace.getPlane();
1461 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1462 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1463 if (!anAttrSelection.get()) {
1464 theError = "Error: Empty attribute selection.";
1468 if (anAttrSelection->contextFeature().get()) {
1469 theError = "Error: Features not allowed for selection.";
1473 ResultPtr aContext = anAttrSelection->context();
1474 if(!aContext.get()) {
1475 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1476 if (!aContFeat.get() || !aContFeat->results().size() ||
1477 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1478 theError = "Error: Empty selection context.";
1482 ResultConstructionPtr aResultConstruction =
1483 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1484 if (aResultConstruction.get()) {
1485 theError = "Error: Result construction not allowed for selection.";
1488 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1489 GeomShapePtr aContextShape = aContext->shape();
1490 if (!aShape.get()) {
1491 aShape = aContextShape;
1493 if (!aShape.get()) {
1494 theError = "Error: Empty shape.";
1497 if (!aShape->isEqual(aContextShape)) {
1498 theError = "Error: Local selection not allowed.";
1502 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1503 // Other list is empty.
1504 if (aShape->isSolid() || aShape->isCompSolid()) {
1505 aSelectedShapesType = GeomAPI_Shape::SOLID;
1507 aSelectedShapesType = GeomAPI_Shape::FACE;
1508 GeomAPI_Face aFace(aShape);
1509 aFacesPln = aFace.getPlane();
1511 if (!aFacesPln.get()) {
1512 theError = "Error: Only planar faces allowed.";
1518 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1519 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1520 theError = "Error: Selected shapes should have the same type.";
1524 GeomAPI_Face aFace(aShape);
1525 GeomPlanePtr aPln = aFace.getPlane();
1528 theError = "Error: Only planar faces allowed.";
1532 if (!aFacesPln->isCoincident(aPln)) {
1533 theError = "Error: Only coincident faces allowed.";
1542 //==================================================================================================
1544 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1545 const std::list<std::string>& theArguments,
1546 Events_InfoMessage& theError) const
1548 if (!theAttribute.get()) {
1549 theError = "Error: empty selection.";
1552 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1553 AttributeSelectionListPtr anAttrSelectionList =
1554 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1555 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1556 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1557 if (!anAttrSelection.get()) {
1558 theError = "Error: empty attribute selection.";
1561 ResultPtr aContext = anAttrSelection->context();
1562 if(!aContext.get()) {
1563 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1564 if (!aContFeat.get() || !aContFeat->results().size() ||
1565 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1566 theError = "Error: Empty selection context.";
1570 FeaturePtr aFeature = anAttrSelection->contextFeature().get() ?
1571 anAttrSelection->contextFeature() : ModelAPI_Feature::feature(aContext);
1572 if (!aFeature.get()) {
1573 theError = "Error: empty feature.";
1576 std::string aFeatureKind = aFeature->getKind();
1577 if (aFeatureKind == "Sketch" ||
1578 aFeatureKind == "Plane" ||
1579 aFeatureKind == "Axis") {
1580 theError = "Error: %1 shape is not allowed for selection.";
1581 theError.arg(aFeatureKind);
1584 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1585 if (!aShape.get()) {
1586 GeomShapePtr aContextShape = aContext->shape();
1587 aShape = aContextShape;
1589 if (!aShape.get()) {
1590 theError = "Error: empty shape.";
1593 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1594 theError = "Error: Local selection not allowed.";
1598 int aShapeType = aShape->shapeType();
1599 // Allow to select edges, faces and solids.
1600 if (aShapeType != GeomAPI_Shape::EDGE &&
1601 aShapeType != GeomAPI_Shape::FACE &&
1602 aShapeType != GeomAPI_Shape::SOLID &&
1603 aShapeType != GeomAPI_Shape::COMPSOLID &&
1604 aShapeType != GeomAPI_Shape::COMPOUND) {
1605 theError = "Error: selected shape has the wrong type.";
1614 //==================================================================================================
1616 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1617 const AttributePtr& theAttribute,
1618 const std::list<std::string>& theArguments,
1619 Events_InfoMessage& theError) const
1621 AttributeSelectionListPtr anAttrSelectionList =
1622 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1623 if (!anAttrSelectionList.get()) {
1625 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1629 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1630 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1631 if (!anAttrSelection.get()) {
1632 theError = "Error: Empty attribute selection.";
1635 ResultPtr aContext = anAttrSelection->context();
1636 if(!aContext.get()) {
1637 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1638 if (!aContFeat.get() || !aContFeat->results().size() ||
1639 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1640 theError = "Error: Empty selection context.";
1644 ResultConstructionPtr aResultConstruction =
1645 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1646 if (aResultConstruction.get()) {
1647 theError = "Error: Result construction not allowed for selection.";
1650 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1651 if (!aShape.get()) {
1652 GeomShapePtr aContextShape = aContext->shape();
1653 aShape = aContextShape;
1655 if (!aShape.get()) {
1656 theError = "Error: Empty shape.";
1659 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1660 theError = "Error: Local selection not allowed.";
1669 //=================================================================================================
1670 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1671 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1672 const std::list<std::string>& theArguments,
1673 Events_InfoMessage& theError) const
1676 if (theArguments.size() != 2) {
1677 theError = "Wrong number of arguments (expected 2).";
1682 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1683 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1685 int anObjectsNb = 0, aToolsNb = 0;
1687 std::list<std::string>::const_iterator anIt = theArguments.begin();
1689 bool isAllInSameCompSolid = true;
1690 ResultBodyPtr aCompSolid;
1692 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1693 if (anAttrSelList) {
1694 anObjectsNb = anAttrSelList->size();
1695 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1696 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1697 ResultPtr aContext = anAttr->context();
1698 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1699 if (aResCompSolidPtr.get()) {
1700 if (aCompSolid.get()) {
1701 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1703 aCompSolid = aResCompSolidPtr;
1706 isAllInSameCompSolid = false;
1713 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1714 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1715 anAttrSelList = theFeature->selectionList(*anIt);
1716 if (anAttrSelList) {
1717 aToolsNb = anAttrSelList->size();
1718 if (isAllInSameCompSolid) {
1719 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1720 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1721 ResultPtr aContext = anAttr->context();
1722 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1723 if (aResCompSolidPtr.get()) {
1724 if (aCompSolid.get()) {
1725 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1727 aCompSolid = aResCompSolidPtr;
1730 isAllInSameCompSolid = false;
1738 if (anObjectsNb + aToolsNb < 2) {
1739 theError = "Not enough arguments for Fuse operation.";
1746 //=================================================================================================
1748 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1749 std::string theFeature,
1750 std::string theAttribute)
1752 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1760 //==================================================================================================
1762 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1763 const AttributePtr& theAttribute,
1764 const std::list<std::string>& theArguments,
1765 Events_InfoMessage& theError) const
1767 AttributeSelectionListPtr anAttrSelectionList =
1768 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1769 if (!anAttrSelectionList.get()) {
1771 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1775 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1776 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1777 if (!anAttrSelection.get()) {
1778 theError = "Error: Empty attribute selection.";
1781 ResultPtr aContext = anAttrSelection->context();
1782 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1783 theError = "Error: Empty selection context.";
1786 ResultConstructionPtr aResultConstruction =
1787 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1788 if (aResultConstruction.get()) {
1789 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1790 theError = "Error: Result construction not allowed for selection.";
1794 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1795 GeomShapePtr aContextShape;
1796 if (aContext.get()) {
1797 aContextShape = aContext->shape();
1799 if (!aShape.get()) {
1800 aShape = aContextShape;
1802 if (!aShape.get()) {
1803 theError = "Error: Empty shape.";
1806 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1807 theError = "Error: Local selection not allowed.";
1811 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1812 theError = "Error: Result construction should be plane.";
1821 //=================================================================================================
1822 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1823 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1824 const std::list<std::string>& theArguments,
1825 Events_InfoMessage& theError) const
1827 if (theArguments.size() != 2) {
1829 theError = "Wrong number of arguments (expected 2).";
1834 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1835 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1837 int anObjectsNb = 0, aToolsNb = 0;
1839 std::list<std::string>::const_iterator anIt = theArguments.begin();
1841 ResultBodyPtr aCompSolid;
1843 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1844 if (anAttrSelList) {
1845 anObjectsNb = anAttrSelList->size();
1848 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1849 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1851 if (!isSimpleMode) {
1852 anAttrSelList = theFeature->selectionList(*anIt);
1853 if (anAttrSelList) {
1854 aToolsNb = anAttrSelList->size();
1858 if ((isSimpleMode && anObjectsNb < 2)
1859 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1860 theError = "Not enough arguments for Fuse operation.";
1866 //=================================================================================================
1868 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1869 std::string theFeature,
1870 std::string theAttribute)
1876 //==================================================================================================
1877 bool FeaturesPlugin_ValidatorDefeaturingSelection::isValid(
1878 const AttributePtr& theAttribute,
1879 const std::list<std::string>& theArguments,
1880 Events_InfoMessage& theError) const
1882 AttributeSelectionListPtr anAttrSelectionList =
1883 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1884 if (!anAttrSelectionList.get()) {
1886 theError = "Error: This validator can only work with selection list attributes.";
1891 // Check selected entities are sub-shapes of solid or compsolid
1892 GeomShapePtr aBaseSolid;
1893 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1894 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1895 if (!anAttrSelection.get()) {
1896 theError = "Error: Empty attribute selection.";
1899 ResultPtr aContext = anAttrSelection->context();
1900 if (!aContext.get()) {
1901 theError = "Error: Empty selection context.";
1905 GeomShapePtr aContextShape = aContext->shape();
1906 if (aContextShape->shapeType() != GeomAPI_Shape::SOLID) {
1907 theError = "Error: Not all selected shapes are sub-shapes of solids.";