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_Face.h>
41 #include <GeomValidators_FeatureKind.h>
42 #include <GeomValidators_ShapeType.h>
44 #include <GeomAPI_DataMapOfShapeShape.h>
45 #include <GeomAPI_Lin.h>
46 #include <GeomAPI_PlanarEdges.h>
47 #include <GeomAPI_ShapeExplorer.h>
48 #include <GeomAPI_ShapeIterator.h>
50 #include <GeomAlgoAPI_CompoundBuilder.h>
51 #include <GeomAlgoAPI_ShapeBuilder.h>
52 #include <GeomAlgoAPI_ShapeTools.h>
53 #include <GeomAlgoAPI_WireBuilder.h>
55 #define _USE_MATH_DEFINES
58 //==================================================================================================
59 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
60 const std::list<std::string>& theArguments,
61 Events_InfoMessage& theError) const
63 AttributeSelectionPtr aPathAttrSelection =
64 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
65 if(!aPathAttrSelection.get()) {
66 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
70 GeomShapePtr aPathShape = aPathAttrSelection->value();
71 ResultPtr aContext = aPathAttrSelection->context();
73 theError = "Error: Empty context.";
76 GeomShapePtr aContextShape = aContext->shape();
77 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
78 !aPathShape->isEqual(aContextShape)) {
79 theError = "Error: Local selection of wires not allowed.";
86 //==================================================================================================
87 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
88 const std::shared_ptr<ModelAPI_Feature>& theFeature,
89 const std::list<std::string>& theArguments,
90 Events_InfoMessage& theError) const
92 static const std::string aCreationMethodID = "creation_method";
93 static const std::string aBaseObjectsID = "base_objects";
94 static const std::string aLocationsID = "locations_objects";
96 if(theFeature->getKind() != "Pipe") {
97 theError = "Error: Feature \"%1\" does not supported by this validator.";
98 theError.arg(theFeature->getKind());
102 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
103 if(!aCreationMethodAttr.get()) {
104 theError = "Error: Could not get \"%1\" attribute.";
105 theError.arg(aCreationMethodID);
109 if(aCreationMethodAttr->value() != "locations") {
113 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
114 if(!aBaseObjectsSelectionList.get()) {
115 theError = "Error: Could not get \"%1\" attribute.";
116 theError.arg(aBaseObjectsID);
120 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
121 if(!aLocationsSelectionList.get()) {
122 theError = "Error: Could not get \"%1\" attribute.";
123 theError.arg(aBaseObjectsID);
127 if(aLocationsSelectionList->size() > 0 &&
128 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
129 theError = "Error: Number of locations should be the same as base objects.";
136 //==================================================================================================
137 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
138 const std::list<std::string>& theArguments,
139 Events_InfoMessage& theError) const
141 if(theArguments.empty()) {
142 theError = "Error: Validator parameters is empty.";
146 // Checking attribute.
147 if(!isValidAttribute(theAttribute, theArguments, theError)) {
148 if(theError.empty()) {
149 theError = "Error: Attribute contains unacceptable shape.";
154 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
155 std::string anAttributeType = theAttribute->attributeType();
156 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
157 AttributeSelectionListPtr aListAttr =
158 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
159 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
160 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
161 ResultPtr aContext = aSelectionAttr->context();
162 if(!aContext.get()) {
163 theError = "Error: Empty context.";
167 ResultConstructionPtr aResultConstruction =
168 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
169 if(!aResultConstruction.get()) {
170 // It is not a result construction.
171 // If shape is compound check that it contains only faces and edges.
172 GeomShapePtr aShape = aSelectionAttr->value();
174 aShape = aContext->shape();
177 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
178 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
179 GeomShapePtr aSubShape = anIt.current();
180 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
181 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
182 theError = "Error: Compound should contain only faces and edges.";
191 GeomShapePtr aShape = aSelectionAttr->value();
192 GeomShapePtr aContextShape = aResultConstruction->shape();
194 // Whole sketch selected.
197 // Object from sketch selected.
198 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
199 GeomShapePtr aWire = anExp.current();
200 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
201 theError = "Error: Wire with wrong orientation selected.";
205 if(aSelectedWiresFromObjects.isBound(aWire)) {
207 "Error: Objects with such wire already selected. Don't allow to select this object.";
211 aSelectedWiresFromObjects.bind(aWire, aWire);
220 //==================================================================================================
221 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
222 const std::shared_ptr<ModelAPI_Feature>& theFeature,
223 const std::list<std::string>& theArguments,
224 Events_InfoMessage& theError) const
226 const std::string aBaseObjectsID = theArguments.front();
228 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
229 if(!aListAttr.get()) {
230 theError = "Error: Could not get \"%1\" attribute.";
231 theError.arg(aBaseObjectsID);
235 std::set<ResultConstructionPtr> aSelectedSketches;
236 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
238 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
239 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
240 ResultPtr aContext = aSelectionAttr->context();
241 if(!aContext.get()) {
242 theError = "Error: Empty context.";
246 ResultConstructionPtr aResultConstruction =
247 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
248 if(!aResultConstruction.get()) {
249 // It is not a result construction.
253 GeomShapePtr aShape = aSelectionAttr->value();
254 GeomShapePtr aContextShape = aResultConstruction->shape();
256 // Whole sketch selected.
257 aSelectedSketches.insert(aResultConstruction);
259 // Object from sketch selected.
260 aSelectedSketchesFromObjects.insert(aResultConstruction);
265 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
266 anIt != aSelectedSketches.cend();
268 ResultConstructionPtr aResultConstruction = *anIt;
269 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
270 aSelectedSketchesFromObjects.cend()) {
271 theError = "Sketch and objects from it can not be selected at the same time.";
279 //==================================================================================================
280 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
281 const std::list<std::string>& theArguments,
282 Events_InfoMessage& theError) const
284 if(!theAttribute.get()) {
285 theError = "Error: Empty attribute.";
289 std::string anAttributeType = theAttribute->attributeType();
290 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
291 AttributeSelectionListPtr aListAttr =
292 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
293 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
294 // If at least one attribute is invalid, the result is false.
295 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
299 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
301 AttributeSelectionPtr anAttr =
302 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
303 ResultPtr aContext = anAttr->context();
304 if(!aContext.get()) {
305 theError = "Error: Attribute have empty context.";
309 GeomShapePtr aShape = anAttr->value();
310 GeomShapePtr aContextShape = aContext->shape();
312 aShape = aContextShape;
315 theError = "Error: Empty shape selected";
319 ResultConstructionPtr aConstruction =
320 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
321 if(aConstruction.get()) {
322 // Construciotn selected. Check that is is not infinite.
323 if(aConstruction->isInfinite()) {
324 theError = "Error: Infinite constructions is not allowed as base.";
328 if(aShape->isEqual(aContextShape)) {
329 // Whole construction selected. Check that it have faces.
330 if(aConstruction->facesNum() > 0) {
334 // Shape on construction selected. Check that it is a face or wire.
335 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
336 aShape->shapeType() == GeomAPI_Shape::FACE) {
344 if(!aShape->isEqual(aContextShape)) {
345 // Local selection on body does not allowed.
347 "Error: Selected shape is in the local selection. Only global selection is allowed.";
351 // Check that object is a shape with allowed type.
352 GeomValidators_ShapeType aShapeTypeValidator;
353 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
354 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
355 "wires on sketch, whole sketch(if it has at least one face), "
356 "and whole objects with shape types: %1";
357 std::string anArgumentString;
358 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
359 if (!anArgumentString.empty())
360 anArgumentString += ", ";
361 anArgumentString += *anIt;
363 theError.arg(anArgumentString);
368 theError = "Error: Attribute \"%1\" does not supported by this validator.";
369 theError.arg(anAttributeType);
376 //==================================================================================================
377 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
378 const std::list<std::string>& theArguments,
379 Events_InfoMessage& theError) const
381 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
382 theError = "Error: The attribute with the %1 type is not processed";
383 theError.arg(theAttribute->attributeType());
386 if (theArguments.size() != 2) {
387 theError = "Error: Wrong parameters in XML definition for %1 type";
388 theError.arg(theAttribute->attributeType());
391 // first argument is for the base attribute, second - for skipping feature kind
392 std::list<std::string>::const_iterator anIt = theArguments.begin();
393 std::string aBaseAttributeId = *anIt;
394 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
395 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
396 if (!aBaseAttribute.get()) {
397 theError = "Wrong parameters in XML definition for %1 type";
398 theError.arg(theAttribute->attributeType());
401 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
402 // this validator is not necessary anymore
406 std::string aFeatureAttributeKind = *anIt;
407 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
408 // check whether the selection is on the sketch
409 std::list<std::string> anArguments;
410 anArguments.push_back(aFeatureAttributeKind);
412 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
413 bool aPlanarFace = false;
414 // check if selection has Face selected
415 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
417 anArguments.push_back("face");
418 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
420 bool aValid = !aFeatureKind && aPlanarFace;
424 //==================================================================================================
425 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
426 const std::shared_ptr<ModelAPI_Feature>& theFeature,
427 const std::list<std::string>& theArguments,
428 Events_InfoMessage& theError) const
430 if(theArguments.size() != 2) {
431 theError = "Error: Validator should be used with 2 parameters for extrusion.";
435 std::list<std::string>::const_iterator
436 anArgsIt = theArguments.begin(), aLast = theArguments.end();
438 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
441 GeomShapePtr aDirShape;
442 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
444 aDirShape = aSelAttr->value();
445 if(!aDirShape.get()) {
446 ResultPtr aContext = aSelAttr->context();
448 aDirShape = aContext->shape();
453 if(!aDirShape.get()) {
454 // Check that dir can be empty.
455 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
456 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
457 "can not be used with default value. Select direction for extrusion.";
458 theError.arg(*anArgsIt);
465 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
467 // If faces selected check that direction not parallel with them.
468 AttributeSelectionListPtr aListAttr =
469 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
470 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
471 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
472 GeomShapePtr aShapeInList = anAttr->value();
473 if(!aShapeInList.get()) {
474 aShapeInList = anAttr->context()->shape();
476 bool isParallel = true;
477 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
478 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
479 for(GeomAPI_ShapeExplorer
480 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
481 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
482 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
487 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
488 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
489 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
490 if(aPlanarEdges.get()) {
491 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
492 if(aDirEdge->isLine()) {
493 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
494 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
506 "Error: Direction is parallel to one of the selected face or face on selected shell.";
514 //==================================================================================================
515 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
516 Events_InfoMessage& theError) const
518 if(!theAttribute.get()) {
522 std::string anAttributeType = theAttribute->attributeType();
523 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
524 AttributeSelectionListPtr aListAttr =
525 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
526 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
527 // If at least one attribute is invalid, the result is false.
528 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
532 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
534 AttributeSelectionPtr anAttr =
535 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
536 ResultPtr aContext = anAttr->context();
537 if(!aContext.get()) {
541 GeomShapePtr aShape = anAttr->value();
542 GeomShapePtr aContextShape = aContext->shape();
544 aShape = aContextShape;
550 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
551 aShape->shapeType() == GeomAPI_Shape::EDGE ||
552 !aShape->isPlanar()) {
562 //==================================================================================================
563 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
564 const std::list<std::string>& theArguments,
565 Events_InfoMessage& theError) const
567 AttributeSelectionListPtr anAttrSelectionList =
568 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
569 if(!anAttrSelectionList.get()) {
571 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
574 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
575 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theAttribute->owner());
576 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
578 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
579 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
580 if(!anAttrSelection.get()) {
581 theError = "Error: Empty attribute selection.";
584 ResultPtr aContext = anAttrSelection->context();
585 if(!aContext.get()) {
586 theError = "Error: Empty selection context.";
589 ResultConstructionPtr aResultConstruction =
590 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
591 if(aResultConstruction.get()) {
592 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
593 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
594 theError = "Error: Result construction not allowed for selection.";
598 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
599 GeomShapePtr aContextShape = aContext->shape();
601 aShape = aContextShape;
604 theError = "Error: Empty shape.";
607 if(!aShape->isEqual(aContextShape)) {
608 theError = "Error: Local selection not allowed.";
612 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
613 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
614 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
615 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
616 anAllowedTypes.insert(GeomAPI_Shape::FACE);
617 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
618 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
619 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
620 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL
621 || anOperationType == FeaturesPlugin_Boolean::BOOL_CUT)
623 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
624 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
625 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
626 anAllowedTypes.insert(GeomAPI_Shape::FACE);
627 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
628 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
629 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
630 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
632 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
633 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
634 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
637 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
638 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
639 theError = "Error: Selected shape has the wrong type.";
648 //==================================================================================================
649 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
650 const std::list<std::string>& theArguments,
651 Events_InfoMessage& theError) const
653 AttributeSelectionListPtr anAttrSelectionList =
654 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
655 if(!anAttrSelectionList.get()) {
657 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
661 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
662 // Check all selected entities are sub-shapes of single solid
663 GeomShapePtr aBaseSolid;
664 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
665 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
666 if(!anAttrSelection.get()) {
667 theError = "Error: Empty attribute selection.";
670 ResultPtr aContext = anAttrSelection->context();
671 if(!aContext.get()) {
672 theError = "Error: Empty selection context.";
676 ResultCompSolidPtr aContextOwner = ModelAPI_Tools::compSolidOwner(aContext);
677 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
679 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
680 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
681 theError = "Error: Not all selected shapes are sub-shapes of solids";
686 aBaseSolid = anOwner;
687 else if (!aBaseSolid->isEqual(anOwner)) {
688 theError = "Error: Sub-shapes of different solids have been selected.";
696 //==================================================================================================
697 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
698 const std::list<std::string>& theArguments,
699 Events_InfoMessage& theError) const
701 AttributeSelectionListPtr anAttrSelectionList =
702 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
703 if(!anAttrSelectionList.get()) {
704 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
708 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
709 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
711 //GeomValidators_BodyShapes aBodyValidator;
712 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
716 GeomValidators_FeatureKind aFeatureKindValidator;
717 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
721 ResultPtr aContext = aSelectAttr->context();
722 ResultConstructionPtr aResultConstruction =
723 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
724 if(aResultConstruction.get()) {
725 theError = "Error: Only body shapes and construction planes are allowed for selection.";
729 ResultCompSolidPtr aResultCompsolid =
730 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
731 if(aResultCompsolid.get()) {
735 theError = "Error: Only body shapes and construction planes are allowed for selection.";
743 //==================================================================================================
744 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
745 const std::list<std::string>& theArguments,
746 Events_InfoMessage& theError) const
748 AttributeSelectionListPtr aSubShapesAttrList =
749 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
750 if(!aSubShapesAttrList.get()) {
752 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
756 static const std::string aBaseShapeID = "base_shape";
757 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
758 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
760 if(!aShapeAttrSelection.get()) {
761 theError = "Error: Could not get \"%1\" attribute.";
762 theError.arg(aBaseShapeID);
766 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
767 ResultPtr aContext = aShapeAttrSelection->context();
768 if(!aContext.get()) {
769 theError = "Error: Empty context.";
772 if(!aBaseShape.get()) {
773 aBaseShape = aContext->shape();
775 if(!aBaseShape.get()) {
776 theError = "Error: Empty base shape.";
780 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
781 bool isSameFound = false;
782 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
783 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
784 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
785 if(anIt.current()->isEqual(aShapeToAdd)) {
791 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
799 //==================================================================================================
800 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
801 const std::shared_ptr<ModelAPI_Feature>& theFeature,
802 const std::list<std::string>& theArguments,
803 Events_InfoMessage& theError) const
805 static const std::string aBaseShapeID = "base_shape";
806 static const std::string aSubShapesID = "subshapes_to_keep";
808 if(theFeature->getKind() != "Remove_SubShapes") {
809 theError = "Error: Feature \"%1\" does not supported by this validator.";
810 theError.arg(theFeature->getKind());
814 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
815 if(!aShapeAttrSelection.get()) {
816 theError = "Error: Could not get \"%1\" attribute.";
817 theError.arg(aBaseShapeID);
821 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
822 if(!aSubShapesAttrList.get()) {
823 theError = "Error: Could not get \"%1\" attribute.";
824 theError.arg(aSubShapesID);
829 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
830 if(!aBaseShape.get()) {
831 theError = "Error: Base shape is empty.";
834 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
836 if (aSubShapesAttrList->size() == 0) {
837 theError = "Error: Resulting shape is not valid.";
841 // Copy sub-shapes from list to new shape.
842 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
843 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
844 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
845 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
849 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
850 theError = "Error: Resulting shape is not valid.";
857 //==================================================================================================
858 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
859 const std::list<std::string>& theArguments,
860 Events_InfoMessage& theError) const
862 AttributeSelectionListPtr aBaseObjectsAttrList =
863 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
864 if(!aBaseObjectsAttrList.get()) {
865 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
866 theError.arg(FeaturesPlugin_Union::ID());
870 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
871 bool isSameFound = false;
872 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
873 ResultPtr aContext = anAttrSelectionInList->context();
874 if (!aContext.get()) {
875 theError = "Error: selection is invalid.";
879 ResultConstructionPtr aConstruction =
880 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
881 if(aConstruction.get()) {
882 theError = "Error: Result construction not allowed for selection.";
886 GeomShapePtr aShape = anAttrSelectionInList->value();
887 GeomShapePtr aContextShape = aContext->shape();
888 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
889 theError = "Error: Local selection not allowed.";
893 ResultCompSolidPtr aResult =
894 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
899 if(aResult->numberOfSubs() > 0) {
900 theError = "Error: Whole compsolids not allowed for selection.";
908 //==================================================================================================
909 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
910 const std::shared_ptr<ModelAPI_Feature>& theFeature,
911 const std::list<std::string>& theArguments,
912 Events_InfoMessage& theError) const
914 // Check feature kind.
915 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
916 theError = "Error: This validator supports only \"%1\" feature.";
917 theError.arg(FeaturesPlugin_Union::ID());
921 // Get base objects attribute list.
922 AttributeSelectionListPtr aBaseObejctsAttrList =
923 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
924 if(!aBaseObejctsAttrList.get()) {
925 theError = "Error: Could not get \"%1\" attribute.";
926 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
931 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
932 ListOfShape aBaseShapesList;
933 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
934 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
935 GeomShapePtr aShape = anAttrSelectionInList->value();
939 aBaseShapesList.push_back(aShape);
940 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
941 GeomAPI_Shape::COMPSOLID;
944 // Make compound and find connected.
945 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
946 ListOfShape aCombined, aFree;
947 GeomAlgoAPI_ShapeTools::combineShapes(
953 if(aFree.size() > 0 || aCombined.size() > 1) {
954 theError = "Error: Not all shapes have shared topology.";
961 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
962 const std::list<std::string>& theArguments,
963 Events_InfoMessage& theError) const
965 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
966 theError = "Error: The attribute with the %1 type is not processed";
967 theError.arg(theAttribute->attributeType());
971 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
973 ObjectPtr aRefObject = aRefAttribute->value();
974 if (!aRefObject.get()) {
975 theError = "Error: Empty feature.";
979 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
980 if (!aRefFeature.get()) {
981 theError = "Error: Empty feature.";
984 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
985 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
987 size_t aConcealedResults = aResults.size();
988 if (!aConcealedResults && !theArguments.empty()) {
989 // find if these results are touched by the feature in another attribute
990 std::list<std::string>::const_iterator anIt = theArguments.begin();
991 std::string aRecoveredList = *anIt;
992 if (!aRecoveredList.empty()) {
993 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
994 theAttribute->owner()->data()->reflist(aRecoveredList);
995 if (aParameterList.get())
996 aConcealedResults = aParameterList->size();
1000 if (aConcealedResults == 0)
1001 theError = "Error: No concealed results.";
1003 return theError.empty();
1006 bool FeaturesPlugin_ValidatorCircular::isValid(const AttributePtr& theAttribute,
1007 const std::list<std::string>& theArguments,
1008 Events_InfoMessage& theError) const
1010 static std::list<std::string> aEdgeArg(1, "circle");
1011 static std::list<std::string> aFaceArg(1, "cylinder");
1013 Events_InfoMessage aError;
1014 bool isValid = GeomValidators_ShapeType().isValid(theAttribute, aEdgeArg, aError);
1016 isValid = GeomValidators_Face().isValid(theAttribute, aFaceArg, aError);
1018 theError = "The shape neither circle nor cylinder";
1023 //=================================================================================================
1024 bool FeaturesPlugin_ValidatorBooleanArguments::isValid(
1025 const std::shared_ptr<ModelAPI_Feature>& theFeature,
1026 const std::list<std::string>& theArguments,
1027 Events_InfoMessage& theError) const
1029 if (theArguments.size() != 2)
1031 theError = "Wrong number of arguments (expected 2).";
1035 int anObjectsNb = 0, aToolsNb = 0;
1036 //int anOperationType = 0;
1038 std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
1040 bool isAllInSameCompSolid = true;
1041 ResultCompSolidPtr aCompSolid;
1043 AttributeSelectionListPtr anAttrSelList = theFeature->selectionList(*anIt);
1046 anObjectsNb = anAttrSelList->size();
1047 for (int anIndex = 0; anIndex < anObjectsNb; ++anIndex)
1049 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1050 ResultPtr aContext = anAttr->context();
1051 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
1052 if (aResCompSolidPtr.get())
1054 if (aCompSolid.get())
1056 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1060 aCompSolid = aResCompSolidPtr;
1065 isAllInSameCompSolid = false;
1073 anAttrSelList = theFeature->selectionList(*anIt);
1076 aToolsNb = anAttrSelList->size();
1077 if (isAllInSameCompSolid)
1079 for (int anIndex = 0; anIndex < aToolsNb; ++anIndex)
1081 AttributeSelectionPtr anAttr = anAttrSelList->value(anIndex);
1082 ResultPtr aContext = anAttr->context();
1083 ResultCompSolidPtr aResCompSolidPtr = ModelAPI_Tools::compSolidOwner(aContext);
1084 if (aResCompSolidPtr.get())
1086 if (aCompSolid.get())
1088 isAllInSameCompSolid = aCompSolid == aResCompSolidPtr;
1092 aCompSolid = aResCompSolidPtr;
1097 isAllInSameCompSolid = false;
1105 std::shared_ptr<FeaturesPlugin_Boolean> aFeature =
1106 std::dynamic_pointer_cast<FeaturesPlugin_Boolean>(theFeature);
1107 FeaturesPlugin_Boolean::OperationType anOperationType = aFeature->operationType();
1109 if (anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE)
1112 if (anObjectsNb + aToolsNb < 2)
1114 theError = "Not enough arguments for Fuse operation.";
1117 else if (isAllInSameCompSolid)
1119 theError = "Operations only between sub-shapes of the same shape not allowed.";
1125 if (anObjectsNb < 1)
1127 theError = "Objects not selected.";
1132 theError = "Tools not selected.";
1135 if (isAllInSameCompSolid)
1137 theError = "Operations only between sub-shapes of the same shape not allowed.";
1145 //=================================================================================================
1146 bool FeaturesPlugin_ValidatorBooleanArguments::isNotObligatory(std::string theFeature,
1147 std::string theAttribute)
1149 if (theAttribute == "main_objects" || theAttribute == "tool_objects")