1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: BuildPlugin_Validators.cpp
4 // Created: 22 March 2016
5 // Author: Dmitry Bobylev
7 #include "BuildPlugin_Validators.h"
9 #include <ModelAPI_AttributeSelectionList.h>
10 #include <ModelAPI_ResultConstruction.h>
12 #include <GeomAPI_PlanarEdges.h>
13 #include <GeomAPI_Pln.h>
14 #include <GeomAPI_ShapeExplorer.h>
16 #include <GeomAlgoAPI_CompoundBuilder.h>
17 #include <GeomAlgoAPI_PaveFiller.h>
18 #include <GeomAlgoAPI_ShapeBuilder.h>
19 #include <GeomAlgoAPI_ShapeTools.h>
20 #include <GeomAlgoAPI_SketchBuilder.h>
21 #include <GeomAlgoAPI_WireBuilder.h>
23 #include <GeomValidators_FeatureKind.h>
24 #include <GeomValidators_ShapeType.h>
26 #include <Events_InfoMessage.h>
28 //=================================================================================================
29 bool BuildPlugin_ValidatorBaseForBuild::isValid(const AttributePtr& theAttribute,
30 const std::list<std::string>& theArguments,
31 Events_InfoMessage& theError) const
33 // Get base objects list.
34 if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
35 std::string aMsg = "Error: BuildPlugin_ValidatorBaseForBuild does "
36 "not support attribute type '%1'\nOnly '%2' is supported.";
37 Events_InfoMessage("BuildPlugin_Validators", aMsg).
38 arg(theAttribute->attributeType()).arg(ModelAPI_AttributeSelectionList::typeId()).send();
41 AttributeSelectionListPtr aSelectionList =
42 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
43 if(!aSelectionList.get()) {
44 theError = "Could not get selection list.";
47 if(aSelectionList->size() == 0) {
48 theError = "Empty selection list.";
52 // Collect base shapes.
53 for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
54 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
55 if(!aSelection.get()) {
56 theError = "Could not get selection.";
59 ResultPtr aContext = aSelection->context();
61 theError = "Attribute have empty context.";
65 GeomShapePtr aShape = aSelection->value();
66 GeomShapePtr aContextShape = aContext->shape();
68 aShape = aContextShape;
71 theError = "Empty shape selected.";
75 // Check that shapes has acceptable type.
76 GeomValidators_ShapeType aValidatorShapeType;
77 if(!aValidatorShapeType.isValid(aSelection, theArguments, theError)) {
81 // Check that it is shape on sketch.
82 ResultConstructionPtr aConstruction =
83 std::dynamic_pointer_cast<ModelAPI_ResultConstruction>(aContext);
84 if(aConstruction.get()) {
85 if(aConstruction->isInfinite()) {
86 theError = "Inifinte objects not acceptable.";
90 std::shared_ptr<GeomAPI_PlanarEdges> anEdges =
91 std::dynamic_pointer_cast<GeomAPI_PlanarEdges>(aContextShape);
93 if(aShape->isEqual(aContextShape)) {
94 // It is whole sketch.
102 if(!aShape->isEqual(aContextShape)) {
103 // Local selection on body does not allowed.
104 theError = "Selected shape is in the local selection. Only global selection is allowed.";
112 //=================================================================================================
113 bool BuildPlugin_ValidatorBaseForWire::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
114 const std::list<std::string>& theArguments,
115 Events_InfoMessage& theError) const
118 if(theArguments.size() != 1) {
119 std::string aMsg = "Error: BuildPlugin_ValidatorBaseForWire should be used only "
120 "with 1 parameter (ID of base objects list).";
121 Events_InfoMessage("BuildPlugin_Validators", aMsg).send();
124 AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
125 if(!aSelectionList.get()) {
126 theError = "Empty attribute \"%1\".";
127 theError.arg(theArguments.front());
132 // Collect base shapes.
133 ListOfShape aListOfShapes;
134 for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
135 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
136 GeomShapePtr aShape = aSelection->value();
138 if (aSelection->context().get())
139 aShape = aSelection->context()->shape();
142 aListOfShapes.push_back(aShape);
146 GeomShapePtr aWire = GeomAlgoAPI_WireBuilder::wire(aListOfShapes);
148 theError = "Result wire empty. Probably it has disconnected edges or non-manifold.";
155 //=================================================================================================
156 bool BuildPlugin_ValidatorBaseForWire::isNotObligatory(std::string theFeature,
157 std::string theAttribute)
162 //=================================================================================================
163 bool BuildPlugin_ValidatorBaseForFace::isValid(const std::shared_ptr<ModelAPI_Feature>& theFeature,
164 const std::list<std::string>& theArguments,
165 Events_InfoMessage& theError) const
168 if(theArguments.size() != 1) {
169 std::string aMsg = "Error: BuildPlugin_ValidatorBaseForFace should be used only with "
170 "1 parameter (ID of base objects list).";
171 Events_InfoMessage("BuildPlugin_Validators", aMsg).send();
174 AttributeSelectionListPtr aSelectionList = theFeature->selectionList(theArguments.front());
175 if(!aSelectionList.get()) {
176 theError = "Empty attribute \"%1\".";
177 theError.arg(theArguments.front());
181 // Collect base shapes.
183 for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
184 AttributeSelectionPtr aSelection = aSelectionList->value(anIndex);
185 GeomShapePtr aShape = aSelection->value();
187 aShape = aSelection->context()->shape();
189 for(GeomAPI_ShapeExplorer anExp(aShape, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
190 GeomShapePtr anEdge = anExp.current();
191 anEdges.push_back(anEdge);
195 if(anEdges.empty()) {
196 theError = "Objects not selected.";
200 // Check that edges does not have intersections.
201 if(anEdges.size() > 1) {
202 GeomAlgoAPI_PaveFiller aPaveFiller(anEdges, false);
203 if(!aPaveFiller.isDone()) {
204 theError = "Error while checking if edges intersects.";
207 GeomShapePtr aSectedEdges = aPaveFiller.shape();
210 for(GeomAPI_ShapeExplorer
211 anExp(aSectedEdges, GeomAPI_Shape::EDGE); anExp.more(); anExp.next()) {
214 if(anEdgesNum != anEdges.size()) {
215 theError = "Selected objects have intersections.";
220 // Check that they are planar.
221 std::shared_ptr<GeomAPI_Pln> aPln = GeomAlgoAPI_ShapeTools::findPlane(anEdges);
223 theError = "Selected object(s) should belong to only one plane.";
227 // Check that selected objects have closed contours.
229 GeomAlgoAPI_SketchBuilder::createFaces(aPln->location(), aPln->xDirection(),
230 aPln->direction(), anEdges, aFaces);
232 theError = "Selected objects do not generate closed contour.";
239 //=================================================================================================
240 bool BuildPlugin_ValidatorBaseForFace::isNotObligatory(std::string theFeature,
241 std::string theAttribute)
246 //=================================================================================================
247 bool BuildPlugin_ValidatorSubShapesSelection::isValid(const AttributePtr& theAttribute,
248 const std::list<std::string>& theArguments,
249 Events_InfoMessage& theError) const
251 if(theArguments.size() != 1) {
252 std::string aMsg = "Error: BuildPlugin_ValidatorSubShapesSelection should be used only with "
253 "1 parameter(Sketch feature id).";
254 Events_InfoMessage("BuildPlugin_Validators", aMsg).send();
258 // Get base objects list.
259 if(theAttribute->attributeType() != ModelAPI_AttributeSelectionList::typeId()) {
261 "Error: BuildPlugin_ValidatorSubShapesSelection does not support attribute type \""
262 "%1\"\n Only \"%2\" supported.";
263 Events_InfoMessage("BuildPlugin_Validators", aMsg).
264 arg(theAttribute->attributeType()).arg(ModelAPI_AttributeSelectionList::typeId()).send();
267 AttributeSelectionListPtr aSelectionList =
268 std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
269 if(!aSelectionList.get()) {
270 theError = "Could not get selection list.";
275 const std::string aBaseShapeId = "base_shape";
276 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
277 AttributeSelectionPtr aShapeAttrSelection = aFeature->selection(aBaseShapeId);
279 if(!aShapeAttrSelection.get()) {
280 theError = "Base shape is empty.";
284 ResultPtr aBaseContext = aShapeAttrSelection->context();
286 GeomShapePtr aBaseShape = aShapeAttrSelection->value();
287 if(!aBaseShape.get()) {
288 theError = "Base shape is empty.";
292 GeomAlgoAPI_ShapeBuilder aBuilder;
293 aBuilder.removeInternal(aBaseShape);
294 aBaseShape = aBuilder.shape();
296 // If selected shape is wire allow to select only vertices. If face - allow vertices and edges.
297 std::set<GeomAPI_Shape::ShapeType> anAllowedTypes;
298 switch(aBaseShape->shapeType()) {
299 case GeomAPI_Shape::FACE: anAllowedTypes.insert(GeomAPI_Shape::EDGE);
300 case GeomAPI_Shape::WIRE: anAllowedTypes.insert(GeomAPI_Shape::VERTEX);
304 // Check selected shapes.
305 GeomValidators_FeatureKind aFeatureKindValidator;
306 std::list<std::string> anArguments;
307 anArguments.push_back(theArguments.front());
308 for(int anIndex = 0; anIndex < aSelectionList->size(); ++anIndex) {
309 AttributeSelectionPtr aSelectionAttrInList = aSelectionList->value(anIndex);
310 if(!aSelectionAttrInList.get()) {
311 theError = "Empty attribute in list.";
315 // If context of selection same skip.
316 if(aBaseContext == aSelectionAttrInList->context()) {
320 // Check that it is a selection on Sketch.
321 if(!aFeatureKindValidator.isValid(aSelectionAttrInList, anArguments, theError)) {
326 GeomShapePtr aShapeInList = aSelectionAttrInList->value();
327 if(!aShapeInList.get()) {
328 aShapeInList = aSelectionAttrInList->context()->shape();
330 if(anAllowedTypes.find(aShapeInList->shapeType()) == anAllowedTypes.cend()) {
331 theError = "Selected shape has unacceptable type.";
335 // Check that shape inside wire or face.
336 if(!GeomAlgoAPI_ShapeTools::isSubShapeInsideShape(aShapeInList, aBaseShape)) {
337 theError = "Selected shape is not inside base face.";