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 //GeomAPI_Shape::Orientation anOrientation = anEdge->orientation();
114 //if (anOrientation == GeomAPI_Shape::REVERSED) {
115 aStartPoint = anEdge->lastPoint();
116 aLastPoint = anEdge->firstPoint();
119 //aStartPoint = anEdge->firstPoint();
120 //aLastPoint = anEdge->lastPoint();
127 std::cout << "<findShapePoints> => "
128 << std::endl << "Attribute point: "
129 << anAttributePnt->x() << ", " << anAttributePnt->y() << ", " << anAttributePnt->z() << "]"
130 << std::endl << "Start Point: ["
131 << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]"
132 << std::endl << "Last Point: ["
133 << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]"
138 std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
139 const std::shared_ptr<GeomAPI_Pnt>& thePoint)
141 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
143 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
144 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
145 ObjectPtr aBaseObject = aBaseObjectAttr->value();
146 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
147 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
150 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
151 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
152 aPointIt != aRefsMap.end() && !aFound; aPointIt++) {
153 if (aPointIt->first->isEqual(thePoint)) {
154 const std::pair<std::list<AttributePoint2DPtr >,
155 std::list<ObjectPtr > >& anInfo = aPointIt->second;
156 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
157 if (!anAttributes.empty()) {
158 aPoint = anAttributes.front()->pnt();
162 aPoint = sketch()->to2D(thePoint);
168 // returns an end of the shape to define direction of split if feature's attribute
170 aPoint = sketch()->to2D(thePoint);
175 void SketchPlugin_Trim::execute()
178 std::cout << "SketchPlugin_Trim::execute" << std::endl;
181 SketchPlugin_Sketch* aSketch = sketch();
185 // Check the base objects are initialized.
186 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
187 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
188 if(!aBaseObjectAttr->isInitialized()) {
189 setError("Error: Base object is not initialized.");
192 ObjectPtr aBaseObject = aBaseObjectAttr->value();
193 if (!aBaseObject.get())
195 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
198 std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
200 std::cout << " Base Feature: " << aBaseFeature->data()->name() << std::endl;
202 findShapePoints(SELECTED_OBJECT(), SELECTED_POINT(), aStartShapePoint, aLastShapePoint);
204 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
206 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
208 std::set<FeaturePtr> aFeaturesToDelete;
209 getConstraints(aFeaturesToDelete);
211 std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
212 std::list<AttributePtr> aRefsToFeature;
213 getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
215 // coincidence to result points
216 // find coincidences to the base object, it should be used when attribute is found
217 // in myObjectToPoints
218 std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
219 getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
221 std::set<AttributePoint2DPtr> aFurtherCoincidences;
222 std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
223 const std::string& aKind = aBaseFeature->getKind();
224 FeaturePtr aReplacingFeature;
225 if (aKind == SketchPlugin_Circle::ID()) {
226 aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
227 aFurtherCoincidences, aModifiedAttributes);
229 aFeaturesToDelete.insert(aBaseFeature);
230 // as circle is removed, erase it from dependencies(arguments) of this feature
231 // otherwise Trim feature will be removed with the circle before
232 // this operation is finished
233 aBaseObjectAttr->setObject(ResultPtr());
235 AttributeReferencePtr aPreviewObjectAttr =
236 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
237 data()->attribute(SketchPlugin_Trim::PREVIEW_OBJECT()));
238 aPreviewObjectAttr->setObject(ResultPtr());
241 else if (aKind == SketchPlugin_Line::ID()) {
242 trimLine(aStartShapePoint2d, aLastShapePoint2d,
243 aFurtherCoincidences, aModifiedAttributes);
245 else if (aKind == SketchPlugin_Arc::ID()) {
246 trimArc(aStartShapePoint2d, aLastShapePoint2d,
247 aFurtherCoincidences, aModifiedAttributes);
250 // constraints to end points of trim feature
251 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
252 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
254 // create coincidence to objects, intersected the base object
255 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
256 for (std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
257 aLast = aFurtherCoincidences.end();
258 anIt != aLast; anIt++) {
259 AttributePoint2DPtr aPointAttribute = (*anIt);
260 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
263 std::cout << "<compare Points> => "
264 << "aPoint2d: [" << aPoint2d->x() << ", " << aPoint2d->y() << "]" << std::endl;
265 if (aStartShapePoint2d.get())
266 std::cout << "Start Point: [" << aStartShapePoint2d->x() << ", " << aStartShapePoint2d->y()
268 if (aLastShapePoint2d.get())
269 std::cout << "Last Point: [" << aLastShapePoint2d->x() << ", " << aLastShapePoint2d->y()
273 std::shared_ptr<GeomAPI_Pnt> aPoint;
274 if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d))
275 aPoint = aStartShapePoint;
276 else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d))
277 aPoint = aLastShapePoint;
282 std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
283 for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
286 if (aRefIt->first->isEqual(aPoint)) {
287 anInfo = aRefIt->second;
291 /*const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
292 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
293 anAttrIt != anAttributes.end(); anAttrIt++) {
294 AttributePtr anAttribute = *anAttrIt;
295 if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
297 FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
298 AttributePtr anOtherAttribute;
299 if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
300 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
301 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
302 else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
303 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
304 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
307 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
310 aRefAttr->setAttr(aPointAttribute);
314 const std::list<ObjectPtr>& anObjects = anInfo.second;
315 for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
316 anObjectIt != anObjects.end(); anObjectIt++) {
317 createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute,
322 // move constraints from base feature to replacing feature: ignore coincidences to feature
323 // if attributes of coincidence participated in split
324 ResultPtr aReplacingResult;
325 if (aReplacingFeature.get()) {
326 aReplacingFeature->execute(); // need it to obtain result
327 aReplacingResult = getFeatureResult(aReplacingFeature);
329 for(std::list<AttributePtr>::const_iterator anIt = aRefsToFeature.begin(),
330 aLast = aRefsToFeature.end();
331 anIt != aLast; anIt++) {
332 AttributePtr anAttribute = *anIt;
333 if (setCoincidenceToAttribute(anAttribute, aFurtherCoincidences))
336 if (aReplacingResult.get()) {
337 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
339 aRefAttr->setObject(aReplacingResult);
341 AttributeReferencePtr aReferenceAttr =
342 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
343 if (aReferenceAttr.get())
344 aReferenceAttr->setObject(aReplacingResult);
349 // Wait all constraints being created, then send update events
350 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
351 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
353 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
355 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
357 // delete constraints
359 std::cout << "remove features and references:" << std::endl;
360 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
361 aDLast = aFeaturesToDelete.end();
362 for (; aDIt != aDLast; aDIt++) {
363 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
364 //std::cout << std::endl;
367 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
368 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
370 // Send events to update the sub-features by the solver.
371 if(isUpdateFlushed) {
372 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
376 std::cout << "SketchPlugin_Trim::done" << std::endl;
380 bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
381 const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
383 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
384 if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
387 AttributePoint2DPtr aRefPointAttr = SketchPlugin_ConstraintCoincidence::getPoint(aFeature);
388 if (!aRefPointAttr.get())
390 std::shared_ptr<GeomAPI_Pnt2d> aRefPnt2d = aRefPointAttr->pnt();
392 std::set<AttributePoint2DPtr>::const_iterator anIt = theFurtherCoincidences.begin(),
393 aLast = theFurtherCoincidences.end();
394 bool aFoundPoint = false;
395 for (; anIt != aLast && !aFoundPoint; anIt++) {
396 AttributePoint2DPtr aPointAttribute = (*anIt);
397 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
398 if (aPoint2d->isEqual(aRefPnt2d)) {
399 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
401 /*if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_A())
402 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
403 aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
404 else if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_B())
405 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
406 aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));*/
407 if (aRefAttr.get()) {
408 aRefAttr->setAttr(aPointAttribute);
413 /*AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
418 aRefAttr->setObject(aReplacingResult);//continue;
420 //AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
421 AttributeReferencePtr aReferenceAttr =
422 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
428 bool SketchPlugin_Trim::isMacro() const
433 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
435 AISObjectPtr anAIS = thePrevious;
437 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
438 GeomShapePtr aPreviewShape = getSubShape(PREVIEW_OBJECT(), PREVIEW_POINT());
439 if (aPreviewShape.get())
440 aShapes.push_back(aPreviewShape);
441 GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
442 if (aSelectedShape.get())
443 aShapes.push_back(aSelectedShape);
446 return AISObjectPtr();
448 GeomShapePtr aBaseShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
449 if (!aBaseShape.get())
450 return AISObjectPtr();
452 if (aBaseShape.get()) {
454 anAIS = AISObjectPtr(new GeomAPI_AISObject);
455 anAIS->createShape(aBaseShape);
457 std::vector<int> aColor;
458 aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color");
459 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
460 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
461 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
462 // width when there is not base object should be extened in several points
463 // in order to see this preview over highlight
464 anAIS->setWidth(aWidth+4);
465 anAIS->setLineStyle(aLineStyle);
468 anAIS = AISObjectPtr();
473 GeomShapePtr SketchPlugin_Trim::getSubShape(const std::string& theObjectAttributeId,
474 const std::string& thePointAttributeId)
476 GeomShapePtr aBaseShape;
478 AttributeReferencePtr anObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
479 data()->attribute(theObjectAttributeId));
480 ObjectPtr aBaseObject = anObjectAttr->value();
481 if (!aBaseObject.get())
485 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
486 data()->attribute(thePointAttributeId));
487 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
488 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
489 anAttributePnt2d->y());
491 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
492 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
494 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
495 if (!aShapes.empty()) {
496 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
497 for (; anIt != aLast; anIt++) {
498 GeomShapePtr aShape = *anIt;
499 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
500 if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint))
507 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
508 AttributePoint2DPtr& theStartPointAttr,
509 AttributePoint2DPtr& theEndPointAttr)
511 std::string aFeatureKind = theFeature->getKind();
512 std::string aStartAttributeName, anEndAttributeName;
513 if (aFeatureKind == SketchPlugin_Line::ID()) {
514 aStartAttributeName = SketchPlugin_Line::START_ID();
515 anEndAttributeName = SketchPlugin_Line::END_ID();
517 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
518 aStartAttributeName = SketchPlugin_Arc::START_ID();
519 anEndAttributeName = SketchPlugin_Arc::END_ID();
521 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
522 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
523 theFeature->attribute(aStartAttributeName));
524 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
525 theFeature->attribute(anEndAttributeName));
529 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
531 std::shared_ptr<ModelAPI_Data> aData = data();
533 // Check the base objects are initialized.
534 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
535 aData->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
536 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
537 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
539 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
540 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
541 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
543 std::set<AttributePtr>::const_iterator aIt;
544 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
545 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
546 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
547 std::string aRefFeatureKind = aRefFeature->getKind();
548 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
549 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
550 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
551 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
552 theFeaturesToDelete.insert(aRefFeature);
556 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
557 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
558 std::list<AttributePtr>& theRefsToFeature)
562 std::list<AttributePtr> aPointAttributes =
563 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
564 std::set<AttributePtr> aPointAttributesSet;
566 std::list<AttributePtr>::const_iterator aPIt =
567 aPointAttributes.begin(), aPLast = aPointAttributes.end();
568 for (; aPIt != aPLast; aPIt++)
569 aPointAttributesSet.insert(*aPIt);
571 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
572 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
573 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
575 std::set<AttributePtr>::const_iterator aIt;
576 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
577 AttributePtr anAttr = (*aIt);
578 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
579 if (anAttrFeature.get() != this &&
580 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
581 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
582 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
583 AttributePtr anAttrInRef = aRefAttr->attr();
584 if (anAttrInRef.get() &&
585 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
586 if (theRefs.find(anAttrInRef) != theRefs.end())
587 theRefs[anAttrInRef].push_back(aRefAttr);
589 std::list<AttributePtr> anAttrList;
590 anAttrList.push_back(aRefAttr);
591 theRefs[anAttrInRef] = anAttrList;
595 else { /// find attributes referenced to feature itself
596 theRefsToFeature.push_back(anAttr);
602 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
603 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
605 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
606 std::set<AttributePtr>::const_iterator aIt;
607 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
608 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
609 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
610 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
612 AttributePtr anAttribute;
613 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
614 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
615 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
617 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
620 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
621 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
622 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
623 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
625 if (!anAttribute.get())
628 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
629 if (aRefAttr->isObject())
630 continue; // one of attributes of coincidence contains link to an attribute
632 anAttribute = aRefAttr->attr();
633 if (anAttribute.get())
635 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
640 void SketchPlugin_Trim::updateRefAttConstraints(
641 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
642 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
643 std::set<FeaturePtr>& theFeaturesToDelete)
646 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
649 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
650 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
651 for (; anIt != aLast; anIt++) {
652 AttributePtr anAttribute = anIt->first;
654 /// not found in references
655 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
657 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
658 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
659 aRLast = aRefAttributes.end();
661 AttributePtr aNewAttribute = anIt->second;
662 for (; aRefIt != aRLast; aRefIt++) {
663 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
664 if (aRefAttr.get()) {
665 if (aNewAttribute.get())
666 aRefAttr->setAttr(aNewAttribute);
668 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
670 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
671 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
678 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
679 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
680 std::set<AttributePoint2DPtr>& thePoints,
681 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
683 // Check the base objects are initialized.
684 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
685 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
686 ObjectPtr aBaseObject = aBaseObjectAttr->value();
687 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
690 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
691 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
693 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
694 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
696 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
697 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
698 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
699 aStartShapePoint, aLastShapePoint);
701 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
702 if (aStartShapePoint.get())
703 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
704 aStartShapePoint->y() << "]" << std::endl;
705 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
706 aStartFeaturePoint->y() << "]" << std::endl;
707 if (aLastShapePoint.get())
708 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
709 aLastShapePoint->y() << "]" << std::endl;
710 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
711 aLastFeaturePoint->y() << "]" << std::endl;
714 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
715 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
716 if (isStartPoint || isLastPoint) {
717 // result is one line: changed existing line
718 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
719 : SketchPlugin_Line::END_ID();
720 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
721 if (aStartShapePoint.get() && aLastShapePoint.get())
722 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
724 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
726 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
727 theModifiedAttributes.insert(
728 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
730 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
731 (aBaseFeature->attribute(aModifiedAttribute)));
734 // result is two lines: start line point - start shape point,
735 // last shape point - last line point
736 // create second line
737 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
738 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
739 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
741 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
742 theModifiedAttributes.insert(
743 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
744 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
747 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
749 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
750 (aBaseFeature->attribute(aModifiedAttribute)));
752 // Collinear constraint for lines
753 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
754 getFeatureResult(aBaseFeature),
755 getFeatureResult(anNewFeature));
760 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
761 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
762 std::set<AttributePoint2DPtr>& thePoints,
763 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
765 // Check the base objects are initialized.
766 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
767 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
768 ObjectPtr aBaseObject = aBaseObjectAttr->value();
769 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
772 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
773 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
775 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
776 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
778 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
779 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
780 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
781 aStartShapePoint, aLastShapePoint);
783 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
784 if (aStartShapePoint.get())
785 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
786 aStartShapePoint->y() << "]" << std::endl;
787 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
788 aStartArcPoint->y() << "]" << std::endl;
789 if (aLastShapePoint.get())
790 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
791 aLastShapePoint->y() << "]" << std::endl;
792 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
793 aLastArcPoint->y() << "]" << std::endl;
796 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
797 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
798 if (isStartPoint || isLastPoint) {
799 // result is one arc: changed existing arc
800 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
801 : SketchPlugin_Arc::END_ID();
802 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
803 if (aStartShapePoint.get() && aLastShapePoint.get())
804 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
806 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
808 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
809 theModifiedAttributes.insert(
810 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
812 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
813 (aBaseFeature->attribute(aModifiedAttribute)));
816 // result is two arcs: start arc point - start shape point, last shape point - last arc point
818 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
819 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
820 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
822 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
823 theModifiedAttributes.insert(
824 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
825 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
828 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
830 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
831 (aBaseFeature->attribute(aModifiedAttribute)));
833 // equal Radius constraint for arcs
834 anArcFeature->execute(); // we need the created arc result to set equal constraint
835 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
836 getFeatureResult(aBaseFeature),
837 getFeatureResult(anArcFeature));
838 // coincident centers constraint
839 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
840 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
841 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
845 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
846 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
847 std::set<AttributePoint2DPtr>& thePoints,
848 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
850 // Check the base objects are initialized.
851 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
852 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
853 ObjectPtr aBaseObject = aBaseObjectAttr->value();
854 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
857 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
858 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
861 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
862 // arc created by trim of circle is always correct, that means that it is not inversed
863 anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
865 theModifiedAttributes.insert(
866 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
867 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
869 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
870 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
871 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
872 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
877 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
878 const AttributePoint2DPtr& theEndPointAttr,
879 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
880 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
882 if (!theFirstPoint.get() || !theLastPoint.get())
885 // if first point is closer to last point, swap first and last values
886 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
887 theStartPointAttr->pnt()->distance(theLastPoint)) {
888 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
889 theFirstPoint = theLastPoint;
890 theLastPoint = aTmpPoint;
894 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
895 const AttributePoint2DPtr& theStartPointAttr,
896 const AttributePoint2DPtr& theEndPointAttr,
897 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
898 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
900 if (!theFirstPoint.get() || !theSecondPoint.get())
903 static const double anAngleTol = 1.e-12;
905 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
906 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
907 bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
909 // collect directions to each point
910 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
911 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
912 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
913 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
914 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
915 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
917 // sort points by their angular values
918 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
919 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
920 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
921 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
922 aFirstPtAngle += aPeriod;
923 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
924 aSecondPtAngle += aPeriod;
926 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
927 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
928 theFirstPoint = theSecondPoint;
929 theSecondPoint = aTmpPoint;
933 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
934 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
936 std::string anAttributeType = theModifiedAttribute->attributeType();
937 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
938 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
939 theModifiedAttribute);
940 aModifiedAttribute->setValue(thePoint);
943 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
944 << thePoint->y() << "]" << std::endl;
950 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
951 const AttributePtr& theSourceAttribute)
953 std::string anAttributeType = theModifiedAttribute->attributeType();
954 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
955 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
956 theModifiedAttribute);
957 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
960 if (aModifiedAttribute.get() && aSourceAttribute.get())
961 aModifiedAttribute->setValue(aSourceAttribute->pnt());
963 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
964 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
965 theModifiedAttribute);
966 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
969 if (aModifiedAttribute.get() && aSourceAttribute.get())
970 aModifiedAttribute->setValue(aSourceAttribute->value());
972 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
973 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
974 theModifiedAttribute);
975 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
977 if (!aSourceRefAttr.get())
978 aRefAttributeToFill->setAttr(theSourceAttribute);
980 if (aSourceRefAttr->isObject())
981 aRefAttributeToFill->setObject(aSourceRefAttr->object());
983 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
988 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
989 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
990 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
993 SketchPlugin_Sketch* aSketch = sketch();
994 if (!aSketch || !theBaseFeature.get())
997 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
999 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
1000 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
1002 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
1003 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
1005 aFeature->execute(); // to obtain result
1010 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
1011 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
1012 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
1014 FeaturePtr aFeature;
1015 SketchPlugin_Sketch* aSketch = sketch();
1016 if (!aSketch || !theBaseFeature.get())
1019 std::string aCenterAttributeId;
1020 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
1021 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
1022 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
1023 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
1025 if (aCenterAttributeId.empty())
1028 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
1029 // update fillet arc: make the arc correct for sure, so, it is not needed to process
1030 // the "attribute updated"
1031 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
1032 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
1034 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
1035 theBaseFeature->attribute(aCenterAttributeId));
1036 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
1037 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
1039 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
1040 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
1042 /// fill referersed state of created arc as it is on the base arc
1043 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
1044 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
1045 aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed);
1047 //aFeature->execute(); // to obtain result
1048 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
1053 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
1054 const AttributePtr& theFirstAttribute,
1055 const AttributePtr& theSecondAttribute)
1057 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1058 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1059 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1060 aRefAttr->setAttr(theFirstAttribute);
1062 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1063 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1064 aRefAttr->setAttr(theSecondAttribute);
1067 std::cout << "<createConstraint to attribute> :"
1068 << "first attribute - " << theFirstAttribute->id()
1069 << "second attribute - " << theSecondAttribute->id()
1076 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
1077 const AttributePtr& theFirstAttribute,
1078 const ObjectPtr& theSecondObject)
1080 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1081 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1082 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1083 aRefAttr->setAttr(theFirstAttribute);
1085 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1086 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1087 aRefAttr->setObject(theSecondObject);
1090 std::cout << "<createConstraint to attribute> :"
1091 << "first attribute - " << theFirstAttribute->id()
1092 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
1099 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
1100 const std::string& theConstraintId,
1101 const ObjectPtr& theFirstObject,
1102 const ObjectPtr& theSecondObject)
1104 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1105 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1106 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1107 aRefAttr->setObject(theFirstObject);
1109 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1110 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1111 aRefAttr->setObject(theSecondObject);
1116 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
1117 const std::shared_ptr<ModelAPI_Feature>& theFeature)
1119 std::shared_ptr<ModelAPI_Result> aResult;
1121 std::string aFeatureKind = theFeature->getKind();
1122 if (aFeatureKind == SketchPlugin_Line::ID())
1123 aResult = theFeature->firstResult();
1124 else if (aFeatureKind == SketchPlugin_Arc::ID())
1125 aResult = theFeature->lastResult();
1126 else if (aFeatureKind == SketchPlugin_Circle::ID())
1127 aResult = theFeature->lastResult();
1132 //********************************************************************
1133 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject,
1134 const ObjectPtr& theSketch,
1135 std::map<ObjectPtr, std::set<GeomShapePtr> >& theCashedShapes,
1136 std::map<ObjectPtr, PointToRefsMap>& theObjectToPoints)
1138 PointToRefsMap aPointsInfo;
1140 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1141 std::map<std::shared_ptr<GeomAPI_Pnt>,
1142 std::list< AttributePoint2DPtr > > aPointToAttributes;
1143 std::map<std::shared_ptr<GeomAPI_Pnt>,
1144 std::list< ObjectPtr > > aPointToObjects;
1146 std::set<AttributePoint2DPtr > aRefAttributes;
1148 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1149 std::set<ResultPtr> anEdgeShapes;
1151 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1152 if (!anEdgeShapes.empty()) {
1153 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1155 // coincidences to the feature
1156 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1157 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1158 // layed on feature coincidences to divide it on several shapes
1159 //SketchPlugin_Sketch* aSketch = sketch();
1160 std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
1161 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1162 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1163 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1164 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1165 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1166 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1167 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1169 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1170 aX->dir(), aY, aPointsInfo);
1172 std::list<FeaturePtr> aFeatures;
1173 CompositeFeaturePtr aSketchComposite =
1174 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
1175 for (int i = 0; i < aSketchComposite->numberOfSubs(); i++) {
1176 FeaturePtr aFeature = aSketchComposite->subFeature(i);
1178 aFeatures.push_back(aFeature);
1180 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1182 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1184 theObjectToPoints[theObject] = aPointsInfo;
1185 theCashedShapes[theObject] = aShapes;