Salome HOME
68857aa2623b8687ddeb06fb4aa5709950f87096
[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_Edge.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* anEdgeValidator = 
52       dynamic_cast<const GeomValidators_Edge*>(aFactory->validator("GeomValidators_Edge"));
53     std::list<std::string> anArguments;
54     anArguments.push_back("circle");
55     bool anEdgeValid = anEdgeValidator->isValid(aRefAttr, anArguments);
56     // the circle line is not a valid case
57     if (anEdgeValid)
58       return false;
59       
60     anArguments.clear();
61     anArguments.push_back("line");
62     anEdgeValid = anEdgeValidator->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 (!anEdgeValid)
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<GeomDataAPI_Point2D> aPoint = SketcherPrs_Tools::getFeaturePoint(aFeature->data(), aParamA);
70     if (aPoint)
71       return true;
72   }
73   return false;
74 }
75 bool SketchPlugin_TangentAttrValidator::isValid(
76   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
77 {
78   // there is a check whether the feature contains a point and a linear edge or two point values
79   std::string aParamA = theArguments.front();
80   SessionPtr aMgr = ModelAPI_Session::get();
81   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
82
83   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
84   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
85   if (!aRefAttr)
86     return false;
87
88   bool isObject = aRefAttr->isObject();
89   ObjectPtr anObject = aRefAttr->object();
90   if (isObject && anObject) {
91     FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
92
93     AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
94     ObjectPtr aOtherObject = aOtherAttr->object();
95     FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
96
97     if (aRefFea->getKind() == SketchPlugin_Line::ID()) {
98       if (aOtherFea->getKind() != SketchPlugin_Arc::ID())
99         return false;
100     } else if (aRefFea->getKind() == SketchPlugin_Arc::ID()) {
101       if (aOtherFea->getKind() != SketchPlugin_Line::ID() &&
102           aOtherFea->getKind() != SketchPlugin_Arc::ID())
103         return false;
104     } else
105       return false;
106
107     // check that both have coincidence
108     FeaturePtr aConstrFeature;
109     std::set<FeaturePtr> aCoinList;
110     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aRefsList = aRefFea->data()->refsToMe();
111     std::set<std::shared_ptr<ModelAPI_Attribute>>::const_iterator aIt;
112     for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
113       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
114       aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
115       if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID()) {
116         AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
117         AttributePtr aAR = aRAttr->attr();
118         if (aAR->id() != SketchPlugin_Arc::CENTER_ID()) // ignore constraint to center of arc
119           aCoinList.insert(aConstrFeature);
120       }
121     }
122     // if there is no coincidence then it is not valid
123     if (aCoinList.size() == 0)
124       return false;
125
126     // find that coincedence is the same
127     const std::set<std::shared_ptr<ModelAPI_Attribute>>& aOtherList = aOtherFea->data()->refsToMe();
128     std::set<FeaturePtr>::const_iterator aCoinsIt;
129     for (aIt = aOtherList.cbegin(); aIt != aOtherList.cend(); ++aIt) {
130       std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
131       aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
132       aCoinsIt = aCoinList.find(aConstrFeature);
133       if (aCoinsIt != aCoinList.end()) {
134         AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(aAttr);
135         AttributePtr aAR = aRAttr->attr();
136         if (aAR->id() != SketchPlugin_Arc::CENTER_ID())
137           return true;
138       }
139     }
140   }
141   return false;
142 }
143
144 bool SketchPlugin_NotFixedValidator::isValid(
145     const AttributePtr& theAttribute, const std::list<std::string>& theArguments) const
146 {
147   std::shared_ptr<SketchPlugin_Feature> aFeature =
148       std::dynamic_pointer_cast<SketchPlugin_Feature>(theAttribute->owner());
149   if (!aFeature)
150     return true;
151
152   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
153   if (!aRefAttr)
154     return false;
155
156   SketchPlugin_Sketch* aSketch = aFeature->sketch();
157   int aNbFeatures = aSketch->numberOfSubs();
158   for (int anInd = 0; anInd < aNbFeatures; anInd++) {
159     FeaturePtr aSubFeature = aSketch->subFeature(anInd);
160     if (aSubFeature->getKind() != SketchPlugin_ConstraintRigid::ID() || aSubFeature == aFeature)
161       continue;
162     AttributeRefAttrPtr aRAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
163         aSubFeature->attribute(SketchPlugin_ConstraintRigid::ENTITY_A()));
164     if (aRefAttr->isObject()) {
165       if (aRefAttr->object() == aRAttr->object())
166         return false;
167     } else if (aRefAttr->attr() == aRAttr->attr())
168       return false;
169   }
170   return true;
171 }
172
173 bool SketchPlugin_EqualAttrValidator::isValid(
174   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
175 {
176   std::string aParamA = theArguments.front();
177   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
178   AttributeRefAttrPtr aRefAttr[2];
179   aRefAttr[0] = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
180   if (!aRefAttr)
181     return false;
182   aRefAttr[1] = aFeature->data()->refattr(aParamA);
183
184   if (!aRefAttr[0]->isObject() || !aRefAttr[1]->isObject())
185     return false;
186
187   int aType[2] = {0, 0}; // types of attributes: 0 - incorrect, 1 - line, 2 - circle, 3 - arc
188   std::list<std::string> anArguments;
189   for (int i = 0; i < 2; i++) {
190     ObjectPtr anObject = aRefAttr[i]->object();
191     aFeature = ModelAPI_Feature::feature(anObject);
192     if (!aFeature)
193       return false;
194
195     if (aFeature->getKind() == SketchPlugin_Line::ID()) {
196       aType[i] = 1;
197       continue;
198     }
199     if (aFeature->getKind() == SketchPlugin_Circle::ID()) {
200       aType[i] = 2;
201       continue;
202     }
203     if (aFeature->getKind() == SketchPlugin_Arc::ID()) {
204       aType[i] = 3;
205       continue;
206     }
207     // wrong type of attribute
208     return false;
209   }
210
211   if ((aType[0] == 1 && aType[1] == 2) ||
212       (aType[0] == 2 && aType[1] == 1))
213     return false;
214   return true;
215 }
216
217 bool SketchPlugin_MirrorAttrValidator::isValid(
218   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
219 {
220   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
221   AttributeSelectionListPtr aSelAttr = 
222     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
223   if (!aSelAttr)
224     return false;
225
226   AttributeRefListPtr aRefListOfMirrored = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
227       aFeature->attribute(SketchPlugin_Constraint::ENTITY_C()));
228   std::list<ObjectPtr> aMirroredObjects = aRefListOfMirrored->list();
229
230   for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
231     std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aSelAttr->value(anInd);
232     std::list<ObjectPtr>::iterator aMirIter = aMirroredObjects.begin();
233     for (; aMirIter != aMirroredObjects.end(); aMirIter++)
234       if (aSelect->context() == *aMirIter)
235         return false;
236   }
237   return true;
238 }
239
240
241 bool SketchPlugin_CoincidenceAttrValidator::isValid(
242   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
243 {
244   // there is a check whether the feature contains a point and a linear edge or two point values
245   std::string aParamA = theArguments.front();
246   SessionPtr aMgr = ModelAPI_Session::get();
247   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
248
249   FeaturePtr aConstraint = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
250   AttributeRefAttrPtr aRefAttrA = aConstraint->data()->refattr(aParamA);
251   if (!aRefAttrA)
252     return false;
253
254   AttributeRefAttrPtr aRefAttrB = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
255   if (!aRefAttrB)
256     return false;
257
258   // first attribute is a point, it may coincide with any object
259   if (!aRefAttrA->isObject())
260     return true;
261   else {
262     FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrA->object());
263     if (!aFeature)
264       return false;
265     if (aFeature->getKind() == SketchPlugin_Point::ID())
266       return true;
267   }
268
269   // second attribute is a point, it may coincide with any object
270   if (!aRefAttrB->isObject())
271     return true;
272   else {
273     FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttrB->object());
274     if (!aFeature)
275       return false;
276     if (aFeature->getKind() == SketchPlugin_Point::ID())
277       return true;
278   }
279
280   return false;
281 }
282
283
284 bool SketchPlugin_CopyValidator::isValid(
285   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
286 {
287   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
288   AttributeSelectionListPtr aSelAttr = 
289     std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
290   if (!aSelAttr)
291     return false;
292
293   AttributeRefListPtr aRefListOfInitial = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
294       aFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
295   AttributeRefListPtr aRefListOfCopied = std::dynamic_pointer_cast<ModelAPI_AttributeRefList>(
296       aFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
297   std::list<ObjectPtr> anInitialObjects = aRefListOfInitial->list();
298   std::list<ObjectPtr> aCopiedObjects = aRefListOfCopied->list();
299
300   std::list<ObjectPtr>::iterator anObjIter;
301   for(int anInd = 0; anInd < aSelAttr->size(); anInd++) {
302     std::shared_ptr<ModelAPI_AttributeSelection> aSelect = aSelAttr->value(anInd);
303     anObjIter = anInitialObjects.begin();
304     for (; anObjIter != anInitialObjects.end(); anObjIter++)
305       if (aSelect->context() == *anObjIter)
306         break;
307     if (anObjIter != anInitialObjects.end())
308       continue;
309     anObjIter = aCopiedObjects.begin();
310     for (; anObjIter != aCopiedObjects.end(); anObjIter++)
311       if (aSelect->context() == *anObjIter)
312         return false;
313   }
314   return true;
315 }
316