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>
39 namespace SketchPlugin_Tools {
41 void clearExpressions(AttributeDoublePtr theAttribute)
43 theAttribute->setText(std::string());
46 void clearExpressions(AttributePointPtr theAttribute)
48 theAttribute->setText(std::string(), std::string(), std::string());
51 void clearExpressions(AttributePoint2DPtr theAttribute)
53 theAttribute->setText(std::string(), std::string());
56 void clearExpressions(AttributePtr theAttribute)
59 AttributeDoublePtr anAttributeDouble =
60 std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
61 if (anAttributeDouble.get())
62 clearExpressions(anAttributeDouble);
64 AttributePointPtr anAttributePoint =
65 std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
66 if (anAttributePoint.get())
67 clearExpressions(anAttributePoint);
69 AttributePoint2DPtr anAttributePoint2D =
70 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
71 if (anAttributePoint2D.get())
72 clearExpressions(anAttributePoint2D);
75 void clearExpressions(FeaturePtr theFeature)
77 if (!theFeature.get())
80 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
81 std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
82 for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
83 clearExpressions(*anAttributeIt);
87 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
89 std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
90 SketchPlugin_Constraint::ENTITY_A());
91 if (aPnt.get() == NULL)
92 aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
96 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
98 std::set<FeaturePtr> aCoincident;
99 const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
100 std::set<AttributePtr>::const_iterator aIt;
101 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
102 FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
103 if (aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
104 aCoincident.insert(aConstrFeature);
109 void findCoincidences(const FeaturePtr theStartCoin,
110 const std::string& theAttr,
111 std::set<FeaturePtr>& theList,
112 const bool theIsAttrOnly)
114 AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
118 FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
119 if(theList.find(aObj) == theList.end()) {
120 std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
121 if(aOrig.get() == NULL) {
124 if(!theIsAttrOnly || !aPnt->isObject()) {
125 theList.insert(aObj);
127 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
128 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
129 for (; aCIt != aCoincidences.end(); ++aCIt) {
130 FeaturePtr aConstrFeature = *aCIt;
131 std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
132 if(aPnt.get() && aOrig->isEqual(aPnt)) {
133 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(),
134 theList, theIsAttrOnly);
135 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(),
136 theList, theIsAttrOnly);
142 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
144 std::set<FeaturePtr> aCoincidentFeatures;
146 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
147 aCoincidentFeatures.insert(anOwner);
149 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
150 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
151 for (; aCIt != aCoincidences.end(); ++aCIt) {
152 bool isPointUsedInCoincidence = false;
153 AttributeRefAttrPtr anOtherCoincidentAttr;
154 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
155 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
158 if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
159 isPointUsedInCoincidence = true;
161 anOtherCoincidentAttr = aRefAttr;
164 if (isPointUsedInCoincidence) {
166 if (anOtherCoincidentAttr->isObject())
167 anObj = anOtherCoincidentAttr->object();
169 anObj = anOtherCoincidentAttr->attr()->owner();
170 aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
174 return aCoincidentFeatures;
177 // Container for point-point coincidences.
178 // Useful to find points coincident to a given point.
179 class CoincidentPoints
182 void addCoincidence(const AttributePoint2DPtr& thePoint1,
183 const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
185 std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
186 std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
187 if (aFound1 == myCoincidentPoints.end()) {
188 std::set<AttributePoint2DPtr> aNewSet;
189 aNewSet.insert(thePoint1);
191 aNewSet.insert(thePoint2);
192 myCoincidentPoints.push_back(aNewSet);
193 } else if (aFound2 == myCoincidentPoints.end()) {
195 aFound1->insert(thePoint2);
197 aFound1->insert(aFound2->begin(), aFound2->end());
198 myCoincidentPoints.erase(aFound2);
202 std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
204 std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
205 if (aFound == myCoincidentPoints.end())
206 return std::set<AttributePoint2DPtr>();
211 std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
213 std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
214 for (; aSeek != myCoincidentPoints.end(); ++aSeek)
215 if (aSeek->find(thePoint) != aSeek->end())
217 return myCoincidentPoints.end();
221 std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
224 std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
226 CoincidentPoints aCoincidentPoints;
227 AttributePoint2DPtr aPoints[2];
229 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
230 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
231 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
232 for (; aCIt != aCoincidences.end(); ++aCIt) {
233 aPoints[0] = AttributePoint2DPtr();
234 aPoints[1] = AttributePoint2DPtr();
235 for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
236 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
239 if (!aRefAttr->isObject())
240 aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
244 aCoincidentPoints.addCoincidence(aPoints[0], aPoints[1]);
247 return aCoincidentPoints.coincidentPoints(thePoint);
250 void resetAttribute(SketchPlugin_Feature* theFeature,
251 const std::string& theId)
253 AttributePtr anAttr = theFeature->attribute(theId);
259 void createCoincidenceOrTangency(SketchPlugin_Feature* theFeature,
260 const std::string& theId,
261 const AttributePtr theAttr,
262 const ObjectPtr theObject,
263 const bool theIsCanBeTangent)
265 AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
266 if(aRefAttr.get() && aRefAttr->isInitialized()) {
267 FeaturePtr aConstraint;
268 if(!theIsCanBeTangent) {
269 aConstraint = theFeature->sketch()
270 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
272 if(aRefAttr->isObject()) {
273 ObjectPtr anObject = aRefAttr->object();
274 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
275 if(aFeature->getKind() == SketchPlugin_Point::ID()) {
276 aConstraint = theFeature->sketch()
277 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
279 aConstraint = theFeature->sketch()
280 ->addFeature(SketchPlugin_ConstraintTangent::ID());
283 aConstraint = theFeature->sketch()
284 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
287 AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
288 aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
289 : aRefAttrA->setAttr(aRefAttr->attr());
290 AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
291 if(theObject.get()) {
292 aRefAttrB->setObject(theObject);
293 } else if(theAttr.get()) {
294 aRefAttrB->setAttr(theAttr);
299 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr,
300 const AttributePtr& theDefaultAttr,
301 std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
302 std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
304 AttributePtr anAttr = theDefaultAttr;
305 if (theRefAttr->isObject()) {
306 FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
308 if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
309 theTangentCurve = aTgFeature->lastResult()->shape();
312 anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
315 anAttr = theRefAttr->attr();
317 thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
321 FeaturePtr createConstraintAttrAttr(SketchPlugin_Sketch* theSketch,
322 const std::string& theConstraintId,
323 const AttributePtr& theFirstAttribute,
324 const AttributePtr& theSecondAttribute)
326 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
327 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
328 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
329 aRefAttr->setAttr(theFirstAttribute);
331 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
332 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
333 aRefAttr->setAttr(theSecondAttribute);
335 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
336 std::cout << "<createConstraint to attribute> :"
337 << " first attribute - " << theFirstAttribute->id()
338 << " second attribute - " << theSecondAttribute->id()
345 FeaturePtr createConstraintAttrObject(SketchPlugin_Sketch* theSketch,
346 const std::string& theConstraintId,
347 const AttributePtr& theFirstAttribute,
348 const ObjectPtr& theSecondObject)
350 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
351 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
352 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
353 aRefAttr->setAttr(theFirstAttribute);
355 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
356 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
357 aRefAttr->setObject(theSecondObject);
359 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
360 std::cout << "<createConstraint to attribute> :"
361 << " first attribute - " << theFirstAttribute->id()
362 << " second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
369 FeaturePtr createConstraintObjectObject(SketchPlugin_Sketch* theSketch,
370 const std::string& theConstraintId,
371 const ObjectPtr& theFirstObject,
372 const ObjectPtr& theSecondObject)
374 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
375 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
376 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
377 aRefAttr->setObject(theFirstObject);
379 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
380 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
381 aRefAttr->setObject(theSecondObject);
383 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
384 std::cout << "<createConstraint to attribute> :"
385 << " first object - " << ModelAPI_Feature::feature(theFirstObject)->getKind()
386 << " second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
393 } // namespace SketchPlugin_Tools