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_AttributeSelectionList.h>
11 #include <ModelAPI_AttributeString.h>
12 #include <ModelAPI_ResultConstruction.h>
13 #include <ModelAPI_AttributeReference.h>
15 #include <Events_Error.h>
17 #include <GeomValidators_FeatureKind.h>
18 #include <GeomValidators_ShapeType.h>
20 #include <GeomAPI_DataMapOfShapeShape.h>
21 #include <GeomAPI_PlanarEdges.h>
22 #include <GeomAPI_ShapeExplorer.h>
23 #include <GeomAlgoAPI_WireBuilder.h>
25 //=================================================================================================
26 bool FeaturesPlugin_ValidatorPipeLocations::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
27 const std::list<std::string>& theArguments,
28 std::string& theError) const
30 static const std::string aCreationMethodID = "creation_method";
31 static const std::string aBaseObjectsID = "base_objects";
32 static const std::string aLocationsID = "locations_objects";
34 if(theFeature->getKind() != "Pipe") {
35 theError = "Feature \"" + theFeature->getKind() + "\" does not supported by this validator.";
39 AttributeStringPtr aCreationMethodAttr = theFeature->string(aCreationMethodID);
40 if(!aCreationMethodAttr.get()) {
41 theError = "Could not get \"" + aCreationMethodID + "\" attribute.";
45 if(aCreationMethodAttr->value() != "locations") {
49 AttributeSelectionListPtr aBaseObjectsSelectionList = theFeature->selectionList(aBaseObjectsID);
50 if(!aBaseObjectsSelectionList.get()) {
51 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
55 AttributeSelectionListPtr aLocationsSelectionList = theFeature->selectionList(aLocationsID);
56 if(!aLocationsSelectionList.get()) {
57 theError = "Could not get \"" + aBaseObjectsID + "\" attribute.";
61 if(aLocationsSelectionList->size() > 0 && aLocationsSelectionList->size() != aBaseObjectsSelectionList->size()) {
62 theError = "Number of locations should be the same as base objects.";
69 //=================================================================================================
70 bool FeaturesPlugin_ValidatorPipeLocations::isNotObligatory(std::string theFeature, std::string theAttribute)
75 //=================================================================================================
76 bool FeaturesPlugin_ValidatorBaseForGeneration::isValid(const AttributePtr& theAttribute,
77 const std::list<std::string>& theArguments,
78 std::string& theError) const
80 if(theArguments.empty()) {
81 theError = "Validator parameters is empty.";
85 // Checking attribute.
86 if(!isValidAttribute(theAttribute, theArguments, theError)) {
87 if(theError.empty()) {
88 theError = "Attribute contains unacceptable shape.";
93 std::set<ResultConstructionPtr> aSelectedSketches;
94 std::set<ResultConstructionPtr> aSelectedSketchesFromObjects;
95 GeomAPI_DataMapOfShapeShape aSelectedWiresFromObjects;
96 std::string anAttributeType = theAttribute->attributeType();
97 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
98 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
99 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
100 AttributeSelectionPtr aSelectionAttr = aListAttr->value(anIndex);
101 ResultConstructionPtr aContext = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aSelectionAttr->context());
102 if(!aContext.get()) {
103 // It is not a result construction, continue.
107 GeomShapePtr aShape = aSelectionAttr->value();
108 GeomShapePtr aContextShape = aContext->shape();
110 // Whole sketch selected.
111 if(aSelectedSketchesFromObjects.find(aContext) != aSelectedSketchesFromObjects.cend()) {
112 theError = "Object from this sketch is already selected. Sketch is not allowed for selection.";
116 aSelectedSketches.insert(aContext);
118 // Object from sketch selected.
119 if(aSelectedSketches.find(aContext) != aSelectedSketches.cend()) {
120 theError = "Whole sketch with this object is already selected. Don't allow to select this object.";
124 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::WIRE); anExp.more(); anExp.next()) {
125 GeomShapePtr aWire = anExp.current();
126 if(aWire->orientation() != GeomAPI_Shape::FORWARD) {
127 theError = "Wire with wrong orientation selected.";
131 if(aSelectedWiresFromObjects.isBound(aWire)) {
132 theError = "Objects with such wire already selected. Don't allow to select this object.";
136 aSelectedWiresFromObjects.bind(aWire, aWire);
137 aSelectedSketchesFromObjects.insert(aContext);
146 //=================================================================================================
147 bool FeaturesPlugin_ValidatorBaseForGeneration::isValidAttribute(const AttributePtr& theAttribute,
148 const std::list<std::string>& theArguments,
149 std::string& theError) const
151 if(!theAttribute.get()) {
152 theError = "Empty attribute.";
156 std::string anAttributeType = theAttribute->attributeType();
157 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
158 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
159 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
160 // If at least one attribute is invalid, the result is false.
161 if(!isValidAttribute(aListAttr->value(anIndex), theArguments, theError)) {
165 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
167 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
168 ResultPtr aContext = anAttr->context();
169 if(!aContext.get()) {
170 theError = "Attribute have empty context.";
174 GeomShapePtr aShape = anAttr->value();
175 GeomShapePtr aContextShape = aContext->shape();
177 aShape = aContextShape;
180 theError = "Empty shape selected";
184 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
185 if(aConstruction.get()) {
186 // Construciotn selected. Check that is is not infinite.
187 if(aConstruction->isInfinite()) {
188 theError = "Infinite constructions is not allowed as base.";
192 if(aShape->isEqual(aContextShape)) {
193 // Whole construction selected. Check that it have faces.
194 if(aConstruction->facesNum() > 0) {
198 // Shape on construction selected. Check that it is a face or wire.
199 if(aShape->shapeType() == GeomAPI_Shape::WIRE || aShape->shapeType() == GeomAPI_Shape::FACE) {
207 if(!aShape->isEqual(aContextShape)) {
208 // Local selection on body does not allowed.
209 theError = "Selected shape is in the local selection. Only global selection is allowed.";
213 // Check that object is a shape with allowed type.
214 GeomValidators_ShapeType aShapeTypeValidator;
215 if(!aShapeTypeValidator.isValid(anAttr, theArguments, theError)) {
216 theError = "Selected shape has unacceptable type. Acceptable types are: faces or wires on sketch, "
217 "whole sketch(if it has at least one face), and whole objects with shape types: ";
218 std::list<std::string>::const_iterator anIt = theArguments.cbegin();
220 for(++anIt; anIt != theArguments.cend(); ++anIt) {
221 theError += ", " + *anIt;
227 theError = "Following attribute does not supported: " + anAttributeType + ".";
234 //=================================================================================================
235 bool FeaturesPlugin_ValidatorCompositeLauncher::isValid(const AttributePtr& theAttribute,
236 const std::list<std::string>& theArguments,
237 std::string& theError) const
239 if (theAttribute->attributeType() != ModelAPI_AttributeReference::typeId()) {
240 theError = "The attribute with the " + theAttribute->attributeType() + " type is not processed";
243 if (theArguments.size() != 2) {
244 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
247 // first argument is for the base attribute, second - for skipping feature kind
248 std::list<std::string>::const_iterator anIt = theArguments.begin();
249 std::string aBaseAttributeId = *anIt;
250 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
251 AttributePtr aBaseAttribute = aFeature->attribute(aBaseAttributeId);
252 if (!aBaseAttribute.get()) {
253 theError = "Wrong parameters in XML definition for " + theAttribute->attributeType() + " type";
256 if (aBaseAttribute->isInitialized()) // when base list of composite feature is already filled,
257 // this validator is not necessary anymore
261 std::string aFeatureAttributeKind = *anIt;
262 GeomValidators_FeatureKind* aValidator = new GeomValidators_FeatureKind();
263 // check whether the selection is on the sketch
264 std::list<std::string> anArguments;
265 anArguments.push_back(aFeatureAttributeKind);
267 bool aFeatureKind = aValidator->isValid(theAttribute, theArguments, theError);
268 bool aPlanarFace = false;
269 // check if selection has Face selected
270 GeomValidators_ShapeType* aShapeType = new GeomValidators_ShapeType();
272 anArguments.push_back("face");
273 aPlanarFace = aShapeType->isValid(theAttribute, anArguments, theError);
275 bool aValid = !aFeatureKind && aPlanarFace;
279 //=================================================================================================
280 bool FeaturesPlugin_ValidatorCanBeEmpty::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
281 const std::list<std::string>& theArguments,
282 std::string& theError) const
284 if(theArguments.size() != 2) {
285 theError = "Validator should be used with 2 parameters for extrusion.";
289 std::list<std::string>::const_iterator anArgsIt = theArguments.begin(), aLast = theArguments.end();
291 AttributePtr aCheckAttribute = theFeature->attribute(*anArgsIt);
294 if(isShapesCanBeEmpty(aCheckAttribute, theError)) {
298 AttributeSelectionPtr aSelAttr = theFeature->selection(*anArgsIt);
299 if(!aSelAttr.get()) {
300 theError = "Could not get selection attribute \"" + *anArgsIt + "\".";
304 GeomShapePtr aShape = aSelAttr->value();
306 ResultPtr aContext = aSelAttr->context();
307 if(!aContext.get()) {
308 theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
309 + "\" can not be used with default value. Select direction for extrusion.";
313 aShape = aContext->shape();
317 theError = "Base objects list contains vertex or edge, so attribute \"" + *anArgsIt
318 + "\" can not be used with default value. Select direction for extrusion.";
325 //=================================================================================================
326 bool FeaturesPlugin_ValidatorCanBeEmpty::isNotObligatory(std::string theFeature, std::string theAttribute)
331 //=================================================================================================
332 bool FeaturesPlugin_ValidatorCanBeEmpty::isShapesCanBeEmpty(const AttributePtr& theAttribute,
333 std::string& theError) const
335 if(!theAttribute.get()) {
339 std::string anAttributeType = theAttribute->attributeType();
340 if(anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
341 AttributeSelectionListPtr aListAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
342 for(int anIndex = 0; anIndex < aListAttr->size(); ++anIndex) {
343 // If at least one attribute is invalid, the result is false.
344 if(!isShapesCanBeEmpty(aListAttr->value(anIndex), theError)) {
348 } else if(anAttributeType == ModelAPI_AttributeSelection::typeId()) {
350 AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
351 ResultPtr aContext = anAttr->context();
352 if(!aContext.get()) {
356 GeomShapePtr aShape = anAttr->value();
357 GeomShapePtr aContextShape = aContext->shape();
359 aShape = aContextShape;
365 if(aShape->shapeType() == GeomAPI_Shape::VERTEX ||
366 aShape->shapeType() == GeomAPI_Shape::EDGE ||
367 !aShape->isPlanar()) {
377 //=================================================================================================
378 bool FeaturesPlugin_ValidatorBaseForWire::isValid(const AttributePtr& theAttribute,
379 const std::list<std::string>& theArguments,
380 std::string& theError) const
382 // Get base objects list.
383 if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
384 Events_Error::send("Validator does not support attribute type \"" + theAttribute->attributeType()
385 + "\"\n Only \"" + ModelAPI_AttributeSelectionList::typeId() + "\" supported.");
388 AttributeSelectionListPtr aSelectionList = std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
389 if(!aSelectionList.get()) {
390 theError = "Could not get selection list.";
393 if(aSelectionList->size() == 0) {
394 theError = "Empty selection list.";
398 // Collect base shapes.
399 ListOfShape aListOfShapes;
400 for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
401 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
402 if(!aSelection.get()) {
403 theError = "Could not get selection.";
406 ResultPtr aContext = aSelection->context();
407 if(!aContext.get()) {
408 theError = "Attribute have empty context.";
412 GeomShapePtr aShape = aSelection->value();
413 GeomShapePtr aContextShape = aContext->shape();
415 aShape = aContextShape;
418 theError = "Empty shape selected.";
422 // Check that shape has acceptable type.
423 if(aShape->shapeType() != GeomAPI_Shape::EDGE && aShape->shapeType() != GeomAPI_Shape::WIRE) {
424 theError = "Selected shape has wrong type. Only edges and wires acceptable.";
428 // Check that it is edge on sketch.
429 ResultConstructionPtr aConstruction = std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
430 if(aConstruction.get()) {
431 if(aConstruction->isInfinite()) {
432 theError = "Inifinte objects not acceptable.";
436 std::shared_ptr<GeomAPI_PlanarEdges> anEdges = std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContextShape);
438 // It is not an edge on the sketch.
439 // Check that it is not local selection.
440 if(!aShape->isEqual(aContextShape)) {
441 // Local selection on body does not allowed.
442 theError = "Selected shape is in the local selection. Only global selection is allowed.";
448 aListOfShapes.push_back(aShape);
452 GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes);
454 theError = "Result wire empty. Probably it has disconnected edges or non-manifold.";