1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: FeaturesPlugin_Validators.cpp
4 // Created: 22 March 2016
5 // Author: Dmitry Bobylev
7 #include "FeaturesPlugin_Validators.h"
9 #include <ModelAPI_Attribute.h>
10 #include <ModelAPI_AttributeInteger.h>
11 #include <ModelAPI_AttributeSelectionList.h>
12 #include <ModelAPI_AttributeString.h>
13 #include <ModelAPI_AttributeReference.h>
14 #include <ModelAPI_Feature.h>
15 #include <ModelAPI_ResultConstruction.h>
17 #include <Events_Error.h>
19 #include <GeomValidators_BodyShapes.h>
20 #include <GeomValidators_FeatureKind.h>
21 #include <GeomValidators_ShapeType.h>
23 #include <GeomAPI_DataMapOfShapeShape.h>
24 #include <GeomAPI_PlanarEdges.h>
25 #include <GeomAPI_ShapeExplorer.h>
26 #include <GeomAlgoAPI_WireBuilder.h>
28 //==================================================================================================
29 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
30 const std::list<std::string>& theArguments,
31 std::string& theError) const
33 static const std::string aCreationMethodID = "creation_method";
34 static const std::string aBaseObjectsID = "base_objects";
35 static const std::string aLocationsID = "locations_objects";
37 if(theFeature->getKind() != "Pipe") {
38 theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
42 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
43 if(!aCreationMethodAttr.get()) {
44 theError = "Could not get \"" + aCreationMethodID + "\" attribute.";
48 if(aCreationMethodAttr->value() != "locations") {
52 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
53 if(!aBaseObjectsSelectionList.get()) {
54 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
58 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
59 if(!aLocationsSelectionList.get()) {
60 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
64 if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
65 theError = "Number of locations should be the same as base objects.";
72 //==================================================================================================
73 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
78 //==================================================================================================
79 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
80 const std::list<std::string>& theArguments,
81 std::string& theError) const
83 if(theArguments.empty()) {
84 theError = "Validator parameters is empty.";
88 // Checking attribute.
89 if(!isValidAttribute(theAttribute, theArguments, theError)) {
90 if(theError.empty()) {
91 theError = "Attribute contains unacceptable shape.";
96 std::set<ResultConstructionPtr> aSelectedSketches;
97 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
98 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
99 std::string anAttributeType = theAttribute->attributeType();
100 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
101 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
102 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
103 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
104 ResultConstructionPtr aContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelectionAttr->context());
105 if(!aContext.get()) {
106 // It is not a result construction, continue.
110 GeomShapePtr aShape = aSelectionAttr->value();
111 GeomShapePtr aContextShape = aContext->shape();
113 // Whole sketch selected.
114 if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) {
115 theError = "Object from this sketch is already selected. Sketch is not allowed for selection.";
119 aSelectedSketches.insert(aContext);
121 // Object from sketch selected.
122 if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) {
123 theError = "Whole sketch with this object is already selected. Don't allow to select this object.";
127 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
128 GeomShapePtr aWire = anExp.current();
129 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
130 theError = "Wire with wrong orientation selected.";
134 if(aSelectedWiresFromObjects.isBound(aWire)) {
135 theError = "Objects with such wire already selected. Don't allow to select this object.";
139 aSelectedWiresFromObjects.bind(aWire, aWire);
140 aSelectedSketchesFromObjects.insert(aContext);
149 //==================================================================================================
150 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
151 const std::list<std::string>& theArguments,
152 std::string& theError) const
154 if(!theAttribute.get()) {
155 theError = "Empty attribute.";
159 std::string anAttributeType = theAttribute->attributeType();
160 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
161 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
162 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
163 // If at least one attribute is invalid, the result is false.
164 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
168 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
170 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
171 ResultPtr aContext = anAttr->context();
172 if(!aContext.get()) {
173 theError = "Attribute have empty context.";
177 GeomShapePtr aShape = anAttr->value();
178 GeomShapePtr aContextShape = aContext->shape();
180 aShape = aContextShape;
183 theError = "Empty shape selected";
187 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
188 if(aConstruction.get()) {
189 // Construciotn selected. Check that is is not infinite.
190 if(aConstruction->isInfinite()) {
191 theError = "Infinite constructions is not allowed as base.";
195 if(aShape->isEqual(aContextShape)) {
196 // Whole construction selected. Check that it have faces.
197 if(aConstruction->facesNum() > 0) {
201 // Shape on construction selected. Check that it is a face or wire.
202 if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
210 if(!aShape->isEqual(aContextShape)) {
211 // Local selection on body does not allowed.
212 theError = "Selected shape is in the local selection. Only global selection is allowed.";
216 // Check that object is a shape with allowed type.
217 GeomValidators_ShapeType aShapeTypeValidator;
218 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
219 theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, "
220 "whole sketch(if it has at least one face), and whole objects with shape types: ";
221 std::list<std::string>::const_iterator anIt = theArguments.cbegin();
223 for(++anIt; anIt != theArguments.cend(); ++anIt) {
224 theError += ", " + *anIt;
230 theError = "Following attribute does not supported: " + anAttributeType + ".";
237 //==================================================================================================
238 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
239 const std::list<std::string>& theArguments,
240 std::string& theError) const
242 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
243 theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
246 if (theArguments.size() != 2) {
247 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
250 // first argument is for the base attribute, second - for skipping feature kind
251 std::list<std::string>::const_iterator anIt = theArguments.begin();
252 std::string aBaseAttributeId = *anIt;
253 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
254 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
255 if (!aBaseAttribute.get()) {
256 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
259 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
260 // this validator is not necessary anymore
264 std::string aFeatureAttributeKind = *anIt;
265 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
266 // check whether the selection is on the sketch
267 std::list<std::string> anArguments;
268 anArguments.push_back(aFeatureAttributeKind);
270 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
271 bool aPlanarFace = false;
272 // check if selection has Face selected
273 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
275 anArguments.push_back("face");
276 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
278 bool aValid = !aFeatureKind && aPlanarFace;
282 //==================================================================================================
283 bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
284 const std::list<std::string>& theArguments,
285 std::string& theError) const
287 if(theArguments.size() != 2) {
288 theError = "Validator should be used with 2 parameters for extrusion.";
292 std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
294 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
297 if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
301 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
302 if(!aSelAttr.get()) {
303 theError = "Could not get selection attribute \"" + *anArgsIt + "\".";
307 GeomShapePtr aShape = aSelAttr->value();
309 ResultPtr aContext = aSelAttr->context();
310 if(!aContext.get()) {
311 theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
312 + "\" can not be used with default value. Select direction for extrusion.";
316 aShape = aContext->shape();
320 theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
321 + "\" can not be used with default value. Select direction for extrusion.";
328 //==================================================================================================
329 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
334 //==================================================================================================
335 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
336 std::string& theError) const
338 if(!theAttribute.get()) {
342 std::string anAttributeType = theAttribute->attributeType();
343 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
344 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
345 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
346 // If at least one attribute is invalid, the result is false.
347 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
351 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
353 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
354 ResultPtr aContext = anAttr->context();
355 if(!aContext.get()) {
359 GeomShapePtr aShape = anAttr->value();
360 GeomShapePtr aContextShape = aContext->shape();
362 aShape = aContextShape;
368 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
369 aShape->shapeType() == GeomAPI_Shape::EDGE ||
370 !aShape->isPlanar()) {
380 //==================================================================================================
381 bool FeaturesPlugin_ValidatorBooleanSelection::isValid(const AttributePtr& theAttribute,
382 const std::list<std::string>& theArguments,
383 std::string& theError) const
385 AttributeSelectionListPtr anAttrSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
386 if(!anAttrSelectionList.get()) {
387 theError = "Error: this validator can only work with selection list attributes in Boolean feature.";
390 FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
391 int anOperationType = aFeature->integer("bool_type")->value();
393 for(int anIndex = 0; anIndex < anAttrSelectionList->size(); ++anIndex) {
394 AttributeSelectionPtr anAttrSelection = anAttrSelectionList->value(anIndex);
395 if(!anAttrSelection.get()) {
396 theError = "Error: empty attribute selection.";
399 ResultPtr aContext = anAttrSelection->context();
400 if(!aContext.get()) {
401 theError = "Error: empty selection context.";
404 ResultConstructionPtr aResultConstruction =
405 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
406 if(aResultConstruction.get()) {
407 theError = "Error: Result construction not allowed for selection.";
410 std::shared_ptr<GeomAPI_Shape> aShape = anAttrSelection->value();
412 aShape = aContext->shape();
415 theError = "Error: empty shape.";
418 int aShapeType = aShape->shapeType();
419 if(anOperationType == 1) {
420 // Fuse operation. Allow to select edges, faces and solids.
421 if(aShapeType != GeomAPI_Shape::EDGE &&
422 aShapeType != GeomAPI_Shape::FACE &&
423 aShapeType != GeomAPI_Shape::SOLID &&
424 aShapeType != GeomAPI_Shape::COMPSOLID &&
425 aShapeType != GeomAPI_Shape::COMPOUND) {
426 theError = "Error: selected shape has the wrong type.";
430 if(aShapeType != GeomAPI_Shape::SOLID &&
431 aShapeType != GeomAPI_Shape::COMPSOLID &&
432 aShapeType != GeomAPI_Shape::COMPOUND) {
433 theError = "Error: selected shape has the wrong type.";
442 //==================================================================================================
443 bool FeaturesPlugin_ValidatorPartitionSelection::isValid(const AttributePtr& theAttribute,
444 const std::list<std::string>& theArguments,
445 std::string& theError) const
447 GeomValidators_BodyShapes aBodyValidator;
448 if(aBodyValidator.isValid(theAttribute, theArguments, theError)) {
452 GeomValidators_FeatureKind aFeatureKindValidator;
453 if(aFeatureKindValidator.isValid(theAttribute, theArguments, theError)) {
457 theError = "Only body shapes and construction planes are allowed for selection.";