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>
16 #include <ModelAPI_AttributeReference.h>
17 #include <ModelAPI_AttributeString.h>
18 #include <ModelAPI_AttributeRefAttr.h>
19 #include <ModelAPI_Tools.h>
20 #include <ModelAPI_AttributeBoolean.h>
22 #include <ModelAPI_Validator.h>
23 #include <ModelAPI_Session.h>
24 #include <ModelAPI_AttributeDouble.h>
26 #include <SketchPlugin_Arc.h>
27 #include <SketchPlugin_ConstraintMiddle.h>
28 #include <SketchPlugin_Circle.h>
29 #include <SketchPlugin_ConstraintCoincidence.h>
30 #include <SketchPlugin_ConstraintEqual.h>
31 //#include <SketchPlugin_ConstraintParallel.h>
32 #include <SketchPlugin_ConstraintTangent.h>
33 #include <SketchPlugin_ConstraintLength.h>
34 #include <SketchPlugin_ConstraintMirror.h>
35 #include <SketchPlugin_ConstraintCollinear.h>
36 #include <SketchPlugin_Line.h>
37 #include <SketchPlugin_MultiRotation.h>
38 #include <SketchPlugin_MultiTranslation.h>
39 #include <SketchPlugin_Point.h>
41 #include <ModelAPI_Events.h>
42 #include <SketchPlugin_Line.h>
43 #include <SketchPlugin_Arc.h>
44 #include <SketchPlugin_Circle.h>
46 #include <ModelGeomAlgo_Point2D.h>
47 #include <Events_Loop.h>
56 static const double PI = 3.141592653589793238463;
58 static const std::string OPERATION_HIGHLIGHT_COLOR() { return "128, 0, 0"; }
59 static const std::string OPERATION_REMOVE_FEATURE_COLOR() { return "255, 174, 201"; }
61 SketchPlugin_Trim::SketchPlugin_Trim()
65 void SketchPlugin_Trim::initAttributes()
67 data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
68 data()->addAttribute(ENTITY_POINT(), GeomDataAPI_Point2D::typeId());
71 void SketchPlugin_Trim::findShapePoints(std::shared_ptr<GeomAPI_Pnt>& aStartPoint,
72 std::shared_ptr<GeomAPI_Pnt>& aLastPoint)
74 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
75 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
76 ObjectPtr aBaseObject = aBaseObjectAttr->value();
78 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
79 data()->attribute(ENTITY_POINT()));
80 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
81 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
82 anAttributePnt2d->y());
84 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
85 fillObjectShapes(aBaseObject);
87 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
88 if (!aShapes.empty()) {
89 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
90 for (; anIt != aLast; anIt++) {
91 GeomShapePtr aBaseShape = *anIt;
92 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
93 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
95 if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
96 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aBaseShape));
97 aStartPoint = anEdge->lastPoint();
98 aLastPoint = anEdge->firstPoint();
104 std::cout << "<findShapePoints> => "
106 << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]"
108 << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]"
113 std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
114 const std::shared_ptr<GeomAPI_Pnt>& thePoint)
116 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
118 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
119 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
120 ObjectPtr aBaseObject = aBaseObjectAttr->value();
121 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
125 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
126 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
127 aPointIt != aRefsMap.end() && !aFound; aPointIt++) {
128 if (aPointIt->first->isEqual(thePoint)) {
129 const std::pair<std::list<AttributePoint2DPtr >,
130 std::list<ObjectPtr > >& anInfo = aPointIt->second;
131 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
132 if (!anAttributes.empty()) {
133 aPoint = anAttributes.front()->pnt();
137 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
138 aPoint = thePoint->to2D(aPlane);
144 // returns an end of the shape to define direction of split if feature's attribute participates
145 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
146 aPoint = thePoint->to2D(aPlane);
151 void SketchPlugin_Trim::execute()
154 std::cout << "SketchPlugin_Trim::execute" << std::endl;
157 SketchPlugin_Sketch* aSketch = sketch();
161 // Check the base objects are initialized.
162 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
163 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
164 if(!aBaseObjectAttr->isInitialized()) {
165 setError("Error: Base object is not initialized.");
168 ObjectPtr aBaseObject = aBaseObjectAttr->value();
169 if (!aBaseObject.get())
171 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
174 std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
175 findShapePoints(aStartShapePoint, aLastShapePoint);
176 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
178 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
180 std::set<FeaturePtr> aFeaturesToDelete;
181 getConstraints(aFeaturesToDelete);
183 std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
184 std::list<AttributePtr> aRefsToFeature;
185 getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
188 // coincidence to result points
189 // find coincidences to the base object, it should be used when attribute is found
190 // in myObjectToPoints
191 std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
192 getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
194 std::set<AttributePoint2DPtr> aFurtherCoincidences;
195 std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
196 const std::string& aKind = aBaseFeature->getKind();
197 FeaturePtr aReplacingFeature;
198 if (aKind == SketchPlugin_Circle::ID()) {
199 aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
200 aFurtherCoincidences, aModifiedAttributes);
202 aFeaturesToDelete.insert(aBaseFeature);
203 // as circle is removed, temporary fill this attribute
204 aBaseObjectAttr->setObject(ResultPtr());
206 else if (aKind == SketchPlugin_Line::ID()) {
207 trimLine(aStartShapePoint2d, aLastShapePoint2d,
208 aFurtherCoincidences, aModifiedAttributes);
210 else if (aKind == SketchPlugin_Arc::ID()) {
211 trimArc(aStartShapePoint2d, aLastShapePoint2d,
212 aFurtherCoincidences, aModifiedAttributes);
216 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
217 std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
218 aLast = aFurtherCoincidences.end();
219 for (; anIt != aLast; anIt++) {
220 AttributePoint2DPtr aPointAttribute = (*anIt);
221 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
223 std::shared_ptr<GeomAPI_Pnt> aPoint;
224 if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d))
225 aPoint = aStartShapePoint;
226 else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d))
227 aPoint = aLastShapePoint;
232 std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
233 for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
236 if (aRefIt->first->isEqual(aPoint)) {
237 anInfo = aRefIt->second;
241 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
242 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
243 anAttrIt != anAttributes.end(); anAttrIt++) {
244 AttributePtr anAttribute = *anAttrIt;
245 if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
247 FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
248 AttributePtr anOtherAttribute;
249 if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
250 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
251 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
252 else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
253 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
254 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
257 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
260 aRefAttr->setAttr(aPointAttribute);
264 const std::list<ObjectPtr>& anObjects = anInfo.second;
265 for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
266 anObjectIt != anObjects.end(); anObjectIt++) {
267 createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute,
272 // move constraints from base feature to replacing feature: ignore coincidences to feature
273 // if attributes of coincidence participated in split
274 if (aReplacingFeature.get()) {
275 ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature);
276 std::list<AttributePtr>::const_iterator anIt = aRefsToFeature.begin(),
277 aLast = aRefsToFeature.end();
278 for (; anIt != aLast; anIt++) {
279 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
282 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner());
283 if (anAttrFeature.get() &&
284 anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
286 if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr ||
287 anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr)
290 aRefAttr->setObject(aReplacingResult);
294 // Wait all constraints being created, then send update events
295 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
296 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
298 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
300 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
302 // delete constraints
304 std::cout << "remove features and references:" << std::endl;
305 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
306 aDLast = aFeaturesToDelete.end();
307 for (; aDIt != aDLast; aDIt++) {
308 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
309 //std::cout << std::endl;
312 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
313 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
315 // Send events to update the sub-features by the solver.
316 if(isUpdateFlushed) {
317 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
321 std::cout << "SketchPlugin_Trim::done" << std::endl;
325 bool SketchPlugin_Trim::isMacro() const
330 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
332 AISObjectPtr anAIS = thePrevious;
334 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
335 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
336 ObjectPtr aBaseObject = aBaseObjectAttr->value();
337 if (!aBaseObject.get())
338 return AISObjectPtr();
339 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
342 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
343 data()->attribute(ENTITY_POINT()));
344 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
345 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
346 anAttributePnt2d->y());
348 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
349 fillObjectShapes(aBaseObject);
351 GeomShapePtr aBaseShape;
353 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
354 if (!aShapes.empty()) {
355 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
356 for (; anIt != aLast; anIt++) {
357 GeomShapePtr aShape = *anIt;
358 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
359 if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, anAttributePnt, aProjectedPoint))
364 if (aBaseShape.get()) {
366 anAIS = AISObjectPtr(new GeomAPI_AISObject);
367 anAIS->createShape(aBaseShape);
369 std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
370 aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
372 bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
373 std::vector<int> aColor;
374 aColor = Config_PropManager::color("Visualization", "operation_remove_feature_color");
375 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
376 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
377 if (isConstruction) {
378 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
379 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
381 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
382 // width is extened in several points in order to see this preview over highlight
383 anAIS->setWidth(aWidth + 2);
384 anAIS->setLineStyle(aLineStyle);
387 anAIS = AISObjectPtr();
392 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
393 AttributePoint2DPtr& theStartPointAttr,
394 AttributePoint2DPtr& theEndPointAttr)
396 std::string aFeatureKind = theFeature->getKind();
397 std::string aStartAttributeName, anEndAttributeName;
398 if (aFeatureKind == SketchPlugin_Line::ID()) {
399 aStartAttributeName = SketchPlugin_Line::START_ID();
400 anEndAttributeName = SketchPlugin_Line::END_ID();
402 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
403 aStartAttributeName = SketchPlugin_Arc::START_ID();
404 anEndAttributeName = SketchPlugin_Arc::END_ID();
406 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
407 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
408 theFeature->attribute(aStartAttributeName));
409 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
410 theFeature->attribute(anEndAttributeName));
414 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
416 std::shared_ptr<ModelAPI_Data> aData = data();
418 // Check the base objects are initialized.
419 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
420 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
421 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
422 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
424 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
425 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
426 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
428 std::set<AttributePtr>::const_iterator aIt;
429 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
430 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
431 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
432 std::string aRefFeatureKind = aRefFeature->getKind();
433 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
434 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
435 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
436 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
437 theFeaturesToDelete.insert(aRefFeature);
441 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
442 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
443 std::list<AttributePtr>& theRefsToFeature)
447 std::list<AttributePtr> aPointAttributes =
448 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
449 std::set<AttributePtr> aPointAttributesSet;
451 std::list<AttributePtr>::const_iterator aPIt =
452 aPointAttributes.begin(), aPLast = aPointAttributes.end();
453 for (; aPIt != aPLast; aPIt++)
454 aPointAttributesSet.insert(*aPIt);
456 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
457 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
458 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
460 std::set<AttributePtr>::const_iterator aIt;
461 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
462 AttributePtr anAttr = (*aIt);
463 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
464 if (anAttrFeature.get() != this &&
465 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
466 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
467 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
468 AttributePtr anAttrInRef = aRefAttr->attr();
469 if (anAttrInRef.get() &&
470 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
471 if (theRefs.find(anAttrInRef) != theRefs.end())
472 theRefs[anAttrInRef].push_back(aRefAttr);
474 std::list<AttributePtr> anAttrList;
475 anAttrList.push_back(aRefAttr);
476 theRefs[anAttrInRef] = anAttrList;
480 else { /// find attributes referenced to feature itself
481 theRefsToFeature.push_back(anAttr);
487 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
488 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
490 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
491 std::set<AttributePtr>::const_iterator aIt;
492 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
493 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
494 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
495 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
497 AttributePtr anAttribute;
498 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
499 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
500 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
502 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
505 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
506 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
507 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
509 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
511 if (anAttribute.get())
513 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
515 anAttribute = aRefAttr->attr();
516 if (anAttribute.get())
517 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
523 void SketchPlugin_Trim::updateRefAttConstraints(
524 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
525 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
526 std::set<FeaturePtr>& theFeaturesToDelete)
529 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
532 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
533 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
534 for (; anIt != aLast; anIt++) {
535 AttributePtr anAttribute = anIt->first;
537 /// not found in references
538 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
540 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
541 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
542 aRLast = aRefAttributes.end();
544 AttributePtr aNewAttribute = anIt->second;
545 for (; aRefIt != aRLast; aRefIt++) {
546 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
547 if (aRefAttr.get()) {
548 if (aNewAttribute.get())
549 aRefAttr->setAttr(aNewAttribute);
551 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
553 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
554 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
561 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
562 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
563 std::set<AttributePoint2DPtr>& thePoints,
564 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
566 // Check the base objects are initialized.
567 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
568 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
569 ObjectPtr aBaseObject = aBaseObjectAttr->value();
570 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
573 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
574 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
576 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
577 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
579 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
580 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
581 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
582 aStartShapePoint, aLastShapePoint);
584 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
585 if (aStartShapePoint.get())
586 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
587 aStartShapePoint->y() << "]" << std::endl;
588 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
589 aStartFeaturePoint->y() << "]" << std::endl;
590 if (aLastShapePoint.get())
591 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
592 aLastShapePoint->y() << "]" << std::endl;
593 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
594 aLastFeaturePoint->y() << "]" << std::endl;
597 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
598 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
599 if (isStartPoint || isLastPoint) {
600 // result is one line: changed existing line
601 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
602 : SketchPlugin_Line::END_ID();
603 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
604 if (aStartShapePoint.get() && aLastShapePoint.get())
605 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
607 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
609 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
610 theModifiedAttributes.insert(
611 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
613 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
614 (aBaseFeature->attribute(aModifiedAttribute)));
617 // result is two lines: start line point - start shape point, last shape point - last line point
618 // create second line
619 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
620 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
621 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
623 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
624 theModifiedAttributes.insert(
625 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
626 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
629 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
631 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
632 (aBaseFeature->attribute(aModifiedAttribute)));
634 // Collinear constraint for lines
635 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
636 getFeatureResult(aBaseFeature),
637 getFeatureResult(anNewFeature));
642 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
643 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
644 std::set<AttributePoint2DPtr>& thePoints,
645 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
647 // Check the base objects are initialized.
648 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
649 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
650 ObjectPtr aBaseObject = aBaseObjectAttr->value();
651 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
654 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
655 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
657 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
658 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
660 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
661 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
662 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
663 aStartShapePoint, aLastShapePoint);
665 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
666 if (aStartShapePoint.get())
667 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
668 aStartShapePoint->y() << "]" << std::endl;
669 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
670 aStartArcPoint->y() << "]" << std::endl;
671 if (aLastShapePoint.get())
672 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
673 aLastShapePoint->y() << "]" << std::endl;
674 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
675 aLastArcPoint->y() << "]" << std::endl;
678 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
679 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
680 if (isStartPoint || isLastPoint) {
681 // result is one arc: changed existing arc
682 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
683 : SketchPlugin_Arc::END_ID();
684 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
685 if (aStartShapePoint.get() && aLastShapePoint.get())
686 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
688 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
690 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
691 theModifiedAttributes.insert(
692 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
694 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
695 (aBaseFeature->attribute(aModifiedAttribute)));
698 // result is two arcs: start arc point - start shape point, last shape point - last arc point
700 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
701 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
702 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
704 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
705 theModifiedAttributes.insert(
706 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
707 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
710 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
712 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
713 (aBaseFeature->attribute(aModifiedAttribute)));
715 // equal Radius constraint for arcs
716 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
717 getFeatureResult(aBaseFeature),
718 getFeatureResult(anArcFeature));
719 // coincident centers constraint
720 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
721 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
722 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
726 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
727 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
728 std::set<AttributePoint2DPtr>& thePoints,
729 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
731 // Check the base objects are initialized.
732 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
733 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
734 ObjectPtr aBaseObject = aBaseObjectAttr->value();
735 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
738 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
739 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
742 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
744 theModifiedAttributes.insert(
745 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
746 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
748 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
749 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
750 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
751 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
756 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
757 const AttributePoint2DPtr& theEndPointAttr,
758 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
759 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
761 if (!theFirstPoint.get() || !theLastPoint.get())
764 // if first point is closer to last point, swap first and last values
765 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
766 theStartPointAttr->pnt()->distance(theLastPoint)) {
767 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
768 theFirstPoint = theLastPoint;
769 theLastPoint = aTmpPoint;
773 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
774 const AttributePoint2DPtr& theStartPointAttr,
775 const AttributePoint2DPtr& theEndPointAttr,
776 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
777 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
779 if (!theFirstPoint.get() || !theSecondPoint.get())
782 static const double anAngleTol = 1.e-12;
784 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
785 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
786 bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
788 // collect directions to each point
789 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
790 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
791 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
792 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
793 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
794 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
796 // sort points by their angular values
797 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
798 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
799 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
800 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
801 aFirstPtAngle += aPeriod;
802 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
803 aSecondPtAngle += aPeriod;
805 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
806 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
807 theFirstPoint = theSecondPoint;
808 theSecondPoint = aTmpPoint;
812 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
813 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
815 std::string anAttributeType = theModifiedAttribute->attributeType();
816 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
817 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
818 theModifiedAttribute);
819 aModifiedAttribute->setValue(thePoint);
822 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
823 << thePoint->y() << "]" << std::endl;
829 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
830 const AttributePtr& theSourceAttribute)
832 std::string anAttributeType = theModifiedAttribute->attributeType();
833 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
834 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
835 theModifiedAttribute);
836 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
839 if (aModifiedAttribute.get() && aSourceAttribute.get())
840 aModifiedAttribute->setValue(aSourceAttribute->pnt());
842 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
843 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
844 theModifiedAttribute);
845 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
848 if (aModifiedAttribute.get() && aSourceAttribute.get())
849 aModifiedAttribute->setValue(aSourceAttribute->value());
851 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
852 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
853 theModifiedAttribute);
854 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
856 if (!aSourceRefAttr.get())
857 aRefAttributeToFill->setAttr(theSourceAttribute);
859 if (aSourceRefAttr->isObject())
860 aRefAttributeToFill->setObject(aSourceRefAttr->object());
862 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
867 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
868 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
869 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
872 SketchPlugin_Sketch* aSketch = sketch();
873 if (!aSketch || !theBaseFeature.get())
876 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
878 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
879 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
881 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
882 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
884 aFeature->execute(); // to obtain result
890 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
891 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
892 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
895 SketchPlugin_Sketch* aSketch = sketch();
896 if (!aSketch || !theBaseFeature.get())
899 std::string aCenterAttributeId;
900 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
901 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
902 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
903 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
905 if (aCenterAttributeId.empty())
908 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
909 // update fillet arc: make the arc correct for sure, so, it is not needed to process
910 // the "attribute updated"
911 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
912 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
914 aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
915 SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
917 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
918 theBaseFeature->attribute(aCenterAttributeId));
919 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
920 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
922 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
923 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
925 /// fill referersed state of created arc as it is on the base arc
926 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
927 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
928 aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
930 aFeature->execute(); // to obtain result
931 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
936 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
937 const AttributePtr& theFirstAttribute,
938 const AttributePtr& theSecondAttribute)
940 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
941 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
942 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
943 aRefAttr->setAttr(theFirstAttribute);
945 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
946 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
947 aRefAttr->setAttr(theSecondAttribute);
950 std::cout << "<createConstraint to attribute> :"
951 << "first attribute - " << theFirstAttribute->id()
952 << "second attribute - " << theSecondAttribute->id()
959 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
960 const AttributePtr& theFirstAttribute,
961 const ObjectPtr& theSecondObject)
963 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
964 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
965 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
966 aRefAttr->setAttr(theFirstAttribute);
968 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
969 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
970 aRefAttr->setObject(theSecondObject);
973 std::cout << "<createConstraint to attribute> :"
974 << "first attribute - " << theFirstAttribute->id()
975 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
982 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
983 const std::string& theConstraintId,
984 const ObjectPtr& theFirstObject,
985 const ObjectPtr& theSecondObject)
987 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
988 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
989 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
990 aRefAttr->setObject(theFirstObject);
992 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
993 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
994 aRefAttr->setObject(theSecondObject);
999 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
1000 const std::shared_ptr<ModelAPI_Feature>& theFeature)
1002 std::shared_ptr<ModelAPI_Result> aResult;
1004 std::string aFeatureKind = theFeature->getKind();
1005 if (aFeatureKind == SketchPlugin_Line::ID())
1006 aResult = theFeature->firstResult();
1007 else if (aFeatureKind == SketchPlugin_Arc::ID())
1008 aResult = theFeature->lastResult();
1009 else if (aFeatureKind == SketchPlugin_Circle::ID())
1010 aResult = theFeature->lastResult();
1015 //********************************************************************
1016 bool SketchPlugin_Trim::useGraphicIntersection() const
1021 //********************************************************************
1022 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
1024 PointToRefsMap aPointsInfo;
1026 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1027 std::map<std::shared_ptr<GeomAPI_Pnt>,
1028 std::list< AttributePoint2DPtr > > aPointToAttributes;
1029 std::map<std::shared_ptr<GeomAPI_Pnt>,
1030 std::list< ObjectPtr > > aPointToObjects;
1032 std::set<AttributePoint2DPtr > aRefAttributes;
1034 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1035 std::set<ResultPtr> anEdgeShapes;
1037 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1038 if (!anEdgeShapes.empty()) {
1039 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1041 // coincidences to the feature
1042 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1043 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1044 // layed on feature coincidences to divide it on several shapes
1045 SketchPlugin_Sketch* aSketch = sketch();
1046 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
1047 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1048 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1049 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1050 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1051 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1052 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1053 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1055 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1056 aX->dir(), aY, aPointsInfo);
1058 // intersection points
1059 if (useGraphicIntersection()) {
1060 std::list<FeaturePtr> aFeatures;
1061 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
1062 FeaturePtr aFeature = aSketch->subFeature(i);
1064 aFeatures.push_back(aFeature);
1066 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1068 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1070 myObjectToPoints[theObject] = aPointsInfo;
1071 myCashedShapes[theObject] = aShapes;
1074 //********************************************************************
1075 void SketchPlugin_Trim::attributeChanged(const std::string& theID)
1077 //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
1078 if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
1079 bool isValidAttribute = false;
1081 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
1082 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
1083 ObjectPtr aBaseObject = aBaseObjectAttr->value();
1084 if (aBaseObject.get()) {
1085 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
1087 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1088 data()->attribute(ENTITY_POINT()));
1089 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
1090 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
1091 anAttributePnt2d->y());
1093 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1094 fillObjectShapes(aBaseObject);
1096 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1097 isValidAttribute = !aShapes.empty();
1099 if (!isValidAttribute) {
1100 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1101 aBaseObjectAttr->setValue(ObjectPtr());
1102 data()->blockSendAttributeUpdated(aWasBlocked);