1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "FeaturesPlugin_Validators.h"
23 #include "FeaturesPlugin_Boolean.h"
24 #include "FeaturesPlugin_Union.h"
26 #include <Events_InfoMessage.h>
28 #include <ModelAPI_Attribute.h>
29 #include <ModelAPI_AttributeInteger.h>
30 #include <ModelAPI_AttributeSelectionList.h>
31 #include <ModelAPI_AttributeString.h>
32 #include <ModelAPI_AttributeReference.h>
33 #include <ModelAPI_AttributeRefList.h>
34 #include <ModelAPI_Feature.h>
35 #include <ModelAPI_ResultCompSolid.h>
36 #include <ModelAPI_ResultConstruction.h>
37 #include <ModelAPI_Tools.h>
39 #include <GeomValidators_BodyShapes.h>
40 #include <GeomValidators_FeatureKind.h>
41 #include <GeomValidators_ShapeType.h>
43 #include <GeomAPI_DataMapOfShapeShape.h>
44 #include <GeomAPI_Lin.h>
45 #include <GeomAPI_PlanarEdges.h>
46 #include <GeomAPI_ShapeExplorer.h>
47 #include <GeomAPI_ShapeIterator.h>
49 #include <GeomAlgoAPI_CompoundBuilder.h>
50 #include <GeomAlgoAPI_ShapeBuilder.h>
51 #include <GeomAlgoAPI_ShapeTools.h>
52 #include <GeomAlgoAPI_WireBuilder.h>
54 #define _USE_MATH_DEFINES
57 //==================================================================================================
58 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
59 const std::list<std::string>& theArguments,
60 Events_InfoMessage& theError) const
62 AttributeSelectionPtr aPathAttrSelection =
63 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
64 if(!aPathAttrSelection.get()) {
65 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
69 GeomShapePtr aPathShape = aPathAttrSelection->value();
70 ResultPtr aContext = aPathAttrSelection->context();
72 theError = "Error: Empty context.";
75 GeomShapePtr aContextShape = aContext->shape();
76 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
77 !aPathShape->isEqual(aContextShape)) {
78 theError = "Error: Local selection of wires not allowed.";
85 //==================================================================================================
86 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
87 const std::shared_ptr<ModelAPI_Feature>& theFeature,
88 const std::list<std::string>& theArguments,
89 Events_InfoMessage& theError) const
91 static const std::string aCreationMethodID = "creation_method";
92 static const std::string aBaseObjectsID = "base_objects";
93 static const std::string aLocationsID = "locations_objects";
95 if(theFeature->getKind() != "Pipe") {
96 theError = "Error: Feature \"%1\" does not supported by this validator.";
97 theError.arg(theFeature->getKind());
101 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
102 if(!aCreationMethodAttr.get()) {
103 theError = "Error: Could not get \"%1\" attribute.";
104 theError.arg(aCreationMethodID);
108 if(aCreationMethodAttr->value() != "locations") {
112 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
113 if(!aBaseObjectsSelectionList.get()) {
114 theError = "Error: Could not get \"%1\" attribute.";
115 theError.arg(aBaseObjectsID);
119 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
120 if(!aLocationsSelectionList.get()) {
121 theError = "Error: Could not get \"%1\" attribute.";
122 theError.arg(aBaseObjectsID);
126 if(aLocationsSelectionList->size() > 0 &&
127 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
128 theError = "Error: Number of locations should be the same as base objects.";
135 //==================================================================================================
136 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature,
137 std::string theAttribute)
142 //==================================================================================================
143 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
144 const std::list<std::string>& theArguments,
145 Events_InfoMessage& theError) const
147 if(theArguments.empty()) {
148 theError = "Error: Validator parameters is empty.";
152 // Checking attribute.
153 if(!isValidAttribute(theAttribute, theArguments, theError)) {
154 if(theError.empty()) {
155 theError = "Error: Attribute contains unacceptable shape.";
160 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
161 std::string anAttributeType = theAttribute->attributeType();
162 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
163 AttributeSelectionListPtr aListAttr =
164 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
165 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
166 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
167 ResultPtr aContext = aSelectionAttr->context();
168 if(!aContext.get()) {
169 theError = "Error: Empty context.";
173 ResultConstructionPtr aResultConstruction =
174 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
175 if(!aResultConstruction.get()) {
176 // It is not a result construction.
177 // If shape is compound check that it contains only faces and edges.
178 GeomShapePtr aShape = aSelectionAttr->value();
180 aShape = aContext->shape();
183 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
184 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
185 GeomShapePtr aSubShape = anIt.current();
186 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
187 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
188 theError = "Error: Compound should contain only faces and edges.";
197 GeomShapePtr aShape = aSelectionAttr->value();
198 GeomShapePtr aContextShape = aResultConstruction->shape();
200 // Whole sketch selected.
203 // Object from sketch selected.
204 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
205 GeomShapePtr aWire = anExp.current();
206 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
207 theError = "Error: Wire with wrong orientation selected.";
211 if(aSelectedWiresFromObjects.isBound(aWire)) {
213 "Error: Objects with such wire already selected. Don't allow to select this object.";
217 aSelectedWiresFromObjects.bind(aWire, aWire);
226 //==================================================================================================
227 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
228 const std::shared_ptr<ModelAPI_Feature>& theFeature,
229 const std::list<std::string>& theArguments,
230 Events_InfoMessage& theError) const
232 const std::string aBaseObjectsID = theArguments.front();
234 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
235 if(!aListAttr.get()) {
236 theError = "Error: Could not get \"%1\" attribute.";
237 theError.arg(aBaseObjectsID);
241 std::set<ResultConstructionPtr> aSelectedSketches;
242 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
244 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
245 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
246 ResultPtr aContext = aSelectionAttr->context();
247 if(!aContext.get()) {
248 theError = "Error: Empty context.";
252 ResultConstructionPtr aResultConstruction =
253 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
254 if(!aResultConstruction.get()) {
255 // It is not a result construction.
259 GeomShapePtr aShape = aSelectionAttr->value();
260 GeomShapePtr aContextShape = aResultConstruction->shape();
262 // Whole sketch selected.
263 aSelectedSketches.insert(aResultConstruction);
265 // Object from sketch selected.
266 aSelectedSketchesFromObjects.insert(aResultConstruction);
271 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
272 anIt != aSelectedSketches.cend();
274 ResultConstructionPtr aResultConstruction = *anIt;
275 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
276 aSelectedSketchesFromObjects.cend()) {
277 theError = "Sketch and objects from it can not be selected at the same time.";
285 //==================================================================================================
286 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isNotObligatory(
287 std::string theFeature,
288 std::string theAttribute)
293 //==================================================================================================
294 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
295 const std::list<std::string>& theArguments,
296 Events_InfoMessage& theError) const
298 if(!theAttribute.get()) {
299 theError = "Error: Empty attribute.";
303 std::string anAttributeType = theAttribute->attributeType();
304 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
305 AttributeSelectionListPtr aListAttr =
306 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
307 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
308 // If at least one attribute is invalid, the result is false.
309 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
313 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
315 AttributeSelectionPtr anAttr =
316 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
317 ResultPtr aContext = anAttr->context();
318 if(!aContext.get()) {
319 theError = "Error: Attribute have empty context.";
323 GeomShapePtr aShape = anAttr->value();
324 GeomShapePtr aContextShape = aContext->shape();
326 aShape = aContextShape;
329 theError = "Error: Empty shape selected";
333 ResultConstructionPtr aConstruction =
334 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
335 if(aConstruction.get()) {
336 // Construciotn selected. Check that is is not infinite.
337 if(aConstruction->isInfinite()) {
338 theError = "Error: Infinite constructions is not allowed as base.";
342 if(aShape->isEqual(aContextShape)) {
343 // Whole construction selected. Check that it have faces.
344 if(aConstruction->facesNum() > 0) {
348 // Shape on construction selected. Check that it is a face or wire.
349 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
350 aShape->shapeType() == GeomAPI_Shape::FACE) {
358 if(!aShape->isEqual(aContextShape)) {
359 // Local selection on body does not allowed.
361 "Error: Selected shape is in the local selection. Only global selection is allowed.";
365 // Check that object is a shape with allowed type.
366 GeomValidators_ShapeType aShapeTypeValidator;
367 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
368 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
369 "wires on sketch, whole sketch(if it has at least one face), "
370 "and whole objects with shape types: %1";
371 std::string anArgumentString;
372 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
373 if (!anArgumentString.empty())
374 anArgumentString += ", ";
375 anArgumentString += *anIt;
377 theError.arg(anArgumentString);
382 theError = "Error: Attribute \"%1\" does not supported by this validator.";
383 theError.arg(anAttributeType);
390 //==================================================================================================
391 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
392 const std::list<std::string>& theArguments,
393 Events_InfoMessage& theError) const
395 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
396 theError = "Error: The attribute with the %1 type is not processed";
397 theError.arg(theAttribute->attributeType());
400 if (theArguments.size() != 2) {
401 theError = "Error: Wrong parameters in XML definition for %1 type";
402 theError.arg(theAttribute->attributeType());
405 // first argument is for the base attribute, second - for skipping feature kind
406 std::list<std::string>::const_iterator anIt = theArguments.begin();
407 std::string aBaseAttributeId = *anIt;
408 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
409 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
410 if (!aBaseAttribute.get()) {
411 theError = "Wrong parameters in XML definition for %1 type";
412 theError.arg(theAttribute->attributeType());
415 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
416 // this validator is not necessary anymore
420 std::string aFeatureAttributeKind = *anIt;
421 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
422 // check whether the selection is on the sketch
423 std::list<std::string> anArguments;
424 anArguments.push_back(aFeatureAttributeKind);
426 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
427 bool aPlanarFace = false;
428 // check if selection has Face selected
429 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
431 anArguments.push_back("face");
432 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
434 bool aValid = !aFeatureKind && aPlanarFace;
438 //==================================================================================================
439 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
440 const std::shared_ptr<ModelAPI_Feature>& theFeature,
441 const std::list<std::string>& theArguments,
442 Events_InfoMessage& theError) const
444 if(theArguments.size() != 2) {
445 theError = "Error: Validator should be used with 2 parameters for extrusion.";
449 std::list<std::string>::const_iterator
450 anArgsIt = theArguments.begin(), aLast = theArguments.end();
452 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
455 GeomShapePtr aDirShape;
456 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
458 aDirShape = aSelAttr->value();
459 if(!aDirShape.get()) {
460 ResultPtr aContext = aSelAttr->context();
462 aDirShape = aContext->shape();
467 if(!aDirShape.get()) {
468 // Check that dir can be empty.
469 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
470 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
471 "can not be used with default value. Select direction for extrusion.";
472 theError.arg(*anArgsIt);
479 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
481 // If faces selected check that direction not parallel with them.
482 AttributeSelectionListPtr aListAttr =
483 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
484 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
485 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
486 GeomShapePtr aShapeInList = anAttr->value();
487 if(!aShapeInList.get()) {
488 aShapeInList = anAttr->context()->shape();
490 bool isParallel = true;
491 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
492 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
493 for(GeomAPI_ShapeExplorer
494 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
495 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
496 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
501 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
502 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
503 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
504 if(aPlanarEdges.get()) {
505 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
506 if(aDirEdge->isLine()) {
507 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
508 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
520 "Error: Direction is parallel to one of the selected face or face on selected shell.";
528 //==================================================================================================
529 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
530 std::string theAttribute)
535 //==================================================================================================
536 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
537 Events_InfoMessage& theError) const
539 if(!theAttribute.get()) {
543 std::string anAttributeType = theAttribute->attributeType();
544 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
545 AttributeSelectionListPtr aListAttr =
546 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
547 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
548 // If at least one attribute is invalid, the result is false.
549 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
553 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
555 AttributeSelectionPtr anAttr =
556 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
557 ResultPtr aContext = anAttr->context();
558 if(!aContext.get()) {
562 GeomShapePtr aShape = anAttr->value();
563 GeomShapePtr aContextShape = aContext->shape();
565 aShape = aContextShape;
571 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
572 aShape->shapeType() == GeomAPI_Shape::EDGE ||
573 !aShape->isPlanar()) {
583 //==================================================================================================
584 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
585 const std::list<std::string>& theArguments,
586 Events_InfoMessage& theError) const
588 AttributeSelectionListPtr anAttrSelectionList =
589 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
590 if(!anAttrSelectionList.get()) {
592 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
595 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
596 int anOperationType = aFeature->integer("bool_type")->value();
598 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
599 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
600 if(!anAttrSelection.get()) {
601 theError = "Error: Empty attribute selection.";
604 ResultPtr aContext = anAttrSelection->context();
605 if(!aContext.get()) {
606 theError = "Error: Empty selection context.";
609 ResultConstructionPtr aResultConstruction =
610 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
611 if(aResultConstruction.get()) {
612 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
613 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
614 theError = "Error: Result construction not allowed for selection.";
618 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
619 GeomShapePtr aContextShape = aContext->shape();
621 aShape = aContextShape;
624 theError = "Error: Empty shape.";
627 if(!aShape->isEqual(aContextShape)) {
628 theError = "Error: Local selection not allowed.";
632 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
633 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
634 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
635 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
636 anAllowedTypes.insert(GeomAPI_Shape::FACE);
637 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
638 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
639 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
640 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL) {
641 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
642 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
643 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
644 anAllowedTypes.insert(GeomAPI_Shape::FACE);
645 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
646 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
647 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
648 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
650 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
651 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
652 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
655 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
656 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
657 theError = "Error: Selected shape has the wrong type.";
666 //==================================================================================================
667 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
668 const std::list<std::string>& theArguments,
669 Events_InfoMessage& theError) const
671 AttributeSelectionListPtr anAttrSelectionList =
672 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
673 if(!anAttrSelectionList.get()) {
675 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
679 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
680 // Check all selected entities are sub-shapes of single solid
681 GeomShapePtr aBaseSolid;
682 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
683 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
684 if(!anAttrSelection.get()) {
685 theError = "Error: Empty attribute selection.";
688 ResultPtr aContext = anAttrSelection->context();
689 if(!aContext.get()) {
690 theError = "Error: Empty selection context.";
694 ResultCompSolidPtr aContextOwner = ModelAPI_Tools::compSolidOwner(aContext);
695 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
697 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
698 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
699 theError = "Error: Not all selected shapes are sub-shapes of solids";
704 aBaseSolid = anOwner;
705 else if (!aBaseSolid->isEqual(anOwner)) {
706 theError = "Error: Sub-shapes of different solids have been selected.";
714 //==================================================================================================
715 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
716 const std::list<std::string>& theArguments,
717 Events_InfoMessage& theError) const
719 AttributeSelectionListPtr anAttrSelectionList =
720 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
721 if(!anAttrSelectionList.get()) {
722 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
726 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
727 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
729 //GeomValidators_BodyShapes aBodyValidator;
730 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
734 GeomValidators_FeatureKind aFeatureKindValidator;
735 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
739 ResultPtr aContext = aSelectAttr->context();
740 ResultConstructionPtr aResultConstruction =
741 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
742 if(aResultConstruction.get()) {
743 theError = "Error: Only body shapes and construction planes are allowed for selection.";
747 ResultCompSolidPtr aResultCompsolid =
748 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
749 if(aResultCompsolid.get()) {
753 theError = "Error: Only body shapes and construction planes are allowed for selection.";
761 //==================================================================================================
762 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
763 const std::list<std::string>& theArguments,
764 Events_InfoMessage& theError) const
766 AttributeSelectionListPtr aSubShapesAttrList =
767 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
768 if(!aSubShapesAttrList.get()) {
770 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
774 static const std::string aBaseShapeID = "base_shape";
775 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
776 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
778 if(!aShapeAttrSelection.get()) {
779 theError = "Error: Could not get \"%1\" attribute.";
780 theError.arg(aBaseShapeID);
784 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
785 ResultPtr aContext = aShapeAttrSelection->context();
786 if(!aContext.get()) {
787 theError = "Error: Empty context.";
790 if(!aBaseShape.get()) {
791 aBaseShape = aContext->shape();
793 if(!aBaseShape.get()) {
794 theError = "Error: Empty base shape.";
798 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
799 bool isSameFound = false;
800 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
801 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
802 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
803 if(anIt.current()->isEqual(aShapeToAdd)) {
809 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
817 //==================================================================================================
818 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
819 const std::shared_ptr<ModelAPI_Feature>& theFeature,
820 const std::list<std::string>& theArguments,
821 Events_InfoMessage& theError) const
823 static const std::string aBaseShapeID = "base_shape";
824 static const std::string aSubShapesID = "subshapes_to_keep";
826 if(theFeature->getKind() != "Remove_SubShapes") {
827 theError = "Error: Feature \"%1\" does not supported by this validator.";
828 theError.arg(theFeature->getKind());
832 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
833 if(!aShapeAttrSelection.get()) {
834 theError = "Error: Could not get \"%1\" attribute.";
835 theError.arg(aBaseShapeID);
839 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
840 if(!aSubShapesAttrList.get()) {
841 theError = "Error: Could not get \"%1\" attribute.";
842 theError.arg(aSubShapesID);
847 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
848 if(!aBaseShape.get()) {
849 theError = "Error: Base shape is empty.";
852 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
854 if (aSubShapesAttrList->size() == 0) {
855 theError = "Error: Resulting shape is not valid.";
859 // Copy sub-shapes from list to new shape.
860 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
861 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
862 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
863 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
867 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
868 theError = "Error: Resulting shape is not valid.";
875 //==================================================================================================
876 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
877 std::string theAttribute)
882 //==================================================================================================
883 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
884 const std::list<std::string>& theArguments,
885 Events_InfoMessage& theError) const
887 AttributeSelectionListPtr aBaseObjectsAttrList =
888 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
889 if(!aBaseObjectsAttrList.get()) {
890 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
891 theError.arg(FeaturesPlugin_Union::ID());
895 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
896 bool isSameFound = false;
897 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
898 ResultPtr aContext = anAttrSelectionInList->context();
899 if (!aContext.get()) {
900 theError = "Error: selection is invalid.";
904 ResultConstructionPtr aConstruction =
905 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
906 if(aConstruction.get()) {
907 theError = "Error: Result construction not allowed for selection.";
911 GeomShapePtr aShape = anAttrSelectionInList->value();
912 GeomShapePtr aContextShape = aContext->shape();
913 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
914 theError = "Error: Local selection not allowed.";
918 ResultCompSolidPtr aResult =
919 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
924 if(aResult->numberOfSubs() > 0) {
925 theError = "Error: Whole compsolids not allowed for selection.";
933 //==================================================================================================
934 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
935 const std::shared_ptr<ModelAPI_Feature>& theFeature,
936 const std::list<std::string>& theArguments,
937 Events_InfoMessage& theError) const
939 // Check feature kind.
940 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
941 theError = "Error: This validator supports only \"%1\" feature.";
942 theError.arg(FeaturesPlugin_Union::ID());
946 // Get base objects attribute list.
947 AttributeSelectionListPtr aBaseObejctsAttrList =
948 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
949 if(!aBaseObejctsAttrList.get()) {
950 theError = "Error: Could not get \"%1\" attribute.";
951 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
956 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
957 ListOfShape aBaseShapesList;
958 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
959 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
960 GeomShapePtr aShape = anAttrSelectionInList->value();
964 aBaseShapesList.push_back(aShape);
965 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
966 GeomAPI_Shape::COMPSOLID;
969 // Make compound and find connected.
970 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
971 ListOfShape aCombined, aFree;
972 GeomAlgoAPI_ShapeTools::combineShapes(
978 if(aFree.size() > 0 || aCombined.size() > 1) {
979 theError = "Error: Not all shapes have shared topology.";
986 //==================================================================================================
987 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
988 std::string theAttribute)
993 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
994 const std::list<std::string>& theArguments,
995 Events_InfoMessage& theError) const
997 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
998 theError = "Error: The attribute with the %1 type is not processed";
999 theError.arg(theAttribute->attributeType());
1003 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
1005 ObjectPtr aRefObject = aRefAttribute->value();
1006 if (!aRefObject.get()) {
1007 theError = "Error: Empty feature.";
1011 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
1012 if (!aRefFeature.get()) {
1013 theError = "Error: Empty feature.";
1016 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
1017 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
1019 size_t aConcealedResults = aResults.size();
1020 if (!aConcealedResults && !theArguments.empty()) {
1021 // find if these results are touched by the feature in another attribute
1022 std::list<std::string>::const_iterator anIt = theArguments.begin();
1023 std::string aRecoveredList = *anIt;
1024 if (!aRecoveredList.empty()) {
1025 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
1026 theAttribute->owner()->data()->reflist(aRecoveredList);
1027 if (aParameterList.get())
1028 aConcealedResults = aParameterList->size();
1032 if (aConcealedResults == 0)
1033 theError = "Error: No concealed results.";
1035 return theError.empty();