Salome HOME
Issue #700 Fillet for edges with not shared point question
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Validators.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        SketchPlugin_Validators.cpp
4 // Created:     01 Aug 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "SketchPlugin_Validators.h"
8 #include "SketchPlugin_ConstraintDistance.h"
9 #include "SketchPlugin_ConstraintCoincidence.h"
10 #include "SketchPlugin_ConstraintRigid.h"
11 #include "SketchPlugin_Line.h"
12 #include "SketchPlugin_Arc.h"
13 #include "SketchPlugin_Circle.h"
14 #include "SketchPlugin_Point.h"
15
16 #include "SketcherPrs_Tools.h"
17
18 #include <ModelAPI_Data.h>
19 #include <ModelAPI_Validator.h>
20 #include <ModelAPI_AttributeDouble.h>
21 #include <ModelAPI_AttributeRefAttr.h>
22 #include <ModelAPI_AttributeRefList.h>
23 #include <ModelAPI_AttributeSelectionList.h>
24 #include <ModelAPI_Session.h>
25
26 #include <GeomValidators_ShapeType.h>
27
28 #include <GeomDataAPI_Point2D.h>
29
30
31 bool SketchPlugin_DistanceAttrValidator::isValid(
32   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
33 {
34   // there is a check whether the feature contains a point and a linear edge or two point values
35   std::string aParamA = theArguments.front();
36   SessionPtr aMgr = ModelAPI_Session::get();
37   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
38
39   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
40   if (!aRefAttr)
41     return false;
42
43   bool isObject = aRefAttr->isObject();
44   if (!isObject) {
45     // an attribute is a point. A point value is valid always for the distance
46     return true;
47   } else {
48     // 1. check whether the references object is a linear
49     ObjectPtr anObject = aRefAttr->object();
50
51     const ModelAPI_AttributeValidator* aShapeValidator = 
52       dynamic_cast<const GeomValidators_ShapeType*>(aFactory->validator("GeomValidators_ShapeType"));
53     std::list<std::string> anArguments;
54     anArguments.push_back("circle");
55     bool aShapeValid = aShapeValidator->isValid(aRefAttr, anArguments);
56     // the circle line is not a valid case
57     if (aShapeValid)
58       return false;
59       
60     anArguments.clear();
61     anArguments.push_back("line");
62     aShapeValid = aShapeValidator->isValid(aRefAttr, anArguments);
63     // if the attribute value is not a line, that means it is a vertex. A vertex is always valid
64     if (!aShapeValid)
65       return true;
66
67     FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
68     // If it is a line then we have to check that first attribute id not a line
69     std::shared_ptr<SketchPlugin_Feature> aSFeature =
70                             std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
71     SketchPlugin_Sketch* aSketch = aSFeature->sketch();
72     std::shared_ptr<GeomAPI_Ax3> aPlane = SketchPlugin_Sketch::plane(aSketch);
73     std::shared_ptr<GeomDataAPI_Point2D> aPoint = SketcherPrs_Tools::getFeaturePoint(
74                                                                aFeature->data(), aParamA, aPlane);
75     if (aPoint)
76       return true;
77   }
78   return false;
79 }
80
81 bool SketchPlugin_CoincidentAttr::isValid(
82   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
83 {
84   // there is a check whether the feature contains a point and a linear edge or two point values
85   std::string aParamA = theArguments.front();
86   SessionPtr aMgr = ModelAPI_Session::get();
87   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
88
89   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
90   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
91   if (!aRefAttr)
92     return false;
93
94   bool isObject = aRefAttr->isObject();
95   ObjectPtr anObject = aRefAttr->object();
96   if (isObject && anObject) {
97     FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
98     AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
99     ObjectPtr aOtherObject = aOtherAttr->object();
100     // if the other attribute is not filled still, the result is true
101     if (!aOtherObject.get())
102       return true;
103     FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
104
105     // check that both have coincidence
106     FeaturePtr aConstrFeature;
107     std::set<FeaturePtr> aCoinList;
108     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefsList = aRefFea->data()->refsToMe();
109     std::set<std::shared_ptr<ModelAPI_Attribute>>::const_iterator aIt;
110     for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
111       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
112       aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
113       if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
114         AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
115         AttributePtr aAR = aRAttr->attr();
116         if (aAR->id() != SketchPlugin_Arc::CENTER_ID()) // ignore constraint to center of arc
117           aCoinList.insert(aConstrFeature);
118       }
119     }
120     // if there is no coincidence then it is not valid
121     if (aCoinList.size() == 0)
122       return false;
123
124     // find that coincedence is the same
125     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aOtherList = aOtherFea->data()->refsToMe();
126     std::set<FeaturePtr>::const_iterator aCoinsIt;
127     for (aIt = aOtherList.cbegin(); aIt != aOtherList.cend(); ++aIt) {
128       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
129       aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
130       aCoinsIt = aCoinList.find(aConstrFeature);
131       if (aCoinsIt != aCoinList.end()) {
132         AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
133         AttributePtr aAR = aRAttr->attr();
134         if (aAR->id() != SketchPlugin_Arc::CENTER_ID())
135           return true;
136       }
137     }
138   }
139   return false;
140 }
141
142 bool SketchPlugin_TangentAttrValidator::isValid(
143   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
144 {
145   // there is a check whether the feature contains a point and a linear edge or two point values
146   std::string aParamA = theArguments.front();
147   SessionPtr aMgr = ModelAPI_Session::get();
148   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
149
150   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
151   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
152   if (!aRefAttr)
153     return false;
154
155   bool isObject = aRefAttr->isObject();
156   ObjectPtr anObject = aRefAttr->object();
157   if (isObject && anObject) {
158     FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
159
160     AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
161     ObjectPtr aOtherObject = aOtherAttr->object();
162     FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
163
164     if (aRefFea->getKind() == SketchPlugin_Line::ID()) {
165       if (aOtherFea->getKind() != SketchPlugin_Arc::ID())
166         return false;
167     } else if (aRefFea->getKind() == SketchPlugin_Arc::ID()) {
168       if (aOtherFea->getKind() != SketchPlugin_Line::ID() &&
169           aOtherFea->getKind() != SketchPlugin_Arc::ID())
170         return false;
171     } else
172       return false;
173
174     return true;
175   }
176   return false;
177 }
178
179 bool SketchPlugin_NotFixedValidator::isValid(
180     const AttributePtr& theAttribute, const std::list<std::string>& theArguments) const
181 {
182   std::shared_ptr<SketchPlugin_Feature> aFeature =
183       std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
184   if (!aFeature)
185     return true;
186
187   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
188   if (!aRefAttr)
189     return false;
190
191   SketchPlugin_Sketch* aSketch = aFeature->sketch();
192   int aNbFeatures = aSketch->numberOfSubs();
193   for (int anInd = 0; anInd < aNbFeatures; anInd++) {
194     FeaturePtr aSubFeature = aSketch->subFeature(anInd);
195     if (aSubFeature->getKind() != SketchPlugin_ConstraintRigid::ID() || aSubFeature == aFeature)
196       continue;
197     AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
198         aSubFeature->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
199     if (aRefAttr->isObject()) {
200       if (aRefAttr->object() == aRAttr->object())
201         return false;
202     } else if (aRefAttr->attr() == aRAttr->attr())
203       return false;
204   }
205   return true;
206 }
207
208 bool SketchPlugin_EqualAttrValidator::isValid(
209   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
210 {
211   std::string aParamA = theArguments.front();
212   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
213   AttributeRefAttrPtr aRefAttr[2];
214   aRefAttr[0] = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
215   if (!aRefAttr)
216     return false;
217   aRefAttr[1] = aFeature->data()->refattr(aParamA);
218
219   if (!aRefAttr[0]->isObject() || !aRefAttr[1]->isObject())
220     return false;
221
222   int aType[2] = {0, 0}; // types of attributes: 0 - incorrect, 1 - line, 2 - circle, 3 - arc
223   std::list<std::string> anArguments;
224   for (int i = 0; i < 2; i++) {
225     ObjectPtr anObject = aRefAttr[i]->object();
226     aFeature = ModelAPI_Feature::feature(anObject);
227     if (!aFeature)
228       return false;
229
230     if (aFeature->getKind() == SketchPlugin_Line::ID()) {
231       aType[i] = 1;
232       continue;
233     }
234     if (aFeature->getKind() == SketchPlugin_Circle::ID()) {
235       aType[i] = 2;
236       continue;
237     }
238     if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
239       aType[i] = 3;
240       continue;
241     }
242     // wrong type of attribute
243     return false;
244   }
245
246   if ((aType[0] == 1 && aType[1] == 2) ||
247       (aType[0] == 2 && aType[1] == 1))
248     return false;
249   return true;
250 }
251
252 bool SketchPlugin_MirrorAttrValidator::isValid(
253   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
254 {
255   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
256   AttributeSelectionListPtr aSelAttr = 
257     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
258   if (!aSelAttr)
259     return false;
260
261   AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
262       aFeature->attribute(SketchPlugin_Constraint::ENTITY_C()));
263   std::list<ObjectPtr> aMirroredObjects = aRefListOfMirrored->list();
264
265   for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
266     std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aSelAttr->value(anInd);
267     std::list<ObjectPtr>::iterator aMirIter = aMirroredObjects.begin();
268     for (; aMirIter != aMirroredObjects.end(); aMirIter++)
269       if (aSelect->context() == *aMirIter)
270         return false;
271   }
272   return true;
273 }
274
275
276 bool SketchPlugin_CoincidenceAttrValidator::isValid(
277   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
278 {
279   // there is a check whether the feature contains a point and a linear edge or two point values
280   std::string aParamA = theArguments.front();
281   SessionPtr aMgr = ModelAPI_Session::get();
282   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
283
284   FeaturePtr aConstraint = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
285   AttributeRefAttrPtr aRefAttrA = aConstraint->data()->refattr(aParamA);
286   if (!aRefAttrA)
287     return false;
288
289   AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
290   if (!aRefAttrB)
291     return false;
292
293   // first attribute is a point, it may coincide with any object
294   if (!aRefAttrA->isObject())
295     return true;
296   else {
297     FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrA->object());
298     if (!aFeature)
299       return false;
300     if (aFeature->getKind() == SketchPlugin_Point::ID())
301       return true;
302   }
303
304   // second attribute is a point, it may coincide with any object
305   if (!aRefAttrB->isObject())
306     return true;
307   else {
308     FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrB->object());
309     if (!aFeature)
310       return false;
311     if (aFeature->getKind() == SketchPlugin_Point::ID())
312       return true;
313   }
314
315   return false;
316 }
317
318
319 bool SketchPlugin_CopyValidator::isValid(
320   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
321 {
322   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
323   AttributeSelectionListPtr aSelAttr = 
324     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
325   if (!aSelAttr)
326     return false;
327
328   AttributeRefListPtr aRefListOfInitial = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
329       aFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
330   AttributeRefListPtr aRefListOfCopied = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
331       aFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
332   std::list<ObjectPtr> anInitialObjects = aRefListOfInitial->list();
333   std::list<ObjectPtr> aCopiedObjects = aRefListOfCopied->list();
334
335   std::list<ObjectPtr>::iterator anObjIter;
336   for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
337     std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aSelAttr->value(anInd);
338     anObjIter = anInitialObjects.begin();
339     for (; anObjIter != anInitialObjects.end(); anObjIter++)
340       if (aSelect->context() == *anObjIter)
341         break;
342     if (anObjIter != anInitialObjects.end())
343       continue;
344     anObjIter = aCopiedObjects.begin();
345     for (; anObjIter != aCopiedObjects.end(); anObjIter++)
346       if (aSelect->context() == *anObjIter)
347         return false;
348   }
349   return true;
350 }
351