]> SALOME platform Git repositories - modules/shaper.git/blob - src/SketchAPI/SketchAPI_Arc.cpp
Salome HOME
Fix dumping tangent arc. Do not dump constraints created by tangent arc.
[modules/shaper.git] / src / SketchAPI / SketchAPI_Arc.cpp
1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
2
3 // File:        SketchAPI_Arc.cpp
4 // Created:     09 June 2016
5 // Author:      Dmitry Bobylev
6
7 #include "SketchAPI_Arc.h"
8
9 #include <GeomAPI_Pnt2d.h>
10
11 #include <ModelHighAPI_Double.h>
12 #include <ModelHighAPI_Dumper.h>
13 #include <ModelHighAPI_Selection.h>
14 #include <ModelHighAPI_Tools.h>
15
16 #include <SketchPlugin_ConstraintCoincidence.h>
17 #include <SketchPlugin_ConstraintTangent.h>
18
19 /// Obtain constraints prepared by tangent arc
20 static std::list<FeaturePtr> tangentArcConstraints(const FeaturePtr& theArc);
21
22 //================================================================================================
23 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature> & theFeature)
24 : SketchAPI_SketchEntity(theFeature)
25 {
26   initialize();
27 }
28
29 //================================================================================================
30 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
31                              double theCenterX, double theCenterY,
32                              double theStartX, double theStartY,
33                              double theEndX, double theEndY,
34                              bool theInversed)
35 : SketchAPI_SketchEntity(theFeature)
36 {
37   if(initialize()) {
38     setByCenterStartEnd(theCenterX, theCenterY, theStartX,
39                         theStartY, theEndX, theEndY, theInversed);
40   }
41 }
42
43 //================================================================================================
44 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
45                              const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
46                              const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
47                              const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
48                              bool theInversed)
49 : SketchAPI_SketchEntity(theFeature)
50 {
51   if(initialize()) {
52     setByCenterStartEnd(theCenter, theStart, theEnd, theInversed);
53   }
54 }
55
56 //================================================================================================
57 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
58                              double theStartX, double theStartY,
59                              double theEndX, double theEndY,
60                              double thePassedX, double thePassedY)
61 : SketchAPI_SketchEntity(theFeature)
62 {
63   if (initialize()) {
64     setByStartEndPassed(theStartX, theStartY, theEndX, theEndY, thePassedX, thePassedY);
65   }
66 }
67
68 //===============================================================================================
69 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
70                              const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
71                              const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
72                              const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
73 : SketchAPI_SketchEntity(theFeature)
74 {
75   if (initialize()) {
76     setByStartEndPassed(theStart, theEnd, thePassed);
77   }
78 }
79
80 //================================================================================================
81 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
82                              const ModelHighAPI_RefAttr& theTangentPoint,
83                              double theEndX, double theEndY,
84                              bool theInversed)
85 : SketchAPI_SketchEntity(theFeature)
86 {
87   if (initialize()) {
88     setByTangent(theTangentPoint, theEndX, theEndY, theInversed);
89   }
90 }
91
92 //================================================================================================
93 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
94                              const ModelHighAPI_RefAttr& theTangentPoint,
95                              const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
96                              bool theInversed)
97 : SketchAPI_SketchEntity(theFeature)
98 {
99   if (initialize()) {
100     setByTangent(theTangentPoint, theEnd, theInversed);
101   }
102 }
103
104 //================================================================================================
105 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
106                              const ModelHighAPI_Selection& theExternal)
107 : SketchAPI_SketchEntity(theFeature)
108 {
109   if (initialize()) {
110     setByExternal(theExternal);
111   }
112 }
113
114 //================================================================================================
115 SketchAPI_Arc::SketchAPI_Arc(const std::shared_ptr<ModelAPI_Feature>& theFeature,
116                              const std::string& theExternalName)
117 : SketchAPI_SketchEntity(theFeature)
118 {
119   if (initialize()) {
120     setByExternalName(theExternalName);
121   }
122 }
123
124 //================================================================================================
125 SketchAPI_Arc::~SketchAPI_Arc()
126 {
127
128 }
129
130 //================================================================================================
131 void SketchAPI_Arc::setByCenterStartEnd(double theCenterX, double theCenterY,
132                                         double theStartX, double theStartY,
133                                         double theEndX, double theEndY,
134                                         bool theInversed)
135 {
136   fillAttribute(SketchPlugin_Arc::ARC_TYPE_CENTER_START_END(), myarcType);
137   fillAttribute(center(), theCenterX, theCenterY);
138   fillAttribute(startPoint(), theStartX, theStartY);
139   fillAttribute(endPoint(), theEndX, theEndY);
140   fillAttribute(theInversed, myinversed);
141
142   execute();
143 }
144
145 //================================================================================================
146 void SketchAPI_Arc::setByCenterStartEnd(const std::shared_ptr<GeomAPI_Pnt2d>& theCenter,
147                                         const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
148                                         const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
149                                         bool theInversed)
150 {
151   fillAttribute(SketchPlugin_Arc::ARC_TYPE_CENTER_START_END(), myarcType);
152   fillAttribute(theCenter, mycenter);
153   fillAttribute(theStart, mystartPoint);
154   fillAttribute(theEnd, myendPoint);
155   fillAttribute(theInversed, myinversed);
156
157   execute();
158 }
159
160 //================================================================================================
161 void SketchAPI_Arc::setByStartEndPassed(double theStartX, double theStartY,
162                                         double theEndX, double theEndY,
163                                         double thePassedX, double thePassedY)
164 {
165   fillAttribute(SketchPlugin_Arc::ARC_TYPE_THREE_POINTS(), myarcType);
166   fillAttribute(startPoint(), theStartX, theStartY);
167   fillAttribute(endPoint(), theEndX, theEndY);
168   fillAttribute(passedPoint(), thePassedX, thePassedY);
169
170   execute();
171 }
172
173 //================================================================================================
174 void SketchAPI_Arc::setByStartEndPassed(const std::shared_ptr<GeomAPI_Pnt2d>& theStart,
175                                         const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
176                                         const std::shared_ptr<GeomAPI_Pnt2d>& thePassed)
177 {
178   fillAttribute(SketchPlugin_Arc::ARC_TYPE_THREE_POINTS(), myarcType);
179   fillAttribute(theStart, mystartPoint);
180   fillAttribute(theEnd, myendPoint);
181   fillAttribute(thePassed, mypassedPoint);
182
183   execute();
184 }
185
186 //================================================================================================
187 void SketchAPI_Arc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoint,
188                                  double theEndX, double theEndY,
189                                  bool theInversed)
190 {
191   fillAttribute(SketchPlugin_Arc::ARC_TYPE_TANGENT(), myarcType);
192   fillAttribute(theTangentPoint, mytangentPoint);
193   fillAttribute(endPoint(), theEndX, theEndY);
194   fillAttribute(theInversed, myinversed);
195
196   execute();
197 }
198
199 //================================================================================================
200 void SketchAPI_Arc::setByTangent(const ModelHighAPI_RefAttr& theTangentPoint,
201                                  const std::shared_ptr<GeomAPI_Pnt2d>& theEnd,
202                                  bool theInversed)
203 {
204   fillAttribute(SketchPlugin_Arc::ARC_TYPE_TANGENT(), myarcType);
205   fillAttribute(theTangentPoint, mytangentPoint);
206   fillAttribute(theEnd, myendPoint);
207   fillAttribute(theInversed, myinversed);
208
209   execute();
210 }
211
212 //================================================================================================
213 void SketchAPI_Arc::setByExternal(const ModelHighAPI_Selection & theExternal)
214 {
215   fillAttribute(theExternal, external());
216
217   execute();
218 }
219
220 //===============================================================================================
221 void SketchAPI_Arc::setByExternalName(const std::string & theExternalName)
222 {
223   fillAttribute(ModelHighAPI_Selection("EDGE", theExternalName), external());
224
225   execute();
226 }
227
228 //===============================================================================================
229 void SketchAPI_Arc::setRadius(double theRadius)
230 {
231   fillAttribute(ModelHighAPI_Double(theRadius), myradius);
232
233   execute();
234 }
235
236 //================================================================================================
237 void SketchAPI_Arc::setAngle(double theAngle)
238 {
239   fillAttribute(ModelHighAPI_Double(theAngle), myangle);
240
241   execute();
242 }
243
244 //================================================================================================
245 void SketchAPI_Arc::dump(ModelHighAPI_Dumper& theDumper) const
246 {
247   if (isCopy())
248     return; // no need to dump copied feature
249
250   FeaturePtr aBase = feature();
251   const std::string& aSketchName = theDumper.parentName(aBase);
252
253   AttributeSelectionPtr anExternal = aBase->selection(SketchPlugin_SketchEntity::EXTERNAL_ID());
254   if (anExternal->context()) {
255     // arc is external
256     theDumper << aBase << " = " << aSketchName << ".addArc(" << anExternal << ")" << std::endl;
257   } else {
258     AttributeStringPtr aType = arcType();
259     if (aType->value() == SketchPlugin_Arc::ARC_TYPE_CENTER_START_END()) {
260       // arc given by center and start, end points
261       theDumper << aBase << " = " << aSketchName << ".addArc(" << center() << ", "
262                 << startPoint() << ", " << endPoint() << ", " << inversed() << ")" << std::endl;
263     } else if (aType->value() == SketchPlugin_Arc::ARC_TYPE_THREE_POINTS()) {
264       // arc given by three points
265       theDumper << aBase << " = " << aSketchName << ".addArc(" << startPoint() << ", "
266                 << endPoint() << ", " << passedPoint() << ")" << std::endl;
267     } else {
268       // do not dump coincidence and tangency constraint built by tangent arc
269       std::list<FeaturePtr> aConstraintsToSkip = tangentArcConstraints(aBase);
270       std::list<FeaturePtr>::iterator anIt = aConstraintsToSkip.begin();
271       for (; anIt != aConstraintsToSkip.end(); ++anIt)
272         theDumper.doNotDumpFeature(*anIt);
273
274       // tangent arc
275       AttributeRefAttrPtr aTangentPoint = tangentPoint();
276       theDumper << aBase << " = " << aSketchName << ".addArc("
277                 << aTangentPoint << ", " << endPoint() << ", " << inversed() << ")" << std::endl;
278     }
279   }
280   // dump "auxiliary" flag if necessary
281   SketchAPI_SketchEntity::dump(theDumper);
282 }
283
284
285 // ====================   Auxiliary functions   ===============================
286 std::list<FeaturePtr> tangentArcConstraints(const FeaturePtr& theArc)
287 {
288   std::list<FeaturePtr> aConstraints;
289
290   std::set<FeaturePtr> aCoincidences;
291   std::set<FeaturePtr> aTangencies;
292
293   const std::set<AttributePtr>& aBaseRefs = theArc->data()->refsToMe();
294   std::set<AttributePtr>::const_iterator anIt = aBaseRefs.begin();
295   for (; anIt != aBaseRefs.end(); ++anIt) {
296     FeaturePtr anOwner = ModelAPI_Feature::feature((*anIt)->owner());
297     if (anOwner->getKind() == SketchPlugin_ConstraintCoincidence::ID())
298       aCoincidences.insert(anOwner);
299   }
300   const std::set<AttributePtr>& aBaseResultRefs = theArc->lastResult()->data()->refsToMe();
301   for (anIt = aBaseResultRefs.begin(); anIt != aBaseResultRefs.end(); ++anIt) {
302     FeaturePtr anOwner = ModelAPI_Feature::feature((*anIt)->owner());
303     if (anOwner->getKind() == SketchPlugin_ConstraintTangent::ID())
304       aTangencies.insert(anOwner);
305   }
306
307   AttributePtr aTangentPoint = theArc->refattr(SketchPlugin_Arc::TANGENT_POINT_ID())->attr();
308   if (aTangentPoint) {
309     FeaturePtr aTangentFeature = ModelAPI_Feature::feature(aTangentPoint->owner());
310
311     const std::set<AttributePtr>& aTgRefs = aTangentFeature->data()->refsToMe();
312     for (anIt = aTgRefs.begin(); anIt != aTgRefs.end(); ++anIt) {
313       FeaturePtr anOwner = ModelAPI_Feature::feature((*anIt)->owner());
314       if (aCoincidences.find(anOwner) != aCoincidences.end()) {
315         // check the coincidence is correct
316         AttributePtr aConstrained1 = anOwner->refattr(SketchPlugin_Constraint::ENTITY_A())->attr();
317         AttributePtr aConstrained2 = anOwner->refattr(SketchPlugin_Constraint::ENTITY_B())->attr();
318         AttributePtr anArcStartPoint = theArc->attribute(SketchPlugin_Arc::START_ID());
319         if ((aConstrained1 == anArcStartPoint && aConstrained2 == aTangentPoint) ||
320             (aConstrained1 == aTangentPoint && aConstrained2 == anArcStartPoint)) {
321           aConstraints.push_back(anOwner);
322           break; // search first applicable coincidence only
323         }
324       }
325     }
326
327     const std::set<AttributePtr>& aTgResultRefs =
328         aTangentFeature->lastResult()->data()->refsToMe();
329     for (anIt = aTgResultRefs.begin(); anIt != aTgResultRefs.end(); ++anIt) {
330       FeaturePtr anOwner = ModelAPI_Feature::feature((*anIt)->owner());
331       if (aTangencies.find(anOwner) != aTangencies.end()) {
332         aConstraints.push_back(anOwner);
333         break; // search first tangency only
334       }
335     }
336   }
337
338   return aConstraints;
339 }