1 // Copyright (C) 2014-20xx CEA/DEN, EDF R&D -->
3 // File: SketchPlugin_Trim.cpp
4 // Created: 22 Feb 2017
5 // Author: Natalia ERMOLAEVA
7 #include "SketchPlugin_Trim.h"
9 #include <GeomAPI_Dir2d.h>
10 #include <GeomAPI_Edge.h>
11 #include <GeomAPI_Pnt2d.h>
12 #include <GeomAPI_XY.h>
13 #include <GeomDataAPI_Point2D.h>
14 #include <GeomAlgoAPI_ShapeTools.h>
15 #include <GeomAlgoAPI_CompoundBuilder.h>
17 #include <ModelAPI_AttributeReference.h>
18 #include <ModelAPI_AttributeString.h>
19 #include <ModelAPI_AttributeRefAttr.h>
20 #include <ModelAPI_Tools.h>
21 #include <ModelAPI_AttributeBoolean.h>
23 #include <ModelAPI_Validator.h>
24 #include <ModelAPI_Session.h>
25 #include <ModelAPI_AttributeDouble.h>
27 #include <ModelGeomAlgo_Shape.h>
29 #include <SketchPlugin_Arc.h>
30 #include <SketchPlugin_ConstraintMiddle.h>
31 #include <SketchPlugin_Circle.h>
32 #include <SketchPlugin_ConstraintCoincidence.h>
33 #include <SketchPlugin_ConstraintEqual.h>
34 //#include <SketchPlugin_ConstraintParallel.h>
35 #include <SketchPlugin_ConstraintTangent.h>
36 #include <SketchPlugin_ConstraintLength.h>
37 #include <SketchPlugin_ConstraintMirror.h>
38 #include <SketchPlugin_ConstraintCollinear.h>
39 #include <SketchPlugin_Line.h>
40 #include <SketchPlugin_MultiRotation.h>
41 #include <SketchPlugin_MultiTranslation.h>
42 #include <SketchPlugin_Point.h>
44 #include <ModelAPI_Events.h>
45 #include <SketchPlugin_Line.h>
46 #include <SketchPlugin_Arc.h>
47 #include <SketchPlugin_Circle.h>
49 #include <ModelGeomAlgo_Point2D.h>
50 #include <Events_Loop.h>
59 static const double PI = 3.141592653589793238463;
61 static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
62 static const std::string OPERATION_REMOVE_FEATURE_COLOR() { return "255, 174, 201"; }
64 SketchPlugin_Trim::SketchPlugin_Trim()
68 void SketchPlugin_Trim::initAttributes()
70 data()->addAttribute(SketchPlugin_Trim::SELECTED_OBJECT(),
71 ModelAPI_AttributeReference::typeId());
72 data()->addAttribute(SELECTED_POINT(), GeomDataAPI_Point2D::typeId());
74 data()->addAttribute(PREVIEW_POINT(), GeomDataAPI_Point2D::typeId());
75 data()->addAttribute(PREVIEW_OBJECT(), ModelAPI_AttributeReference::typeId());
77 data()->attribute(PREVIEW_POINT())->setIsArgument(false);
78 data()->attribute(SELECTED_POINT())->setIsArgument(false);
79 data()->attribute(PREVIEW_OBJECT())->setIsArgument(false);
81 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_POINT());
82 ModelAPI_Session::get()->validators()->registerNotObligatory(getKind(), PREVIEW_OBJECT());
85 void SketchPlugin_Trim::findShapePoints(const std::string& theObjectAttributeId,
86 const std::string& thePointAttributeId,
87 std::shared_ptr<GeomAPI_Pnt>& aStartPoint,
88 std::shared_ptr<GeomAPI_Pnt>& aLastPoint)
90 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
91 data()->attribute(theObjectAttributeId));
92 ObjectPtr aBaseObject = aBaseObjectAttr->value();
94 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
95 data()->attribute(thePointAttributeId));
96 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
97 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
98 anAttributePnt2d->y());
100 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
101 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
103 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
104 if (!aShapes.empty()) {
105 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
106 for (; anIt != aLast; anIt++) {
107 GeomShapePtr aBaseShape = *anIt;
108 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
109 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
111 if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
112 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aBaseShape));
113 aStartPoint = anEdge->lastPoint();
114 aLastPoint = anEdge->firstPoint();
120 std::cout << "<findShapePoints> => "
122 << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]"
124 << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]"
129 std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
130 const std::shared_ptr<GeomAPI_Pnt>& thePoint)
132 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
134 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
135 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
136 ObjectPtr aBaseObject = aBaseObjectAttr->value();
137 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
138 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
141 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
142 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
143 aPointIt != aRefsMap.end() && !aFound; aPointIt++) {
144 if (aPointIt->first->isEqual(thePoint)) {
145 const std::pair<std::list<AttributePoint2DPtr >,
146 std::list<ObjectPtr > >& anInfo = aPointIt->second;
147 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
148 if (!anAttributes.empty()) {
149 aPoint = anAttributes.front()->pnt();
153 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
154 aPoint = thePoint->to2D(aPlane);
160 // returns an end of the shape to define direction of split if feature's attribute
162 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
163 aPoint = thePoint->to2D(aPlane);
168 void SketchPlugin_Trim::execute()
171 std::cout << "SketchPlugin_Trim::execute" << std::endl;
174 SketchPlugin_Sketch* aSketch = sketch();
178 // Check the base objects are initialized.
179 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
180 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
181 if(!aBaseObjectAttr->isInitialized()) {
182 setError("Error: Base object is not initialized.");
185 ObjectPtr aBaseObject = aBaseObjectAttr->value();
186 if (!aBaseObject.get())
188 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
191 std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
192 findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint);
193 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
195 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
197 std::set<FeaturePtr> aFeaturesToDelete;
198 getConstraints(aFeaturesToDelete);
200 std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
201 std::list<AttributePtr> aRefsToFeature;
202 getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
205 // coincidence to result points
206 // find coincidences to the base object, it should be used when attribute is found
207 // in myObjectToPoints
208 std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
209 getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
211 std::set<AttributePoint2DPtr> aFurtherCoincidences;
212 std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
213 const std::string& aKind = aBaseFeature->getKind();
214 FeaturePtr aReplacingFeature;
215 if (aKind == SketchPlugin_Circle::ID()) {
216 aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
217 aFurtherCoincidences, aModifiedAttributes);
219 aFeaturesToDelete.insert(aBaseFeature);
220 // as circle is removed, erase it from dependencies(arguments) of this feature
221 // otherwise Trim feature will be removed with the circle before
222 // this operation is finished
223 aBaseObjectAttr->setObject(ResultPtr());
225 AttributeReferencePtr aPreviewObjectAttr =
226 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
227 data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
228 aPreviewObjectAttr->setObject(ResultPtr());
231 else if (aKind == SketchPlugin_Line::ID()) {
232 trimLine(aStartShapePoint2d, aLastShapePoint2d,
233 aFurtherCoincidences, aModifiedAttributes);
235 else if (aKind == SketchPlugin_Arc::ID()) {
236 trimArc(aStartShapePoint2d, aLastShapePoint2d,
237 aFurtherCoincidences, aModifiedAttributes);
241 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
242 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
244 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
245 std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
246 aLast = aFurtherCoincidences.end();
247 for (; anIt != aLast; anIt++) {
248 AttributePoint2DPtr aPointAttribute = (*anIt);
249 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
251 std::shared_ptr<GeomAPI_Pnt> aPoint;
252 if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d))
253 aPoint = aStartShapePoint;
254 else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d))
255 aPoint = aLastShapePoint;
260 std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
261 for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
264 if (aRefIt->first->isEqual(aPoint)) {
265 anInfo = aRefIt->second;
269 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
270 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
271 anAttrIt != anAttributes.end(); anAttrIt++) {
272 AttributePtr anAttribute = *anAttrIt;
273 if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
275 FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
276 AttributePtr anOtherAttribute;
277 if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
278 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
279 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
280 else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
281 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
282 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
285 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
288 aRefAttr->setAttr(aPointAttribute);
292 const std::list<ObjectPtr>& anObjects = anInfo.second;
293 for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
294 anObjectIt != anObjects.end(); anObjectIt++) {
295 createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute,
300 // move constraints from base feature to replacing feature: ignore coincidences to feature
301 // if attributes of coincidence participated in split
302 if (aReplacingFeature.get()) {
303 ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature);
304 std::list<AttributePtr>::const_iterator anIt = aRefsToFeature.begin(),
305 aLast = aRefsToFeature.end();
306 for (; anIt != aLast; anIt++) {
307 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
310 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner());
311 if (anAttrFeature.get() &&
312 anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
314 if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr ||
315 anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr)
318 aRefAttr->setObject(aReplacingResult);
322 // Wait all constraints being created, then send update events
323 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
324 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
326 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
328 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
330 // delete constraints
332 std::cout << "remove features and references:" << std::endl;
333 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
334 aDLast = aFeaturesToDelete.end();
335 for (; aDIt != aDLast; aDIt++) {
336 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
337 //std::cout << std::endl;
340 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
341 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
343 // Send events to update the sub-features by the solver.
344 if(isUpdateFlushed) {
345 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
349 std::cout << "SketchPlugin_Trim::done" << std::endl;
353 bool SketchPlugin_Trim::isMacro() const
358 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
360 AISObjectPtr anAIS = thePrevious;
362 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
363 GeomShapePtr aPreviewShape = getSubShape(PREVIEW_OBJECT(), PREVIEW_POINT());
364 if (aPreviewShape.get())
365 aShapes.push_back(aPreviewShape);
366 GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
367 if (aSelectedShape.get())
368 aShapes.push_back(aSelectedShape);
371 return AISObjectPtr();
373 GeomShapePtr aBaseShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
374 if (!aBaseShape.get())
375 return AISObjectPtr();
377 if (aBaseShape.get()) {
379 anAIS = AISObjectPtr(new GeomAPI_AISObject);
380 anAIS->createShape(aBaseShape);
382 std::vector<int> aColor;
383 aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color");
384 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
385 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
386 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
387 // width when there is not base object should be extened in several points
388 // in order to see this preview over highlight
389 anAIS->setWidth(aWidth+4);
390 anAIS->setLineStyle(aLineStyle);
393 anAIS = AISObjectPtr();
398 GeomShapePtr SketchPlugin_Trim::getSubShape(const std::string& theObjectAttributeId,
399 const std::string& thePointAttributeId)
401 GeomShapePtr aBaseShape;
403 AttributeReferencePtr anObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
404 data()->attribute(theObjectAttributeId));
405 ObjectPtr aBaseObject = anObjectAttr->value();
406 if (!aBaseObject.get())
410 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
411 data()->attribute(thePointAttributeId));
412 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
413 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
414 anAttributePnt2d->y());
416 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
417 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
419 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
420 if (!aShapes.empty()) {
421 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
422 for (; anIt != aLast; anIt++) {
423 GeomShapePtr aShape = *anIt;
424 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
425 if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint))
432 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
433 AttributePoint2DPtr& theStartPointAttr,
434 AttributePoint2DPtr& theEndPointAttr)
436 std::string aFeatureKind = theFeature->getKind();
437 std::string aStartAttributeName, anEndAttributeName;
438 if (aFeatureKind == SketchPlugin_Line::ID()) {
439 aStartAttributeName = SketchPlugin_Line::START_ID();
440 anEndAttributeName = SketchPlugin_Line::END_ID();
442 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
443 aStartAttributeName = SketchPlugin_Arc::START_ID();
444 anEndAttributeName = SketchPlugin_Arc::END_ID();
446 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
447 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
448 theFeature->attribute(aStartAttributeName));
449 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
450 theFeature->attribute(anEndAttributeName));
454 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
456 std::shared_ptr<ModelAPI_Data> aData = data();
458 // Check the base objects are initialized.
459 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
460 aData->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
461 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
462 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
464 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
465 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
466 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
468 std::set<AttributePtr>::const_iterator aIt;
469 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
470 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
471 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
472 std::string aRefFeatureKind = aRefFeature->getKind();
473 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
474 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
475 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
476 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
477 theFeaturesToDelete.insert(aRefFeature);
481 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
482 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
483 std::list<AttributePtr>& theRefsToFeature)
487 std::list<AttributePtr> aPointAttributes =
488 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
489 std::set<AttributePtr> aPointAttributesSet;
491 std::list<AttributePtr>::const_iterator aPIt =
492 aPointAttributes.begin(), aPLast = aPointAttributes.end();
493 for (; aPIt != aPLast; aPIt++)
494 aPointAttributesSet.insert(*aPIt);
496 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
497 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
498 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
500 std::set<AttributePtr>::const_iterator aIt;
501 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
502 AttributePtr anAttr = (*aIt);
503 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
504 if (anAttrFeature.get() != this &&
505 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
506 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
507 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
508 AttributePtr anAttrInRef = aRefAttr->attr();
509 if (anAttrInRef.get() &&
510 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
511 if (theRefs.find(anAttrInRef) != theRefs.end())
512 theRefs[anAttrInRef].push_back(aRefAttr);
514 std::list<AttributePtr> anAttrList;
515 anAttrList.push_back(aRefAttr);
516 theRefs[anAttrInRef] = anAttrList;
520 else { /// find attributes referenced to feature itself
521 theRefsToFeature.push_back(anAttr);
527 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
528 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
530 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
531 std::set<AttributePtr>::const_iterator aIt;
532 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
533 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
534 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
535 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
537 AttributePtr anAttribute;
538 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
539 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
540 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
542 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
545 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
546 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
547 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
549 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
551 if (anAttribute.get())
553 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
555 anAttribute = aRefAttr->attr();
556 if (anAttribute.get())
557 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
563 void SketchPlugin_Trim::updateRefAttConstraints(
564 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
565 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
566 std::set<FeaturePtr>& theFeaturesToDelete)
569 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
572 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
573 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
574 for (; anIt != aLast; anIt++) {
575 AttributePtr anAttribute = anIt->first;
577 /// not found in references
578 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
580 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
581 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
582 aRLast = aRefAttributes.end();
584 AttributePtr aNewAttribute = anIt->second;
585 for (; aRefIt != aRLast; aRefIt++) {
586 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
587 if (aRefAttr.get()) {
588 if (aNewAttribute.get())
589 aRefAttr->setAttr(aNewAttribute);
591 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
593 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
594 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
601 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
602 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
603 std::set<AttributePoint2DPtr>& thePoints,
604 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
606 // Check the base objects are initialized.
607 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
608 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
609 ObjectPtr aBaseObject = aBaseObjectAttr->value();
610 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
613 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
614 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
616 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
617 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
619 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
620 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
621 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
622 aStartShapePoint, aLastShapePoint);
624 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
625 if (aStartShapePoint.get())
626 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
627 aStartShapePoint->y() << "]" << std::endl;
628 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
629 aStartFeaturePoint->y() << "]" << std::endl;
630 if (aLastShapePoint.get())
631 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
632 aLastShapePoint->y() << "]" << std::endl;
633 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
634 aLastFeaturePoint->y() << "]" << std::endl;
637 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
638 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
639 if (isStartPoint || isLastPoint) {
640 // result is one line: changed existing line
641 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
642 : SketchPlugin_Line::END_ID();
643 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
644 if (aStartShapePoint.get() && aLastShapePoint.get())
645 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
647 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
649 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
650 theModifiedAttributes.insert(
651 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
653 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
654 (aBaseFeature->attribute(aModifiedAttribute)));
657 // result is two lines: start line point - start shape point,
658 // last shape point - last line point
659 // create second line
660 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
661 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
662 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
664 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
665 theModifiedAttributes.insert(
666 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
667 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
670 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
672 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
673 (aBaseFeature->attribute(aModifiedAttribute)));
675 // Collinear constraint for lines
676 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
677 getFeatureResult(aBaseFeature),
678 getFeatureResult(anNewFeature));
683 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
684 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
685 std::set<AttributePoint2DPtr>& thePoints,
686 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
688 // Check the base objects are initialized.
689 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
690 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
691 ObjectPtr aBaseObject = aBaseObjectAttr->value();
692 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
695 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
696 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
698 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
699 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
701 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
702 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
703 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
704 aStartShapePoint, aLastShapePoint);
706 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
707 if (aStartShapePoint.get())
708 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
709 aStartShapePoint->y() << "]" << std::endl;
710 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
711 aStartArcPoint->y() << "]" << std::endl;
712 if (aLastShapePoint.get())
713 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
714 aLastShapePoint->y() << "]" << std::endl;
715 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
716 aLastArcPoint->y() << "]" << std::endl;
719 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
720 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
721 if (isStartPoint || isLastPoint) {
722 // result is one arc: changed existing arc
723 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
724 : SketchPlugin_Arc::END_ID();
725 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
726 if (aStartShapePoint.get() && aLastShapePoint.get())
727 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
729 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
731 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
732 theModifiedAttributes.insert(
733 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
735 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
736 (aBaseFeature->attribute(aModifiedAttribute)));
739 // result is two arcs: start arc point - start shape point, last shape point - last arc point
741 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
742 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
743 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
745 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
746 theModifiedAttributes.insert(
747 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
748 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
751 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
753 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
754 (aBaseFeature->attribute(aModifiedAttribute)));
756 // equal Radius constraint for arcs
757 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
758 getFeatureResult(aBaseFeature),
759 getFeatureResult(anArcFeature));
760 // coincident centers constraint
761 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
762 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
763 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
767 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
768 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
769 std::set<AttributePoint2DPtr>& thePoints,
770 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
772 // Check the base objects are initialized.
773 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
774 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
775 ObjectPtr aBaseObject = aBaseObjectAttr->value();
776 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
779 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
780 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
783 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
785 theModifiedAttributes.insert(
786 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
787 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
789 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
790 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
791 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
792 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
797 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
798 const AttributePoint2DPtr& theEndPointAttr,
799 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
800 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
802 if (!theFirstPoint.get() || !theLastPoint.get())
805 // if first point is closer to last point, swap first and last values
806 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
807 theStartPointAttr->pnt()->distance(theLastPoint)) {
808 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
809 theFirstPoint = theLastPoint;
810 theLastPoint = aTmpPoint;
814 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
815 const AttributePoint2DPtr& theStartPointAttr,
816 const AttributePoint2DPtr& theEndPointAttr,
817 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
818 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
820 if (!theFirstPoint.get() || !theSecondPoint.get())
823 static const double anAngleTol = 1.e-12;
825 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
826 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
827 bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
829 // collect directions to each point
830 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
831 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
832 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
833 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
834 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
835 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
837 // sort points by their angular values
838 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
839 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
840 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
841 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
842 aFirstPtAngle += aPeriod;
843 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
844 aSecondPtAngle += aPeriod;
846 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
847 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
848 theFirstPoint = theSecondPoint;
849 theSecondPoint = aTmpPoint;
853 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
854 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
856 std::string anAttributeType = theModifiedAttribute->attributeType();
857 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
858 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
859 theModifiedAttribute);
860 aModifiedAttribute->setValue(thePoint);
863 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
864 << thePoint->y() << "]" << std::endl;
870 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
871 const AttributePtr& theSourceAttribute)
873 std::string anAttributeType = theModifiedAttribute->attributeType();
874 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
875 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
876 theModifiedAttribute);
877 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
880 if (aModifiedAttribute.get() && aSourceAttribute.get())
881 aModifiedAttribute->setValue(aSourceAttribute->pnt());
883 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
884 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
885 theModifiedAttribute);
886 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
889 if (aModifiedAttribute.get() && aSourceAttribute.get())
890 aModifiedAttribute->setValue(aSourceAttribute->value());
892 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
893 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
894 theModifiedAttribute);
895 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
897 if (!aSourceRefAttr.get())
898 aRefAttributeToFill->setAttr(theSourceAttribute);
900 if (aSourceRefAttr->isObject())
901 aRefAttributeToFill->setObject(aSourceRefAttr->object());
903 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
908 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
909 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
910 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
913 SketchPlugin_Sketch* aSketch = sketch();
914 if (!aSketch || !theBaseFeature.get())
917 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
919 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
920 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
922 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
923 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
925 aFeature->execute(); // to obtain result
931 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
932 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
933 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
936 SketchPlugin_Sketch* aSketch = sketch();
937 if (!aSketch || !theBaseFeature.get())
940 std::string aCenterAttributeId;
941 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
942 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
943 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
944 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
946 if (aCenterAttributeId.empty())
949 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
950 // update fillet arc: make the arc correct for sure, so, it is not needed to process
951 // the "attribute updated"
952 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
953 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
955 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
956 theBaseFeature->attribute(aCenterAttributeId));
957 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
958 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
960 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
961 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
963 /// fill referersed state of created arc as it is on the base arc
964 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
965 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
966 aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed);
968 aFeature->execute(); // to obtain result
969 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
974 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
975 const AttributePtr& theFirstAttribute,
976 const AttributePtr& theSecondAttribute)
978 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
979 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
980 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
981 aRefAttr->setAttr(theFirstAttribute);
983 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
984 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
985 aRefAttr->setAttr(theSecondAttribute);
988 std::cout << "<createConstraint to attribute> :"
989 << "first attribute - " << theFirstAttribute->id()
990 << "second attribute - " << theSecondAttribute->id()
997 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
998 const AttributePtr& theFirstAttribute,
999 const ObjectPtr& theSecondObject)
1001 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1002 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1003 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1004 aRefAttr->setAttr(theFirstAttribute);
1006 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1007 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1008 aRefAttr->setObject(theSecondObject);
1011 std::cout << "<createConstraint to attribute> :"
1012 << "first attribute - " << theFirstAttribute->id()
1013 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
1020 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
1021 const std::string& theConstraintId,
1022 const ObjectPtr& theFirstObject,
1023 const ObjectPtr& theSecondObject)
1025 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1026 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1027 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1028 aRefAttr->setObject(theFirstObject);
1030 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1031 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1032 aRefAttr->setObject(theSecondObject);
1037 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
1038 const std::shared_ptr<ModelAPI_Feature>& theFeature)
1040 std::shared_ptr<ModelAPI_Result> aResult;
1042 std::string aFeatureKind = theFeature->getKind();
1043 if (aFeatureKind == SketchPlugin_Line::ID())
1044 aResult = theFeature->firstResult();
1045 else if (aFeatureKind == SketchPlugin_Arc::ID())
1046 aResult = theFeature->lastResult();
1047 else if (aFeatureKind == SketchPlugin_Circle::ID())
1048 aResult = theFeature->lastResult();
1053 //********************************************************************
1054 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject,
1055 const ObjectPtr& theSketch,
1056 std::map<ObjectPtr, std::set<GeomShapePtr> >& theCashedShapes,
1057 std::map<ObjectPtr, PointToRefsMap>& theObjectToPoints)
1059 PointToRefsMap aPointsInfo;
1061 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1062 std::map<std::shared_ptr<GeomAPI_Pnt>,
1063 std::list< AttributePoint2DPtr > > aPointToAttributes;
1064 std::map<std::shared_ptr<GeomAPI_Pnt>,
1065 std::list< ObjectPtr > > aPointToObjects;
1067 std::set<AttributePoint2DPtr > aRefAttributes;
1069 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1070 std::set<ResultPtr> anEdgeShapes;
1072 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1073 if (!anEdgeShapes.empty()) {
1074 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1076 // coincidences to the feature
1077 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1078 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1079 // layed on feature coincidences to divide it on several shapes
1080 //SketchPlugin_Sketch* aSketch = sketch();
1081 std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
1082 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1083 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1084 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1085 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1086 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1087 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1088 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1090 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1091 aX->dir(), aY, aPointsInfo);
1093 std::list<FeaturePtr> aFeatures;
1094 CompositeFeaturePtr aSketchComposite =
1095 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
1096 for (int i = 0; i < aSketchComposite->numberOfSubs(); i++) {
1097 FeaturePtr aFeature = aSketchComposite->subFeature(i);
1099 aFeatures.push_back(aFeature);
1101 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1103 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1105 theObjectToPoints[theObject] = aPointsInfo;
1106 theCashedShapes[theObject] = aShapes;