]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchPlugin/SketchPlugin_Tools.cpp
Salome HOME
Add copyright header according to request of CEA from 06.06.2017
[modules/shaper.git] / src / SketchPlugin / SketchPlugin_Tools.cpp
1 // Copyright (C) 2014-2017  CEA/DEN, EDF R&D
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
16 //
17 // See http://www.salome-platform.org/ or email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
18 //
19
20 #include "SketchPlugin_Tools.h"
21
22 #include "SketchPlugin_ConstraintCoincidence.h"
23 #include "SketchPlugin_ConstraintTangent.h"
24 #include "SketchPlugin_Point.h"
25 #include "SketchPlugin_SketchEntity.h"
26
27 #include <SketcherPrs_Tools.h>
28
29 #include <ModelAPI_AttributeDouble.h>
30
31 #include <GeomDataAPI_Point.h>
32 #include <GeomDataAPI_Point2D.h>
33
34 namespace SketchPlugin_Tools {
35
36 void clearExpressions(AttributeDoublePtr theAttribute)
37 {
38   theAttribute->setText(std::string());
39 }
40
41 void clearExpressions(AttributePointPtr theAttribute)
42 {
43   theAttribute->setText(std::string(), std::string(), std::string());
44 }
45
46 void clearExpressions(AttributePoint2DPtr theAttribute)
47 {
48   theAttribute->setText(std::string(), std::string());
49 }
50
51 void clearExpressions(AttributePtr theAttribute)
52 {
53   // Double
54   AttributeDoublePtr anAttributeDouble =
55       std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
56   if (anAttributeDouble.get())
57     clearExpressions(anAttributeDouble);
58   // Point
59   AttributePointPtr anAttributePoint =
60       std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
61   if (anAttributePoint.get())
62     clearExpressions(anAttributePoint);
63   // Point2D
64   AttributePoint2DPtr anAttributePoint2D =
65       std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
66   if (anAttributePoint2D.get())
67     clearExpressions(anAttributePoint2D);
68 }
69
70 void clearExpressions(FeaturePtr theFeature)
71 {
72   if (!theFeature.get())
73     return;
74
75   std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
76   std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
77   for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
78     clearExpressions(*anAttributeIt);
79   }
80 }
81
82 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
83 {
84   std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
85                                                           SketchPlugin_Constraint::ENTITY_A());
86   if (aPnt.get() == NULL)
87     aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
88   return aPnt;
89 }
90
91 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
92 {
93   std::set<FeaturePtr> aCoincident;
94   const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
95   std::set<AttributePtr>::const_iterator aIt;
96   for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
97     FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
98     if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
99       aCoincident.insert(aConstrFeature);
100   }
101   return aCoincident;
102 }
103
104 void findCoincidences(const FeaturePtr theStartCoin,
105                       const std::string& theAttr,
106                       std::set<FeaturePtr>& theList)
107 {
108   AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
109   if(!aPnt) {
110     return;
111   }
112   FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
113   if(theList.find(aObj) == theList.end()) {
114     std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
115     if(aOrig.get() == NULL) {
116       return;
117     }
118     theList.insert(aObj);
119     std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
120     std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
121     for (; aCIt != aCoincidences.end(); ++aCIt) {
122       FeaturePtr aConstrFeature = *aCIt;
123       std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
124       if(aPnt.get() && aOrig->isEqual(aPnt)) {
125         findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(), theList);
126         findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(), theList);
127       }
128     }
129   }
130 }
131
132 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
133 {
134   std::set<FeaturePtr> aCoincidentFeatures;
135
136   FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
137   aCoincidentFeatures.insert(anOwner);
138
139   std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
140   std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
141   for (; aCIt != aCoincidences.end(); ++aCIt) {
142     bool isPointUsedInCoincidence = false;
143     AttributeRefAttrPtr anOtherCoincidentAttr;
144     for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
145       AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
146       if (!aRefAttr)
147         continue;
148       if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
149         isPointUsedInCoincidence = true;
150       else
151         anOtherCoincidentAttr = aRefAttr;
152     }
153
154     if (isPointUsedInCoincidence) {
155       ObjectPtr anObj;
156       if (anOtherCoincidentAttr->isObject())
157         anObj = anOtherCoincidentAttr->object();
158       else
159         anObj = anOtherCoincidentAttr->attr()->owner();
160       aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
161     }
162   }
163
164   return aCoincidentFeatures;
165 }
166
167 // Container for point-point coincidences.
168 // Useful to find points coincident to a given point.
169 class CoincidentPoints
170 {
171 public:
172   void addCoincidence(const AttributePoint2DPtr& thePoint1,
173                       const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
174   {
175     std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
176     std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
177     if (aFound1 == myCoincidentPoints.end()) {
178       std::set<AttributePoint2DPtr> aNewSet;
179       aNewSet.insert(thePoint1);
180       if (thePoint2)
181         aNewSet.insert(thePoint2);
182       myCoincidentPoints.push_back(aNewSet);
183     } else if (aFound2 == myCoincidentPoints.end()) {
184       if (thePoint2)
185         aFound1->insert(thePoint2);
186     } else {
187       aFound1->insert(aFound2->begin(), aFound2->end());
188       myCoincidentPoints.erase(aFound2);
189     }
190   }
191
192   std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
193   {
194     std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
195     if (aFound == myCoincidentPoints.end())
196       return std::set<AttributePoint2DPtr>();
197     return *aFound;
198   }
199
200 private:
201   std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
202   {
203     std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
204     for (; aSeek != myCoincidentPoints.end(); ++aSeek)
205       if (aSeek->find(thePoint) != aSeek->end())
206         return aSeek;
207     return myCoincidentPoints.end();
208   }
209
210 private:
211   std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
212 };
213
214 std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
215 {
216   CoincidentPoints aCoincidentPoints;
217   AttributePoint2DPtr aPoints[2];
218
219   FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
220   std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
221   std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
222   for (; aCIt != aCoincidences.end(); ++aCIt) {
223     aPoints[0] = AttributePoint2DPtr();
224     aPoints[1] = AttributePoint2DPtr();
225     for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
226       AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
227       if (!aRefAttr)
228         continue;
229       if (!aRefAttr->isObject())
230         aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
231     }
232
233     if (aPoints[0])
234       aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]);
235   }
236
237   return aCoincidentPoints.coincidentPoints(thePoint);
238 }
239
240 void resetAttribute(SketchPlugin_Feature* theFeature,
241                     const std::string& theId)
242 {
243   AttributePtr anAttr = theFeature->attribute(theId);
244   if(anAttr.get()) {
245     anAttr->reset();
246   }
247 }
248
249 void createConstraint(SketchPlugin_Feature* theFeature,
250                       const std::string& theId,
251                       const AttributePtr theAttr,
252                       const ObjectPtr theObject,
253                       const bool theIsCanBeTangent)
254 {
255   AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
256   if(aRefAttr.get() && aRefAttr->isInitialized()) {
257     FeaturePtr aConstraint;
258     if(!theIsCanBeTangent) {
259       aConstraint = theFeature->sketch()
260                               ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
261     } else {
262       if(aRefAttr->isObject()) {
263         ObjectPtr anObject = aRefAttr->object();
264         FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
265         if(aFeature->getKind() == SketchPlugin_Point::ID()) {
266           aConstraint = theFeature->sketch()
267                                   ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
268         } else {
269           aConstraint = theFeature->sketch()
270                                   ->addFeature(SketchPlugin_ConstraintTangent::ID());
271         }
272       } else {
273         aConstraint = theFeature->sketch()
274                                 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
275       }
276     }
277     AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
278     aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
279                          : aRefAttrA->setAttr(aRefAttr->attr());
280     AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
281     if(theObject.get()) {
282       aRefAttrB->setObject(theObject);
283     } else if(theAttr.get()) {
284       aRefAttrB->setAttr(theAttr);
285     }
286   }
287 }
288
289 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr&      theRefAttr,
290                                          const AttributePtr&             theDefaultAttr,
291                                          std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
292                                          std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
293 {
294   AttributePtr anAttr = theDefaultAttr;
295   if (theRefAttr->isObject()) {
296     FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
297     if (aTgFeature) {
298       if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
299         theTangentCurve = aTgFeature->lastResult()->shape();
300         return;
301       }
302       anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
303     }
304   } else
305     anAttr = theRefAttr->attr();
306
307   thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
308 }
309
310 } // namespace SketchPlugin_Tools