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 email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
20 #include "FeaturesPlugin_Validators.h"
22 #include "FeaturesPlugin_Union.h"
24 #include <Events_InfoMessage.h>
26 #include <ModelAPI_Attribute.h>
27 #include <ModelAPI_AttributeInteger.h>
28 #include <ModelAPI_AttributeSelectionList.h>
29 #include <ModelAPI_AttributeString.h>
30 #include <ModelAPI_AttributeReference.h>
31 #include <ModelAPI_AttributeRefList.h>
32 #include <ModelAPI_Feature.h>
33 #include <ModelAPI_ResultCompSolid.h>
34 #include <ModelAPI_ResultConstruction.h>
35 #include <ModelAPI_Tools.h>
37 #include <GeomValidators_BodyShapes.h>
38 #include <GeomValidators_FeatureKind.h>
39 #include <GeomValidators_ShapeType.h>
41 #include <GeomAPI_DataMapOfShapeShape.h>
42 #include <GeomAPI_Lin.h>
43 #include <GeomAPI_PlanarEdges.h>
44 #include <GeomAPI_ShapeExplorer.h>
45 #include <GeomAPI_ShapeIterator.h>
47 #include <GeomAlgoAPI_CompoundBuilder.h>
48 #include <GeomAlgoAPI_ShapeBuilder.h>
49 #include <GeomAlgoAPI_ShapeTools.h>
50 #include <GeomAlgoAPI_WireBuilder.h>
52 #define _USE_MATH_DEFINES
55 //==================================================================================================
56 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
57 const std::list<std::string>& theArguments,
58 Events_InfoMessage& theError) const
60 AttributeSelectionPtr aPathAttrSelection =
61 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
62 if(!aPathAttrSelection.get()) {
63 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
67 GeomShapePtr aPathShape = aPathAttrSelection->value();
68 ResultPtr aContext = aPathAttrSelection->context();
70 theError = "Error: Empty context.";
73 GeomShapePtr aContextShape = aContext->shape();
74 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
75 !aPathShape->isEqual(aContextShape)) {
76 theError = "Error: Local selection of wires not allowed.";
83 //==================================================================================================
84 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
85 const std::shared_ptr<ModelAPI_Feature>& theFeature,
86 const std::list<std::string>& theArguments,
87 Events_InfoMessage& theError) const
89 static const std::string aCreationMethodID = "creation_method";
90 static const std::string aBaseObjectsID = "base_objects";
91 static const std::string aLocationsID = "locations_objects";
93 if(theFeature->getKind() != "Pipe") {
94 theError = "Error: Feature \"%1\" does not supported by this validator.";
95 theError.arg(theFeature->getKind());
99 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
100 if(!aCreationMethodAttr.get()) {
101 theError = "Error: Could not get \"%1\" attribute.";
102 theError.arg(aCreationMethodID);
106 if(aCreationMethodAttr->value() != "locations") {
110 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
111 if(!aBaseObjectsSelectionList.get()) {
112 theError = "Error: Could not get \"%1\" attribute.";
113 theError.arg(aBaseObjectsID);
117 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
118 if(!aLocationsSelectionList.get()) {
119 theError = "Error: Could not get \"%1\" attribute.";
120 theError.arg(aBaseObjectsID);
124 if(aLocationsSelectionList->size() > 0 &&
125 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
126 theError = "Error: Number of locations should be the same as base objects.";
133 //==================================================================================================
134 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature,
135 std::string theAttribute)
140 //==================================================================================================
141 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
142 const std::list<std::string>& theArguments,
143 Events_InfoMessage& theError) const
145 if(theArguments.empty()) {
146 theError = "Error: Validator parameters is empty.";
150 // Checking attribute.
151 if(!isValidAttribute(theAttribute, theArguments, theError)) {
152 if(theError.empty()) {
153 theError = "Error: Attribute contains unacceptable shape.";
158 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
159 std::string anAttributeType = theAttribute->attributeType();
160 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
161 AttributeSelectionListPtr aListAttr =
162 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
163 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
164 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
165 ResultPtr aContext = aSelectionAttr->context();
166 if(!aContext.get()) {
167 theError = "Error: Empty context.";
171 ResultConstructionPtr aResultConstruction =
172 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
173 if(!aResultConstruction.get()) {
174 // It is not a result construction.
175 // If shape is compound check that it contains only faces and edges.
176 GeomShapePtr aShape = aSelectionAttr->value();
178 aShape = aContext->shape();
181 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
182 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
183 GeomShapePtr aSubShape = anIt.current();
184 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
185 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
186 theError = "Error: Compound should contain only faces and edges.";
195 GeomShapePtr aShape = aSelectionAttr->value();
196 GeomShapePtr aContextShape = aResultConstruction->shape();
198 // Whole sketch selected.
201 // Object from sketch selected.
202 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
203 GeomShapePtr aWire = anExp.current();
204 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
205 theError = "Error: Wire with wrong orientation selected.";
209 if(aSelectedWiresFromObjects.isBound(aWire)) {
211 "Error: Objects with such wire already selected. Don't allow to select this object.";
215 aSelectedWiresFromObjects.bind(aWire, aWire);
224 //==================================================================================================
225 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
226 const std::shared_ptr<ModelAPI_Feature>& theFeature,
227 const std::list<std::string>& theArguments,
228 Events_InfoMessage& theError) const
230 const std::string aBaseObjectsID = theArguments.front();
232 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
233 if(!aListAttr.get()) {
234 theError = "Error: Could not get \"%1\" attribute.";
235 theError.arg(aBaseObjectsID);
239 std::set<ResultConstructionPtr> aSelectedSketches;
240 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
242 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
243 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
244 ResultPtr aContext = aSelectionAttr->context();
245 if(!aContext.get()) {
246 theError = "Error: Empty context.";
250 ResultConstructionPtr aResultConstruction =
251 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
252 if(!aResultConstruction.get()) {
253 // It is not a result construction.
257 GeomShapePtr aShape = aSelectionAttr->value();
258 GeomShapePtr aContextShape = aResultConstruction->shape();
260 // Whole sketch selected.
261 aSelectedSketches.insert(aResultConstruction);
263 // Object from sketch selected.
264 aSelectedSketchesFromObjects.insert(aResultConstruction);
269 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
270 anIt != aSelectedSketches.cend();
272 ResultConstructionPtr aResultConstruction = *anIt;
273 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
274 aSelectedSketchesFromObjects.cend()) {
275 theError = "Sketch and objects from it can not be selected at the same time.";
283 //==================================================================================================
284 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isNotObligatory(
285 std::string theFeature,
286 std::string theAttribute)
291 //==================================================================================================
292 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
293 const std::list<std::string>& theArguments,
294 Events_InfoMessage& theError) const
296 if(!theAttribute.get()) {
297 theError = "Error: Empty attribute.";
301 std::string anAttributeType = theAttribute->attributeType();
302 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
303 AttributeSelectionListPtr aListAttr =
304 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
305 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
306 // If at least one attribute is invalid, the result is false.
307 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
311 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
313 AttributeSelectionPtr anAttr =
314 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
315 ResultPtr aContext = anAttr->context();
316 if(!aContext.get()) {
317 theError = "Error: Attribute have empty context.";
321 GeomShapePtr aShape = anAttr->value();
322 GeomShapePtr aContextShape = aContext->shape();
324 aShape = aContextShape;
327 theError = "Error: Empty shape selected";
331 ResultConstructionPtr aConstruction =
332 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
333 if(aConstruction.get()) {
334 // Construciotn selected. Check that is is not infinite.
335 if(aConstruction->isInfinite()) {
336 theError = "Error: Infinite constructions is not allowed as base.";
340 if(aShape->isEqual(aContextShape)) {
341 // Whole construction selected. Check that it have faces.
342 if(aConstruction->facesNum() > 0) {
346 // Shape on construction selected. Check that it is a face or wire.
347 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
348 aShape->shapeType() == GeomAPI_Shape::FACE) {
356 if(!aShape->isEqual(aContextShape)) {
357 // Local selection on body does not allowed.
359 "Error: Selected shape is in the local selection. Only global selection is allowed.";
363 // Check that object is a shape with allowed type.
364 GeomValidators_ShapeType aShapeTypeValidator;
365 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
366 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
367 "wires on sketch, whole sketch(if it has at least one face), "
368 "and whole objects with shape types: %1";
369 std::string anArgumentString;
370 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
371 if (!anArgumentString.empty())
372 anArgumentString += ", ";
373 anArgumentString += *anIt;
375 theError.arg(anArgumentString);
380 theError = "Error: Attribute \"%1\" does not supported by this validator.";
381 theError.arg(anAttributeType);
388 //==================================================================================================
389 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
390 const std::list<std::string>& theArguments,
391 Events_InfoMessage& theError) const
393 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
394 theError = "Error: The attribute with the %1 type is not processed";
395 theError.arg(theAttribute->attributeType());
398 if (theArguments.size() != 2) {
399 theError = "Error: Wrong parameters in XML definition for %1 type";
400 theError.arg(theAttribute->attributeType());
403 // first argument is for the base attribute, second - for skipping feature kind
404 std::list<std::string>::const_iterator anIt = theArguments.begin();
405 std::string aBaseAttributeId = *anIt;
406 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
407 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
408 if (!aBaseAttribute.get()) {
409 theError = "Wrong parameters in XML definition for %1 type";
410 theError.arg(theAttribute->attributeType());
413 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
414 // this validator is not necessary anymore
418 std::string aFeatureAttributeKind = *anIt;
419 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
420 // check whether the selection is on the sketch
421 std::list<std::string> anArguments;
422 anArguments.push_back(aFeatureAttributeKind);
424 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
425 bool aPlanarFace = false;
426 // check if selection has Face selected
427 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
429 anArguments.push_back("face");
430 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
432 bool aValid = !aFeatureKind && aPlanarFace;
436 //==================================================================================================
437 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
438 const std::shared_ptr<ModelAPI_Feature>& theFeature,
439 const std::list<std::string>& theArguments,
440 Events_InfoMessage& theError) const
442 if(theArguments.size() != 2) {
443 theError = "Error: Validator should be used with 2 parameters for extrusion.";
447 std::list<std::string>::const_iterator
448 anArgsIt = theArguments.begin(), aLast = theArguments.end();
450 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
453 GeomShapePtr aDirShape;
454 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
456 aDirShape = aSelAttr->value();
457 if(!aDirShape.get()) {
458 ResultPtr aContext = aSelAttr->context();
460 aDirShape = aContext->shape();
465 if(!aDirShape.get()) {
466 // Check that dir can be empty.
467 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
468 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
469 "can not be used with default value. Select direction for extrusion.";
470 theError.arg(*anArgsIt);
477 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
479 // If faces selected check that direction not parallel with them.
480 AttributeSelectionListPtr aListAttr =
481 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
482 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
483 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
484 GeomShapePtr aShapeInList = anAttr->value();
485 if(!aShapeInList.get()) {
486 aShapeInList = anAttr->context()->shape();
488 bool isParallel = true;
489 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
490 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
491 for(GeomAPI_ShapeExplorer
492 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
493 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
494 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
499 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
500 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
501 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
502 if(aPlanarEdges.get()) {
503 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
504 if(aDirEdge->isLine()) {
505 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
506 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
518 "Error: Direction is parallel to one of the selected face or face on selected shell.";
526 //==================================================================================================
527 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
528 std::string theAttribute)
533 //==================================================================================================
534 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
535 Events_InfoMessage& theError) const
537 if(!theAttribute.get()) {
541 std::string anAttributeType = theAttribute->attributeType();
542 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
543 AttributeSelectionListPtr aListAttr =
544 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
545 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
546 // If at least one attribute is invalid, the result is false.
547 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
551 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
553 AttributeSelectionPtr anAttr =
554 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
555 ResultPtr aContext = anAttr->context();
556 if(!aContext.get()) {
560 GeomShapePtr aShape = anAttr->value();
561 GeomShapePtr aContextShape = aContext->shape();
563 aShape = aContextShape;
569 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
570 aShape->shapeType() == GeomAPI_Shape::EDGE ||
571 !aShape->isPlanar()) {
581 //==================================================================================================
582 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
583 const std::list<std::string>& theArguments,
584 Events_InfoMessage& theError) const
586 AttributeSelectionListPtr anAttrSelectionList =
587 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
588 if(!anAttrSelectionList.get()) {
590 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
593 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
594 int anOperationType = aFeature->integer("bool_type")->value();
596 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
597 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
598 if(!anAttrSelection.get()) {
599 theError = "Error: Empty attribute selection.";
602 ResultPtr aContext = anAttrSelection->context();
603 if(!aContext.get()) {
604 theError = "Error: Empty selection context.";
607 ResultConstructionPtr aResultConstruction =
608 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
609 if(aResultConstruction.get()) {
610 theError = "Error: Result construction not allowed for selection.";
613 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
614 GeomShapePtr aContextShape = aContext->shape();
616 aShape = aContextShape;
619 theError = "Error: Empty shape.";
622 if(!aShape->isEqual(aContextShape)) {
623 theError = "Error: Local selection not allowed.";
627 int aShapeType = aShape->shapeType();
628 if(anOperationType == 1) {
629 // Fuse operation. Allow to select edges, faces and solids.
630 if(aShapeType != GeomAPI_Shape::EDGE &&
631 aShapeType != GeomAPI_Shape::FACE &&
632 aShapeType != GeomAPI_Shape::SOLID &&
633 aShapeType != GeomAPI_Shape::COMPSOLID &&
634 aShapeType != GeomAPI_Shape::COMPOUND) {
635 theError = "Error: Selected shape has the wrong type.";
639 if(aShapeType != GeomAPI_Shape::SOLID &&
640 aShapeType != GeomAPI_Shape::COMPSOLID &&
641 aShapeType != GeomAPI_Shape::COMPOUND) {
642 theError = "Error: Selected shape has the wrong type.";
651 //==================================================================================================
652 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
653 const std::list<std::string>& theArguments,
654 Events_InfoMessage& theError) const
656 AttributeSelectionListPtr anAttrSelectionList =
657 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
658 if(!anAttrSelectionList.get()) {
659 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
663 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
664 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
666 //GeomValidators_BodyShapes aBodyValidator;
667 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
671 GeomValidators_FeatureKind aFeatureKindValidator;
672 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
676 ResultPtr aContext = aSelectAttr->context();
677 ResultConstructionPtr aResultConstruction =
678 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
679 if(aResultConstruction.get()) {
680 theError = "Error: Only body shapes and construction planes are allowed for selection.";
684 ResultCompSolidPtr aResultCompsolid =
685 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
686 if(aResultCompsolid.get()) {
690 theError = "Error: Only body shapes and construction planes are allowed for selection.";
698 //==================================================================================================
699 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
700 const std::list<std::string>& theArguments,
701 Events_InfoMessage& theError) const
703 AttributeSelectionListPtr aSubShapesAttrList =
704 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
705 if(!aSubShapesAttrList.get()) {
707 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
711 static const std::string aBaseShapeID = "base_shape";
712 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
713 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
715 if(!aShapeAttrSelection.get()) {
716 theError = "Error: Could not get \"%1\" attribute.";
717 theError.arg(aBaseShapeID);
721 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
722 ResultPtr aContext = aShapeAttrSelection->context();
723 if(!aContext.get()) {
724 theError = "Error: Empty context.";
727 if(!aBaseShape.get()) {
728 aBaseShape = aContext->shape();
730 if(!aBaseShape.get()) {
731 theError = "Error: Empty base shape.";
735 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
736 bool isSameFound = false;
737 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
738 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
739 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
740 if(anIt.current()->isEqual(aShapeToAdd)) {
746 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
754 //==================================================================================================
755 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
756 const std::shared_ptr<ModelAPI_Feature>& theFeature,
757 const std::list<std::string>& theArguments,
758 Events_InfoMessage& theError) const
760 static const std::string aBaseShapeID = "base_shape";
761 static const std::string aSubShapesID = "subshapes";
763 if(theFeature->getKind() != "Remove_SubShapes") {
764 theError = "Error: Feature \"%1\" does not supported by this validator.";
765 theError.arg(theFeature->getKind());
769 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
770 if(!aShapeAttrSelection.get()) {
771 theError = "Error: Could not get \"%1\" attribute.";
772 theError.arg(aBaseShapeID);
776 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
777 if(!aSubShapesAttrList.get()) {
778 theError = "Error: Could not get \"%1\" attribute.";
779 theError.arg(aSubShapesID);
784 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
785 if(!aBaseShape.get()) {
786 theError = "Error: Base shape is empty.";
789 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
791 // Copy sub-shapes from list to new shape.
792 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
793 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
794 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
795 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
799 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
800 theError = "Error: Resulting shape is not valid.";
807 //==================================================================================================
808 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
809 std::string theAttribute)
814 //==================================================================================================
815 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
816 const std::list<std::string>& theArguments,
817 Events_InfoMessage& theError) const
819 AttributeSelectionListPtr aBaseObjectsAttrList =
820 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
821 if(!aBaseObjectsAttrList.get()) {
822 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
823 theError.arg(FeaturesPlugin_Union::ID());
827 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
828 bool isSameFound = false;
829 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
830 ResultCompSolidPtr aResult =
831 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
835 if(aResult->numberOfSubs() > 0) {
836 theError = "Error: Whole compsolids not allowed for selection.";
844 //==================================================================================================
845 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
846 const std::shared_ptr<ModelAPI_Feature>& theFeature,
847 const std::list<std::string>& theArguments,
848 Events_InfoMessage& theError) const
850 // Check feature kind.
851 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
852 theError = "Error: This validator supports only \"%1\" feature.";
853 theError.arg(FeaturesPlugin_Union::ID());
857 // Get base objects attribute list.
858 AttributeSelectionListPtr aBaseObejctsAttrList =
859 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
860 if(!aBaseObejctsAttrList.get()) {
861 theError = "Error: Could not get \"%1\" attribute.";
862 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
867 ListOfShape aBaseShapesList;
868 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
869 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
870 GeomShapePtr aShape = anAttrSelectionInList->value();
871 aBaseShapesList.push_back(aShape);
874 // Make componud and find connected.
875 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
876 ListOfShape aCombined, aFree;
877 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
879 if(aFree.size() > 0 || aCombined.size() > 1) {
880 theError = "Error: Not all shapes have shared topology.";
887 //==================================================================================================
888 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
889 std::string theAttribute)
894 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
895 const std::list<std::string>& theArguments,
896 Events_InfoMessage& theError) const
898 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
899 theError = "Error: The attribute with the %1 type is not processed";
900 theError.arg(theAttribute->attributeType());
904 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
906 ObjectPtr aRefObject = aRefAttribute->value();
907 if (!aRefObject.get()) {
908 theError = "Error: Empty feature.";
912 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
913 if (!aRefFeature.get()) {
914 theError = "Error: Empty feature.";
917 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
918 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
920 size_t aConcealedResults = aResults.size();
921 if (!aConcealedResults && !theArguments.empty()) {
922 // find if these results are touched by the feature in another attribute
923 std::list<std::string>::const_iterator anIt = theArguments.begin();
924 std::string aRecoveredList = *anIt;
925 if (!aRecoveredList.empty()) {
926 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
927 theAttribute->owner()->data()->reflist(aRecoveredList);
928 if (aParameterList.get())
929 aConcealedResults = aParameterList->size();
933 if (aConcealedResults == 0)
934 theError = "Error: No concealed results.";
936 return theError.empty();