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
66 #pragma warning(disable: 4100)
69 //==================================================================================================
70 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
71 const std::list<std::string>& theArguments,
72 Events_InfoMessage& theError) const
74 AttributeSelectionPtr aPathAttrSelection =
75 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
76 if(!aPathAttrSelection.get()) {
78 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
83 GeomShapePtr aPathShape = aPathAttrSelection->value();
84 ResultPtr aContext = aPathAttrSelection->context();
86 theError = "Error: Empty context.";
89 GeomShapePtr aContextShape = aContext->shape();
90 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
91 !aPathShape->isEqual(aContextShape)) {
92 theError = "Error: Local selection of wires not allowed.";
99 //==================================================================================================
100 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const AttributePtr& theAttribute,
101 const std::list<std::string>& theArguments,
102 Events_InfoMessage& theError) const
104 AttributeSelectionListPtr anAttrSelectionList =
105 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
106 if(!anAttrSelectionList.get()) {
109 "Error: This validator can only work with selection list attributes in \"Pipe\" feature.";
113 std::shared_ptr<FeaturesPlugin_Pipe> aFeature =
114 std::dynamic_pointer_cast<FeaturesPlugin_Pipe>(theAttribute->owner());
116 AttributeSelectionPtr aPathSelection = aFeature->selection(FeaturesPlugin_Pipe::PATH_OBJECT_ID());
117 if (!aPathSelection.get()) {
119 theError = "Error: Path not selected.";
124 GeomShapePtr aPathShape = aPathSelection->value();
125 if (!aPathShape.get()) {
126 ResultPtr aContext = aPathSelection->context();
127 if (!aContext.get()) {
128 FeaturePtr aContFeat = aPathSelection->contextFeature();
129 if (!aContFeat.get() || !aContFeat->results().size()) {
130 theError = "Error: Empty selection context.";
134 aPathShape = aContext->shape();
137 if (!aPathShape.get()) {
138 theError = "Error: Empty path shape.";
142 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
143 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
144 if (!anAttrSelection.get()) {
145 theError = "Error: Empty attribute selection.";
148 ResultPtr aContext = anAttrSelection->context();
149 if (!aContext.get()) {
150 FeaturePtr aContFeat = anAttrSelection->contextFeature();
151 if (!aContFeat.get() || !aContFeat->results().size()) {
152 theError = "Error: Empty selection context.";
156 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
157 if (!aShape.get() && aContext.get()) {
158 GeomShapePtr aContextShape = aContext->shape();
159 aShape = aContextShape;
162 theError = "Error: Empty shape.";
166 if (!aPathShape->isSubShape(aShape)) {
167 theError = "Error: Location should be a vertex subshape from path shape.";
175 //==================================================================================================
177 bool FeaturesPlugin_ValidatorPipeLocationsNumber::isValid(
178 const std::shared_ptr<ModelAPI_Feature>& theFeature,
179 const std::list<std::string>& theArguments,
180 Events_InfoMessage& theError) const
182 static const std::string aCreationMethodID = "creation_method";
183 static const std::string aBaseObjectsID = "base_objects";
184 static const std::string aLocationsID = "locations_objects";
186 if(theFeature->getKind() != "Pipe") {
187 theError = "Error: Feature \"%1\" does not supported by this validator.";
188 theError.arg(theFeature->getKind());
192 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
193 if(!aCreationMethodAttr.get()) {
194 theError = "Error: Could not get \"%1\" attribute.";
195 theError.arg(aCreationMethodID);
199 if(aCreationMethodAttr->value() != "locations") {
203 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
204 if(!aBaseObjectsSelectionList.get()) {
205 theError = "Error: Could not get \"%1\" attribute.";
206 theError.arg(aBaseObjectsID);
210 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
211 if(!aLocationsSelectionList.get()) {
212 theError = "Error: Could not get \"%1\" attribute.";
213 theError.arg(aBaseObjectsID);
217 if(aLocationsSelectionList->size() > 0 &&
218 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
219 theError = "Error: Number of locations should be the same as base objects.";
227 //==================================================================================================
228 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
229 const std::list<std::string>& theArguments,
230 Events_InfoMessage& theError) const
233 if(theArguments.empty()) {
234 theError = "Error: Validator parameters is empty.";
239 // Checking attribute.
240 if(!isValidAttribute(theAttribute, theArguments, theError)) {
241 if(theError.empty()) {
242 theError = "Error: Attribute contains unacceptable shape.";
247 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
248 std::string anAttributeType = theAttribute->attributeType();
249 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
250 AttributeSelectionListPtr aListAttr =
251 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
252 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
253 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
254 ResultPtr aContext = aSelectionAttr->context();
255 if(!aContext.get() && !aSelectionAttr->contextFeature().get()) {
256 theError = "Error: Empty context.";
260 ResultConstructionPtr aResultConstruction =
261 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
262 if(!aResultConstruction.get()) {
263 // It is not a result construction.
264 // If shape is compound check that it contains only faces, edges or vertices.
265 GeomShapePtr aShape = aSelectionAttr->value();
267 if (aContext.get()) {
268 aShape = aContext->shape();
270 theError = "Error: Empty context.";
275 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
276 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
277 GeomShapePtr aSubShape = anIt.current();
278 if (aSubShape->shapeType() > GeomAPI_Shape::VERTEX ||
279 aSubShape->shapeType() < GeomAPI_Shape::FACE) {
280 theError = "Error: Compound should contain only faces, edges or vertices.";
289 GeomShapePtr aShape = aSelectionAttr->value();
290 GeomShapePtr aContextShape = aResultConstruction->shape();
292 // Whole sketch selected.
295 // Object from sketch selected.
296 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
297 GeomShapePtr aWire = anExp.current();
298 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
299 theError = "Error: Wire with wrong orientation selected.";
303 if(aSelectedWiresFromObjects.isBound(aWire)) {
305 "Error: Objects with this wire already selected. Don't allow to select this object.";
309 aSelectedWiresFromObjects.bind(aWire, aWire);
318 //==================================================================================================
319 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
320 const std::shared_ptr<ModelAPI_Feature>& theFeature,
321 const std::list<std::string>& theArguments,
322 Events_InfoMessage& theError) const
324 const std::string aBaseObjectsID = theArguments.front();
326 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
327 if(!aListAttr.get()) {
329 theError = "Error: Could not get \"%1\" attribute.";
330 theError.arg(aBaseObjectsID);
335 std::set<ResultConstructionPtr> aSelectedSketches;
336 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
338 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
339 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
340 ResultPtr aContext = aSelectionAttr->context();
341 if(!aContext.get()) {
342 FeaturePtr aFeature = aSelectionAttr->contextFeature();
343 if (!aFeature.get() || aFeature->results().empty()) {
344 theError = "Error: Empty context.";
347 aContext = aFeature->firstResult();
351 ResultConstructionPtr aResultConstruction =
352 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
353 if(!aResultConstruction.get()) {
354 // It is not a result construction.
358 GeomShapePtr aShape = aSelectionAttr->value();
359 GeomShapePtr aContextShape = aResultConstruction->shape();
361 // Whole sketch selected.
362 aSelectedSketches.insert(aResultConstruction);
364 // Object from sketch selected.
365 aSelectedSketchesFromObjects.insert(aResultConstruction);
370 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
371 anIt != aSelectedSketches.cend();
373 ResultConstructionPtr aResultConstruction = *anIt;
374 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
375 aSelectedSketchesFromObjects.cend()) {
376 theError = "Sketch and objects from it can not be selected at the same time.";
384 //==================================================================================================
385 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
386 const std::list<std::string>& theArguments,
387 Events_InfoMessage& theError) const
389 if(!theAttribute.get()) {
391 theError = "Error: Empty attribute.";
396 std::string anAttributeType = theAttribute->attributeType();
397 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
398 AttributeSelectionListPtr aListAttr =
399 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
400 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
401 // If at least one attribute is invalid, the result is false.
402 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
406 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
408 AttributeSelectionPtr anAttr =
409 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
410 ResultPtr aContext = anAttr->context();
411 if(!aContext.get() && !anAttr->contextFeature().get()) {
412 theError = "Error: Attribute have empty context.";
416 GeomShapePtr aShape = anAttr->value();
417 GeomShapePtr aContextShape;
418 if(!aShape.get() && aContext.get()) {
419 aContextShape = aContext->shape();
420 aShape = aContextShape;
423 theError = "Error: Empty shape selected";
427 ResultConstructionPtr aConstruction;
428 if (!aContext.get() && anAttr->contextFeature()->results().size() == 1) {
429 aContext = anAttr->contextFeature()->firstResult();
432 aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
433 if(aConstruction.get()) {
434 // Construction selected. Check that it is not infinite.
435 if(aConstruction->isInfinite()) {
436 theError = "Error: Infinite constructions is not allowed as base.";
440 aContextShape = aContext->shape();
441 if(aShape->isEqual(aContextShape)) {
442 // Whole construction selected. Check that it have faces.
443 if(aConstruction->facesNum() > 0) {
447 // Shape on construction selected. Check that it is a face or wire.
448 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
449 aShape->shapeType() == GeomAPI_Shape::FACE) {
456 if(aContextShape.get() && !aShape->isEqual(aContextShape)) {
457 // Local selection on body does not allowed.
459 "Error: Selected shape is in the local selection. Only global selection is allowed.";
463 // Check that object is a shape with allowed type.
464 GeomValidators_ShapeType aShapeTypeValidator;
465 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
466 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
467 "wires on sketch, whole sketch (if it has at least one face), "
468 "and whole objects with shape types: %1";
469 std::string anArgumentString;
470 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
471 if (!anArgumentString.empty())
472 anArgumentString += ", ";
473 anArgumentString += *anIt;
475 theError.arg(anArgumentString);
481 theError = "Error: Attribute \"%1\" does not supported by this validator.";
482 theError.arg(anAttributeType);
490 //==================================================================================================
492 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
493 const std::list<std::string>& theArguments,
494 Events_InfoMessage& theError) const
496 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
497 theError = "Error: The attribute with the %1 type is not processed";
498 theError.arg(theAttribute->attributeType());
501 if (theArguments.size() != 2) {
502 theError = "Error: Wrong parameters in XML definition for %1 type";
503 theError.arg(theAttribute->attributeType());
506 // first argument is for the base attribute, second - for skipping feature kind
507 std::list<std::string>::const_iterator anIt = theArguments.begin();
508 std::string aBaseAttributeId = *anIt;
509 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
510 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
511 if (!aBaseAttribute.get()) {
512 theError = "Wrong parameters in XML definition for %1 type";
513 theError.arg(theAttribute->attributeType());
516 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
517 // this validator is not necessary anymore
521 std::string aFeatureAttributeKind = *anIt;
522 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
523 // check whether the selection is on the sketch
524 std::list<std::string> anArguments;
525 anArguments.push_back(aFeatureAttributeKind);
527 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
528 bool aPlanarFace = false;
529 // check if selection has Face selected
530 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
532 anArguments.push_back("face");
533 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
535 bool aValid = !aFeatureKind && aPlanarFace;
540 //==================================================================================================
541 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
542 const std::shared_ptr<ModelAPI_Feature>& theFeature,
543 const std::list<std::string>& theArguments,
544 Events_InfoMessage& theError) const
546 if(theArguments.size() != 2) {
548 theError = "Error: Validator should be used with 2 parameters for extrusion.";
553 std::list<std::string>::const_iterator anArgsIt = theArguments.begin();
555 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
558 GeomShapePtr aDirShape;
559 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
561 aDirShape = aSelAttr->value();
562 if(!aDirShape.get()) {
563 ResultPtr aContext = aSelAttr->context();
564 if(!aContext.get()) {
565 FeaturePtr aFeature = aSelAttr->contextFeature();
566 if (aFeature.get() && !aFeature->results().empty()) {
567 aContext = aFeature->firstResult();
572 aDirShape = aContext->shape();
575 if (aDirShape.get() && aDirShape->isCompound()) {
576 GeomAPI_ShapeIterator anIt(aDirShape);
577 aDirShape = anIt.current();
582 if(!aDirShape.get() || aDirShape->isNull() ||
583 aDirShape->shapeType() != GeomAPI_Shape::EDGE) {
584 // Check that dir can be empty.
585 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
586 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
587 "can not be used with default value. Select direction for extrusion.";
588 theError.arg(*anArgsIt);
595 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
597 // If faces selected check that direction not parallel with them.
598 AttributeSelectionListPtr aListAttr =
599 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
600 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
601 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
602 GeomShapePtr aShapeInList = anAttr->value();
603 if(!aShapeInList.get()) {
604 aShapeInList = anAttr->context()->shape();
606 bool isParallel = true;
607 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
608 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
609 for(GeomAPI_ShapeExplorer
610 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
611 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
612 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
617 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
618 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
619 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
620 if(aPlanarEdges.get()) {
621 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
622 if(aDirEdge->isLine()) {
623 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
624 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
636 "Error: Direction is parallel to one of the selected face or face on selected shell.";
644 //==================================================================================================
645 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
646 Events_InfoMessage& theError) const
649 if(!theAttribute.get()) {
654 std::string anAttributeType = theAttribute->attributeType();
655 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
656 AttributeSelectionListPtr aListAttr =
657 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
658 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
659 // If at least one attribute is invalid, the result is false.
660 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
664 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
666 AttributeSelectionPtr anAttr =
667 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
668 ResultPtr aContext = anAttr->context();
669 if(!aContext.get() && !anAttr->contextFeature().get()) {
673 GeomShapePtr aShape = anAttr->value();
674 if(!aShape.get() && aContext.get()) {
675 GeomShapePtr aContextShape = aContext->shape();
676 aShape = aContextShape;
682 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
683 aShape->shapeType() == GeomAPI_Shape::EDGE ||
684 !aShape->isPlanar()) {
694 //==================================================================================================
695 bool FeaturesPlugin_ValidatorExtrusionBoundaryFace::isValid(
696 const AttributePtr& theAttribute,
697 const std::list<std::string>& theArguments,
698 Events_InfoMessage& theError) const
700 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
702 // Collect all necessary attributes and try to build prism
705 AttributeSelectionListPtr aBaseShapeAttr =
706 aFeature->selectionList(FeaturesPlugin_Extrusion::BASE_OBJECTS_ID());
707 ListOfShape aBaseShapeList;
709 if (!FeaturesPlugin_Tools::getShape(aBaseShapeAttr, true, aBaseShapeList, anError)) {
715 AttributeSelectionPtr aSelection =
716 aFeature->selection(FeaturesPlugin_Extrusion::DIRECTION_OBJECT_ID());
717 GeomShapePtr aShape = aSelection->value();
718 if (!aShape.get() && aSelection->context().get())
719 aShape = aSelection->context()->shape();
723 if (aShape->isEdge())
724 anEdge = aShape->edge();
725 else if (aShape->isCompound()) {
726 GeomAPI_ShapeIterator anIt(aShape);
727 anEdge = anIt.current()->edge();
731 std::shared_ptr<GeomAPI_Dir> aDir;
732 if (anEdge.get() && anEdge->isLine())
733 aDir = anEdge->line()->direction();
736 GeomShapePtr aFromShape, aToShape;
737 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::TO_OBJECT_ID());
738 if (aSelection.get()) {
739 aToShape = aSelection->value();
740 if (!aToShape.get() && aSelection->context().get())
741 aToShape = aSelection->context()->shape();
742 if (aToShape.get() && aToShape->isCompound()) {
743 GeomAPI_ShapeIterator anIt(aToShape);
744 aToShape = anIt.current();
746 if (aToShape.get() && !aToShape->isFace()) {
747 theError = "\"To\" shape is not a face";
751 aSelection = aFeature->selection(FeaturesPlugin_Extrusion::FROM_OBJECT_ID());
752 if (aSelection.get()) {
753 aFromShape = aSelection->value();
754 if (!aFromShape.get() && aSelection->context().get())
755 aFromShape = aSelection->context()->shape();
756 if (aFromShape.get() && aFromShape->isCompound()) {
757 GeomAPI_ShapeIterator anIt(aFromShape);
758 aFromShape = anIt.current();
760 if (aFromShape.get() && !aFromShape->isFace()) {
761 theError = "\"From\" shape is not a face";
766 double aToSize = aFeature->real(FeaturesPlugin_Extrusion::TO_OFFSET_ID())->value();
767 double aFromSize = aFeature->real(FeaturesPlugin_Extrusion::FROM_OFFSET_ID())->value();
770 for (ListOfShape::iterator anIt = aBaseShapeList.begin(); anIt != aBaseShapeList.end(); anIt++) {
771 std::shared_ptr<GeomAPI_Shape> aBaseShape = *anIt;
773 std::shared_ptr<GeomAlgoAPI_Prism> aPrismAlgo(
774 new GeomAlgoAPI_Prism(aBaseShape, aDir, aToShape, aToSize, aFromShape, aFromSize));
775 bool isFailed = GeomAlgoAPI_Tools::AlgoError::isAlgorithmFailed(aPrismAlgo,
776 FeaturesPlugin_Extrusion::ID(),
787 //==================================================================================================
788 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
789 const std::list<std::string>& theArguments,
790 Events_InfoMessage& theError) const
792 AttributeSelectionListPtr anAttrSelectionList =
793 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
794 if(!anAttrSelectionList.get()) {
797 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
801 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
802 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
803 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
805 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
806 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
807 if(!anAttrSelection.get()) {
808 theError = "Error: Empty attribute selection.";
811 ResultPtr aContext = anAttrSelection->context();
812 if(!aContext.get()) {
813 FeaturePtr aContFeat = anAttrSelection->contextFeature();
814 if (!aContFeat.get() || !aContFeat->results().size()) {
815 theError = "Error: Empty selection context.";
819 ResultConstructionPtr aResultConstruction =
820 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
821 if(aResultConstruction.get()) {
822 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
823 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
824 theError = "Error: Result construction not allowed for selection.";
828 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
829 if(!aShape.get() && aContext.get()) {
830 GeomShapePtr aContextShape = aContext->shape();
831 aShape = aContextShape;
834 theError = "Error: Empty shape.";
837 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
838 theError = "Error: Local selection not allowed.";
842 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
843 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
844 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
845 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
846 anAllowedTypes.insert(GeomAPI_Shape::FACE);
847 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
848 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
849 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
850 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
851 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
853 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
854 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
855 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
856 anAllowedTypes.insert(GeomAPI_Shape::FACE);
857 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
858 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
859 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
860 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
862 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
863 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
864 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
867 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
868 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
869 theError = "Error: Selected shape has the wrong type.";
878 //==================================================================================================
879 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
880 const std::list<std::string>& theArguments,
881 Events_InfoMessage& theError) const
883 AttributeSelectionListPtr anAttrSelectionList =
884 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
885 if(!anAttrSelectionList.get()) {
888 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
893 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
894 // Check all selected entities are sub-shapes of single solid
895 GeomShapePtr aBaseSolid;
896 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
897 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
898 if(!anAttrSelection.get()) {
899 theError = "Error: Empty attribute selection.";
902 ResultPtr aContext = anAttrSelection->context();
903 if(!aContext.get()) {
904 FeaturePtr aContFeat = anAttrSelection->contextFeature();
905 if (!aContFeat.get() || !aContFeat->results().size() ||
906 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
907 theError = "Error: Empty selection context.";
910 if (aContFeat->results().size() == 1)
911 aContext = aContFeat->firstResult();
913 theError = "Error: Too many shapes selected.";
918 ResultBodyPtr aContextOwner = ModelAPI_Tools::bodyOwner(aContext, true);
919 GeomShapePtr anOwner = aContext->shape();
920 GeomShapePtr aTopLevelOwner = aContextOwner.get() ? aContextOwner->shape() : anOwner;
923 theError = "Error: wrong feature is selected.";
927 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
928 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
929 theError = "Error: Not all selected shapes are sub-shapes of solids.";
934 aBaseSolid = aTopLevelOwner;
935 else if (!aBaseSolid->isEqual(aTopLevelOwner)) {
936 theError = "Error: Sub-shapes of different solids have been selected.";
944 //==================================================================================================
945 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
946 const std::list<std::string>& theArguments,
947 Events_InfoMessage& theError) const
949 AttributeSelectionListPtr anAttrSelectionList =
950 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
951 if(!anAttrSelectionList.get()) {
953 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
958 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
959 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
961 //GeomValidators_BodyShapes aBodyValidator;
962 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
966 GeomValidators_FeatureKind aFeatureKindValidator;
967 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
971 ResultPtr aContext = aSelectAttr->context();
972 ResultConstructionPtr aResultConstruction =
973 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
974 if(aResultConstruction.get()) {
975 theError = "Error: Only body shapes and construction planes are allowed for selection.";
979 ResultBodyPtr aResultBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
980 if(aResultBody.get()) {
983 FeaturePtr aResultFeature = aSelectAttr->contextFeature();
984 if(aResultFeature.get()) {
986 std::list<ResultPtr>::const_iterator aFRes = aResultFeature->results().cbegin();
987 for(; aFRes != aResultFeature->results().cend() && !aOkRes; aFRes++) {
988 ResultBodyPtr aBody = std::dynamic_pointer_cast<ModelAPI_ResultBody>(*aFRes);
989 if (aBody.get() && !aBody->isDisabled())
996 theError = "Error: Only body shapes and construction planes are allowed for selection.";
1004 //==================================================================================================
1005 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
1006 const std::list<std::string>& theArguments,
1007 Events_InfoMessage& theError) const
1009 AttributeSelectionListPtr aSubShapesAttrList =
1010 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1011 if(!aSubShapesAttrList.get()) {
1014 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
1019 static const std::string aBaseShapeID = "base_shape";
1020 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1021 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
1023 if(!aShapeAttrSelection.get()) {
1025 theError = "Error: Could not get \"%1\" attribute.";
1026 theError.arg(aBaseShapeID);
1031 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1032 ResultPtr aContext = aShapeAttrSelection->context();
1033 if(!aContext.get()) {
1034 theError = "Error: Empty context.";
1037 if(!aBaseShape.get()) {
1038 aBaseShape = aContext->shape();
1040 if(!aBaseShape.get()) {
1041 theError = "Error: Empty base shape.";
1045 std::list<GeomShapePtr> aSubShapes = GeomAlgoAPI_ShapeTools::getLowLevelSubShapes(aBaseShape);
1046 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1047 bool isSameFound = false;
1048 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1049 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1050 for (ListOfShape::const_iterator anIt = aSubShapes.cbegin(); anIt != aSubShapes.cend(); ++anIt)
1052 if ((*anIt)->isEqual(aShapeToAdd)) {
1058 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
1066 //==================================================================================================
1067 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
1068 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1069 const std::list<std::string>& theArguments,
1070 Events_InfoMessage& theError) const
1072 static const std::string aBaseShapeID = "base_shape";
1073 static const std::string aSubShapesID = "subshapes_to_keep";
1076 if(theFeature->getKind() != "Remove_SubShapes") {
1077 theError = "Error: Feature \"%1\" does not supported by this validator.";
1078 theError.arg(theFeature->getKind());
1082 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
1083 if(!aShapeAttrSelection.get()) {
1084 theError = "Error: Could not get \"%1\" attribute.";
1085 theError.arg(aBaseShapeID);
1089 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
1090 if(!aSubShapesAttrList.get()) {
1091 theError = "Error: Could not get \"%1\" attribute.";
1092 theError.arg(aSubShapesID);
1098 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
1099 if(!aBaseShape.get()) {
1100 theError = "Error: Base shape is empty.";
1103 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
1105 if (aSubShapesAttrList->size() == 0) {
1106 theError = "Error: Resulting shape is not valid.";
1110 // Copy sub-shapes from list to new shape.
1111 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
1112 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
1113 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
1114 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
1118 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
1119 theError = "Error: Resulting shape is not valid.";
1126 //==================================================================================================
1128 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
1129 const std::list<std::string>& theArguments,
1130 Events_InfoMessage& theError) const
1132 AttributeSelectionListPtr aBaseObjectsAttrList =
1133 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1134 if(!aBaseObjectsAttrList.get()) {
1135 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
1136 theError.arg(FeaturesPlugin_Union::ID());
1140 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
1141 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
1142 ResultPtr aContext = anAttrSelectionInList->context();
1143 if (!aContext.get()) {
1144 theError = "Error: selection is invalid.";
1148 ResultConstructionPtr aConstruction =
1149 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1150 if(aConstruction.get()) {
1151 theError = "Error: Result construction not allowed for selection.";
1155 GeomShapePtr aShape = anAttrSelectionInList->value();
1156 GeomShapePtr aContextShape = aContext->shape();
1157 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
1158 theError = "Error: Local selection not allowed.";
1162 ResultBodyPtr aResult =
1163 std::dynamic_pointer_cast<ModelAPI_ResultBody>(aContext);
1164 if(!aResult.get()) {
1168 if(aResult->numberOfSubs() > 0) {
1169 theError = "Error: Whole compsolids not allowed for selection.";
1178 //==================================================================================================
1179 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
1180 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1181 const std::list<std::string>& theArguments,
1182 Events_InfoMessage& theError) const
1185 // Check feature kind.
1186 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
1187 theError = "Error: This validator supports only \"%1\" feature.";
1188 theError.arg(FeaturesPlugin_Union::ID());
1192 // Get base objects attribute list.
1193 AttributeSelectionListPtr aBaseObejctsAttrList =
1194 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1195 if(!aBaseObejctsAttrList.get()) {
1196 theError = "Error: Could not get \"%1\" attribute.";
1197 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
1203 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
1204 ListOfShape aBaseShapesList;
1205 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
1206 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
1207 GeomShapePtr aShape = anAttrSelectionInList->value();
1208 if (!aShape.get()) {
1211 aBaseShapesList.push_back(aShape);
1212 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
1213 GeomAPI_Shape::COMPSOLID;
1216 // Make compound and find connected.
1217 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
1218 ListOfShape aResults;
1219 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, aType, aResults);
1221 if(aResults.size() > 1 || (aResults.size() == 1 && aResults.front()->shapeType() > aType)) {
1222 theError = "Error: Not all shapes have shared topology.";
1229 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
1230 const std::list<std::string>& theArguments,
1231 Events_InfoMessage& theError) const
1233 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
1235 theError = "Error: The attribute with the %1 type is not processed";
1236 theError.arg(theAttribute->attributeType());
1241 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1243 ObjectPtr aRefObject = aRefAttribute->value();
1244 if (!aRefObject.get()) {
1245 theError = "Error: Empty feature.";
1249 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1250 if (!aRefFeature.get()) {
1251 theError = "Error: Empty feature.";
1254 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1255 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1257 size_t aConcealedResults = aResults.size();
1258 if (!aConcealedResults && !theArguments.empty()) {
1259 // find if these results are touched by the feature in another attribute
1260 std::list<std::string>::const_iterator anIt = theArguments.begin();
1261 std::string aRecoveredList = *anIt;
1262 if (!aRecoveredList.empty()) {
1263 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1264 theAttribute->owner()->data()->reflist(aRecoveredList);
1265 if (aParameterList.get())
1266 aConcealedResults = aParameterList->size();
1270 if (aConcealedResults == 0)
1271 theError = "Error: No concealed results.";
1273 return theError.empty();
1276 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1277 const std::list<std::string>& theArguments,
1278 Events_InfoMessage& theError) const
1280 static std::list<std::string> aEdgeArg(1, "circle");
1281 static std::list<std::string> aFaceArg(1, "cylinder");
1283 Events_InfoMessage aError;
1284 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1286 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1288 theError = "The shape neither circle nor cylinder";
1293 //=================================================================================================
1294 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1295 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1296 const std::list<std::string>& theArguments,
1297 Events_InfoMessage& theError) const
1300 if (theArguments.size() != 2)
1302 theError = "Wrong number of arguments (expected 2).";
1307 int anObjectsToolsNb[2] = { 0, 0 };
1309 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1311 bool isAllInSameCompSolid = true;
1312 ResultBodyPtr aCompSolid;
1314 for (int* anArgNbIt = anObjectsToolsNb; anIt != aLast; ++anIt, ++anArgNbIt) {
1315 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1318 *anArgNbIt = anAttrSelList->size();
1319 if (isAllInSameCompSolid) {
1320 for (int anIndex = 0; anIndex < *anArgNbIt; ++anIndex)
1322 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1323 ResultPtr aContext = anAttr->context();
1324 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1325 if (aResCompSolidPtr.get())
1327 if (aCompSolid.get())
1329 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1333 aCompSolid = aResCompSolidPtr;
1338 isAllInSameCompSolid = false;
1346 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1347 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1348 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1350 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1353 if (anObjectsToolsNb[0] + anObjectsToolsNb[1] < 2)
1355 theError = "Not enough arguments for Fuse operation.";
1358 else if (isAllInSameCompSolid)
1360 theError = "Operations only between sub-shapes of the same shape not allowed.";
1366 if (anObjectsToolsNb[0] < 1) // check number of objects
1368 theError = "Objects not selected.";
1371 if (anObjectsToolsNb[1] < 1) // check number of tools
1373 theError = "Tools not selected.";
1376 if (isAllInSameCompSolid)
1378 theError = "Operations only between sub-shapes of the same shape not allowed.";
1386 //=================================================================================================
1388 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1389 std::string theAttribute)
1391 if (theAttribute == "main_objects" || theAttribute == "tool_objects")
1400 //==================================================================================================
1401 bool FeaturesPlugin_ValidatorBooleanSmashSelection::isValid(
1402 const AttributePtr& theAttribute,
1403 const std::list<std::string>& theArguments,
1404 Events_InfoMessage& theError) const
1406 std::shared_ptr<FeaturesPlugin_BooleanSmash> aFeature =
1407 std::dynamic_pointer_cast<FeaturesPlugin_BooleanSmash>(theAttribute->owner());
1409 AttributeSelectionListPtr anAttrSelectionList =
1410 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1411 if (!aFeature.get() || !anAttrSelectionList.get()) {
1414 "Error: Validator used in wrong feature or attribute";
1419 AttributeSelectionListPtr anOtherAttrSelectionList;
1420 if (theAttribute->id() == FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID()) {
1421 anOtherAttrSelectionList =
1422 aFeature->selectionList(FeaturesPlugin_BooleanSmash::TOOL_LIST_ID());
1424 anOtherAttrSelectionList =
1425 aFeature->selectionList(FeaturesPlugin_BooleanSmash::OBJECT_LIST_ID());
1428 GeomAPI_Shape::ShapeType aSelectedShapesType = GeomAPI_Shape::SHAPE;
1429 GeomAPI_DataMapOfShapeShape aSelectedCompSolidsInOtherList;
1430 GeomPlanePtr aFacesPln;
1432 for (int anIndex = 0; anIndex < anOtherAttrSelectionList->size(); ++anIndex) {
1433 AttributeSelectionPtr anAttrSelection = anOtherAttrSelectionList->value(anIndex);
1435 if (anAttrSelection->contextFeature().get()) {
1436 theError = "Error: Features not allowed for selection.";
1440 ResultPtr aContext = anAttrSelection->context();
1441 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1442 if (!aShape.get()) {
1443 if (!aContext.get()) {
1444 theError = "Error: Empty selection.";
1447 aShape = aContext->shape();
1450 if (aShape->isSolid() || aShape->isCompSolid()) {
1451 aSelectedShapesType = GeomAPI_Shape::SOLID;
1452 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1453 if (aResCompSolidPtr.get()) {
1454 GeomShapePtr aCompSolidShape = aResCompSolidPtr->shape();
1455 aSelectedCompSolidsInOtherList.bind(aCompSolidShape, aCompSolidShape);
1458 aSelectedShapesType = GeomAPI_Shape::FACE;
1459 GeomAPI_Face aFace(aShape);
1460 aFacesPln = aFace.getPlane();
1465 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1466 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1467 if (!anAttrSelection.get()) {
1468 theError = "Error: Empty attribute selection.";
1472 if (anAttrSelection->contextFeature().get()) {
1473 theError = "Error: Features not allowed for selection.";
1477 ResultPtr aContext = anAttrSelection->context();
1478 if(!aContext.get()) {
1479 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1480 if (!aContFeat.get() || !aContFeat->results().size() ||
1481 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1482 theError = "Error: Empty selection context.";
1486 ResultConstructionPtr aResultConstruction =
1487 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1488 if (aResultConstruction.get()) {
1489 theError = "Error: Result construction not allowed for selection.";
1492 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1493 GeomShapePtr aContextShape = aContext->shape();
1494 if (!aShape.get()) {
1495 aShape = aContextShape;
1497 if (!aShape.get()) {
1498 theError = "Error: Empty shape.";
1501 if (!aShape->isEqual(aContextShape)) {
1502 theError = "Error: Local selection not allowed.";
1506 if (aSelectedShapesType == GeomAPI_Shape::SHAPE) {
1507 // Other list is empty.
1508 if (aShape->isSolid() || aShape->isCompSolid()) {
1509 aSelectedShapesType = GeomAPI_Shape::SOLID;
1511 aSelectedShapesType = GeomAPI_Shape::FACE;
1512 GeomAPI_Face aFace(aShape);
1513 aFacesPln = aFace.getPlane();
1515 if (!aFacesPln.get()) {
1516 theError = "Error: Only planar faces allowed.";
1522 } else if (aSelectedShapesType == GeomAPI_Shape::SOLID) {
1523 if (!aShape->isSolid() && !aShape->isCompSolid()) {
1524 theError = "Error: Selected shapes should have the same type.";
1528 GeomAPI_Face aFace(aShape);
1529 GeomPlanePtr aPln = aFace.getPlane();
1532 theError = "Error: Only planar faces allowed.";
1536 if (!aFacesPln->isCoincident(aPln)) {
1537 theError = "Error: Only coincident faces allowed.";
1546 //==================================================================================================
1548 bool FeaturesPlugin_IntersectionSelection::isValid(const AttributePtr& theAttribute,
1549 const std::list<std::string>& theArguments,
1550 Events_InfoMessage& theError) const
1552 if (!theAttribute.get()) {
1553 theError = "Error: empty selection.";
1556 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
1557 AttributeSelectionListPtr anAttrSelectionList =
1558 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1559 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1560 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1561 if (!anAttrSelection.get()) {
1562 theError = "Error: empty attribute selection.";
1565 ResultPtr aContext = anAttrSelection->context();
1566 if (aContext.get()) {
1567 aFeature = ModelAPI_Feature::feature(aContext);
1569 aFeature = anAttrSelection->contextFeature();
1570 if (!aFeature.get() || !aFeature->results().size() ||
1571 aFeature->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1572 theError = "Error: Empty selection context.";
1576 if (!aFeature.get()) {
1577 theError = "Error: empty feature.";
1580 std::string aFeatureKind = aFeature->getKind();
1581 if (aFeatureKind == "Sketch" ||
1582 aFeatureKind == "Plane" ||
1583 aFeatureKind == "Axis") {
1584 theError = "Error: %1 shape is not allowed for selection.";
1585 theError.arg(aFeatureKind);
1588 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1589 if (!aShape.get()) {
1590 GeomShapePtr aContextShape = aContext->shape();
1591 aShape = aContextShape;
1593 if (!aShape.get()) {
1594 theError = "Error: empty shape.";
1597 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1598 theError = "Error: Local selection not allowed.";
1602 int aShapeType = aShape->shapeType();
1603 // Allow to select edges, faces and solids.
1604 if (aShapeType != GeomAPI_Shape::EDGE &&
1605 aShapeType != GeomAPI_Shape::FACE &&
1606 aShapeType != GeomAPI_Shape::SOLID &&
1607 aShapeType != GeomAPI_Shape::COMPSOLID &&
1608 aShapeType != GeomAPI_Shape::COMPOUND) {
1609 theError = "Error: selected shape has the wrong type.";
1618 //==================================================================================================
1620 bool FeaturesPlugin_ValidatorBooleanFuseSelection::isValid(
1621 const AttributePtr& theAttribute,
1622 const std::list<std::string>& theArguments,
1623 Events_InfoMessage& theError) const
1625 AttributeSelectionListPtr anAttrSelectionList =
1626 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1627 if (!anAttrSelectionList.get()) {
1629 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1633 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1634 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1635 if (!anAttrSelection.get()) {
1636 theError = "Error: Empty attribute selection.";
1639 ResultPtr aContext = anAttrSelection->context();
1640 if(!aContext.get()) {
1641 FeaturePtr aContFeat = anAttrSelection->contextFeature();
1642 if (!aContFeat.get() || !aContFeat->results().size() ||
1643 aContFeat->firstResult()->groupName() != ModelAPI_ResultBody::group()) {
1644 theError = "Error: Empty selection context.";
1648 ResultConstructionPtr aResultConstruction =
1649 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1650 if (aResultConstruction.get()) {
1651 theError = "Error: Result construction not allowed for selection.";
1654 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1655 if (!aShape.get()) {
1656 GeomShapePtr aContextShape = aContext->shape();
1657 aShape = aContextShape;
1659 if (!aShape.get()) {
1660 theError = "Error: Empty shape.";
1663 if (aContext.get() && !aShape->isEqual(aContext->shape())) {
1664 theError = "Error: Local selection not allowed.";
1673 //=================================================================================================
1674 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isValid(
1675 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1676 const std::list<std::string>& theArguments,
1677 Events_InfoMessage& theError) const
1680 if (theArguments.size() != 2) {
1681 theError = "Wrong number of arguments (expected 2).";
1686 std::shared_ptr<FeaturesPlugin_BooleanFuse> aFeature =
1687 std::dynamic_pointer_cast<FeaturesPlugin_BooleanFuse>(theFeature);
1689 int anObjectsNb = 0, aToolsNb = 0;
1691 std::list<std::string>::const_iterator anIt = theArguments.begin();
1693 bool isAllInSameCompSolid = true;
1694 ResultBodyPtr aCompSolid;
1696 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1697 if (anAttrSelList) {
1698 anObjectsNb = anAttrSelList->size();
1699 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex) {
1700 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1701 ResultPtr aContext = anAttr->context();
1702 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1703 if (aResCompSolidPtr.get()) {
1704 if (aCompSolid.get()) {
1705 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1707 aCompSolid = aResCompSolidPtr;
1710 isAllInSameCompSolid = false;
1717 if (aFeature->string(FeaturesPlugin_BooleanFuse::CREATION_METHOD())->value()
1718 == FeaturesPlugin_BooleanFuse::CREATION_METHOD_ADVANCED()) {
1719 anAttrSelList = theFeature->selectionList(*anIt);
1720 if (anAttrSelList) {
1721 aToolsNb = anAttrSelList->size();
1722 if (isAllInSameCompSolid) {
1723 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex) {
1724 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1725 ResultPtr aContext = anAttr->context();
1726 ResultBodyPtr aResCompSolidPtr = ModelAPI_Tools::bodyOwner(aContext);
1727 if (aResCompSolidPtr.get()) {
1728 if (aCompSolid.get()) {
1729 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1731 aCompSolid = aResCompSolidPtr;
1734 isAllInSameCompSolid = false;
1742 if (anObjectsNb + aToolsNb < 2) {
1743 theError = "Not enough arguments for Fuse operation.";
1750 //=================================================================================================
1752 bool FeaturesPlugin_ValidatorBooleanFuseArguments::isNotObligatory(
1753 std::string theFeature,
1754 std::string theAttribute)
1756 if (theAttribute == "main_objects" || theAttribute == "tool_objects") {
1764 //==================================================================================================
1766 bool FeaturesPlugin_ValidatorBooleanCommonSelection::isValid(
1767 const AttributePtr& theAttribute,
1768 const std::list<std::string>& theArguments,
1769 Events_InfoMessage& theError) const
1771 AttributeSelectionListPtr anAttrSelectionList =
1772 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1773 if (!anAttrSelectionList.get()) {
1775 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
1779 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1780 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1781 if (!anAttrSelection.get()) {
1782 theError = "Error: Empty attribute selection.";
1785 ResultPtr aContext = anAttrSelection->context();
1786 if (!aContext.get() && !anAttrSelection->contextFeature().get()) {
1787 theError = "Error: Empty selection context.";
1790 ResultConstructionPtr aResultConstruction =
1791 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
1792 if (aResultConstruction.get()) {
1793 if (theAttribute->id() != FeaturesPlugin_BooleanCommon::TOOL_LIST_ID()) {
1794 theError = "Error: Result construction not allowed for selection.";
1798 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
1799 GeomShapePtr aContextShape;
1800 if (aContext.get()) {
1801 aContextShape = aContext->shape();
1803 if (!aShape.get()) {
1804 aShape = aContextShape;
1806 if (!aShape.get()) {
1807 theError = "Error: Empty shape.";
1810 if (aContextShape.get() && !aShape->isEqual(aContextShape)) {
1811 theError = "Error: Local selection not allowed.";
1815 if (aResultConstruction.get() && aShape->shapeType() != GeomAPI_Shape::FACE) {
1816 theError = "Error: Result construction should be plane.";
1825 //=================================================================================================
1826 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isValid(
1827 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1828 const std::list<std::string>& theArguments,
1829 Events_InfoMessage& theError) const
1831 if (theArguments.size() != 2) {
1833 theError = "Wrong number of arguments (expected 2).";
1838 std::shared_ptr<FeaturesPlugin_BooleanCommon> aFeature =
1839 std::dynamic_pointer_cast<FeaturesPlugin_BooleanCommon>(theFeature);
1841 int anObjectsNb = 0, aToolsNb = 0;
1843 std::list<std::string>::const_iterator anIt = theArguments.begin();
1845 ResultBodyPtr aCompSolid;
1847 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1848 if (anAttrSelList) {
1849 anObjectsNb = anAttrSelList->size();
1852 bool isSimpleMode = aFeature->string(FeaturesPlugin_BooleanCommon::CREATION_METHOD())->value()
1853 == FeaturesPlugin_BooleanCommon::CREATION_METHOD_SIMPLE();
1855 if (!isSimpleMode) {
1856 anAttrSelList = theFeature->selectionList(*anIt);
1857 if (anAttrSelList) {
1858 aToolsNb = anAttrSelList->size();
1862 if ((isSimpleMode && anObjectsNb < 2)
1863 || (!isSimpleMode && (anObjectsNb == 0 || aToolsNb == 0))) {
1864 theError = "Not enough arguments for Fuse operation.";
1870 //=================================================================================================
1872 bool FeaturesPlugin_ValidatorBooleanCommonArguments::isNotObligatory(
1873 std::string theFeature,
1874 std::string theAttribute)
1880 //==================================================================================================
1881 bool FeaturesPlugin_ValidatorDefeaturingSelection::isValid(
1882 const AttributePtr& theAttribute,
1883 const std::list<std::string>& theArguments,
1884 Events_InfoMessage& theError) const
1886 AttributeSelectionListPtr anAttrSelectionList =
1887 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
1888 if (!anAttrSelectionList.get()) {
1890 theError = "Error: This validator can only work with selection list attributes.";
1895 // Check selected entities are sub-shapes of solid or compsolid
1896 GeomShapePtr aBaseSolid;
1897 for (int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
1898 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
1899 if (!anAttrSelection.get()) {
1900 theError = "Error: Empty attribute selection.";
1903 ResultPtr aContext = anAttrSelection->context();
1904 if (!aContext.get()) {
1905 theError = "Error: Empty selection context.";
1909 GeomShapePtr aContextShape = aContext->shape();
1910 if (aContextShape->shapeType() != GeomAPI_Shape::SOLID) {
1911 theError = "Error: Not all selected shapes are sub-shapes of solids.";