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