1 // Copyright (C) 2014-2017 CEA/DEN, EDF R&D
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.
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.
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
17 // See http://www.salome-platform.org/ or
18 // email : webmaster.salome@opencascade.com<mailto:webmaster.salome@opencascade.com>
21 #include "SketchPlugin_Tools.h"
23 #include "SketchPlugin_ConstraintCoincidence.h"
24 #include "SketchPlugin_ConstraintTangent.h"
25 #include "SketchPlugin_Point.h"
26 #include "SketchPlugin_SketchEntity.h"
28 #include <SketcherPrs_Tools.h>
30 #include <ModelAPI_AttributeDouble.h>
32 #include <GeomDataAPI_Point.h>
33 #include <GeomDataAPI_Point2D.h>
35 namespace SketchPlugin_Tools {
37 void clearExpressions(AttributeDoublePtr theAttribute)
39 theAttribute->setText(std::string());
42 void clearExpressions(AttributePointPtr theAttribute)
44 theAttribute->setText(std::string(), std::string(), std::string());
47 void clearExpressions(AttributePoint2DPtr theAttribute)
49 theAttribute->setText(std::string(), std::string());
52 void clearExpressions(AttributePtr theAttribute)
55 AttributeDoublePtr anAttributeDouble =
56 std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
57 if (anAttributeDouble.get())
58 clearExpressions(anAttributeDouble);
60 AttributePointPtr anAttributePoint =
61 std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
62 if (anAttributePoint.get())
63 clearExpressions(anAttributePoint);
65 AttributePoint2DPtr anAttributePoint2D =
66 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
67 if (anAttributePoint2D.get())
68 clearExpressions(anAttributePoint2D);
71 void clearExpressions(FeaturePtr theFeature)
73 if (!theFeature.get())
76 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
77 std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
78 for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
79 clearExpressions(*anAttributeIt);
83 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
85 std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
86 SketchPlugin_Constraint::ENTITY_A());
87 if (aPnt.get() == NULL)
88 aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
92 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
94 std::set<FeaturePtr> aCoincident;
95 const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
96 std::set<AttributePtr>::const_iterator aIt;
97 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
98 FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
99 if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
100 aCoincident.insert(aConstrFeature);
105 void findCoincidences(const FeaturePtr theStartCoin,
106 const std::string& theAttr,
107 std::set<FeaturePtr>& theList,
108 const bool theIsAttrOnly)
110 AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
114 FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
115 if(theList.find(aObj) == theList.end()) {
116 std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
117 if(aOrig.get() == NULL) {
120 if(!theIsAttrOnly || !aPnt->isObject()) {
121 theList.insert(aObj);
123 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
124 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
125 for (; aCIt != aCoincidences.end(); ++aCIt) {
126 FeaturePtr aConstrFeature = *aCIt;
127 std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
128 if(aPnt.get() && aOrig->isEqual(aPnt)) {
129 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(),
130 theList, theIsAttrOnly);
131 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(),
132 theList, theIsAttrOnly);
138 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
140 std::set<FeaturePtr> aCoincidentFeatures;
142 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
143 aCoincidentFeatures.insert(anOwner);
145 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
146 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
147 for (; aCIt != aCoincidences.end(); ++aCIt) {
148 bool isPointUsedInCoincidence = false;
149 AttributeRefAttrPtr anOtherCoincidentAttr;
150 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
151 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
154 if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
155 isPointUsedInCoincidence = true;
157 anOtherCoincidentAttr = aRefAttr;
160 if (isPointUsedInCoincidence) {
162 if (anOtherCoincidentAttr->isObject())
163 anObj = anOtherCoincidentAttr->object();
165 anObj = anOtherCoincidentAttr->attr()->owner();
166 aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
170 return aCoincidentFeatures;
173 // Container for point-point coincidences.
174 // Useful to find points coincident to a given point.
175 class CoincidentPoints
178 void addCoincidence(const AttributePoint2DPtr& thePoint1,
179 const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
181 std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
182 std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
183 if (aFound1 == myCoincidentPoints.end()) {
184 std::set<AttributePoint2DPtr> aNewSet;
185 aNewSet.insert(thePoint1);
187 aNewSet.insert(thePoint2);
188 myCoincidentPoints.push_back(aNewSet);
189 } else if (aFound2 == myCoincidentPoints.end()) {
191 aFound1->insert(thePoint2);
193 aFound1->insert(aFound2->begin(), aFound2->end());
194 myCoincidentPoints.erase(aFound2);
198 std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
200 std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
201 if (aFound == myCoincidentPoints.end())
202 return std::set<AttributePoint2DPtr>();
207 std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
209 std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
210 for (; aSeek != myCoincidentPoints.end(); ++aSeek)
211 if (aSeek->find(thePoint) != aSeek->end())
213 return myCoincidentPoints.end();
217 std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
220 std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
222 CoincidentPoints aCoincidentPoints;
223 AttributePoint2DPtr aPoints[2];
225 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
226 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
227 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
228 for (; aCIt != aCoincidences.end(); ++aCIt) {
229 aPoints[0] = AttributePoint2DPtr();
230 aPoints[1] = AttributePoint2DPtr();
231 for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
232 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
235 if (!aRefAttr->isObject())
236 aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
240 aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]);
243 return aCoincidentPoints.coincidentPoints(thePoint);
246 void resetAttribute(SketchPlugin_Feature* theFeature,
247 const std::string& theId)
249 AttributePtr anAttr = theFeature->attribute(theId);
255 void createConstraint(SketchPlugin_Feature* theFeature,
256 const std::string& theId,
257 const AttributePtr theAttr,
258 const ObjectPtr theObject,
259 const bool theIsCanBeTangent)
261 AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
262 if(aRefAttr.get() && aRefAttr->isInitialized()) {
263 FeaturePtr aConstraint;
264 if(!theIsCanBeTangent) {
265 aConstraint = theFeature->sketch()
266 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
268 if(aRefAttr->isObject()) {
269 ObjectPtr anObject = aRefAttr->object();
270 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
271 if(aFeature->getKind() == SketchPlugin_Point::ID()) {
272 aConstraint = theFeature->sketch()
273 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
275 aConstraint = theFeature->sketch()
276 ->addFeature(SketchPlugin_ConstraintTangent::ID());
279 aConstraint = theFeature->sketch()
280 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
283 AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
284 aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
285 : aRefAttrA->setAttr(aRefAttr->attr());
286 AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
287 if(theObject.get()) {
288 aRefAttrB->setObject(theObject);
289 } else if(theAttr.get()) {
290 aRefAttrB->setAttr(theAttr);
295 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr,
296 const AttributePtr& theDefaultAttr,
297 std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
298 std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
300 AttributePtr anAttr = theDefaultAttr;
301 if (theRefAttr->isObject()) {
302 FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
304 if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
305 theTangentCurve = aTgFeature->lastResult()->shape();
308 anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
311 anAttr = theRefAttr->attr();
313 thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
316 } // namespace SketchPlugin_Tools