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_Union.h"
25 #include <Events_InfoMessage.h>
27 #include <ModelAPI_Attribute.h>
28 #include <ModelAPI_AttributeInteger.h>
29 #include <ModelAPI_AttributeSelectionList.h>
30 #include <ModelAPI_AttributeString.h>
31 #include <ModelAPI_AttributeReference.h>
32 #include <ModelAPI_AttributeRefList.h>
33 #include <ModelAPI_Feature.h>
34 #include <ModelAPI_ResultCompSolid.h>
35 #include <ModelAPI_ResultConstruction.h>
36 #include <ModelAPI_Tools.h>
38 #include <GeomValidators_BodyShapes.h>
39 #include <GeomValidators_FeatureKind.h>
40 #include <GeomValidators_ShapeType.h>
42 #include <GeomAPI_DataMapOfShapeShape.h>
43 #include <GeomAPI_Lin.h>
44 #include <GeomAPI_PlanarEdges.h>
45 #include <GeomAPI_ShapeExplorer.h>
46 #include <GeomAPI_ShapeIterator.h>
48 #include <GeomAlgoAPI_CompoundBuilder.h>
49 #include <GeomAlgoAPI_ShapeBuilder.h>
50 #include <GeomAlgoAPI_ShapeTools.h>
51 #include <GeomAlgoAPI_WireBuilder.h>
53 #define _USE_MATH_DEFINES
56 //==================================================================================================
57 bool FeaturesPlugin_ValidatorPipePath::isValid(const AttributePtr& theAttribute,
58 const std::list<std::string>& theArguments,
59 Events_InfoMessage& theError) const
61 AttributeSelectionPtr aPathAttrSelection =
62 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
63 if(!aPathAttrSelection.get()) {
64 theError = "Error: This validator can only work with path selector in \"Pipe\" feature.";
68 GeomShapePtr aPathShape = aPathAttrSelection->value();
69 ResultPtr aContext = aPathAttrSelection->context();
71 theError = "Error: Empty context.";
74 GeomShapePtr aContextShape = aContext->shape();
75 if(aPathShape.get() && aPathShape->shapeType() == GeomAPI_Shape::WIRE &&
76 !aPathShape->isEqual(aContextShape)) {
77 theError = "Error: Local selection of wires not allowed.";
84 //==================================================================================================
85 bool FeaturesPlugin_ValidatorPipeLocations::isValid(
86 const std::shared_ptr<ModelAPI_Feature>& theFeature,
87 const std::list<std::string>& theArguments,
88 Events_InfoMessage& theError) const
90 static const std::string aCreationMethodID = "creation_method";
91 static const std::string aBaseObjectsID = "base_objects";
92 static const std::string aLocationsID = "locations_objects";
94 if(theFeature->getKind() != "Pipe") {
95 theError = "Error: Feature \"%1\" does not supported by this validator.";
96 theError.arg(theFeature->getKind());
100 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
101 if(!aCreationMethodAttr.get()) {
102 theError = "Error: Could not get \"%1\" attribute.";
103 theError.arg(aCreationMethodID);
107 if(aCreationMethodAttr->value() != "locations") {
111 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
112 if(!aBaseObjectsSelectionList.get()) {
113 theError = "Error: Could not get \"%1\" attribute.";
114 theError.arg(aBaseObjectsID);
118 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
119 if(!aLocationsSelectionList.get()) {
120 theError = "Error: Could not get \"%1\" attribute.";
121 theError.arg(aBaseObjectsID);
125 if(aLocationsSelectionList->size() > 0 &&
126 aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
127 theError = "Error: Number of locations should be the same as base objects.";
134 //==================================================================================================
135 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature,
136 std::string theAttribute)
141 //==================================================================================================
142 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
143 const std::list<std::string>& theArguments,
144 Events_InfoMessage& theError) const
146 if(theArguments.empty()) {
147 theError = "Error: Validator parameters is empty.";
151 // Checking attribute.
152 if(!isValidAttribute(theAttribute, theArguments, theError)) {
153 if(theError.empty()) {
154 theError = "Error: Attribute contains unacceptable shape.";
159 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
160 std::string anAttributeType = theAttribute->attributeType();
161 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
162 AttributeSelectionListPtr aListAttr =
163 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
164 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
165 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
166 ResultPtr aContext = aSelectionAttr->context();
167 if(!aContext.get()) {
168 theError = "Error: Empty context.";
172 ResultConstructionPtr aResultConstruction =
173 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
174 if(!aResultConstruction.get()) {
175 // It is not a result construction.
176 // If shape is compound check that it contains only faces and edges.
177 GeomShapePtr aShape = aSelectionAttr->value();
179 aShape = aContext->shape();
182 if(aShape->shapeType() == GeomAPI_Shape::COMPOUND) {
183 for(GeomAPI_ShapeIterator anIt(aShape); anIt.more(); anIt.next()) {
184 GeomShapePtr aSubShape = anIt.current();
185 if(aSubShape->shapeType() != GeomAPI_Shape::EDGE
186 && aSubShape->shapeType() != GeomAPI_Shape::FACE) {
187 theError = "Error: Compound should contain only faces and edges.";
196 GeomShapePtr aShape = aSelectionAttr->value();
197 GeomShapePtr aContextShape = aResultConstruction->shape();
199 // Whole sketch selected.
202 // Object from sketch selected.
203 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
204 GeomShapePtr aWire = anExp.current();
205 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
206 theError = "Error: Wire with wrong orientation selected.";
210 if(aSelectedWiresFromObjects.isBound(aWire)) {
212 "Error: Objects with such wire already selected. Don't allow to select this object.";
216 aSelectedWiresFromObjects.bind(aWire, aWire);
225 //==================================================================================================
226 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isValid(
227 const std::shared_ptr<ModelAPI_Feature>& theFeature,
228 const std::list<std::string>& theArguments,
229 Events_InfoMessage& theError) const
231 const std::string aBaseObjectsID = theArguments.front();
233 AttributeSelectionListPtr aListAttr = theFeature->selectionList(aBaseObjectsID);
234 if(!aListAttr.get()) {
235 theError = "Error: Could not get \"%1\" attribute.";
236 theError.arg(aBaseObjectsID);
240 std::set<ResultConstructionPtr> aSelectedSketches;
241 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
243 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
244 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
245 ResultPtr aContext = aSelectionAttr->context();
246 if(!aContext.get()) {
247 theError = "Error: Empty context.";
251 ResultConstructionPtr aResultConstruction =
252 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
253 if(!aResultConstruction.get()) {
254 // It is not a result construction.
258 GeomShapePtr aShape = aSelectionAttr->value();
259 GeomShapePtr aContextShape = aResultConstruction->shape();
261 // Whole sketch selected.
262 aSelectedSketches.insert(aResultConstruction);
264 // Object from sketch selected.
265 aSelectedSketchesFromObjects.insert(aResultConstruction);
270 for(std::set<ResultConstructionPtr>::const_iterator anIt = aSelectedSketches.cbegin();
271 anIt != aSelectedSketches.cend();
273 ResultConstructionPtr aResultConstruction = *anIt;
274 if(aSelectedSketchesFromObjects.find(aResultConstruction) !=
275 aSelectedSketchesFromObjects.cend()) {
276 theError = "Sketch and objects from it can not be selected at the same time.";
284 //==================================================================================================
285 bool FeaturesPlugin_ValidatorBaseForGenerationSketchOrSketchObjects::isNotObligatory(
286 std::string theFeature,
287 std::string theAttribute)
292 //==================================================================================================
293 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
294 const std::list<std::string>& theArguments,
295 Events_InfoMessage& theError) const
297 if(!theAttribute.get()) {
298 theError = "Error: Empty attribute.";
302 std::string anAttributeType = theAttribute->attributeType();
303 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
304 AttributeSelectionListPtr aListAttr =
305 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
306 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
307 // If at least one attribute is invalid, the result is false.
308 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
312 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
314 AttributeSelectionPtr anAttr =
315 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
316 ResultPtr aContext = anAttr->context();
317 if(!aContext.get()) {
318 theError = "Error: Attribute have empty context.";
322 GeomShapePtr aShape = anAttr->value();
323 GeomShapePtr aContextShape = aContext->shape();
325 aShape = aContextShape;
328 theError = "Error: Empty shape selected";
332 ResultConstructionPtr aConstruction =
333 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
334 if(aConstruction.get()) {
335 // Construciotn selected. Check that is is not infinite.
336 if(aConstruction->isInfinite()) {
337 theError = "Error: Infinite constructions is not allowed as base.";
341 if(aShape->isEqual(aContextShape)) {
342 // Whole construction selected. Check that it have faces.
343 if(aConstruction->facesNum() > 0) {
347 // Shape on construction selected. Check that it is a face or wire.
348 if(aShape->shapeType() == GeomAPI_Shape::WIRE ||
349 aShape->shapeType() == GeomAPI_Shape::FACE) {
357 if(!aShape->isEqual(aContextShape)) {
358 // Local selection on body does not allowed.
360 "Error: Selected shape is in the local selection. Only global selection is allowed.";
364 // Check that object is a shape with allowed type.
365 GeomValidators_ShapeType aShapeTypeValidator;
366 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
367 theError = "Error: Selected shape has unacceptable type. Acceptable types are: faces or "
368 "wires on sketch, whole sketch(if it has at least one face), "
369 "and whole objects with shape types: %1";
370 std::string anArgumentString;
371 for(auto anIt = theArguments.cbegin(); anIt != theArguments.cend(); ++anIt) {
372 if (!anArgumentString.empty())
373 anArgumentString += ", ";
374 anArgumentString += *anIt;
376 theError.arg(anArgumentString);
381 theError = "Error: Attribute \"%1\" does not supported by this validator.";
382 theError.arg(anAttributeType);
389 //==================================================================================================
390 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
391 const std::list<std::string>& theArguments,
392 Events_InfoMessage& theError) const
394 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
395 theError = "Error: The attribute with the %1 type is not processed";
396 theError.arg(theAttribute->attributeType());
399 if (theArguments.size() != 2) {
400 theError = "Error: Wrong parameters in XML definition for %1 type";
401 theError.arg(theAttribute->attributeType());
404 // first argument is for the base attribute, second - for skipping feature kind
405 std::list<std::string>::const_iterator anIt = theArguments.begin();
406 std::string aBaseAttributeId = *anIt;
407 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
408 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
409 if (!aBaseAttribute.get()) {
410 theError = "Wrong parameters in XML definition for %1 type";
411 theError.arg(theAttribute->attributeType());
414 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
415 // this validator is not necessary anymore
419 std::string aFeatureAttributeKind = *anIt;
420 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
421 // check whether the selection is on the sketch
422 std::list<std::string> anArguments;
423 anArguments.push_back(aFeatureAttributeKind);
425 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
426 bool aPlanarFace = false;
427 // check if selection has Face selected
428 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
430 anArguments.push_back("face");
431 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
433 bool aValid = !aFeatureKind && aPlanarFace;
437 //==================================================================================================
438 bool FeaturesPlugin_ValidatorExtrusionDir::isValid(
439 const std::shared_ptr<ModelAPI_Feature>& theFeature,
440 const std::list<std::string>& theArguments,
441 Events_InfoMessage& theError) const
443 if(theArguments.size() != 2) {
444 theError = "Error: Validator should be used with 2 parameters for extrusion.";
448 std::list<std::string>::const_iterator
449 anArgsIt = theArguments.begin(), aLast = theArguments.end();
451 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
454 GeomShapePtr aDirShape;
455 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
457 aDirShape = aSelAttr->value();
458 if(!aDirShape.get()) {
459 ResultPtr aContext = aSelAttr->context();
461 aDirShape = aContext->shape();
466 if(!aDirShape.get()) {
467 // Check that dir can be empty.
468 if(!isShapesCanBeEmpty(aCheckAttribute, theError)) {
469 theError = "Error: Base objects list contains vertex or edge, so attribute \"%1\" "
470 "can not be used with default value. Select direction for extrusion.";
471 theError.arg(*anArgsIt);
478 std::shared_ptr<GeomAPI_Edge> aDirEdge(new GeomAPI_Edge(aDirShape));
480 // If faces selected check that direction not parallel with them.
481 AttributeSelectionListPtr aListAttr =
482 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(aCheckAttribute);
483 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
484 AttributeSelectionPtr anAttr = aListAttr->value(anIndex);
485 GeomShapePtr aShapeInList = anAttr->value();
486 if(!aShapeInList.get()) {
487 aShapeInList = anAttr->context()->shape();
489 bool isParallel = true;
490 if(aShapeInList->shapeType() == GeomAPI_Shape::FACE ||
491 aShapeInList->shapeType() == GeomAPI_Shape::SHELL) {
492 for(GeomAPI_ShapeExplorer
493 anExp(aShapeInList, GeomAPI_Shape::FACE); anExp.more(); anExp.next()) {
494 std::shared_ptr<GeomAPI_Face> aFace(new GeomAPI_Face(anExp.current()));
495 isParallel = GeomAlgoAPI_ShapeTools::isParallel(aDirEdge, aFace);
500 } else if(aShapeInList->shapeType() == GeomAPI_Shape::COMPOUND) {
501 std::shared_ptr<GeomAPI_PlanarEdges> aPlanarEdges =
502 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aShapeInList);
503 if(aPlanarEdges.get()) {
504 std::shared_ptr<GeomAPI_Dir> aSketchDir = aPlanarEdges->norm();
505 if(aDirEdge->isLine()) {
506 std::shared_ptr<GeomAPI_Dir> aDir = aDirEdge->line()->direction();
507 isParallel = fabs(aSketchDir->angle(aDir) - M_PI / 2.0) < 10e-7;
519 "Error: Direction is parallel to one of the selected face or face on selected shell.";
527 //==================================================================================================
528 bool FeaturesPlugin_ValidatorExtrusionDir::isNotObligatory(std::string theFeature,
529 std::string theAttribute)
534 //==================================================================================================
535 bool FeaturesPlugin_ValidatorExtrusionDir::isShapesCanBeEmpty(const AttributePtr& theAttribute,
536 Events_InfoMessage& theError) const
538 if(!theAttribute.get()) {
542 std::string anAttributeType = theAttribute->attributeType();
543 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
544 AttributeSelectionListPtr aListAttr =
545 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
546 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
547 // If at least one attribute is invalid, the result is false.
548 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
552 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
554 AttributeSelectionPtr anAttr =
555 std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
556 ResultPtr aContext = anAttr->context();
557 if(!aContext.get()) {
561 GeomShapePtr aShape = anAttr->value();
562 GeomShapePtr aContextShape = aContext->shape();
564 aShape = aContextShape;
570 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
571 aShape->shapeType() == GeomAPI_Shape::EDGE ||
572 !aShape->isPlanar()) {
582 //==================================================================================================
583 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
584 const std::list<std::string>& theArguments,
585 Events_InfoMessage& theError) const
587 AttributeSelectionListPtr anAttrSelectionList =
588 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
589 if(!anAttrSelectionList.get()) {
591 "Error: This validator can only work with selection list attributes in \"Boolean\" feature.";
594 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
595 int anOperationType = aFeature->integer("bool_type")->value();
597 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
598 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
599 if(!anAttrSelection.get()) {
600 theError = "Error: Empty attribute selection.";
603 ResultPtr aContext = anAttrSelection->context();
604 if(!aContext.get()) {
605 theError = "Error: Empty selection context.";
608 ResultConstructionPtr aResultConstruction =
609 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
610 if(aResultConstruction.get()) {
611 theError = "Error: Result construction not allowed for selection.";
614 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
615 GeomShapePtr aContextShape = aContext->shape();
617 aShape = aContextShape;
620 theError = "Error: Empty shape.";
623 if(!aShape->isEqual(aContextShape)) {
624 theError = "Error: Local selection not allowed.";
628 int aShapeType = aShape->shapeType();
629 if(anOperationType == 1) {
630 // Fuse operation. Allow to select edges, faces and solids.
631 if(aShapeType != GeomAPI_Shape::EDGE &&
632 aShapeType != GeomAPI_Shape::FACE &&
633 aShapeType != GeomAPI_Shape::SOLID &&
634 aShapeType != GeomAPI_Shape::COMPSOLID &&
635 aShapeType != GeomAPI_Shape::COMPOUND) {
636 theError = "Error: Selected shape has the wrong type.";
640 if(aShapeType != GeomAPI_Shape::SOLID &&
641 aShapeType != GeomAPI_Shape::COMPSOLID &&
642 aShapeType != GeomAPI_Shape::COMPOUND) {
643 theError = "Error: Selected shape has the wrong type.";
652 //==================================================================================================
653 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
654 const std::list<std::string>& theArguments,
655 Events_InfoMessage& theError) const
657 AttributeSelectionListPtr anAttrSelectionList =
658 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
659 if(!anAttrSelectionList.get()) {
660 theError = "Error: This validator can only work with selection list in \"Partition\" feature.";
664 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
665 AttributeSelectionPtr aSelectAttr = anAttrSelectionList->value(anIndex);
667 //GeomValidators_BodyShapes aBodyValidator;
668 //if(aBodyValidator.isValid(aSelectAttr, theArguments, theError)) {
672 GeomValidators_FeatureKind aFeatureKindValidator;
673 if(aFeatureKindValidator.isValid(aSelectAttr, theArguments, theError)) {
677 ResultPtr aContext = aSelectAttr->context();
678 ResultConstructionPtr aResultConstruction =
679 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
680 if(aResultConstruction.get()) {
681 theError = "Error: Only body shapes and construction planes are allowed for selection.";
685 ResultCompSolidPtr aResultCompsolid =
686 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(aContext);
687 if(aResultCompsolid.get()) {
691 theError = "Error: Only body shapes and construction planes are allowed for selection.";
699 //==================================================================================================
700 bool FeaturesPlugin_ValidatorRemoveSubShapesSelection::isValid(const AttributePtr& theAttribute,
701 const std::list<std::string>& theArguments,
702 Events_InfoMessage& theError) const
704 AttributeSelectionListPtr aSubShapesAttrList =
705 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
706 if(!aSubShapesAttrList.get()) {
708 "Error: This validator can only work with selection list in \"Remove Sub-Shapes\" feature.";
712 static const std::string aBaseShapeID = "base_shape";
713 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
714 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeID);
716 if(!aShapeAttrSelection.get()) {
717 theError = "Error: Could not get \"%1\" attribute.";
718 theError.arg(aBaseShapeID);
722 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
723 ResultPtr aContext = aShapeAttrSelection->context();
724 if(!aContext.get()) {
725 theError = "Error: Empty context.";
728 if(!aBaseShape.get()) {
729 aBaseShape = aContext->shape();
731 if(!aBaseShape.get()) {
732 theError = "Error: Empty base shape.";
736 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
737 bool isSameFound = false;
738 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
739 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
740 for(GeomAPI_ShapeIterator anIt(aBaseShape); anIt.more(); anIt.next()) {
741 if(anIt.current()->isEqual(aShapeToAdd)) {
747 theError = "Error: Only sub-shapes of selected shape is allowed for selection.";
755 //==================================================================================================
756 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isValid(
757 const std::shared_ptr<ModelAPI_Feature>& theFeature,
758 const std::list<std::string>& theArguments,
759 Events_InfoMessage& theError) const
761 static const std::string aBaseShapeID = "base_shape";
762 static const std::string aSubShapesID = "subshapes";
764 if(theFeature->getKind() != "Remove_SubShapes") {
765 theError = "Error: Feature \"%1\" does not supported by this validator.";
766 theError.arg(theFeature->getKind());
770 AttributeSelectionPtr aShapeAttrSelection = theFeature->selection(aBaseShapeID);
771 if(!aShapeAttrSelection.get()) {
772 theError = "Error: Could not get \"%1\" attribute.";
773 theError.arg(aBaseShapeID);
777 AttributeSelectionListPtr aSubShapesAttrList = theFeature->selectionList(aSubShapesID);
778 if(!aSubShapesAttrList.get()) {
779 theError = "Error: Could not get \"%1\" attribute.";
780 theError.arg(aSubShapesID);
785 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
786 if(!aBaseShape.get()) {
787 theError = "Error: Base shape is empty.";
790 GeomShapePtr aResultShape = aBaseShape->emptyCopied();
792 // Copy sub-shapes from list to new shape.
793 for(int anIndex = 0; anIndex < aSubShapesAttrList->size(); ++anIndex) {
794 AttributeSelectionPtr anAttrSelectionInList = aSubShapesAttrList->value(anIndex);
795 GeomShapePtr aShapeToAdd = anAttrSelectionInList->value();
796 GeomAlgoAPI_ShapeBuilder::add(aResultShape, aShapeToAdd);
800 if(!GeomAlgoAPI_ShapeTools::isShapeValid(aResultShape)) {
801 theError = "Error: Resulting shape is not valid.";
808 //==================================================================================================
809 bool FeaturesPlugin_ValidatorRemoveSubShapesResult::isNotObligatory(std::string theFeature,
810 std::string theAttribute)
815 //==================================================================================================
816 bool FeaturesPlugin_ValidatorUnionSelection::isValid(const AttributePtr& theAttribute,
817 const std::list<std::string>& theArguments,
818 Events_InfoMessage& theError) const
820 AttributeSelectionListPtr aBaseObjectsAttrList =
821 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
822 if(!aBaseObjectsAttrList.get()) {
823 theError = "Error: This validator can only work with selection list in \"%1\" feature.";
824 theError.arg(FeaturesPlugin_Union::ID());
828 for(int anIndex = 0; anIndex < aBaseObjectsAttrList->size(); ++anIndex) {
829 bool isSameFound = false;
830 AttributeSelectionPtr anAttrSelectionInList = aBaseObjectsAttrList->value(anIndex);
831 ResultCompSolidPtr aResult =
832 std::dynamic_pointer_cast<ModelAPI_ResultCompSolid>(anAttrSelectionInList->context());
836 if(aResult->numberOfSubs() > 0) {
837 theError = "Error: Whole compsolids not allowed for selection.";
845 //==================================================================================================
846 bool FeaturesPlugin_ValidatorUnionArguments::isValid(
847 const std::shared_ptr<ModelAPI_Feature>& theFeature,
848 const std::list<std::string>& theArguments,
849 Events_InfoMessage& theError) const
851 // Check feature kind.
852 if(theFeature->getKind() != FeaturesPlugin_Union::ID()) {
853 theError = "Error: This validator supports only \"%1\" feature.";
854 theError.arg(FeaturesPlugin_Union::ID());
858 // Get base objects attribute list.
859 AttributeSelectionListPtr aBaseObejctsAttrList =
860 theFeature->selectionList(FeaturesPlugin_Union::BASE_OBJECTS_ID());
861 if(!aBaseObejctsAttrList.get()) {
862 theError = "Error: Could not get \"%1\" attribute.";
863 theError.arg(FeaturesPlugin_Union::BASE_OBJECTS_ID());
868 ListOfShape aBaseShapesList;
869 for(int anIndex = 0; anIndex < aBaseObejctsAttrList->size(); ++anIndex) {
870 AttributeSelectionPtr anAttrSelectionInList = aBaseObejctsAttrList->value(anIndex);
871 GeomShapePtr aShape = anAttrSelectionInList->value();
872 aBaseShapesList.push_back(aShape);
875 // Make componud and find connected.
876 GeomShapePtr aCompound = GeomAlgoAPI_CompoundBuilder::compound(aBaseShapesList);
877 ListOfShape aCombined, aFree;
878 GeomAlgoAPI_ShapeTools::combineShapes(aCompound, GeomAPI_Shape::COMPSOLID, aCombined, aFree);
880 if(aFree.size() > 0 || aCombined.size() > 1) {
881 theError = "Error: Not all shapes have shared topology.";
888 //==================================================================================================
889 bool FeaturesPlugin_ValidatorUnionArguments::isNotObligatory(std::string theFeature,
890 std::string theAttribute)
895 bool FeaturesPlugin_ValidatorConcealedResult::isValid(const AttributePtr& theAttribute,
896 const std::list<std::string>& theArguments,
897 Events_InfoMessage& theError) const
899 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
900 theError = "Error: The attribute with the %1 type is not processed";
901 theError.arg(theAttribute->attributeType());
905 AttributeReferencePtr aRefAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeReference>
907 ObjectPtr aRefObject = aRefAttribute->value();
908 if (!aRefObject.get()) {
909 theError = "Error: Empty feature.";
913 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aRefObject);
914 if (!aRefFeature.get()) {
915 theError = "Error: Empty feature.";
918 std::list<std::shared_ptr<ModelAPI_Result> > aResults;
919 ModelAPI_Tools::getConcealedResults(aRefFeature, aResults);
921 size_t aConcealedResults = aResults.size();
922 if (!aConcealedResults && !theArguments.empty()) {
923 // find if these results are touched by the feature in another attribute
924 std::list<std::string>::const_iterator anIt = theArguments.begin();
925 std::string aRecoveredList = *anIt;
926 if (!aRecoveredList.empty()) {
927 std::shared_ptr<ModelAPI_AttributeRefList> aParameterList =
928 theAttribute->owner()->data()->reflist(aRecoveredList);
929 if (aParameterList.get())
930 aConcealedResults = aParameterList->size();
934 if (aConcealedResults == 0)
935 theError = "Error: No concealed results.";
937 return theError.empty();