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 =
338 std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
340 aRefAttr->setObject(aReplacingResult);
342 AttributeReferencePtr aReferenceAttr =
343 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
344 if (aReferenceAttr.get())
345 aReferenceAttr->setObject(aReplacingResult);
350 // Wait all constraints being created, then send update events
351 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
352 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
354 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
356 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
358 // delete constraints
360 std::cout << "remove features and references:" << std::endl;
361 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
362 aDLast = aFeaturesToDelete.end();
363 for (; aDIt != aDLast; aDIt++) {
364 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
365 //std::cout << std::endl;
368 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
369 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
371 // Send events to update the sub-features by the solver.
372 if(isUpdateFlushed) {
373 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
377 std::cout << "SketchPlugin_Trim::done" << std::endl;
381 bool SketchPlugin_Trim::setCoincidenceToAttribute(const AttributePtr& theAttribute,
382 const std::set<AttributePoint2DPtr>& theFurtherCoincidences)
384 FeaturePtr aFeature = ModelAPI_Feature::feature(theAttribute->owner());
385 if (aFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
388 AttributePoint2DPtr aRefPointAttr = SketchPlugin_ConstraintCoincidence::getPoint(aFeature);
389 if (!aRefPointAttr.get())
391 std::shared_ptr<GeomAPI_Pnt2d> aRefPnt2d = aRefPointAttr->pnt();
393 std::set<AttributePoint2DPtr>::const_iterator anIt = theFurtherCoincidences.begin(),
394 aLast = theFurtherCoincidences.end();
395 bool aFoundPoint = false;
396 for (; anIt != aLast && !aFoundPoint; anIt++) {
397 AttributePoint2DPtr aPointAttribute = (*anIt);
398 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
399 if (aPoint2d->isEqual(aRefPnt2d)) {
400 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
402 /*if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_A())
403 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
404 aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_B()));
405 else if (theAttribute->id() == SketchPlugin_ConstraintCoincidence::ENTITY_B())
406 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
407 aFeature->attribute(SketchPlugin_ConstraintCoincidence::ENTITY_A()));*/
408 if (aRefAttr.get()) {
409 aRefAttr->setAttr(aPointAttribute);
414 /*AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(theAttribute);
419 aRefAttr->setObject(aReplacingResult);//continue;
421 //AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
422 AttributeReferencePtr aReferenceAttr =
423 std::dynamic_pointer_cast<ModelAPI_AttributeReference>(anAttribute);
429 bool SketchPlugin_Trim::isMacro() const
434 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
436 AISObjectPtr anAIS = thePrevious;
438 std::list<std::shared_ptr<GeomAPI_Shape> > aShapes;
439 GeomShapePtr aPreviewShape = getSubShape(PREVIEW_OBJECT(), PREVIEW_POINT());
440 if (aPreviewShape.get())
441 aShapes.push_back(aPreviewShape);
442 GeomShapePtr aSelectedShape = getSubShape(SELECTED_OBJECT(), SELECTED_POINT());
443 if (aSelectedShape.get())
444 aShapes.push_back(aSelectedShape);
447 return AISObjectPtr();
449 GeomShapePtr aBaseShape = GeomAlgoAPI_CompoundBuilder::compound(aShapes);
450 if (!aBaseShape.get())
451 return AISObjectPtr();
453 if (aBaseShape.get()) {
455 anAIS = AISObjectPtr(new GeomAPI_AISObject);
456 anAIS->createShape(aBaseShape);
458 std::vector<int> aColor;
459 aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color");
460 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
461 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
462 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
463 // width when there is not base object should be extened in several points
464 // in order to see this preview over highlight
465 anAIS->setWidth(aWidth+4);
466 anAIS->setLineStyle(aLineStyle);
469 anAIS = AISObjectPtr();
474 GeomShapePtr SketchPlugin_Trim::getSubShape(const std::string& theObjectAttributeId,
475 const std::string& thePointAttributeId)
477 GeomShapePtr aBaseShape;
479 AttributeReferencePtr anObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
480 data()->attribute(theObjectAttributeId));
481 ObjectPtr aBaseObject = anObjectAttr->value();
482 if (!aBaseObject.get())
486 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
487 data()->attribute(thePointAttributeId));
488 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
489 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
490 anAttributePnt2d->y());
492 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
493 fillObjectShapes(aBaseObject, sketch()->data()->owner(), myCashedShapes, myObjectToPoints);
495 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
496 if (!aShapes.empty()) {
497 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
498 for (; anIt != aLast; anIt++) {
499 GeomShapePtr aShape = *anIt;
500 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
501 if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint))
508 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
509 AttributePoint2DPtr& theStartPointAttr,
510 AttributePoint2DPtr& theEndPointAttr)
512 std::string aFeatureKind = theFeature->getKind();
513 std::string aStartAttributeName, anEndAttributeName;
514 if (aFeatureKind == SketchPlugin_Line::ID()) {
515 aStartAttributeName = SketchPlugin_Line::START_ID();
516 anEndAttributeName = SketchPlugin_Line::END_ID();
518 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
519 aStartAttributeName = SketchPlugin_Arc::START_ID();
520 anEndAttributeName = SketchPlugin_Arc::END_ID();
522 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
523 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
524 theFeature->attribute(aStartAttributeName));
525 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
526 theFeature->attribute(anEndAttributeName));
530 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
532 std::shared_ptr<ModelAPI_Data> aData = data();
534 // Check the base objects are initialized.
535 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
536 aData->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
537 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
538 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
540 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
541 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
542 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
544 std::set<AttributePtr>::const_iterator aIt;
545 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
546 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
547 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
548 std::string aRefFeatureKind = aRefFeature->getKind();
549 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
550 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
551 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
552 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
553 theFeaturesToDelete.insert(aRefFeature);
557 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
558 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
559 std::list<AttributePtr>& theRefsToFeature)
563 std::list<AttributePtr> aPointAttributes =
564 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
565 std::set<AttributePtr> aPointAttributesSet;
567 std::list<AttributePtr>::const_iterator aPIt =
568 aPointAttributes.begin(), aPLast = aPointAttributes.end();
569 for (; aPIt != aPLast; aPIt++)
570 aPointAttributesSet.insert(*aPIt);
572 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
573 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
574 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
576 std::set<AttributePtr>::const_iterator aIt;
577 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
578 AttributePtr anAttr = (*aIt);
579 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
580 if (anAttrFeature.get() != this &&
581 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
582 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
583 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
584 AttributePtr anAttrInRef = aRefAttr->attr();
585 if (anAttrInRef.get() &&
586 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
587 if (theRefs.find(anAttrInRef) != theRefs.end())
588 theRefs[anAttrInRef].push_back(aRefAttr);
590 std::list<AttributePtr> anAttrList;
591 anAttrList.push_back(aRefAttr);
592 theRefs[anAttrInRef] = anAttrList;
596 else { /// find attributes referenced to feature itself
597 theRefsToFeature.push_back(anAttr);
603 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
604 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
606 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
607 std::set<AttributePtr>::const_iterator aIt;
608 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
609 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
610 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
611 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
613 AttributePtr anAttribute;
614 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
615 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
616 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
618 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
621 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
622 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
623 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
624 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
626 if (!anAttribute.get())
629 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttribute);
630 if (aRefAttr->isObject())
631 continue; // one of attributes of coincidence contains link to an attribute
633 anAttribute = aRefAttr->attr();
634 if (anAttribute.get())
636 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
641 void SketchPlugin_Trim::updateRefAttConstraints(
642 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
643 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
644 std::set<FeaturePtr>& theFeaturesToDelete)
647 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
650 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
651 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
652 for (; anIt != aLast; anIt++) {
653 AttributePtr anAttribute = anIt->first;
655 /// not found in references
656 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
658 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
659 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
660 aRLast = aRefAttributes.end();
662 AttributePtr aNewAttribute = anIt->second;
663 for (; aRefIt != aRLast; aRefIt++) {
664 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
665 if (aRefAttr.get()) {
666 if (aNewAttribute.get())
667 aRefAttr->setAttr(aNewAttribute);
669 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
671 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
672 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
679 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
680 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
681 std::set<AttributePoint2DPtr>& thePoints,
682 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
684 // Check the base objects are initialized.
685 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
686 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
687 ObjectPtr aBaseObject = aBaseObjectAttr->value();
688 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
691 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
692 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
694 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
695 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
697 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
698 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
699 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
700 aStartShapePoint, aLastShapePoint);
702 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
703 if (aStartShapePoint.get())
704 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
705 aStartShapePoint->y() << "]" << std::endl;
706 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
707 aStartFeaturePoint->y() << "]" << std::endl;
708 if (aLastShapePoint.get())
709 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
710 aLastShapePoint->y() << "]" << std::endl;
711 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
712 aLastFeaturePoint->y() << "]" << std::endl;
715 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
716 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
717 if (isStartPoint || isLastPoint) {
718 // result is one line: changed existing line
719 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
720 : SketchPlugin_Line::END_ID();
721 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
722 if (aStartShapePoint.get() && aLastShapePoint.get())
723 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
725 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
727 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
728 theModifiedAttributes.insert(
729 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
731 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
732 (aBaseFeature->attribute(aModifiedAttribute)));
735 // result is two lines: start line point - start shape point,
736 // last shape point - last line point
737 // create second line
738 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
739 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
740 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
742 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
743 theModifiedAttributes.insert(
744 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
745 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
748 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
750 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
751 (aBaseFeature->attribute(aModifiedAttribute)));
753 // Collinear constraint for lines
754 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
755 getFeatureResult(aBaseFeature),
756 getFeatureResult(anNewFeature));
761 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
762 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
763 std::set<AttributePoint2DPtr>& thePoints,
764 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
766 // Check the base objects are initialized.
767 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
768 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
769 ObjectPtr aBaseObject = aBaseObjectAttr->value();
770 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
773 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
774 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
776 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
777 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
779 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
780 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
781 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
782 aStartShapePoint, aLastShapePoint);
784 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
785 if (aStartShapePoint.get())
786 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
787 aStartShapePoint->y() << "]" << std::endl;
788 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
789 aStartArcPoint->y() << "]" << std::endl;
790 if (aLastShapePoint.get())
791 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
792 aLastShapePoint->y() << "]" << std::endl;
793 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
794 aLastArcPoint->y() << "]" << std::endl;
797 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
798 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
799 if (isStartPoint || isLastPoint) {
800 // result is one arc: changed existing arc
801 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
802 : SketchPlugin_Arc::END_ID();
803 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
804 if (aStartShapePoint.get() && aLastShapePoint.get())
805 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
807 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
809 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
810 theModifiedAttributes.insert(
811 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
813 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
814 (aBaseFeature->attribute(aModifiedAttribute)));
817 // result is two arcs: start arc point - start shape point, last shape point - last arc point
819 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
820 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
821 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
823 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
824 theModifiedAttributes.insert(
825 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
826 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
829 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
831 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
832 (aBaseFeature->attribute(aModifiedAttribute)));
834 // equal Radius constraint for arcs
835 anArcFeature->execute(); // we need the created arc result to set equal constraint
836 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
837 getFeatureResult(aBaseFeature),
838 getFeatureResult(anArcFeature));
839 // coincident centers constraint
840 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
841 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
842 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
846 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
847 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
848 std::set<AttributePoint2DPtr>& thePoints,
849 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
851 // Check the base objects are initialized.
852 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
853 data()->attribute(SketchPlugin_Trim::SELECTED_OBJECT()));
854 ObjectPtr aBaseObject = aBaseObjectAttr->value();
855 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
858 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
859 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
862 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
863 // arc created by trim of circle is always correct, that means that it is not inversed
864 anArcFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(false);
866 theModifiedAttributes.insert(
867 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
868 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
870 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
871 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
872 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
873 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
878 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
879 const AttributePoint2DPtr& theEndPointAttr,
880 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
881 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
883 if (!theFirstPoint.get() || !theLastPoint.get())
886 // if first point is closer to last point, swap first and last values
887 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
888 theStartPointAttr->pnt()->distance(theLastPoint)) {
889 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
890 theFirstPoint = theLastPoint;
891 theLastPoint = aTmpPoint;
895 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
896 const AttributePoint2DPtr& theStartPointAttr,
897 const AttributePoint2DPtr& theEndPointAttr,
898 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
899 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
901 if (!theFirstPoint.get() || !theSecondPoint.get())
904 static const double anAngleTol = 1.e-12;
906 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
907 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
908 bool isReversed = theArc->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
910 // collect directions to each point
911 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
912 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
913 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
914 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
915 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
916 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
918 // sort points by their angular values
919 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
920 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
921 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
922 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
923 aFirstPtAngle += aPeriod;
924 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
925 aSecondPtAngle += aPeriod;
927 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
928 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
929 theFirstPoint = theSecondPoint;
930 theSecondPoint = aTmpPoint;
934 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
935 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
937 std::string anAttributeType = theModifiedAttribute->attributeType();
938 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
939 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
940 theModifiedAttribute);
941 aModifiedAttribute->setValue(thePoint);
944 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
945 << thePoint->y() << "]" << std::endl;
951 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
952 const AttributePtr& theSourceAttribute)
954 std::string anAttributeType = theModifiedAttribute->attributeType();
955 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
956 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
957 theModifiedAttribute);
958 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
961 if (aModifiedAttribute.get() && aSourceAttribute.get())
962 aModifiedAttribute->setValue(aSourceAttribute->pnt());
964 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
965 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
966 theModifiedAttribute);
967 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
970 if (aModifiedAttribute.get() && aSourceAttribute.get())
971 aModifiedAttribute->setValue(aSourceAttribute->value());
973 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
974 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
975 theModifiedAttribute);
976 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
978 if (!aSourceRefAttr.get())
979 aRefAttributeToFill->setAttr(theSourceAttribute);
981 if (aSourceRefAttr->isObject())
982 aRefAttributeToFill->setObject(aSourceRefAttr->object());
984 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
989 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
990 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
991 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
994 SketchPlugin_Sketch* aSketch = sketch();
995 if (!aSketch || !theBaseFeature.get())
998 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
1000 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
1001 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
1003 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
1004 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
1006 aFeature->execute(); // to obtain result
1011 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
1012 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
1013 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
1015 FeaturePtr aFeature;
1016 SketchPlugin_Sketch* aSketch = sketch();
1017 if (!aSketch || !theBaseFeature.get())
1020 std::string aCenterAttributeId;
1021 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
1022 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
1023 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
1024 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
1026 if (aCenterAttributeId.empty())
1029 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
1030 // update fillet arc: make the arc correct for sure, so, it is not needed to process
1031 // the "attribute updated"
1032 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
1033 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
1035 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
1036 theBaseFeature->attribute(aCenterAttributeId));
1037 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
1038 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
1040 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
1041 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
1043 /// fill referersed state of created arc as it is on the base arc
1044 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
1045 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->value();
1046 aFeature->boolean(SketchPlugin_Arc::REVERSED_ID())->setValue(aReversed);
1048 //aFeature->execute(); // to obtain result
1049 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
1054 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
1055 const AttributePtr& theFirstAttribute,
1056 const AttributePtr& theSecondAttribute)
1058 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1059 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1060 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1061 aRefAttr->setAttr(theFirstAttribute);
1063 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1064 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1065 aRefAttr->setAttr(theSecondAttribute);
1068 std::cout << "<createConstraint to attribute> :"
1069 << "first attribute - " << theFirstAttribute->id()
1070 << "second attribute - " << theSecondAttribute->id()
1077 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
1078 const AttributePtr& theFirstAttribute,
1079 const ObjectPtr& theSecondObject)
1081 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1082 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1083 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1084 aRefAttr->setAttr(theFirstAttribute);
1086 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1087 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1088 aRefAttr->setObject(theSecondObject);
1091 std::cout << "<createConstraint to attribute> :"
1092 << "first attribute - " << theFirstAttribute->id()
1093 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
1100 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
1101 const std::string& theConstraintId,
1102 const ObjectPtr& theFirstObject,
1103 const ObjectPtr& theSecondObject)
1105 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
1106 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1107 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
1108 aRefAttr->setObject(theFirstObject);
1110 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
1111 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
1112 aRefAttr->setObject(theSecondObject);
1117 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
1118 const std::shared_ptr<ModelAPI_Feature>& theFeature)
1120 std::shared_ptr<ModelAPI_Result> aResult;
1122 std::string aFeatureKind = theFeature->getKind();
1123 if (aFeatureKind == SketchPlugin_Line::ID())
1124 aResult = theFeature->firstResult();
1125 else if (aFeatureKind == SketchPlugin_Arc::ID())
1126 aResult = theFeature->lastResult();
1127 else if (aFeatureKind == SketchPlugin_Circle::ID())
1128 aResult = theFeature->lastResult();
1133 //********************************************************************
1134 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject,
1135 const ObjectPtr& theSketch,
1136 std::map<ObjectPtr, std::set<GeomShapePtr> >& theCashedShapes,
1137 std::map<ObjectPtr, PointToRefsMap>& theObjectToPoints)
1139 PointToRefsMap aPointsInfo;
1141 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1142 std::map<std::shared_ptr<GeomAPI_Pnt>,
1143 std::list< AttributePoint2DPtr > > aPointToAttributes;
1144 std::map<std::shared_ptr<GeomAPI_Pnt>,
1145 std::list< ObjectPtr > > aPointToObjects;
1147 std::set<AttributePoint2DPtr > aRefAttributes;
1149 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1150 std::set<ResultPtr> anEdgeShapes;
1152 ModelGeomAlgo_Shape::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1153 if (!anEdgeShapes.empty()) {
1154 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1156 // coincidences to the feature
1157 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1158 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1159 // layed on feature coincidences to divide it on several shapes
1160 //SketchPlugin_Sketch* aSketch = sketch();
1161 std::shared_ptr<ModelAPI_Data> aData = theSketch->data();
1162 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1163 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1164 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1165 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1166 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1167 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1168 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1170 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1171 aX->dir(), aY, aPointsInfo);
1173 std::list<FeaturePtr> aFeatures;
1174 CompositeFeaturePtr aSketchComposite =
1175 std::dynamic_pointer_cast<ModelAPI_CompositeFeature>(theSketch);
1176 for (int i = 0; i < aSketchComposite->numberOfSubs(); i++) {
1177 FeaturePtr aFeature = aSketchComposite->subFeature(i);
1179 aFeatures.push_back(aFeature);
1181 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1183 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1185 theObjectToPoints[theObject] = aPointsInfo;
1186 theCashedShapes[theObject] = aShapes;