Salome HOME
Merge branch 'master' into cgt/devCEA
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Tools.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        SketchPlugin_Tools.cpp
4 // Created:     07 July 2015
5 // Author:      Sergey POKHODENKO
6
7 #include "SketchPlugin_Tools.h"
8
9 #include "SketchPlugin_ConstraintCoincidence.h"
10 #include "SketchPlugin_ConstraintTangent.h"
11 #include "SketchPlugin_Point.h"
12 #include "SketchPlugin_SketchEntity.h"
13
14 #include <SketcherPrs_Tools.h>
15
16 #include <ModelAPI_AttributeDouble.h>
17
18 #include <GeomDataAPI_Point.h>
19 #include <GeomDataAPI_Point2D.h>
20
21 namespace SketchPlugin_Tools {
22
23 void clearExpressions(AttributeDoublePtr theAttribute)
24 {
25   theAttribute->setText(std::string());
26 }
27
28 void clearExpressions(AttributePointPtr theAttribute)
29 {
30   theAttribute->setText(std::string(), std::string(), std::string());
31 }
32
33 void clearExpressions(AttributePoint2DPtr theAttribute)
34 {
35   theAttribute->setText(std::string(), std::string());
36 }
37
38 void clearExpressions(AttributePtr theAttribute)
39 {
40   // Double
41   AttributeDoublePtr anAttributeDouble =
42       std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
43   if (anAttributeDouble.get())
44     clearExpressions(anAttributeDouble);
45   // Point
46   AttributePointPtr anAttributePoint =
47       std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
48   if (anAttributePoint.get())
49     clearExpressions(anAttributePoint);
50   // Point2D
51   AttributePoint2DPtr anAttributePoint2D =
52       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
53   if (anAttributePoint2D.get())
54     clearExpressions(anAttributePoint2D);
55 }
56
57 void clearExpressions(FeaturePtr theFeature)
58 {
59   if (!theFeature.get())
60     return;
61
62   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
63   std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
64   for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
65     clearExpressions(*anAttributeIt);
66   }
67 }
68
69 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
70 {
71   std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
72                                                           SketchPlugin_Constraint::ENTITY_A());
73   if (aPnt.get() == NULL)
74     aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
75   return aPnt;
76 }
77
78 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
79 {
80   std::set<FeaturePtr> aCoincident;
81   const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
82   std::set<AttributePtr>::const_iterator aIt;
83   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
84     FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
85     if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
86       aCoincident.insert(aConstrFeature);
87   }
88   return aCoincident;
89 }
90
91 void findCoincidences(const FeaturePtr theStartCoin,
92                       const std::string& theAttr,
93                       std::set<FeaturePtr>& theList)
94 {
95   AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
96   if(!aPnt) {
97     return;
98   }
99   FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
100   if(theList.find(aObj) == theList.end()) {
101     std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
102     if(aOrig.get() == NULL) {
103       return;
104     }
105     theList.insert(aObj);
106     std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
107     std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
108     for (; aCIt != aCoincidences.end(); ++aCIt) {
109       FeaturePtr aConstrFeature = *aCIt;
110       std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
111       if(aPnt.get() && aOrig->isEqual(aPnt)) {
112         findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
113         findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
114       }
115     }
116   }
117 }
118
119 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
120 {
121   std::set<FeaturePtr> aCoincidentFeatures;
122
123   FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
124   aCoincidentFeatures.insert(anOwner);
125
126   std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
127   std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
128   for (; aCIt != aCoincidences.end(); ++aCIt) {
129     bool isPointUsedInCoincidence = false;
130     AttributeRefAttrPtr anOtherCoincidentAttr;
131     for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
132       AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
133       if (!aRefAttr)
134         continue;
135       if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
136         isPointUsedInCoincidence = true;
137       else
138         anOtherCoincidentAttr = aRefAttr;
139     }
140
141     if (isPointUsedInCoincidence) {
142       ObjectPtr anObj;
143       if (anOtherCoincidentAttr->isObject())
144         anObj = anOtherCoincidentAttr->object();
145       else
146         anObj = anOtherCoincidentAttr->attr()->owner();
147       aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
148     }
149   }
150
151   return aCoincidentFeatures;
152 }
153
154 void resetAttribute(SketchPlugin_Feature* theFeature,
155                     const std::string& theId)
156 {
157   AttributePtr anAttr = theFeature->attribute(theId);
158   if(anAttr.get()) {
159     anAttr->reset();
160   }
161 }
162
163 void createConstraint(SketchPlugin_Feature* theFeature,
164                       const std::string& theId,
165                       const AttributePtr theAttr,
166                       const ObjectPtr theObject,
167                       const bool theIsCanBeTangent)
168 {
169   AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
170   if(aRefAttr.get() && aRefAttr->isInitialized()) {
171     FeaturePtr aConstraint;
172     if(!theIsCanBeTangent) {
173       aConstraint = theFeature->sketch()
174                               ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
175     } else {
176       if(aRefAttr->isObject()) {
177         ObjectPtr anObject = aRefAttr->object();
178         FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
179         if(aFeature->getKind() == SketchPlugin_Point::ID()) {
180           aConstraint = theFeature->sketch()
181                                   ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
182         } else {
183           aConstraint = theFeature->sketch()
184                                   ->addFeature(SketchPlugin_ConstraintTangent::ID());
185         }
186       } else {
187         aConstraint = theFeature->sketch()
188                                 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
189       }
190     }
191     AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
192     aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
193                          : aRefAttrA->setAttr(aRefAttr->attr());
194     AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
195     if(theObject.get()) {
196       aRefAttrB->setObject(theObject);
197     } else if(theAttr.get()) {
198       aRefAttrB->setAttr(theAttr);
199     }
200   }
201 }
202
203 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr&      theRefAttr,
204                                          const AttributePtr&             theDefaultAttr,
205                                          std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
206                                          std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
207 {
208   AttributePtr anAttr = theDefaultAttr;
209   if (theRefAttr->isObject()) {
210     FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
211     if (aTgFeature) {
212       if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
213         theTangentCurve = aTgFeature->lastResult()->shape();
214         return;
215       }
216       anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
217     }
218   } else
219     anAttr = theRefAttr->attr();
220
221   thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
222 }
223
224 } // namespace SketchPlugin_Tools