1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_Tools.cpp
4 // Created: 07 July 2015
5 // Author: Sergey POKHODENKO
7 #include "SketchPlugin_Tools.h"
9 #include "SketchPlugin_ConstraintCoincidence.h"
10 #include "SketchPlugin_ConstraintTangent.h"
11 #include "SketchPlugin_Point.h"
12 #include "SketchPlugin_SketchEntity.h"
14 #include <SketcherPrs_Tools.h>
16 #include <ModelAPI_AttributeDouble.h>
18 #include <GeomDataAPI_Point.h>
19 #include <GeomDataAPI_Point2D.h>
21 namespace SketchPlugin_Tools {
23 void clearExpressions(AttributeDoublePtr theAttribute)
25 theAttribute->setText(std::string());
28 void clearExpressions(AttributePointPtr theAttribute)
30 theAttribute->setText(std::string(), std::string(), std::string());
33 void clearExpressions(AttributePoint2DPtr theAttribute)
35 theAttribute->setText(std::string(), std::string());
38 void clearExpressions(AttributePtr theAttribute)
41 AttributeDoublePtr anAttributeDouble =
42 std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
43 if (anAttributeDouble.get())
44 clearExpressions(anAttributeDouble);
46 AttributePointPtr anAttributePoint =
47 std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
48 if (anAttributePoint.get())
49 clearExpressions(anAttributePoint);
51 AttributePoint2DPtr anAttributePoint2D =
52 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
53 if (anAttributePoint2D.get())
54 clearExpressions(anAttributePoint2D);
57 void clearExpressions(FeaturePtr theFeature)
59 if (!theFeature.get())
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);
69 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
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());
78 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
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);
91 void findCoincidences(const FeaturePtr theStartCoin,
92 const std::string& theAttr,
93 std::set<FeaturePtr>& theList)
95 AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
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) {
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);
119 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
121 std::set<FeaturePtr> aCoincidentFeatures;
123 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
124 aCoincidentFeatures.insert(anOwner);
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));
135 if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
136 isPointUsedInCoincidence = true;
138 anOtherCoincidentAttr = aRefAttr;
141 if (isPointUsedInCoincidence) {
143 if (anOtherCoincidentAttr->isObject())
144 anObj = anOtherCoincidentAttr->object();
146 anObj = anOtherCoincidentAttr->attr()->owner();
147 aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
151 return aCoincidentFeatures;
154 // Container for point-point coincidences.
155 // Useful to find points coincident to a given point.
156 class CoincidentPoints
159 void addCoincidence(const AttributePoint2DPtr& thePoint1,
160 const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
162 std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
163 std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
164 if (aFound1 == myCoincidentPoints.end()) {
165 std::set<AttributePoint2DPtr> aNewSet;
166 aNewSet.insert(thePoint1);
168 aNewSet.insert(thePoint2);
169 myCoincidentPoints.push_back(aNewSet);
170 } else if (aFound2 == myCoincidentPoints.end()) {
172 aFound1->insert(thePoint2);
174 aFound1->insert(aFound2->begin(), aFound2->end());
175 myCoincidentPoints.erase(aFound2);
179 std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
181 std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
182 if (aFound == myCoincidentPoints.end())
183 return std::set<AttributePoint2DPtr>();
188 std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
190 std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
191 for (; aSeek != myCoincidentPoints.end(); ++aSeek)
192 if (aSeek->find(thePoint) != aSeek->end())
194 return myCoincidentPoints.end();
198 std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
201 std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
203 CoincidentPoints aCoincidentPoints;
204 AttributePoint2DPtr aPoints[2];
206 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
207 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
208 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
209 for (; aCIt != aCoincidences.end(); ++aCIt) {
210 aPoints[0] = AttributePoint2DPtr();
211 aPoints[1] = AttributePoint2DPtr();
212 for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
213 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
216 if (!aRefAttr->isObject())
217 aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
221 aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]);
224 return aCoincidentPoints.coincidentPoints(thePoint);
227 void resetAttribute(SketchPlugin_Feature* theFeature,
228 const std::string& theId)
230 AttributePtr anAttr = theFeature->attribute(theId);
236 void createConstraint(SketchPlugin_Feature* theFeature,
237 const std::string& theId,
238 const AttributePtr theAttr,
239 const ObjectPtr theObject,
240 const bool theIsCanBeTangent)
242 AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
243 if(aRefAttr.get() && aRefAttr->isInitialized()) {
244 FeaturePtr aConstraint;
245 if(!theIsCanBeTangent) {
246 aConstraint = theFeature->sketch()
247 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
249 if(aRefAttr->isObject()) {
250 ObjectPtr anObject = aRefAttr->object();
251 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
252 if(aFeature->getKind() == SketchPlugin_Point::ID()) {
253 aConstraint = theFeature->sketch()
254 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
256 aConstraint = theFeature->sketch()
257 ->addFeature(SketchPlugin_ConstraintTangent::ID());
260 aConstraint = theFeature->sketch()
261 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
264 AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
265 aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
266 : aRefAttrA->setAttr(aRefAttr->attr());
267 AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
268 if(theObject.get()) {
269 aRefAttrB->setObject(theObject);
270 } else if(theAttr.get()) {
271 aRefAttrB->setAttr(theAttr);
276 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr,
277 const AttributePtr& theDefaultAttr,
278 std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
279 std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
281 AttributePtr anAttr = theDefaultAttr;
282 if (theRefAttr->isObject()) {
283 FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
285 if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
286 theTangentCurve = aTgFeature->lastResult()->shape();
289 anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
292 anAttr = theRefAttr->attr();
294 thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
297 } // namespace SketchPlugin_Tools