1 // Copyright (C) 2014-2019 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 email : webmaster.salome@opencascade.com
20 #include "SketchPlugin_Tools.h"
22 #include "SketchPlugin_Arc.h"
23 #include "SketchPlugin_ConstraintCoincidence.h"
24 #include "SketchPlugin_ConstraintCoincidenceInternal.h"
25 #include "SketchPlugin_ConstraintLength.h"
26 #include "SketchPlugin_ConstraintTangent.h"
27 #include "SketchPlugin_Ellipse.h"
28 #include "SketchPlugin_EllipticArc.h"
29 #include "SketchPlugin_Line.h"
30 #include "SketchPlugin_Point.h"
31 #include "SketchPlugin_Projection.h"
32 #include "SketchPlugin_SketchEntity.h"
33 #include "SketchPlugin_Split.h"
34 #include "SketchPlugin_Trim.h"
36 #include <SketcherPrs_Tools.h>
38 #include <ModelAPI_AttributeDouble.h>
40 #include <ModelGeomAlgo_Point2D.h>
41 #include <ModelGeomAlgo_Shape.h>
43 #include <GeomAPI_Dir2d.h>
44 #include <GeomAPI_Edge.h>
45 #include <GeomAPI_Pnt2d.h>
46 #include <GeomAPI_XY.h>
48 #include <GeomAlgoAPI_CompoundBuilder.h>
49 #include <GeomAlgoAPI_ShapeTools.h>
51 #include <GeomDataAPI_Point.h>
52 #include <GeomDataAPI_Point2D.h>
58 namespace SketchPlugin_Tools {
60 void clearExpressions(AttributeDoublePtr theAttribute)
62 theAttribute->setText(std::string());
65 void clearExpressions(AttributePointPtr theAttribute)
67 theAttribute->setText(std::string(), std::string(), std::string());
70 void clearExpressions(AttributePoint2DPtr theAttribute)
72 theAttribute->setText(std::string(), std::string());
75 void clearExpressions(AttributePtr theAttribute)
78 AttributeDoublePtr anAttributeDouble =
79 std::dynamic_pointer_cast<ModelAPI_AttributeDouble>(theAttribute);
80 if (anAttributeDouble.get())
81 clearExpressions(anAttributeDouble);
83 AttributePointPtr anAttributePoint =
84 std::dynamic_pointer_cast<GeomDataAPI_Point>(theAttribute);
85 if (anAttributePoint.get())
86 clearExpressions(anAttributePoint);
88 AttributePoint2DPtr anAttributePoint2D =
89 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theAttribute);
90 if (anAttributePoint2D.get())
91 clearExpressions(anAttributePoint2D);
94 void clearExpressions(FeaturePtr theFeature)
96 if (!theFeature.get())
99 std::list<AttributePtr> anAttributes = theFeature->data()->attributes(std::string());
100 std::list<AttributePtr>::iterator anAttributeIt = anAttributes.begin();
101 for (; anAttributeIt != anAttributes.end(); ++anAttributeIt) {
102 clearExpressions(*anAttributeIt);
106 std::shared_ptr<GeomAPI_Pnt2d> getCoincidencePoint(const FeaturePtr theStartCoin)
108 std::shared_ptr<GeomAPI_Pnt2d> aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(),
109 SketchPlugin_Constraint::ENTITY_A());
110 if (aPnt.get() == NULL)
111 aPnt = SketcherPrs_Tools::getPoint(theStartCoin.get(), SketchPlugin_Constraint::ENTITY_B());
115 std::set<FeaturePtr> findCoincidentConstraints(const FeaturePtr& theFeature)
117 std::set<FeaturePtr> aCoincident;
118 const std::set<AttributePtr>& aRefsList = theFeature->data()->refsToMe();
119 std::set<AttributePtr>::const_iterator aIt;
120 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
121 FeaturePtr aConstrFeature = std::dynamic_pointer_cast<ModelAPI_Feature>((*aIt)->owner());
122 if (aConstrFeature && aConstrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
123 aCoincident.insert(aConstrFeature);
128 void findCoincidences(const FeaturePtr theStartCoin,
129 const std::string& theAttr,
130 std::set<FeaturePtr>& theList,
131 const bool theIsAttrOnly)
133 AttributeRefAttrPtr aPnt = theStartCoin->refattr(theAttr);
137 FeaturePtr aObj = ModelAPI_Feature::feature(aPnt->object());
138 if(theList.find(aObj) == theList.end()) {
139 std::shared_ptr<GeomAPI_Pnt2d> aOrig = getCoincidencePoint(theStartCoin);
140 if(aOrig.get() == NULL) {
143 if(!theIsAttrOnly || !aPnt->isObject()) {
144 theList.insert(aObj);
146 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(aObj);
147 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
148 for (; aCIt != aCoincidences.end(); ++aCIt) {
149 FeaturePtr aConstrFeature = *aCIt;
150 std::shared_ptr<GeomAPI_Pnt2d> aPnt = getCoincidencePoint(aConstrFeature);
151 if(aPnt.get() && aOrig->isEqual(aPnt)) {
152 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_A(),
153 theList, theIsAttrOnly);
154 findCoincidences(aConstrFeature, SketchPlugin_ConstraintCoincidence::ENTITY_B(),
155 theList, theIsAttrOnly);
161 std::set<FeaturePtr> findFeaturesCoincidentToPoint(const AttributePoint2DPtr& thePoint)
163 std::set<FeaturePtr> aCoincidentFeatures;
165 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
166 aCoincidentFeatures.insert(anOwner);
168 std::set<FeaturePtr> aCoincidences = findCoincidentConstraints(anOwner);
169 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
170 for (; aCIt != aCoincidences.end(); ++aCIt) {
171 bool isPointUsedInCoincidence = false;
172 AttributeRefAttrPtr anOtherCoincidentAttr;
173 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
174 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
177 if (!aRefAttr->isObject() && aRefAttr->attr() == thePoint)
178 isPointUsedInCoincidence = true;
180 anOtherCoincidentAttr = aRefAttr;
183 if (isPointUsedInCoincidence) {
185 if (anOtherCoincidentAttr->isObject())
186 anObj = anOtherCoincidentAttr->object();
188 anObj = anOtherCoincidentAttr->attr()->owner();
189 aCoincidentFeatures.insert(ModelAPI_Feature::feature(anObj));
193 return aCoincidentFeatures;
196 // Container for point-point coincidences.
197 // Useful to find points coincident to a given point.
198 class CoincidentPoints
201 void addCoincidence(const AttributePoint2DPtr& thePoint1,
202 const AttributePoint2DPtr& thePoint2 = AttributePoint2DPtr())
204 std::list< std::set<AttributePoint2DPtr> >::iterator aFound1 = find(thePoint1);
205 std::list< std::set<AttributePoint2DPtr> >::iterator aFound2 = find(thePoint2);
206 if (aFound1 == myCoincidentPoints.end()) {
207 if (aFound2 == myCoincidentPoints.end()) {
208 std::set<AttributePoint2DPtr> aNewSet;
209 aNewSet.insert(thePoint1);
211 aNewSet.insert(thePoint2);
212 myCoincidentPoints.push_back(aNewSet);
214 aFound2->insert(thePoint1);
215 } else if (aFound2 == myCoincidentPoints.end()) {
217 aFound1->insert(thePoint2);
219 aFound1->insert(aFound2->begin(), aFound2->end());
220 myCoincidentPoints.erase(aFound2);
224 std::set<AttributePoint2DPtr> coincidentPoints(const AttributePoint2DPtr& thePoint)
226 collectCoincidentPoints(thePoint);
228 std::list< std::set<AttributePoint2DPtr> >::iterator aFound = find(thePoint);
229 if (aFound == myCoincidentPoints.end())
230 return std::set<AttributePoint2DPtr>();
235 void coincidences(const FeaturePtr& theFeature,
236 std::set<FeaturePtr>& theCoincidences) const
238 // iterate through coincideces for the given feature
239 std::set<FeaturePtr> aCoincidences = SketchPlugin_Tools::findCoincidentConstraints(theFeature);
240 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
241 for (; aCIt != aCoincidences.end(); ++aCIt)
243 if (theCoincidences.find(*aCIt) != theCoincidences.end())
244 continue; // already processed
245 theCoincidences.insert(*aCIt);
246 // iterate on coincident attributes
247 for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
248 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
249 if (aRefAttr && !aRefAttr->isObject())
251 FeaturePtr anOwner = ModelAPI_Feature::feature(aRefAttr->attr()->owner());
252 if (anOwner != theFeature)
253 coincidences(anOwner, theCoincidences);
259 // Iteratively search points coincident to the given point
260 // (two points may be coincident through the third point)
261 void collectCoincidentPoints(const AttributePoint2DPtr& thePoint)
263 AttributePoint2DPtr aPoints[2];
265 FeaturePtr anOwner = ModelAPI_Feature::feature(thePoint->owner());
266 std::set<FeaturePtr> aCoincidences;
267 coincidences(anOwner, aCoincidences);
269 std::set<FeaturePtr>::const_iterator aCIt = aCoincidences.begin();
270 for (; aCIt != aCoincidences.end(); ++aCIt) {
271 aPoints[0] = AttributePoint2DPtr();
272 aPoints[1] = AttributePoint2DPtr();
273 for (int i = 0, aPtInd = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
274 AttributeRefAttrPtr aRefAttr = (*aCIt)->refattr(SketchPlugin_Constraint::ATTRIBUTE(i));
275 if (aRefAttr && !aRefAttr->isObject())
276 aPoints[aPtInd++] = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
279 if (aPoints[0] && aPoints[1])
280 addCoincidence(aPoints[0], aPoints[1]);
284 std::list< std::set<AttributePoint2DPtr> >::iterator find(const AttributePoint2DPtr& thePoint)
286 std::list< std::set<AttributePoint2DPtr> >::iterator aSeek = myCoincidentPoints.begin();
287 for (; aSeek != myCoincidentPoints.end(); ++aSeek)
288 if (aSeek->find(thePoint) != aSeek->end())
290 return myCoincidentPoints.end();
294 std::list< std::set<AttributePoint2DPtr> > myCoincidentPoints;
297 std::set<AttributePoint2DPtr> findPointsCoincidentToPoint(const AttributePoint2DPtr& thePoint)
299 CoincidentPoints aCoincidentPoints;
300 return aCoincidentPoints.coincidentPoints(thePoint);
303 void resetAttribute(SketchPlugin_Feature* theFeature,
304 const std::string& theId)
306 AttributePtr anAttr = theFeature->attribute(theId);
312 void createCoincidenceOrTangency(SketchPlugin_Feature* theFeature,
313 const std::string& theId,
314 const AttributePtr theAttr,
315 const ObjectPtr theObject,
316 const bool theIsCanBeTangent)
318 AttributeRefAttrPtr aRefAttr = theFeature->refattr(theId);
319 if(aRefAttr.get() && aRefAttr->isInitialized()) {
320 FeaturePtr aConstraint;
321 if(!theIsCanBeTangent) {
322 aConstraint = theFeature->sketch()
323 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
325 if(aRefAttr->isObject()) {
326 ObjectPtr anObject = aRefAttr->object();
327 FeaturePtr aFeature = ModelAPI_Feature::feature(anObject);
328 if(aFeature->getKind() == SketchPlugin_Point::ID()) {
329 aConstraint = theFeature->sketch()
330 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
332 aConstraint = theFeature->sketch()
333 ->addFeature(SketchPlugin_ConstraintTangent::ID());
336 aConstraint = theFeature->sketch()
337 ->addFeature(SketchPlugin_ConstraintCoincidence::ID());
340 AttributeRefAttrPtr aRefAttrA = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
341 aRefAttr->isObject() ? aRefAttrA->setObject(aRefAttr->object())
342 : aRefAttrA->setAttr(aRefAttr->attr());
343 AttributeRefAttrPtr aRefAttrB = aConstraint->refattr(SketchPlugin_Constraint::ENTITY_B());
344 if(theObject.get()) {
345 aRefAttrB->setObject(theObject);
346 } else if(theAttr.get()) {
347 aRefAttrB->setAttr(theAttr);
352 void convertRefAttrToPointOrTangentCurve(const AttributeRefAttrPtr& theRefAttr,
353 const AttributePtr& theDefaultAttr,
354 std::shared_ptr<GeomAPI_Shape>& theTangentCurve,
355 std::shared_ptr<GeomAPI_Pnt2d>& thePassingPoint)
357 AttributePtr anAttr = theDefaultAttr;
358 if (theRefAttr->isObject()) {
359 FeaturePtr aTgFeature = ModelAPI_Feature::feature(theRefAttr->object());
361 if (aTgFeature->getKind() != SketchPlugin_Point::ID()) {
362 theTangentCurve = aTgFeature->lastResult()->shape();
365 anAttr = aTgFeature->attribute(SketchPlugin_Point::COORD_ID());
368 anAttr = theRefAttr->attr();
370 thePassingPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(anAttr)->pnt();
374 FeaturePtr createConstraintAttrAttr(SketchPlugin_Sketch* theSketch,
375 const std::string& theConstraintId,
376 const AttributePtr& theFirstAttribute,
377 const AttributePtr& theSecondAttribute)
379 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
380 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
381 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
382 aRefAttr->setAttr(theFirstAttribute);
384 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
385 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
386 aRefAttr->setAttr(theSecondAttribute);
388 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
389 std::cout << "<createConstraint to attribute> :"
390 << " first attribute - " << theFirstAttribute->id()
391 << " second attribute - " << theSecondAttribute->id()
398 FeaturePtr createConstraintAttrObject(SketchPlugin_Sketch* theSketch,
399 const std::string& theConstraintId,
400 const AttributePtr& theFirstAttribute,
401 const ObjectPtr& theSecondObject)
403 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
404 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
405 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
406 aRefAttr->setAttr(theFirstAttribute);
408 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
409 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
410 aRefAttr->setObject(theSecondObject);
412 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
413 std::cout << "<createConstraint to attribute> :"
414 << " first attribute - " << theFirstAttribute->id()
415 << " second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
422 FeaturePtr createConstraintObjectObject(SketchPlugin_Sketch* theSketch,
423 const std::string& theConstraintId,
424 const ObjectPtr& theFirstObject,
425 const ObjectPtr& theSecondObject)
427 FeaturePtr aConstraint = theSketch->addFeature(theConstraintId);
428 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
429 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
430 aRefAttr->setObject(theFirstObject);
432 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
433 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
434 aRefAttr->setObject(theSecondObject);
436 #if defined(DEBUG_TRIM) || defined(DEBUG_SPLIT)
437 std::cout << "<createConstraint to attribute> :"
438 << " first object - " << ModelAPI_Feature::feature(theFirstObject)->getKind()
439 << " second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
446 void createAuxiliaryPointOnEllipse(const FeaturePtr& theEllipseFeature,
447 const std::string& theEllipsePoint)
449 SketchPlugin_Sketch* aSketch =
450 std::dynamic_pointer_cast<SketchPlugin_Feature>(theEllipseFeature)->sketch();
452 FeaturePtr aPointFeature = aSketch->addFeature(SketchPlugin_Point::ID());
453 aPointFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
454 aPointFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theEllipseFeature);
456 AttributePoint2DPtr anElPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
457 theEllipseFeature->attribute(theEllipsePoint));
459 AttributePoint2DPtr aCoord = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
460 aPointFeature->attribute(SketchPlugin_Point::COORD_ID()));
461 aCoord->setValue(anElPoint->x(), anElPoint->y());
463 aPointFeature->execute();
464 std::string aName = theEllipseFeature->name() + "_" + theEllipsePoint;
465 aPointFeature->data()->setName(aName);
466 aPointFeature->lastResult()->data()->setName(aName);
468 createConstraintAttrAttr(aSketch,
469 SketchPlugin_ConstraintCoincidenceInternal::ID(), anElPoint, aCoord);
472 void createAuxiliaryAxisOfEllipse(const FeaturePtr& theEllipseFeature,
473 const std::string& theStartPoint,
474 const std::string& theEndPoint)
476 SketchPlugin_Sketch* aSketch =
477 std::dynamic_pointer_cast<SketchPlugin_Feature>(theEllipseFeature)->sketch();
479 FeaturePtr aLineFeature = aSketch->addFeature(SketchPlugin_Line::ID());
480 aLineFeature->boolean(SketchPlugin_Point::AUXILIARY_ID())->setValue(true);
481 aLineFeature->reference(SketchPlugin_Point::PARENT_ID())->setValue(theEllipseFeature);
483 AttributePoint2DPtr aStartPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
484 theEllipseFeature->attribute(theStartPoint));
485 AttributePoint2DPtr aEndPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
486 theEllipseFeature->attribute(theEndPoint));
488 AttributePoint2DPtr aLineStart = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
489 aLineFeature->attribute(SketchPlugin_Line::START_ID()));
490 aLineStart->setValue(aStartPoint->x(), aStartPoint->y());
492 AttributePoint2DPtr aLineEnd = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
493 aLineFeature->attribute(SketchPlugin_Line::END_ID()));
494 aLineEnd->setValue(aEndPoint->x(), aEndPoint->y());
496 aLineFeature->execute();
497 std::string aName = theEllipseFeature->name() + "_" +
498 (theStartPoint == SketchPlugin_Ellipse::MAJOR_AXIS_START_ID() ? "major_axis" : "minor_axis");
499 aLineFeature->data()->setName(aName);
500 aLineFeature->lastResult()->data()->setName(aName);
502 createConstraintAttrAttr(aSketch,
503 SketchPlugin_ConstraintCoincidenceInternal::ID(), aStartPoint, aLineStart);
504 createConstraintAttrAttr(aSketch,
505 SketchPlugin_ConstraintCoincidenceInternal::ID(), aEndPoint, aLineEnd);
508 GeomPnt2dPtr flyoutPointCoordinates(const ConstraintPtr& theConstraint)
510 // currently process Length constraints only
511 if (theConstraint->getKind() != SketchPlugin_ConstraintLength::ID())
512 return GeomPnt2dPtr();
514 AttributeRefAttrPtr aLineAttr = theConstraint->refattr(SketchPlugin_Constraint::ENTITY_A());
515 if (!aLineAttr || !aLineAttr->isObject())
516 return GeomPnt2dPtr();
517 FeaturePtr aLine = ModelAPI_Feature::feature(aLineAttr->object());
518 if (!aLine || aLine->getKind() != SketchPlugin_Line::ID())
519 return GeomPnt2dPtr();
521 std::shared_ptr<GeomAPI_XY> aStartPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
522 aLine->attribute(SketchPlugin_Line::START_ID()))->pnt()->xy();
523 std::shared_ptr<GeomAPI_XY> aEndPnt = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
524 aLine->attribute(SketchPlugin_Line::END_ID()))->pnt()->xy();
526 std::shared_ptr<GeomDataAPI_Point2D> aFlyoutAttr =
527 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
528 theConstraint->attribute(SketchPlugin_Constraint::FLYOUT_VALUE_PNT()));
529 std::shared_ptr<GeomAPI_Pnt2d> aFltPnt = aFlyoutAttr->pnt();
531 std::shared_ptr<GeomAPI_Dir2d> aLineDir(new GeomAPI_Dir2d(aEndPnt->decreased(aStartPnt)));
533 double X = aStartPnt->x() + aFltPnt->x() * aLineDir->x() - aFltPnt->y() * aLineDir->y();
534 double Y = aStartPnt->y() + aFltPnt->x() * aLineDir->y() + aFltPnt->y() * aLineDir->x();
536 return GeomPnt2dPtr(new GeomAPI_Pnt2d(X, Y));
539 } // namespace SketchPlugin_Tools
542 // =================================================================================================
543 // namespace SketchPlugin_SegmentationTools
544 // =================================================================================================
546 void SketchPlugin_SegmentationTools::getFeaturePoints(const FeaturePtr& theFeature,
547 AttributePoint2DPtr& theStartPointAttr,
548 AttributePoint2DPtr& theEndPointAttr)
550 std::string aFeatureKind = theFeature->getKind();
551 std::string aStartAttributeName, anEndAttributeName;
552 if (aFeatureKind == SketchPlugin_Line::ID()) {
553 aStartAttributeName = SketchPlugin_Line::START_ID();
554 anEndAttributeName = SketchPlugin_Line::END_ID();
556 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
557 aStartAttributeName = SketchPlugin_Arc::START_ID();
558 anEndAttributeName = SketchPlugin_Arc::END_ID();
560 else if (aFeatureKind == SketchPlugin_EllipticArc::ID()) {
561 aStartAttributeName = SketchPlugin_EllipticArc::START_POINT_ID();
562 anEndAttributeName = SketchPlugin_EllipticArc::END_POINT_ID();
564 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
565 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
566 theFeature->attribute(aStartAttributeName));
567 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
568 theFeature->attribute(anEndAttributeName));
573 void SketchPlugin_SegmentationTools::getRefAttributes(
574 const FeaturePtr& theFeature,
575 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
576 std::list<AttributePtr>& theRefsToFeature)
580 std::list<AttributePtr> aPointAttributes =
581 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
582 std::set<AttributePtr> aPointAttributesSet;
584 std::list<AttributePtr>::const_iterator aPIt =
585 aPointAttributes.begin(), aPLast = aPointAttributes.end();
586 for (; aPIt != aPLast; aPIt++)
587 aPointAttributesSet.insert(*aPIt);
589 std::set<AttributePtr> aRefsAttributes = theFeature->lastResult()->data()->refsToMe();
590 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
591 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
593 std::set<AttributePtr>::const_iterator aIt;
594 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
595 AttributePtr anAttr = (*aIt);
596 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
597 if (!anAttrFeature->isMacro() && // <- skip reference from Trim or Split feature
598 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
599 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
600 if (!aRefAttr->isObject()) { // find attributes referenced to feature point attributes
601 AttributePtr anAttrInRef = aRefAttr->attr();
602 if (anAttrInRef.get() &&
603 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
604 if (theRefs.find(anAttrInRef) != theRefs.end())
605 theRefs[anAttrInRef].push_back(aRefAttr);
607 std::list<AttributePtr> anAttrList;
608 anAttrList.push_back(aRefAttr);
609 theRefs[anAttrInRef] = anAttrList;
613 else { // find attributes referenced to feature itself
614 theRefsToFeature.push_back(anAttr);
620 GeomShapePtr SketchPlugin_SegmentationTools::getSubShape(
621 SketchPlugin_Feature* theFeature,
622 const std::string& theObjectAttributeId,
623 const std::string& thePointAttributeId,
624 std::map<ObjectPtr, std::set<GeomShapePtr> >& theCashedShapes,
625 std::map<ObjectPtr, GeomAlgoAPI_ShapeTools::PointToRefsMap>& theObjectToPoints)
627 GeomShapePtr aBaseShape;
629 AttributeReferencePtr anObjectAttr = theFeature->reference(theObjectAttributeId);
630 ObjectPtr aBaseObject = anObjectAttr->value();
631 if (!aBaseObject.get())
635 AttributePoint2DPtr aPointAttr =
636 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(theFeature->attribute(thePointAttributeId));
637 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPointAttr->pnt();
638 std::shared_ptr<GeomAPI_Pnt> anAttributePnt =
639 theFeature->sketch()->to3D(anAttributePnt2d->x(), anAttributePnt2d->y());
641 if (theCashedShapes.find(aBaseObject) == theCashedShapes.end())
642 fillObjectShapes(theFeature, aBaseObject, theCashedShapes, theObjectToPoints);
644 std::shared_ptr<GeomAPI_Pnt> aStartPoint;
645 std::shared_ptr<GeomAPI_Pnt> aSecondPoint;
646 const std::set<GeomShapePtr>& aShapes = theCashedShapes[aBaseObject];
647 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
648 for (; anIt != aLast; anIt++) {
649 GeomShapePtr aCurrentShape = *anIt;
650 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
651 if (ModelGeomAlgo_Point2D::isPointOnEdge(aCurrentShape, anAttributePnt, aProjectedPoint)) {
652 if (theFeature->getKind() == SketchPlugin_Split::ID()) {
653 // for Split operation collect start and end points of the shape
654 if (aCurrentShape->shapeType() == GeomAPI_Shape::EDGE) {
655 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aCurrentShape));
656 aStartPoint = anEdge->firstPoint();
657 aSecondPoint = anEdge->lastPoint();
661 aBaseShape = aCurrentShape;
666 if (!aStartPoint.get() || !aSecondPoint.get())
669 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObject);
670 if (anObjectAttr->isInitialized() && aBaseFeature.get() && aPointAttr->isInitialized()) {
671 ResultPtr aResult = aBaseFeature->lastResult();
672 GeomShapePtr aResultShape = aResult->shape();
673 std::list<std::shared_ptr<GeomAPI_Pnt> > aPoints;
675 aPoints.push_back(aStartPoint);
676 aPoints.push_back(aSecondPoint);
678 std::set<std::shared_ptr<GeomAPI_Shape> > aSplitShapes;
679 GeomAlgoAPI_ShapeTools::splitShape_p(aResultShape, aPoints, aSplitShapes);
680 aBaseShape = GeomAlgoAPI_ShapeTools::findShape(aPoints, aSplitShapes);
685 void SketchPlugin_SegmentationTools::fillObjectShapes(
686 SketchPlugin_Feature* theOpFeature,
687 const ObjectPtr& theObject,
688 std::map<ObjectPtr, std::set<GeomShapePtr> >& theCashedShapes,
689 std::map<ObjectPtr, GeomAlgoAPI_ShapeTools::PointToRefsMap>& theObjectToPoints)
691 SketchPlugin_Sketch* aSketch = theOpFeature->sketch();
693 GeomAlgoAPI_ShapeTools::PointToRefsMap aPoints;
694 std::set<GeomShapePtr> aShapes;
696 std::set<AttributePoint2DPtr > aRefAttributes;
698 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
699 std::set<ResultPtr> anEdgeShapes;
701 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
702 if (!anEdgeShapes.empty()) {
703 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
705 // coincidences to the feature
706 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
707 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
708 // layed on feature coincidences to divide it on several shapes
709 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
710 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
711 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
712 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
713 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
714 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
715 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
716 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
718 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
719 aX->dir(), aY, aPoints);
721 if (theOpFeature->getKind() == SketchPlugin_Trim::ID()) {
722 // collect all intersection points with other edges for Trim operation only
723 std::list<FeaturePtr> aFeatures;
724 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
725 FeaturePtr aFeature = aSketch->subFeature(i);
726 if (aFeature.get() && aFeature->getKind() != SketchPlugin_Projection::ID())
727 aFeatures.push_back(aFeature);
729 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPoints);
732 if (!aPoints.empty())
733 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPoints, aShapes);
735 theObjectToPoints[theObject] = aPoints;
736 theCashedShapes[theObject] = aShapes;
739 void SketchPlugin_SegmentationTools::updateRefAttConstraints(
740 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
741 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes)
743 #if defined DEBUG_SPLIT || defined DEBUG_TRIM
744 std::cout << "updateRefAttConstraints" << std::endl;
747 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
748 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
749 for (; anIt != aLast; anIt++) {
750 AttributePtr anAttribute = anIt->first;
751 AttributePtr aNewAttribute = anIt->second;
753 // not found in references
754 if (!aNewAttribute.get() ||
755 theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
757 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
758 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
759 aRLast = aRefAttributes.end();
761 for (; aRefIt != aRLast; aRefIt++) {
762 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
763 if (aRefAttr.get()) {
764 aRefAttr->setAttr(aNewAttribute);
766 FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
767 std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
774 void SketchPlugin_SegmentationTools::updateFeaturesAfterOperation(
775 const std::set<FeaturePtr>& theFeaturesToUpdate)
777 std::set<FeaturePtr>::const_iterator anIt = theFeaturesToUpdate.begin(),
778 aLast = theFeaturesToUpdate.end();
779 for (; anIt != aLast; anIt++) {
780 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(*anIt);
781 std::string aRefFeatureKind = aRefFeature->getKind();
782 if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID()) {
783 std::shared_ptr<SketchPlugin_ConstraintLength> aLenghtFeature =
784 std::dynamic_pointer_cast<SketchPlugin_ConstraintLength>(*anIt);
785 if (aLenghtFeature.get()) {
786 std::shared_ptr<ModelAPI_AttributeDouble> aValueAttr = std::dynamic_pointer_cast<
787 ModelAPI_AttributeDouble>(aLenghtFeature->attribute(SketchPlugin_Constraint::VALUE()));
789 if (aLenghtFeature->computeLenghtValue(aValue) && aValueAttr.get())
790 aValueAttr->setValue(aValue);
796 AISObjectPtr SketchPlugin_SegmentationTools::getAISObject(
797 AISObjectPtr thePrevious,
798 SketchPlugin_Feature* theOpFeature,
799 const std::string& thePreviewObjectAttrName,
800 const std::string& thePreviewPointAttrName,
801 const std::string& theSelectedObjectAttrName,
802 const std::string& theSelectedPointAttrName)
804 #if defined DEBUG_SPLIT || defined DEBUG_TRIM_METHODS
805 std::cout << "getAISObject: " << theOpFeature->data()->name() << std::endl;
808 AISObjectPtr anAIS = thePrevious;
810 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
811 std::map<ObjectPtr, std::set<GeomShapePtr> > aCashedShapes;
812 std::map<ObjectPtr, GeomAlgoAPI_ShapeTools::PointToRefsMap> aObjectToPoints;
813 GeomShapePtr aPreviewShape = getSubShape(theOpFeature,
814 thePreviewObjectAttrName, thePreviewPointAttrName, aCashedShapes, aObjectToPoints);
815 if (aPreviewShape.get())
816 aShapes.push_back(aPreviewShape);
817 GeomShapePtr aSelectedShape = getSubShape(theOpFeature,
818 theSelectedObjectAttrName, theSelectedPointAttrName, aCashedShapes, aObjectToPoints);
819 if (aSelectedShape.get())
820 aShapes.push_back(aSelectedShape);
823 return AISObjectPtr();
825 GeomShapePtr aBaseShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
826 if (!aBaseShape.get())
827 return AISObjectPtr();
829 if (aBaseShape.get()) {
831 anAIS = AISObjectPtr(new GeomAPI_AISObject);
832 anAIS->createShape(aBaseShape);
834 std::vector<int> aColor;
835 aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color");
836 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
837 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
838 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
839 // width when there is not base object should be extened in several points
840 // in order to see this preview over highlight
841 anAIS->setWidth(aWidth+4);
842 anAIS->setLineStyle(aLineStyle);
845 anAIS = AISObjectPtr();