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"; }
60 SketchPlugin_Trim::SketchPlugin_Trim()
64 void SketchPlugin_Trim::initAttributes()
66 data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
67 data()->addAttribute(ENTITY_POINT(), GeomDataAPI_Point2D::typeId());
70 void SketchPlugin_Trim::findShapePoints(std::shared_ptr<GeomAPI_Pnt>& aStartPoint,
71 std::shared_ptr<GeomAPI_Pnt>& aLastPoint)
73 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
74 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
75 ObjectPtr aBaseObject = aBaseObjectAttr->value();
77 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
78 data()->attribute(ENTITY_POINT()));
79 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
80 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
81 anAttributePnt2d->y());
83 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
84 fillObjectShapes(aBaseObject);
86 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
87 if (!aShapes.empty()) {
88 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
89 for (; anIt != aLast; anIt++) {
90 GeomShapePtr aBaseShape = *anIt;
91 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
92 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
94 if (aBaseShape->shapeType() == GeomAPI_Shape::EDGE) {
95 std::shared_ptr<GeomAPI_Edge> anEdge(new GeomAPI_Edge(aBaseShape));
96 aStartPoint = anEdge->lastPoint();
97 aLastPoint = anEdge->firstPoint();
103 std::cout << "<findShapePoints> => "
105 << aStartPoint->x() << ", " << aStartPoint->y() << ", " << aStartPoint->z() << "]"
107 << aLastPoint->x() << ", " << aLastPoint->y() << ", " << aLastPoint->z() << "]"
112 std::shared_ptr<GeomAPI_Pnt2d> SketchPlugin_Trim::convertPoint(
113 const std::shared_ptr<GeomAPI_Pnt>& thePoint)
115 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
117 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
118 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
119 ObjectPtr aBaseObject = aBaseObjectAttr->value();
120 if (myObjectToPoints.find(aBaseObject) == myObjectToPoints.end())
124 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
125 for (PointToRefsMap::const_iterator aPointIt = aRefsMap.begin();
126 aPointIt != aRefsMap.end() && !aFound; aPointIt++) {
127 if (aPointIt->first->isEqual(thePoint)) {
128 const std::pair<std::list<AttributePoint2DPtr >,
129 std::list<ObjectPtr > >& anInfo = aPointIt->second;
130 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
131 if (!anAttributes.empty()) {
132 aPoint = anAttributes.front()->pnt();
136 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
137 aPoint = thePoint->to2D(aPlane);
143 // returns an end of the shape to define direction of split if feature's attribute participates
144 std::shared_ptr<GeomAPI_Pln> aPlane = sketch()->plane();
145 aPoint = thePoint->to2D(aPlane);
150 void SketchPlugin_Trim::execute()
153 std::cout << "SketchPlugin_Trim::execute" << std::endl;
156 SketchPlugin_Sketch* aSketch = sketch();
160 // Check the base objects are initialized.
161 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
162 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
163 if(!aBaseObjectAttr->isInitialized()) {
164 setError("Error: Base object is not initialized.");
167 ObjectPtr aBaseObject = aBaseObjectAttr->value();
168 if (!aBaseObject.get())
170 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
173 std::shared_ptr<GeomAPI_Pnt> aStartShapePoint, aLastShapePoint;
174 findShapePoints(aStartShapePoint, aLastShapePoint);
175 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint2d = convertPoint(aStartShapePoint);
177 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint2d = convertPoint(aLastShapePoint);
179 std::set<FeaturePtr> aFeaturesToDelete, aFeaturesToUpdate;
180 getConstraints(aFeaturesToDelete, aFeaturesToUpdate);
182 std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
183 std::list<AttributePtr> aRefsToFeature;
184 getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
186 std::set<AttributePoint2DPtr> aFurtherCoincidences;
187 std::set<FeaturePtr> aCreatedFeatures;
188 std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
189 const std::string& aKind = aBaseFeature->getKind();
190 if (aKind == SketchPlugin_Circle::ID()) {
191 trimCircle(aStartShapePoint2d, aLastShapePoint2d,
192 aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
193 updateRefFeatureConstraints(getFeatureResult(aBaseFeature), aRefsToFeature);
195 aFeaturesToDelete.insert(aBaseFeature);
196 // as circle is removed, temporary fill this attribute
197 aBaseObjectAttr->setObject(ResultPtr());
199 else if (aKind == SketchPlugin_Line::ID()) {
200 trimLine(aStartShapePoint2d, aLastShapePoint2d,
201 aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
203 else if (aKind == SketchPlugin_Arc::ID()) {
204 trimArc(aStartShapePoint2d, aLastShapePoint2d,
205 aFurtherCoincidences, aCreatedFeatures, aModifiedAttributes);
208 // coincidence to result points
209 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
210 std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
211 aLast = aFurtherCoincidences.end();
212 for (; anIt != aLast; anIt++) {
213 AttributePoint2DPtr aPointAttribute = (*anIt);
214 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
216 std::shared_ptr<GeomAPI_Pnt> aPoint;
217 if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d))
218 aPoint = aStartShapePoint;
219 else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d))
220 aPoint = aLastShapePoint;
225 std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
226 for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
229 if (aRefIt->first->isEqual(aPoint)) {
230 anInfo = aRefIt->second;
234 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
235 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
236 anAttrIt != anAttributes.end(); anAttrIt++) {
237 createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, *anAttrIt);
240 const std::list<ObjectPtr>& anObjects = anInfo.second;
241 for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
242 anObjectIt != anObjects.end(); anObjectIt++) {
243 createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute,
248 // Wait all constraints being created, then send update events
249 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
250 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
252 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
254 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
256 // delete constraints
258 std::cout << "remove features and references:" << std::endl;
259 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
260 aDLast = aFeaturesToDelete.end();
261 for (; aDIt != aDLast; aDIt++) {
262 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
263 //std::cout << std::endl;
266 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
267 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
269 // Send events to update the sub-features by the solver.
270 if(isUpdateFlushed) {
271 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
275 std::cout << "SketchPlugin_Trim::done" << std::endl;
279 bool SketchPlugin_Trim::isMacro() const
284 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
286 AISObjectPtr anAIS = thePrevious;
288 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
289 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
290 ObjectPtr aBaseObject = aBaseObjectAttr->value();
291 if (!aBaseObject.get())
293 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
296 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
297 data()->attribute(ENTITY_POINT()));
298 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
299 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
300 anAttributePnt2d->y());
302 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
303 fillObjectShapes(aBaseObject);
305 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
306 if (!aShapes.empty()) {
307 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
308 for (; anIt != aLast; anIt++) {
309 GeomShapePtr aBaseShape = *anIt;
310 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
311 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
314 anAIS = AISObjectPtr(new GeomAPI_AISObject);
315 anAIS->createShape(aBaseShape);
317 std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
318 aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
320 bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
322 std::vector<int> aColor;
323 aColor = Config_PropManager::color("Visualization", "operation_highlight_color",
324 OPERATION_HIGHLIGHT_COLOR());
325 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
326 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
327 if (isConstruction) {
328 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
329 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
331 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
332 // modification of width should be replaced to value 1 after highlight problem is fixed
333 anAIS->setWidth(aWidth + 2);//1);
334 anAIS->setLineStyle(aLineStyle);
344 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
345 AttributePoint2DPtr& theStartPointAttr,
346 AttributePoint2DPtr& theEndPointAttr)
348 std::string aFeatureKind = theFeature->getKind();
349 std::string aStartAttributeName, anEndAttributeName;
350 if (aFeatureKind == SketchPlugin_Line::ID()) {
351 aStartAttributeName = SketchPlugin_Line::START_ID();
352 anEndAttributeName = SketchPlugin_Line::END_ID();
354 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
355 aStartAttributeName = SketchPlugin_Arc::START_ID();
356 anEndAttributeName = SketchPlugin_Arc::END_ID();
358 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
359 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
360 theFeature->attribute(aStartAttributeName));
361 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
362 theFeature->attribute(anEndAttributeName));
366 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
367 std::set<FeaturePtr>& theFeaturesToUpdate)
369 std::shared_ptr<ModelAPI_Data> aData = data();
371 // Check the base objects are initialized.
372 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
373 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
374 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
375 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
377 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
378 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
379 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
381 std::set<AttributePtr>::const_iterator aIt;
382 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
383 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
384 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
385 std::string aRefFeatureKind = aRefFeature->getKind();
386 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
387 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
388 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
389 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
390 theFeaturesToDelete.insert(aRefFeature);
391 else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
392 theFeaturesToUpdate.insert(aRefFeature);
393 else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
394 if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
395 /// until tangency between arc and line is implemented
396 theFeaturesToDelete.insert(aRefFeature);
398 std::string anAttributeToBeModified;
399 AttributePoint2DPtr aTangentPoint;
400 ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
401 ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
402 if (aResult1.get() && aResult2.get()) {
403 FeaturePtr aCoincidenceFeature =
404 SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
405 (ModelAPI_Feature::feature(aResult1),
406 ModelAPI_Feature::feature(aResult2));
407 // get the point not lying on the splitting feature
408 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
409 AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(
410 SketchPlugin_Trim::BASE_OBJECT());
411 if (!aRefAttr || aRefAttr->isObject())
413 AttributePoint2DPtr aPoint =
414 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
417 if (aPoint->owner() != aBaseFeature) {
418 aTangentPoint = aPoint;
423 if (aTangentPoint.get()) {
424 // collect tangent feaures
426 else /// there is not coincident point between tangent constraint
427 theFeaturesToDelete.insert(aRefFeature);
433 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
434 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
435 std::list<AttributePtr>& theRefsToFeature)
439 std::list<AttributePtr> aPointAttributes =
440 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
441 std::set<AttributePtr> aPointAttributesSet;
443 std::list<AttributePtr>::const_iterator aPIt =
444 aPointAttributes.begin(), aPLast = aPointAttributes.end();
445 for (; aPIt != aPLast; aPIt++)
446 aPointAttributesSet.insert(*aPIt);
448 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
449 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
450 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
452 std::set<AttributePtr>::const_iterator aIt;
453 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
454 AttributePtr anAttr = (*aIt);
455 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
456 if (anAttrFeature.get() != this &&
457 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
458 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
459 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
460 AttributePtr anAttrInRef = aRefAttr->attr();
461 if (anAttrInRef.get() &&
462 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
463 if (theRefs.find(anAttrInRef) != theRefs.end())
464 theRefs[anAttrInRef].push_back(aRefAttr);
466 std::list<AttributePtr> anAttrList;
467 anAttrList.push_back(aRefAttr);
468 theRefs[anAttrInRef] = anAttrList;
472 else { /// find attributes referenced to feature itself
473 theRefsToFeature.push_back(anAttr);
479 void SketchPlugin_Trim::updateRefFeatureConstraints(
480 const ResultPtr& theFeatureBaseResult,
481 const std::list<AttributePtr>& theRefsToFeature)
483 std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
484 aLast = theRefsToFeature.end();
485 for (; anIt != aLast; anIt++) {
486 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
488 aRefAttr->setObject(theFeatureBaseResult);
492 void SketchPlugin_Trim::updateRefAttConstraints(
493 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
494 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
495 std::set<FeaturePtr>& theFeaturesToDelete)
498 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
501 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
502 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
503 for (; anIt != aLast; anIt++) {
504 AttributePtr anAttribute = anIt->first;
506 /// not found in references
507 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
509 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
510 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
511 aRLast = aRefAttributes.end();
513 AttributePtr aNewAttribute = anIt->second;
514 for (; aRefIt != aRLast; aRefIt++) {
515 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
516 if (aRefAttr.get()) {
517 if (aNewAttribute.get())
518 aRefAttr->setAttr(aNewAttribute);
520 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
522 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
523 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
530 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
531 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
532 std::set<AttributePoint2DPtr>& thePoints,
533 std::set<FeaturePtr>& theCreatedFeatures,
534 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
536 // Check the base objects are initialized.
537 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
538 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
539 ObjectPtr aBaseObject = aBaseObjectAttr->value();
540 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
543 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
544 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
546 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
547 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
549 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
550 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
551 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
552 aStartShapePoint, aLastShapePoint);
554 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
555 if (aStartShapePoint.get())
556 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
557 aStartShapePoint->y() << "]" << std::endl;
558 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
559 aStartFeaturePoint->y() << "]" << std::endl;
560 if (aLastShapePoint.get())
561 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
562 aLastShapePoint->y() << "]" << std::endl;
563 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
564 aLastFeaturePoint->y() << "]" << std::endl;
567 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
568 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
569 if (isStartPoint || isLastPoint) {
570 // result is one line: changed existing line
571 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
572 : SketchPlugin_Line::END_ID();
573 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
574 if (aStartShapePoint.get() && aLastShapePoint.get())
575 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
577 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
579 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
580 theModifiedAttributes.insert(
581 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
583 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
584 (aBaseFeature->attribute(aModifiedAttribute)));
587 // result is two lines: start line point - start shape point, last shape point - last line point
588 // create second line
589 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
590 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
591 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
593 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
594 theModifiedAttributes.insert(
595 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
596 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
599 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
601 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
602 (aBaseFeature->attribute(aModifiedAttribute)));
604 // Collinear constraint for lines
605 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
606 getFeatureResult(aBaseFeature),
607 getFeatureResult(anNewFeature));
612 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
613 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
614 std::set<AttributePoint2DPtr>& thePoints,
615 std::set<FeaturePtr>& theCreatedFeatures,
616 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
618 // Check the base objects are initialized.
619 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
620 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
621 ObjectPtr aBaseObject = aBaseObjectAttr->value();
622 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
625 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
626 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
628 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
629 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
631 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
632 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
633 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
634 aStartShapePoint, aLastShapePoint);
636 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
637 if (aStartShapePoint.get())
638 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
639 aStartShapePoint->y() << "]" << std::endl;
640 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
641 aStartArcPoint->y() << "]" << std::endl;
642 if (aLastShapePoint.get())
643 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
644 aLastShapePoint->y() << "]" << std::endl;
645 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
646 aLastArcPoint->y() << "]" << std::endl;
649 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
650 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
651 if (isStartPoint || isLastPoint) {
652 // result is one arc: changed existing arc
653 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
654 : SketchPlugin_Arc::END_ID();
655 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
656 if (aStartShapePoint.get() && aLastShapePoint.get())
657 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
659 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
661 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
662 theModifiedAttributes.insert(
663 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
665 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
666 (aBaseFeature->attribute(aModifiedAttribute)));
669 // result is two arcs: start arc point - start shape point, last shape point - last arc point
671 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
672 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
673 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
675 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
676 theModifiedAttributes.insert(
677 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
678 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
681 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
683 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
684 (aBaseFeature->attribute(aModifiedAttribute)));
686 // equal Radius constraint for arcs
687 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
688 getFeatureResult(aBaseFeature),
689 getFeatureResult(anArcFeature));
690 // coincident centers constraint
691 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
692 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
693 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
697 void SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
698 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
699 std::set<AttributePoint2DPtr>& thePoints,
700 std::set<FeaturePtr>& theCreatedFeatures,
701 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
703 // Check the base objects are initialized.
704 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
705 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
706 ObjectPtr aBaseObject = aBaseObjectAttr->value();
707 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
710 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
711 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
714 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
716 theModifiedAttributes.insert(
717 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
718 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
720 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
721 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
722 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
723 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
726 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
727 const AttributePoint2DPtr& theEndPointAttr,
728 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
729 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
731 if (!theFirstPoint.get() || !theLastPoint.get())
734 // if first point is closer to last point, swap first and last values
735 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
736 theStartPointAttr->pnt()->distance(theLastPoint)) {
737 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
738 theFirstPoint = theLastPoint;
739 theLastPoint = aTmpPoint;
743 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
744 const AttributePoint2DPtr& theStartPointAttr,
745 const AttributePoint2DPtr& theEndPointAttr,
746 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
747 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
749 if (!theFirstPoint.get() || !theSecondPoint.get())
752 static const double anAngleTol = 1.e-12;
754 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
755 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
756 bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
758 // collect directions to each point
759 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
760 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
761 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
762 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
763 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
764 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
766 // sort points by their angular values
767 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
768 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
769 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
770 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
771 aFirstPtAngle += aPeriod;
772 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
773 aSecondPtAngle += aPeriod;
775 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
776 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
777 theFirstPoint = theSecondPoint;
778 theSecondPoint = aTmpPoint;
782 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
783 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
785 std::string anAttributeType = theModifiedAttribute->attributeType();
786 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
787 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
788 theModifiedAttribute);
789 aModifiedAttribute->setValue(thePoint);
792 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
793 << thePoint->y() << "]" << std::endl;
799 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
800 const AttributePtr& theSourceAttribute)
802 std::string anAttributeType = theModifiedAttribute->attributeType();
803 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
804 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
805 theModifiedAttribute);
806 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
809 if (aModifiedAttribute.get() && aSourceAttribute.get())
810 aModifiedAttribute->setValue(aSourceAttribute->pnt());
812 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
813 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
814 theModifiedAttribute);
815 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
818 if (aModifiedAttribute.get() && aSourceAttribute.get())
819 aModifiedAttribute->setValue(aSourceAttribute->value());
821 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
822 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
823 theModifiedAttribute);
824 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
826 if (!aSourceRefAttr.get())
827 aRefAttributeToFill->setAttr(theSourceAttribute);
829 if (aSourceRefAttr->isObject())
830 aRefAttributeToFill->setObject(aSourceRefAttr->object());
832 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
837 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
838 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
839 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
842 SketchPlugin_Sketch* aSketch = sketch();
843 if (!aSketch || !theBaseFeature.get())
846 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
848 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
849 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
851 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
852 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
854 aFeature->execute(); // to obtain result
860 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
861 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
862 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
865 SketchPlugin_Sketch* aSketch = sketch();
866 if (!aSketch || !theBaseFeature.get())
869 std::string aCenterAttributeId;
870 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
871 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
872 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
873 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
875 if (aCenterAttributeId.empty())
878 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
879 // update fillet arc: make the arc correct for sure, so, it is not needed to process
880 // the "attribute updated"
881 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
882 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
884 aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
885 SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
887 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
888 theBaseFeature->attribute(aCenterAttributeId));
889 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
890 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
892 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
893 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
895 /// fill referersed state of created arc as it is on the base arc
896 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
897 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
898 aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
900 aFeature->execute(); // to obtain result
901 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
906 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
907 const AttributePtr& theFirstAttribute,
908 const AttributePtr& theSecondAttribute)
910 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
911 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
912 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
913 aRefAttr->setAttr(theFirstAttribute);
915 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
916 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
917 aRefAttr->setAttr(theSecondAttribute);
920 std::cout << "<createConstraint to attribute> :"
921 << "first attribute - " << theFirstAttribute->id()
922 << "second attribute - " << theSecondAttribute->id()
929 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
930 const AttributePtr& theFirstAttribute,
931 const ObjectPtr& theSecondObject)
933 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
934 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
935 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
936 aRefAttr->setAttr(theFirstAttribute);
938 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
939 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
940 aRefAttr->setObject(theSecondObject);
943 std::cout << "<createConstraint to attribute> :"
944 << "first attribute - " << theFirstAttribute->id()
945 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
952 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
953 const std::string& theConstraintId,
954 const ObjectPtr& theFirstObject,
955 const ObjectPtr& theSecondObject)
957 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
958 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
959 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
960 aRefAttr->setObject(theFirstObject);
962 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
963 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
964 aRefAttr->setObject(theSecondObject);
969 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
970 const std::shared_ptr<ModelAPI_Feature>& theFeature)
972 std::shared_ptr<ModelAPI_Result> aResult;
974 std::string aFeatureKind = theFeature->getKind();
975 if (aFeatureKind == SketchPlugin_Line::ID())
976 aResult = theFeature->firstResult();
977 else if (aFeatureKind == SketchPlugin_Arc::ID())
978 aResult = theFeature->lastResult();
979 else if (aFeatureKind == SketchPlugin_Circle::ID())
980 aResult = theFeature->lastResult();
985 //********************************************************************
986 bool SketchPlugin_Trim::useGraphicIntersection() const
991 //********************************************************************
992 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
994 PointToRefsMap aPointsInfo;
996 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
997 std::map<std::shared_ptr<GeomAPI_Pnt>,
998 std::list< AttributePoint2DPtr > > aPointToAttributes;
999 std::map<std::shared_ptr<GeomAPI_Pnt>,
1000 std::list< ObjectPtr > > aPointToObjects;
1002 std::set<AttributePoint2DPtr > aRefAttributes;
1004 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1005 std::set<ResultPtr> anEdgeShapes;
1007 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1008 if (!anEdgeShapes.empty()) {
1009 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1011 // coincidences to the feature
1012 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1013 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1014 // layed on feature coincidences to divide it on several shapes
1015 SketchPlugin_Sketch* aSketch = sketch();
1016 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
1017 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1018 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1019 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1020 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1021 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1022 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1023 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1025 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1026 aX->dir(), aY, aPointsInfo);
1028 // intersection points
1029 if (useGraphicIntersection()) {
1030 std::list<FeaturePtr> aFeatures;
1031 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
1032 FeaturePtr aFeature = aSketch->subFeature(i);
1034 aFeatures.push_back(aFeature);
1036 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1038 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1040 myObjectToPoints[theObject] = aPointsInfo;
1041 myCashedShapes[theObject] = aShapes;
1044 //********************************************************************
1045 void SketchPlugin_Trim::attributeChanged(const std::string& theID)
1047 //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
1048 if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
1049 bool isValidAttribute = false;
1051 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
1052 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
1053 ObjectPtr aBaseObject = aBaseObjectAttr->value();
1054 if (aBaseObject.get()) {
1055 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
1057 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1058 data()->attribute(ENTITY_POINT()));
1059 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
1060 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
1061 anAttributePnt2d->y());
1063 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1064 fillObjectShapes(aBaseObject);
1066 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1067 isValidAttribute = !aShapes.empty();
1069 if (!isValidAttribute) {
1070 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1071 aBaseObjectAttr->setValue(ObjectPtr());
1072 data()->blockSendAttributeUpdated(aWasBlocked);