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 OPERATION_REMOVE_FEATURE_COLOR());
376 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
377 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
378 if (isConstruction) {
379 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
380 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
382 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
383 // width is extened in several points in order to see this preview over highlight
384 anAIS->setWidth(aWidth + 2);
385 anAIS->setLineStyle(aLineStyle);
388 anAIS = AISObjectPtr();
393 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
394 AttributePoint2DPtr& theStartPointAttr,
395 AttributePoint2DPtr& theEndPointAttr)
397 std::string aFeatureKind = theFeature->getKind();
398 std::string aStartAttributeName, anEndAttributeName;
399 if (aFeatureKind == SketchPlugin_Line::ID()) {
400 aStartAttributeName = SketchPlugin_Line::START_ID();
401 anEndAttributeName = SketchPlugin_Line::END_ID();
403 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
404 aStartAttributeName = SketchPlugin_Arc::START_ID();
405 anEndAttributeName = SketchPlugin_Arc::END_ID();
407 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
408 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
409 theFeature->attribute(aStartAttributeName));
410 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
411 theFeature->attribute(anEndAttributeName));
415 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
417 std::shared_ptr<ModelAPI_Data> aData = data();
419 // Check the base objects are initialized.
420 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
421 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
422 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
423 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
425 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
426 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
427 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
429 std::set<AttributePtr>::const_iterator aIt;
430 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
431 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
432 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
433 std::string aRefFeatureKind = aRefFeature->getKind();
434 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
435 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
436 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
437 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
438 theFeaturesToDelete.insert(aRefFeature);
442 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
443 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
444 std::list<AttributePtr>& theRefsToFeature)
448 std::list<AttributePtr> aPointAttributes =
449 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
450 std::set<AttributePtr> aPointAttributesSet;
452 std::list<AttributePtr>::const_iterator aPIt =
453 aPointAttributes.begin(), aPLast = aPointAttributes.end();
454 for (; aPIt != aPLast; aPIt++)
455 aPointAttributesSet.insert(*aPIt);
457 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
458 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
459 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
461 std::set<AttributePtr>::const_iterator aIt;
462 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
463 AttributePtr anAttr = (*aIt);
464 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
465 if (anAttrFeature.get() != this &&
466 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
467 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
468 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
469 AttributePtr anAttrInRef = aRefAttr->attr();
470 if (anAttrInRef.get() &&
471 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
472 if (theRefs.find(anAttrInRef) != theRefs.end())
473 theRefs[anAttrInRef].push_back(aRefAttr);
475 std::list<AttributePtr> anAttrList;
476 anAttrList.push_back(aRefAttr);
477 theRefs[anAttrInRef] = anAttrList;
481 else { /// find attributes referenced to feature itself
482 theRefsToFeature.push_back(anAttr);
488 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
489 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
491 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
492 std::set<AttributePtr>::const_iterator aIt;
493 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
494 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
495 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
496 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
498 AttributePtr anAttribute;
499 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
500 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
501 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
503 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
506 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
507 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
508 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
510 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
512 if (anAttribute.get())
514 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
516 anAttribute = aRefAttr->attr();
517 if (anAttribute.get())
518 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
524 void SketchPlugin_Trim::updateRefAttConstraints(
525 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
526 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
527 std::set<FeaturePtr>& theFeaturesToDelete)
530 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
533 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
534 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
535 for (; anIt != aLast; anIt++) {
536 AttributePtr anAttribute = anIt->first;
538 /// not found in references
539 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
541 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
542 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
543 aRLast = aRefAttributes.end();
545 AttributePtr aNewAttribute = anIt->second;
546 for (; aRefIt != aRLast; aRefIt++) {
547 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
548 if (aRefAttr.get()) {
549 if (aNewAttribute.get())
550 aRefAttr->setAttr(aNewAttribute);
552 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
554 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
555 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
562 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
563 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
564 std::set<AttributePoint2DPtr>& thePoints,
565 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
567 // Check the base objects are initialized.
568 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
569 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
570 ObjectPtr aBaseObject = aBaseObjectAttr->value();
571 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
574 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
575 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
577 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
578 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
580 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
581 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
582 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
583 aStartShapePoint, aLastShapePoint);
585 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
586 if (aStartShapePoint.get())
587 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
588 aStartShapePoint->y() << "]" << std::endl;
589 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
590 aStartFeaturePoint->y() << "]" << std::endl;
591 if (aLastShapePoint.get())
592 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
593 aLastShapePoint->y() << "]" << std::endl;
594 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
595 aLastFeaturePoint->y() << "]" << std::endl;
598 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
599 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
600 if (isStartPoint || isLastPoint) {
601 // result is one line: changed existing line
602 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
603 : SketchPlugin_Line::END_ID();
604 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
605 if (aStartShapePoint.get() && aLastShapePoint.get())
606 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
608 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
610 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
611 theModifiedAttributes.insert(
612 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
614 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
615 (aBaseFeature->attribute(aModifiedAttribute)));
618 // result is two lines: start line point - start shape point, last shape point - last line point
619 // create second line
620 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
621 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
622 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
624 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
625 theModifiedAttributes.insert(
626 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
627 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
630 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
632 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
633 (aBaseFeature->attribute(aModifiedAttribute)));
635 // Collinear constraint for lines
636 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
637 getFeatureResult(aBaseFeature),
638 getFeatureResult(anNewFeature));
643 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
644 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
645 std::set<AttributePoint2DPtr>& thePoints,
646 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
648 // Check the base objects are initialized.
649 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
650 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
651 ObjectPtr aBaseObject = aBaseObjectAttr->value();
652 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
655 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
656 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
658 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
659 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
661 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
662 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
663 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
664 aStartShapePoint, aLastShapePoint);
666 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
667 if (aStartShapePoint.get())
668 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
669 aStartShapePoint->y() << "]" << std::endl;
670 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
671 aStartArcPoint->y() << "]" << std::endl;
672 if (aLastShapePoint.get())
673 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
674 aLastShapePoint->y() << "]" << std::endl;
675 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
676 aLastArcPoint->y() << "]" << std::endl;
679 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
680 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
681 if (isStartPoint || isLastPoint) {
682 // result is one arc: changed existing arc
683 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
684 : SketchPlugin_Arc::END_ID();
685 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
686 if (aStartShapePoint.get() && aLastShapePoint.get())
687 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
689 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
691 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
692 theModifiedAttributes.insert(
693 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
695 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
696 (aBaseFeature->attribute(aModifiedAttribute)));
699 // result is two arcs: start arc point - start shape point, last shape point - last arc point
701 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
702 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
703 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
705 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
706 theModifiedAttributes.insert(
707 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
708 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
711 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
713 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
714 (aBaseFeature->attribute(aModifiedAttribute)));
716 // equal Radius constraint for arcs
717 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
718 getFeatureResult(aBaseFeature),
719 getFeatureResult(anArcFeature));
720 // coincident centers constraint
721 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
722 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
723 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
727 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
728 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
729 std::set<AttributePoint2DPtr>& thePoints,
730 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
732 // Check the base objects are initialized.
733 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
734 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
735 ObjectPtr aBaseObject = aBaseObjectAttr->value();
736 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
739 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
740 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
743 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
745 theModifiedAttributes.insert(
746 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
747 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
749 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
750 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
751 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
752 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
757 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
758 const AttributePoint2DPtr& theEndPointAttr,
759 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
760 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
762 if (!theFirstPoint.get() || !theLastPoint.get())
765 // if first point is closer to last point, swap first and last values
766 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
767 theStartPointAttr->pnt()->distance(theLastPoint)) {
768 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
769 theFirstPoint = theLastPoint;
770 theLastPoint = aTmpPoint;
774 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
775 const AttributePoint2DPtr& theStartPointAttr,
776 const AttributePoint2DPtr& theEndPointAttr,
777 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
778 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
780 if (!theFirstPoint.get() || !theSecondPoint.get())
783 static const double anAngleTol = 1.e-12;
785 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
786 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
787 bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
789 // collect directions to each point
790 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
791 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
792 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
793 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
794 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
795 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
797 // sort points by their angular values
798 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
799 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
800 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
801 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
802 aFirstPtAngle += aPeriod;
803 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
804 aSecondPtAngle += aPeriod;
806 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
807 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
808 theFirstPoint = theSecondPoint;
809 theSecondPoint = aTmpPoint;
813 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
814 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
816 std::string anAttributeType = theModifiedAttribute->attributeType();
817 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
818 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
819 theModifiedAttribute);
820 aModifiedAttribute->setValue(thePoint);
823 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
824 << thePoint->y() << "]" << std::endl;
830 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
831 const AttributePtr& theSourceAttribute)
833 std::string anAttributeType = theModifiedAttribute->attributeType();
834 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
835 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
836 theModifiedAttribute);
837 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
840 if (aModifiedAttribute.get() && aSourceAttribute.get())
841 aModifiedAttribute->setValue(aSourceAttribute->pnt());
843 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
844 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
845 theModifiedAttribute);
846 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
849 if (aModifiedAttribute.get() && aSourceAttribute.get())
850 aModifiedAttribute->setValue(aSourceAttribute->value());
852 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
853 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
854 theModifiedAttribute);
855 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
857 if (!aSourceRefAttr.get())
858 aRefAttributeToFill->setAttr(theSourceAttribute);
860 if (aSourceRefAttr->isObject())
861 aRefAttributeToFill->setObject(aSourceRefAttr->object());
863 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
868 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
869 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
870 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
873 SketchPlugin_Sketch* aSketch = sketch();
874 if (!aSketch || !theBaseFeature.get())
877 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
879 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
880 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
882 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
883 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
885 aFeature->execute(); // to obtain result
891 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
892 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
893 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
896 SketchPlugin_Sketch* aSketch = sketch();
897 if (!aSketch || !theBaseFeature.get())
900 std::string aCenterAttributeId;
901 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
902 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
903 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
904 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
906 if (aCenterAttributeId.empty())
909 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
910 // update fillet arc: make the arc correct for sure, so, it is not needed to process
911 // the "attribute updated"
912 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
913 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
915 aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
916 SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
918 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
919 theBaseFeature->attribute(aCenterAttributeId));
920 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
921 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
923 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
924 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
926 /// fill referersed state of created arc as it is on the base arc
927 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
928 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
929 aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
931 aFeature->execute(); // to obtain result
932 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
937 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
938 const AttributePtr& theFirstAttribute,
939 const AttributePtr& theSecondAttribute)
941 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
942 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
943 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
944 aRefAttr->setAttr(theFirstAttribute);
946 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
947 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
948 aRefAttr->setAttr(theSecondAttribute);
951 std::cout << "<createConstraint to attribute> :"
952 << "first attribute - " << theFirstAttribute->id()
953 << "second attribute - " << theSecondAttribute->id()
960 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
961 const AttributePtr& theFirstAttribute,
962 const ObjectPtr& theSecondObject)
964 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
965 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
966 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
967 aRefAttr->setAttr(theFirstAttribute);
969 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
970 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
971 aRefAttr->setObject(theSecondObject);
974 std::cout << "<createConstraint to attribute> :"
975 << "first attribute - " << theFirstAttribute->id()
976 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
983 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
984 const std::string& theConstraintId,
985 const ObjectPtr& theFirstObject,
986 const ObjectPtr& theSecondObject)
988 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
989 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
990 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
991 aRefAttr->setObject(theFirstObject);
993 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
994 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
995 aRefAttr->setObject(theSecondObject);
1000 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
1001 const std::shared_ptr<ModelAPI_Feature>& theFeature)
1003 std::shared_ptr<ModelAPI_Result> aResult;
1005 std::string aFeatureKind = theFeature->getKind();
1006 if (aFeatureKind == SketchPlugin_Line::ID())
1007 aResult = theFeature->firstResult();
1008 else if (aFeatureKind == SketchPlugin_Arc::ID())
1009 aResult = theFeature->lastResult();
1010 else if (aFeatureKind == SketchPlugin_Circle::ID())
1011 aResult = theFeature->lastResult();
1016 //********************************************************************
1017 bool SketchPlugin_Trim::useGraphicIntersection() const
1022 //********************************************************************
1023 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
1025 PointToRefsMap aPointsInfo;
1027 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1028 std::map<std::shared_ptr<GeomAPI_Pnt>,
1029 std::list< AttributePoint2DPtr > > aPointToAttributes;
1030 std::map<std::shared_ptr<GeomAPI_Pnt>,
1031 std::list< ObjectPtr > > aPointToObjects;
1033 std::set<AttributePoint2DPtr > aRefAttributes;
1035 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1036 std::set<ResultPtr> anEdgeShapes;
1038 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1039 if (!anEdgeShapes.empty()) {
1040 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1042 // coincidences to the feature
1043 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1044 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1045 // layed on feature coincidences to divide it on several shapes
1046 SketchPlugin_Sketch* aSketch = sketch();
1047 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
1048 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1049 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1050 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1051 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1052 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1053 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1054 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1056 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1057 aX->dir(), aY, aPointsInfo);
1059 // intersection points
1060 if (useGraphicIntersection()) {
1061 std::list<FeaturePtr> aFeatures;
1062 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
1063 FeaturePtr aFeature = aSketch->subFeature(i);
1065 aFeatures.push_back(aFeature);
1067 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1069 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1071 myObjectToPoints[theObject] = aPointsInfo;
1072 myCashedShapes[theObject] = aShapes;
1075 //********************************************************************
1076 void SketchPlugin_Trim::attributeChanged(const std::string& theID)
1078 //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
1079 if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
1080 bool isValidAttribute = false;
1082 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
1083 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
1084 ObjectPtr aBaseObject = aBaseObjectAttr->value();
1085 if (aBaseObject.get()) {
1086 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
1088 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1089 data()->attribute(ENTITY_POINT()));
1090 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
1091 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
1092 anAttributePnt2d->y());
1094 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1095 fillObjectShapes(aBaseObject);
1097 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1098 isValidAttribute = !aShapes.empty();
1100 if (!isValidAttribute) {
1101 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1102 aBaseObjectAttr->setValue(ObjectPtr());
1103 data()->blockSendAttributeUpdated(aWasBlocked);