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_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
137 const std::list<std::string>& theArguments,
138 Events_InfoMessage& theError) const
140 if(theArguments.empty()) {
141 theError = "Error: Validator parameters is empty.";
145 // Checking attribute.
146 if(!isValidAttribute(theAttribute, theArguments, theError)) {
147 if(theError.empty()) {
148 theError = "Error: Attribute contains unacceptable shape.";
153 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
154 std::string anAttributeType = theAttribute->attributeType();
155 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
156 AttributeSelectionListPtr aListAttr =
157 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
158 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
159 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
160 ResultPtr aContext = aSelectionAttr->context();
161 if(!aContext.get()) {
162 theError = "Error: Empty context.";
166 ResultConstructionPtr aResultConstruction =
167 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
168 if(!aResultConstruction.get()) {
169 // It is not a result construction.
170 // If shape is compound check that it contains only faces and edges.
171 GeomShapePtr aShape = aSelectionAttr->value();
173 aShape = aContext->shape();
176 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
177 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
178 GeomShapePtr aSubShape = anIt.current();
179 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
180 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
181 theError = "Error: Compound should contain only faces and edges.";
190 GeomShapePtr aShape = aSelectionAttr->value();
191 GeomShapePtr aContextShape = aResultConstruction->shape();
193 // Whole sketch selected.
196 // Object from sketch selected.
197 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
198 GeomShapePtr aWire = anExp.current();
199 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
200 theError = "Error: Wire with wrong orientation selected.";
204 if(aSelectedWiresFromObjects.isBound(aWire)) {
206 "Error: Objects with such wire already selected. Don't allow to select this object.";
210 aSelectedWiresFromObjects.bind(aWire, aWire);
219 //==================================================================================================
220 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
221 const std::shared_ptr<ModelAPI_Feature>& theFeature,
222 const std::list<std::string>& theArguments,
223 Events_InfoMessage& theError) const
225 const std::string aBaseObjectsID = theArguments.front();
227 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
228 if(!aListAttr.get()) {
229 theError = "Error: Could not get \"%1\" attribute.";
230 theError.arg(aBaseObjectsID);
234 std::set<ResultConstructionPtr> aSelectedSketches;
235 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
237 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
238 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
239 ResultPtr aContext = aSelectionAttr->context();
240 if(!aContext.get()) {
241 theError = "Error: Empty context.";
245 ResultConstructionPtr aResultConstruction =
246 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
247 if(!aResultConstruction.get()) {
248 // It is not a result construction.
252 GeomShapePtr aShape = aSelectionAttr->value();
253 GeomShapePtr aContextShape = aResultConstruction->shape();
255 // Whole sketch selected.
256 aSelectedSketches.insert(aResultConstruction);
258 // Object from sketch selected.
259 aSelectedSketchesFromObjects.insert(aResultConstruction);
264 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
265 anIt != aSelectedSketches.cend();
267 ResultConstructionPtr aResultConstruction = *anIt;
268 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
269 aSelectedSketchesFromObjects.cend()) {
270 theError = "Sketch and objects from it can not be selected at the same time.";
278 //==================================================================================================
279 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
280 const std::list<std::string>& theArguments,
281 Events_InfoMessage& theError) const
283 if(!theAttribute.get()) {
284 theError = "Error: Empty attribute.";
288 std::string anAttributeType = theAttribute->attributeType();
289 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
290 AttributeSelectionListPtr aListAttr =
291 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
292 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
293 // If at least one attribute is invalid, the result is false.
294 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
298 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
300 AttributeSelectionPtr anAttr =
301 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
302 ResultPtr aContext = anAttr->context();
303 if(!aContext.get()) {
304 theError = "Error: Attribute have empty context.";
308 GeomShapePtr aShape = anAttr->value();
309 GeomShapePtr aContextShape = aContext->shape();
311 aShape = aContextShape;
314 theError = "Error: Empty shape selected";
318 ResultConstructionPtr aConstruction =
319 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
320 if(aConstruction.get()) {
321 // Construciotn selected. Check that is is not infinite.
322 if(aConstruction->isInfinite()) {
323 theError = "Error: Infinite constructions is not allowed as base.";
327 if(aShape->isEqual(aContextShape)) {
328 // Whole construction selected. Check that it have faces.
329 if(aConstruction->facesNum() > 0) {
333 // Shape on construction selected. Check that it is a face or wire.
334 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
335 aShape->shapeType() == GeomAPI_Shape::FACE) {
343 if(!aShape->isEqual(aContextShape)) {
344 // Local selection on body does not allowed.
346 "Error: Selected shape is in the local selection. Only global selection is allowed.";
350 // Check that object is a shape with allowed type.
351 GeomValidators_ShapeType aShapeTypeValidator;
352 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
353 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
354 "wires on sketch, whole sketch(if it has at least one face), "
355 "and whole objects with shape types: %1";
356 std::string anArgumentString;
357 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
358 if (!anArgumentString.empty())
359 anArgumentString += ", ";
360 anArgumentString += *anIt;
362 theError.arg(anArgumentString);
367 theError = "Error: Attribute \"%1\" does not supported by this validator.";
368 theError.arg(anAttributeType);
375 //==================================================================================================
376 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
377 const std::list<std::string>& theArguments,
378 Events_InfoMessage& theError) const
380 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
381 theError = "Error: The attribute with the %1 type is not processed";
382 theError.arg(theAttribute->attributeType());
385 if (theArguments.size() != 2) {
386 theError = "Error: Wrong parameters in XML definition for %1 type";
387 theError.arg(theAttribute->attributeType());
390 // first argument is for the base attribute, second - for skipping feature kind
391 std::list<std::string>::const_iterator anIt = theArguments.begin();
392 std::string aBaseAttributeId = *anIt;
393 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
394 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
395 if (!aBaseAttribute.get()) {
396 theError = "Wrong parameters in XML definition for %1 type";
397 theError.arg(theAttribute->attributeType());
400 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
401 // this validator is not necessary anymore
405 std::string aFeatureAttributeKind = *anIt;
406 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
407 // check whether the selection is on the sketch
408 std::list<std::string> anArguments;
409 anArguments.push_back(aFeatureAttributeKind);
411 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
412 bool aPlanarFace = false;
413 // check if selection has Face selected
414 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
416 anArguments.push_back("face");
417 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
419 bool aValid = !aFeatureKind && aPlanarFace;
423 //==================================================================================================
424 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
425 const std::shared_ptr<ModelAPI_Feature>& theFeature,
426 const std::list<std::string>& theArguments,
427 Events_InfoMessage& theError) const
429 if(theArguments.size() != 2) {
430 theError = "Error: Validator should be used with 2 parameters for extrusion.";
434 std::list<std::string>::const_iterator
435 anArgsIt = theArguments.begin(), aLast = theArguments.end();
437 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
440 GeomShapePtr aDirShape;
441 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
443 aDirShape = aSelAttr->value();
444 if(!aDirShape.get()) {
445 ResultPtr aContext = aSelAttr->context();
447 aDirShape = aContext->shape();
452 if(!aDirShape.get()) {
453 // Check that dir can be empty.
454 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
455 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
456 "can not be used with default value. Select direction for extrusion.";
457 theError.arg(*anArgsIt);
464 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
466 // If faces selected check that direction not parallel with them.
467 AttributeSelectionListPtr aListAttr =
468 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
469 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
470 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
471 GeomShapePtr aShapeInList = anAttr->value();
472 if(!aShapeInList.get()) {
473 aShapeInList = anAttr->context()->shape();
475 bool isParallel = true;
476 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
477 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
478 for(GeomAPI_ShapeExplorer
479 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
480 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
481 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
486 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
487 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
488 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
489 if(aPlanarEdges.get()) {
490 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
491 if(aDirEdge->isLine()) {
492 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
493 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
505 "Error: Direction is parallel to one of the selected face or face on selected shell.";
513 //==================================================================================================
514 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
515 Events_InfoMessage& theError) const
517 if(!theAttribute.get()) {
521 std::string anAttributeType = theAttribute->attributeType();
522 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
523 AttributeSelectionListPtr aListAttr =
524 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
525 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
526 // If at least one attribute is invalid, the result is false.
527 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
531 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
533 AttributeSelectionPtr anAttr =
534 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
535 ResultPtr aContext = anAttr->context();
536 if(!aContext.get()) {
540 GeomShapePtr aShape = anAttr->value();
541 GeomShapePtr aContextShape = aContext->shape();
543 aShape = aContextShape;
549 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
550 aShape->shapeType() == GeomAPI_Shape::EDGE ||
551 !aShape->isPlanar()) {
561 //==================================================================================================
562 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
563 const std::list<std::string>& theArguments,
564 Events_InfoMessage& theError) const
566 AttributeSelectionListPtr anAttrSelectionList =
567 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
568 if(!anAttrSelectionList.get()) {
570 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
573 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
574 int anOperationType = aFeature->integer("bool_type")->value();
576 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
577 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
578 if(!anAttrSelection.get()) {
579 theError = "Error: Empty attribute selection.";
582 ResultPtr aContext = anAttrSelection->context();
583 if(!aContext.get()) {
584 theError = "Error: Empty selection context.";
587 ResultConstructionPtr aResultConstruction =
588 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
589 if(aResultConstruction.get()) {
590 if (anOperationType != FeaturesPlugin_Boolean::BOOL_FILL
591 || theAttribute->id() != FeaturesPlugin_Boolean::TOOL_LIST_ID()) {
592 theError = "Error: Result construction not allowed for selection.";
596 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
597 GeomShapePtr aContextShape = aContext->shape();
599 aShape = aContextShape;
602 theError = "Error: Empty shape.";
605 if(!aShape->isEqual(aContextShape)) {
606 theError = "Error: Local selection not allowed.";
610 GeomAPI_Shape::ShapeType aShapeType = aShape->shapeType();
611 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
612 if(anOperationType == FeaturesPlugin_Boolean::BOOL_FUSE) {
613 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
614 anAllowedTypes.insert(GeomAPI_Shape::FACE);
615 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
616 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
617 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
618 } else if (anOperationType == FeaturesPlugin_Boolean::BOOL_FILL) {
619 anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
620 anAllowedTypes.insert(GeomAPI_Shape::EDGE);
621 anAllowedTypes.insert(GeomAPI_Shape::WIRE);
622 anAllowedTypes.insert(GeomAPI_Shape::FACE);
623 anAllowedTypes.insert(GeomAPI_Shape::SHELL);
624 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
625 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
626 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
628 anAllowedTypes.insert(GeomAPI_Shape::SOLID);
629 anAllowedTypes.insert(GeomAPI_Shape::COMPSOLID);
630 anAllowedTypes.insert(GeomAPI_Shape::COMPOUND);
633 if(anAllowedTypes.find(aShapeType) == anAllowedTypes.end()
634 || (aResultConstruction.get() && aShapeType != GeomAPI_Shape::FACE)) {
635 theError = "Error: Selected shape has the wrong type.";
644 //==================================================================================================
645 bool FeaturesPlugin_ValidatorFilletSelection::isValid(const AttributePtr& theAttribute,
646 const std::list<std::string>& theArguments,
647 Events_InfoMessage& theError) const
649 AttributeSelectionListPtr anAttrSelectionList =
650 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
651 if(!anAttrSelectionList.get()) {
653 "Error: This validator can only work with selection list attributes in \"Fillet\" feature.";
657 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
658 // Check all selected entities are sub-shapes of single solid
659 GeomShapePtr aBaseSolid;
660 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
661 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
662 if(!anAttrSelection.get()) {
663 theError = "Error: Empty attribute selection.";
666 ResultPtr aContext = anAttrSelection->context();
667 if(!aContext.get()) {
668 theError = "Error: Empty selection context.";
672 ResultCompSolidPtr aContextOwner = ModelAPI_Tools::compSolidOwner(aContext);
673 GeomShapePtr anOwner = aContextOwner.get() ? aContextOwner->shape() : aContext->shape();
675 if (anOwner->shapeType() != GeomAPI_Shape::SOLID &&
676 anOwner->shapeType() != GeomAPI_Shape::COMPSOLID) {
677 theError = "Error: Not all selected shapes are sub-shapes of solids";
682 aBaseSolid = anOwner;
683 else if (!aBaseSolid->isEqual(anOwner)) {
684 theError = "Error: Sub-shapes of different solids have been selected.";
692 //==================================================================================================
693 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
694 const std::list<std::string>& theArguments,
695 Events_InfoMessage& theError) const
697 AttributeSelectionListPtr anAttrSelectionList =
698 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
699 if(!anAttrSelectionList.get()) {
700 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
704 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
705 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
707 //GeomValidators_BodyShapes aBodyValidator;
708 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
712 GeomValidators_FeatureKind aFeatureKindValidator;
713 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
717 ResultPtr aContext = aSelectAttr->context();
718 ResultConstructionPtr aResultConstruction =
719 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
720 if(aResultConstruction.get()) {
721 theError = "Error: Only body shapes and construction planes are allowed for selection.";
725 ResultCompSolidPtr aResultCompsolid =
726 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
727 if(aResultCompsolid.get()) {
731 theError = "Error: Only body shapes and construction planes are allowed for selection.";
739 //==================================================================================================
740 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
741 const std::list<std::string>& theArguments,
742 Events_InfoMessage& theError) const
744 AttributeSelectionListPtr aSubShapesAttrList =
745 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
746 if(!aSubShapesAttrList.get()) {
748 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
752 static const std::string aBaseShapeID = "base_shape";
753 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
754 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
756 if(!aShapeAttrSelection.get()) {
757 theError = "Error: Could not get \"%1\" attribute.";
758 theError.arg(aBaseShapeID);
762 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
763 ResultPtr aContext = aShapeAttrSelection->context();
764 if(!aContext.get()) {
765 theError = "Error: Empty context.";
768 if(!aBaseShape.get()) {
769 aBaseShape = aContext->shape();
771 if(!aBaseShape.get()) {
772 theError = "Error: Empty base shape.";
776 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
777 bool isSameFound = false;
778 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
779 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
780 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
781 if(anIt.current()->isEqual(aShapeToAdd)) {
787 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
795 //==================================================================================================
796 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
797 const std::shared_ptr<ModelAPI_Feature>& theFeature,
798 const std::list<std::string>& theArguments,
799 Events_InfoMessage& theError) const
801 static const std::string aBaseShapeID = "base_shape";
802 static const std::string aSubShapesID = "subshapes_to_keep";
804 if(theFeature->getKind() != "Remove_SubShapes") {
805 theError = "Error: Feature \"%1\" does not supported by this validator.";
806 theError.arg(theFeature->getKind());
810 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
811 if(!aShapeAttrSelection.get()) {
812 theError = "Error: Could not get \"%1\" attribute.";
813 theError.arg(aBaseShapeID);
817 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
818 if(!aSubShapesAttrList.get()) {
819 theError = "Error: Could not get \"%1\" attribute.";
820 theError.arg(aSubShapesID);
825 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
826 if(!aBaseShape.get()) {
827 theError = "Error: Base shape is empty.";
830 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
832 if (aSubShapesAttrList->size() == 0) {
833 theError = "Error: Resulting shape is not valid.";
837 // Copy sub-shapes from list to new shape.
838 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
839 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
840 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
841 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
845 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
846 theError = "Error: Resulting shape is not valid.";
853 //==================================================================================================
854 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
855 const std::list<std::string>& theArguments,
856 Events_InfoMessage& theError) const
858 AttributeSelectionListPtr aBaseObjectsAttrList =
859 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
860 if(!aBaseObjectsAttrList.get()) {
861 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
862 theError.arg(FeaturesPlugin_Union::ID());
866 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
867 bool isSameFound = false;
868 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
869 ResultPtr aContext = anAttrSelectionInList->context();
870 if (!aContext.get()) {
871 theError = "Error: selection is invalid.";
875 ResultConstructionPtr aConstruction =
876 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
877 if(aConstruction.get()) {
878 theError = "Error: Result construction not allowed for selection.";
882 GeomShapePtr aShape = anAttrSelectionInList->value();
883 GeomShapePtr aContextShape = aContext->shape();
884 if (aShape.get() && aContextShape.get() && !aContextShape->isEqual(aShape)) {
885 theError = "Error: Local selection not allowed.";
889 ResultCompSolidPtr aResult =
890 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
895 if(aResult->numberOfSubs() > 0) {
896 theError = "Error: Whole compsolids not allowed for selection.";
904 //==================================================================================================
905 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
906 const std::shared_ptr<ModelAPI_Feature>& theFeature,
907 const std::list<std::string>& theArguments,
908 Events_InfoMessage& theError) const
910 // Check feature kind.
911 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
912 theError = "Error: This validator supports only \"%1\" feature.";
913 theError.arg(FeaturesPlugin_Union::ID());
917 // Get base objects attribute list.
918 AttributeSelectionListPtr aBaseObejctsAttrList =
919 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
920 if(!aBaseObejctsAttrList.get()) {
921 theError = "Error: Could not get \"%1\" attribute.";
922 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
927 GeomAPI_Shape::ShapeType aType = GeomAPI_Shape::COMPSOLID;
928 ListOfShape aBaseShapesList;
929 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
930 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
931 GeomShapePtr aShape = anAttrSelectionInList->value();
935 aBaseShapesList.push_back(aShape);
936 aType = aShape->shapeType() == GeomAPI_Shape::FACE ? GeomAPI_Shape::SHELL :
937 GeomAPI_Shape::COMPSOLID;
940 // Make compound and find connected.
941 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
942 ListOfShape aCombined, aFree;
943 GeomAlgoAPI_ShapeTools::combineShapes(
949 if(aFree.size() > 0 || aCombined.size() > 1) {
950 theError = "Error: Not all shapes have shared topology.";
957 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
958 const std::list<std::string>& theArguments,
959 Events_InfoMessage& theError) const
961 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
962 theError = "Error: The attribute with the %1 type is not processed";
963 theError.arg(theAttribute->attributeType());
967 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
969 ObjectPtr aRefObject = aRefAttribute->value();
970 if (!aRefObject.get()) {
971 theError = "Error: Empty feature.";
975 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
976 if (!aRefFeature.get()) {
977 theError = "Error: Empty feature.";
980 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
981 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
983 size_t aConcealedResults = aResults.size();
984 if (!aConcealedResults && !theArguments.empty()) {
985 // find if these results are touched by the feature in another attribute
986 std::list<std::string>::const_iterator anIt = theArguments.begin();
987 std::string aRecoveredList = *anIt;
988 if (!aRecoveredList.empty()) {
989 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
990 theAttribute->owner()->data()->reflist(aRecoveredList);
991 if (aParameterList.get())
992 aConcealedResults = aParameterList->size();
996 if (aConcealedResults == 0)
997 theError = "Error: No concealed results.";
999 return theError.empty();