]> SALOME platform Git repositories - modules/shaper.git/blob - src/PartSet/PartSet_Validators.cpp
Salome HOME
Create mirror symbols
[modules/shaper.git] / src / PartSet / PartSet_Validators.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D
2
3 // File:        PartSet_Validators.cpp
4 // Created:     09 July 2014
5 // Author:      Vitaly SMETANNIKOV
6
7 #include "PartSet_Validators.h"
8
9 #include <TopoDS.hxx>
10 #include <TopoDS_Edge.hxx>
11 #include <BRep_Tool.hxx>
12 #include <GeomAdaptor_Curve.hxx>
13 #include <GeomAbs_CurveType.hxx>
14 #include <GeomValidators_Tools.h>
15 #include <ModuleBase_ISelection.h>
16 #include <ModuleBase_WidgetShapeSelector.h>
17
18 #include <ModelAPI_AttributeRefAttr.h>
19 #include <ModelAPI_AttributeSelection.h>
20 #include <ModelAPI_AttributeReference.h>
21 #include <ModelAPI_AttributeSelectionList.h>
22 #include <ModelAPI_Object.h>
23 #include <ModelAPI_Session.h>
24
25 #include <SketchPlugin_Sketch.h>
26
27 #include <list>
28 #ifdef _DEBUG
29 #include <iostream>
30 #endif
31
32 int shapesNbPoints(const ModuleBase_ISelection* theSelection)
33 {
34   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();  
35   int aCount = 0;
36   foreach (ModuleBase_ViewerPrs aPrs, aList) {
37     const TopoDS_Shape& aShape = aPrs.shape();
38     if (!aShape.IsNull()) {
39       if (aShape.ShapeType() == TopAbs_VERTEX)
40         aCount++;
41     }
42   }
43   return aCount;
44 }
45
46 int shapesNbLines(const ModuleBase_ISelection* theSelection)
47 {
48   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
49   int aCount = 0;
50   foreach(ModuleBase_ViewerPrs aPrs, aList) {
51     const TopoDS_Shape& aShape = aPrs.shape();
52     if (!aShape.IsNull()) {
53       if (aShape.ShapeType() == TopAbs_EDGE) {
54         TopoDS_Edge aEdge = TopoDS::Edge(aShape);
55         Standard_Real aStart, aEnd;
56         Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
57         GeomAdaptor_Curve aAdaptor(aCurve);
58         if (aAdaptor.GetType() == GeomAbs_Line)
59           aCount++;
60       }
61     }
62   }
63   return aCount;
64 }
65
66 bool PartSet_DistanceSelection::isValid(const ModuleBase_ISelection* theSelection) const
67 {
68   int aCount = shapesNbPoints(theSelection) + shapesNbLines(theSelection);
69   return (aCount > 0) && (aCount < 3);
70 }
71
72 bool PartSet_LengthSelection::isValid(const ModuleBase_ISelection* theSelection) const
73 {
74   int aCount = shapesNbLines(theSelection);
75   return (aCount == 1);
76 }
77
78 bool PartSet_PerpendicularSelection::isValid(const ModuleBase_ISelection* theSelection) const
79 {
80   int aCount = shapesNbLines(theSelection);
81   return (aCount > 0) && (aCount < 3);
82 }
83
84 bool PartSet_ParallelSelection::isValid(const ModuleBase_ISelection* theSelection) const
85 {
86   int aCount = shapesNbLines(theSelection);
87   return (aCount > 0) && (aCount < 3);
88 }
89
90 bool PartSet_RadiusSelection::isValid(const ModuleBase_ISelection* theSelection) const
91 {
92   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
93   ModuleBase_ViewerPrs aPrs;
94   int aCount = 0;
95   foreach (ModuleBase_ViewerPrs aPrs, aList) {
96     const TopoDS_Shape& aShape = aPrs.shape();
97     if (!aShape.IsNull()) {
98       if (aShape.ShapeType() == TopAbs_EDGE) {
99         TopoDS_Edge aEdge = TopoDS::Edge(aShape);
100         Standard_Real aStart, aEnd;
101         Handle(Geom_Curve) aCurve = BRep_Tool::Curve(aEdge, aStart, aEnd);
102         GeomAdaptor_Curve aAdaptor(aCurve);
103         if (aAdaptor.GetType() == GeomAbs_Circle)
104           aCount++;
105       }
106     }
107   }
108   return (aCount == 1);
109 }
110
111 bool PartSet_RigidSelection::isValid(const ModuleBase_ISelection* theSelection) const
112 {
113   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();  
114   return (aList.count() == 1);
115 }
116
117
118 bool PartSet_CoincidentSelection::isValid(const ModuleBase_ISelection* theSelection) const
119 {
120   int aCount = shapesNbPoints(theSelection);
121   return (aCount > 0) && (aCount < 3);
122 }
123
124 bool PartSet_HVDirSelection::isValid(const ModuleBase_ISelection* theSelection) const
125 {
126   int aCount = shapesNbLines(theSelection);
127   return (aCount == 1);
128 }
129
130 bool PartSet_TangentSelection::isValid(const ModuleBase_ISelection* theSelection) const
131 {
132   QList<ModuleBase_ViewerPrs> aList = theSelection->getSelected();
133   ModuleBase_ViewerPrs aPrs;
134   if (aList.size() != 2)
135     return false;
136
137   ModuleBase_ViewerPrs aPrs1 = aList.first();
138   ModuleBase_ViewerPrs aPrs2 = aList.last();
139
140   const TopoDS_Shape& aShape1 = aPrs1.shape();
141   const TopoDS_Shape& aShape2 = aPrs2.shape();
142   if (aShape1.IsNull() || aShape2.IsNull())
143     return false;
144
145   if ((aShape1.ShapeType() != TopAbs_EDGE) || (aShape2.ShapeType() != TopAbs_EDGE))
146     return false;
147
148   TopoDS_Edge aEdge1 = TopoDS::Edge(aShape1);
149   TopoDS_Edge aEdge2 = TopoDS::Edge(aShape2);
150
151   Standard_Real aStart, aEnd;
152   Handle(Geom_Curve) aCurve1 = BRep_Tool::Curve(aEdge1, aStart, aEnd);
153   Handle(Geom_Curve) aCurve2 = BRep_Tool::Curve(aEdge2, aStart, aEnd);
154
155   GeomAdaptor_Curve aAdaptor1(aCurve1);
156   GeomAdaptor_Curve aAdaptor2(aCurve2);
157   if (aAdaptor1.GetType() == GeomAbs_Circle)
158     return aAdaptor2.GetType() == GeomAbs_Line;
159   else if (aAdaptor2.GetType() == GeomAbs_Circle)
160     return aAdaptor1.GetType() == GeomAbs_Line;
161   return false;
162 }
163
164
165 bool PartSet_DifferentObjectsValidator::isValid(const AttributePtr& theAttribute, 
166                                                 const std::list<std::string>& theArguments) const
167 {
168   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
169
170   // the type of validated attributes should be equal, attributes with different types are not validated
171   // Check RefAttr attributes
172   std::string anAttrType = theAttribute->attributeType();
173   std::list<std::shared_ptr<ModelAPI_Attribute> > anAttrs;
174
175   if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
176     AttributeRefAttrPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
177     bool isObject = anAttr->isObject();
178     ObjectPtr anObject = anAttr->object();
179     AttributePtr anAttributeAttr = anAttr->attr();
180
181     anAttrs = aFeature->data()->attributes(ModelAPI_AttributeRefAttr::typeId());
182     if (anAttrs.size() > 0) {
183       std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
184       for(; anAttr != anAttrs.end(); anAttr++) {
185       if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
186           std::shared_ptr<ModelAPI_AttributeRefAttr> aRef =
187                                       std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anAttr);
188           if (aRef->isObject() != isObject)
189             continue;
190           if (isObject) {
191             if (aRef->object() == anObject)
192               return false;
193           }
194           else { // the attribute reference
195             if (aRef->attr() == theAttribute)
196               return false;
197           }
198         }
199       }
200     }
201   }
202   else if (anAttrType == ModelAPI_AttributeRefAttr::typeId()) {
203     AttributeSelectionPtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(theAttribute);
204     ResultPtr aContext = anAttr->context();
205     GeomShapePtr aShape = anAttr->value();
206
207     // Check selection attributes
208     anAttrs = aFeature->data()->attributes(ModelAPI_AttributeSelection::typeId());
209     if (anAttrs.size() > 0) {
210       std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
211       for(; anAttr != anAttrs.end(); anAttr++) {
212         if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
213           std::shared_ptr<ModelAPI_AttributeSelection> aRef =
214                                         std::dynamic_pointer_cast<ModelAPI_AttributeSelection>(*anAttr);
215           // check the object is already presented
216           if (aRef->context() == aContext) {
217             bool aHasShape = aShape.get() != NULL;
218             if (!aHasShape || aRef->value()->isEqual(aShape))
219               return false;
220           }
221         }
222       }
223     }
224   }
225   else if (anAttrType == ModelAPI_AttributeReference::typeId()) {
226     AttributeReferencePtr anAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(theAttribute);
227     ObjectPtr anObject = anAttr->value();
228     // Check selection attributes
229     anAttrs = aFeature->data()->attributes(ModelAPI_AttributeReference::typeId());
230     if (anAttrs.size() > 0) {
231       std::list<std::shared_ptr<ModelAPI_Attribute> >::iterator anAttr = anAttrs.begin();
232       for(; anAttr != anAttrs.end(); anAttr++) {
233         if ((*anAttr).get() && (*anAttr)->id() != theAttribute->id()) {
234           std::shared_ptr<ModelAPI_AttributeReference> aRef =
235             std::dynamic_pointer_cast<ModelAPI_AttributeReference>(*anAttr);
236           // check the object is already presented
237           if (aRef->value() == anObject)
238             return false;
239         }
240         return true;
241       }
242     }
243   }
244   return !featureHasReferences(theAttribute);
245 }
246
247 bool PartSet_DifferentObjectsValidator::featureHasReferences(const AttributePtr& theAttribute) const
248 {
249   std::list<std::pair<std::string, std::list<ObjectPtr> > > allRefs;
250   if (theAttribute->owner().get() && theAttribute->owner()->data().get())
251     theAttribute->owner()->data()->referencesToObjects(allRefs);
252   // collect object referenced by theAttribute
253   std::list<ObjectPtr>* anAttrObjs = 0;
254   std::list<std::pair<std::string, std::list<ObjectPtr> > >::iterator aRefIter = allRefs.begin();
255   for(; aRefIter != allRefs.end(); aRefIter++) {
256     if (theAttribute->id() == aRefIter->first)
257       anAttrObjs = &(aRefIter->second);
258   }
259   if (!anAttrObjs || anAttrObjs->empty())
260     return false; // theAttribute does not references to anything
261   // check with all others
262   for(aRefIter = allRefs.begin(); aRefIter != allRefs.end(); aRefIter++) {
263     if (theAttribute->id() == aRefIter->first)
264       continue; // do not check with myself
265     std::list<ObjectPtr>::iterator aReferenced = aRefIter->second.begin();
266     for(; aReferenced != aRefIter->second.end(); aReferenced++) {
267       std::list<ObjectPtr>::iterator aReferencedByMe = anAttrObjs->begin();
268       for(; aReferencedByMe != anAttrObjs->end(); aReferencedByMe++) {
269         if (*aReferenced == *aReferencedByMe) // found same objects!
270           return true;
271       }
272     }
273   }
274   return false;
275 }
276
277 bool PartSet_SketchEntityValidator::isValid(const AttributePtr& theAttribute,
278                                             const std::list<std::string>& theArguments) const
279 {
280   bool isSketchEntities = true;
281   std::set<std::string> anEntityKinds;
282   std::list<std::string>::const_iterator anIt = theArguments.begin(), aLast = theArguments.end();
283   for (; anIt != aLast; anIt++) {
284     anEntityKinds.insert(*anIt);
285   }
286
287   std::string anAttributeType = theAttribute->attributeType();
288   if (anAttributeType == ModelAPI_AttributeSelectionList::typeId()) {
289     AttributeSelectionListPtr aSelectionListAttr = 
290                       std::dynamic_pointer_cast<ModelAPI_AttributeSelectionList>(theAttribute);
291     // it filters only selection list attributes
292     std::string aType = aSelectionListAttr->selectionType().c_str();
293     // all context objects should be sketch entities
294     int aSize = aSelectionListAttr->size();
295     for (int i = 0; i < aSelectionListAttr->size() && isSketchEntities; i++) {
296       AttributeSelectionPtr aSelectAttr = aSelectionListAttr->value(i);
297       ObjectPtr anObject = aSelectAttr->context();
298       // a context of the selection attribute is a feature result. It can be a case when the result
299       // of the feature is null, e.g. the feature is modified and has not been executed yet.
300       // The validator returns an invalid result here. The case is an extrusion built on a sketch
301       // feature. A new sketch element creation leads to an empty result.
302       if (!anObject.get())
303         isSketchEntities = false;
304       else {
305         FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
306         isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
307       }
308     }
309   }
310   if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
311     std::shared_ptr<ModelAPI_AttributeRefAttr> aRef = 
312                      std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
313     isSketchEntities = false;
314     if (aRef->isObject()) {
315       ObjectPtr anObject = aRef->object();
316       if (anObject.get() != NULL) {
317         FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
318         if (aFeature.get() != NULL)
319           isSketchEntities = anEntityKinds.find(aFeature->getKind()) != anEntityKinds.end();
320       }
321     }
322   }
323
324   return isSketchEntities;
325 }
326
327
328
329 bool PartSet_SameTypeAttrValidator::isValid(
330   const AttributePtr& theAttribute, const std::list<std::string>& theArguments ) const
331 {
332   // there is a check whether the feature contains a point and a linear edge or two point values
333   std::string aParamA = theArguments.front();
334   SessionPtr aMgr = ModelAPI_Session::get();
335   ModelAPI_ValidatorsFactory* aFactory = aMgr->validators();
336
337   FeaturePtr aFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(theAttribute->owner());
338   AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
339   if (!aRefAttr)
340     return false;
341
342   bool isObject = aRefAttr->isObject();
343   ObjectPtr anObject = aRefAttr->object();
344   if (isObject && anObject) {
345     FeaturePtr aRefFea = ModelAPI_Feature::feature(anObject);
346
347     AttributeRefAttrPtr aOtherAttr = aFeature->data()->refattr(aParamA);
348     ObjectPtr aOtherObject = aOtherAttr->object();
349     FeaturePtr aOtherFea = ModelAPI_Feature::feature(aOtherObject);
350     return aRefFea->getKind() == aOtherFea->getKind();
351   }
352   return false;
353 }
354