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 createConstraint(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute, *anObjectIt);
247 // Wait all constraints being created, then send update events
248 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
249 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
251 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
253 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
255 // delete constraints
257 std::cout << "remove features and references:" << std::endl;
258 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
259 aDLast = aFeaturesToDelete.end();
260 for (; aDIt != aDLast; aDIt++) {
261 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
262 //std::cout << std::endl;
265 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
266 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
268 // Send events to update the sub-features by the solver.
269 if(isUpdateFlushed) {
270 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
274 std::cout << "SketchPlugin_Trim::done" << std::endl;
278 bool SketchPlugin_Trim::isMacro() const
283 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
285 AISObjectPtr anAIS = thePrevious;
287 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
288 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
289 ObjectPtr aBaseObject = aBaseObjectAttr->value();
290 if (!aBaseObject.get())
292 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
295 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
296 data()->attribute(ENTITY_POINT()));
297 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
298 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
299 anAttributePnt2d->y());
301 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
302 fillObjectShapes(aBaseObject);
304 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
305 if (!aShapes.empty()) {
306 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
307 for (; anIt != aLast; anIt++) {
308 GeomShapePtr aBaseShape = *anIt;
309 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
310 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
313 anAIS = AISObjectPtr(new GeomAPI_AISObject);
314 anAIS->createShape(aBaseShape);
316 std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
317 aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
319 bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
321 std::vector<int> aColor;
322 aColor = Config_PropManager::color("Visualization", "operation_highlight_color",
323 OPERATION_HIGHLIGHT_COLOR());
324 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
325 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
326 if (isConstruction) {
327 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
328 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
330 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
331 // modification of width should be replaced to value 1 after highlight problem is fixed
332 anAIS->setWidth(aWidth + 2);//1);
333 anAIS->setLineStyle(aLineStyle);
343 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
344 AttributePoint2DPtr& theStartPointAttr,
345 AttributePoint2DPtr& theEndPointAttr)
347 std::string aFeatureKind = theFeature->getKind();
348 std::string aStartAttributeName, anEndAttributeName;
349 if (aFeatureKind == SketchPlugin_Line::ID()) {
350 aStartAttributeName = SketchPlugin_Line::START_ID();
351 anEndAttributeName = SketchPlugin_Line::END_ID();
353 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
354 aStartAttributeName = SketchPlugin_Arc::START_ID();
355 anEndAttributeName = SketchPlugin_Arc::END_ID();
357 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
358 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
359 theFeature->attribute(aStartAttributeName));
360 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
361 theFeature->attribute(anEndAttributeName));
365 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
366 std::set<FeaturePtr>& theFeaturesToUpdate)
368 std::shared_ptr<ModelAPI_Data> aData = data();
370 // Check the base objects are initialized.
371 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
372 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
373 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
374 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
376 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
377 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
378 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
380 std::set<AttributePtr>::const_iterator aIt;
381 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
382 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
383 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
384 std::string aRefFeatureKind = aRefFeature->getKind();
385 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
386 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
387 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
388 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
389 theFeaturesToDelete.insert(aRefFeature);
390 else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
391 theFeaturesToUpdate.insert(aRefFeature);
392 else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
393 if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
394 /// until tangency between arc and line is implemented
395 theFeaturesToDelete.insert(aRefFeature);
397 std::string anAttributeToBeModified;
398 AttributePoint2DPtr aTangentPoint;
399 ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
400 ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
401 if (aResult1.get() && aResult2.get()) {
402 FeaturePtr aCoincidenceFeature =
403 SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
404 (ModelAPI_Feature::feature(aResult1),
405 ModelAPI_Feature::feature(aResult2));
406 // get the point not lying on the splitting feature
407 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
408 AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(
409 SketchPlugin_Trim::BASE_OBJECT());
410 if (!aRefAttr || aRefAttr->isObject())
412 AttributePoint2DPtr aPoint =
413 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
416 if (aPoint->owner() != aBaseFeature) {
417 aTangentPoint = aPoint;
422 if (aTangentPoint.get()) {
423 // collect tangent feaures
425 else /// there is not coincident point between tangent constraint
426 theFeaturesToDelete.insert(aRefFeature);
432 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
433 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
434 std::list<AttributePtr>& theRefsToFeature)
438 std::list<AttributePtr> aPointAttributes =
439 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
440 std::set<AttributePtr> aPointAttributesSet;
442 std::list<AttributePtr>::const_iterator aPIt =
443 aPointAttributes.begin(), aPLast = aPointAttributes.end();
444 for (; aPIt != aPLast; aPIt++)
445 aPointAttributesSet.insert(*aPIt);
447 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
448 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
449 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
451 std::set<AttributePtr>::const_iterator aIt;
452 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
453 AttributePtr anAttr = (*aIt);
454 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
455 if (anAttrFeature.get() != this &&
456 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
457 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
458 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
459 AttributePtr anAttrInRef = aRefAttr->attr();
460 if (anAttrInRef.get() &&
461 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
462 if (theRefs.find(anAttrInRef) != theRefs.end())
463 theRefs[anAttrInRef].push_back(aRefAttr);
465 std::list<AttributePtr> anAttrList;
466 anAttrList.push_back(aRefAttr);
467 theRefs[anAttrInRef] = anAttrList;
471 else { /// find attributes referenced to feature itself
472 theRefsToFeature.push_back(anAttr);
478 void SketchPlugin_Trim::updateRefFeatureConstraints(
479 const ResultPtr& theFeatureBaseResult,
480 const std::list<AttributePtr>& theRefsToFeature)
482 std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
483 aLast = theRefsToFeature.end();
484 for (; anIt != aLast; anIt++) {
485 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
487 aRefAttr->setObject(theFeatureBaseResult);
491 void SketchPlugin_Trim::updateRefAttConstraints(
492 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
493 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
494 std::set<FeaturePtr>& theFeaturesToDelete)
497 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
500 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
501 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
502 for (; anIt != aLast; anIt++) {
503 AttributePtr anAttribute = anIt->first;
505 /// not found in references
506 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
508 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
509 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
510 aRLast = aRefAttributes.end();
512 AttributePtr aNewAttribute = anIt->second;
513 for (; aRefIt != aRLast; aRefIt++) {
514 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
515 if (aRefAttr.get()) {
516 if (aNewAttribute.get())
517 aRefAttr->setAttr(aNewAttribute);
519 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
521 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
522 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
529 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
530 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
531 std::set<AttributePoint2DPtr>& thePoints,
532 std::set<FeaturePtr>& theCreatedFeatures,
533 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
535 // Check the base objects are initialized.
536 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
537 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
538 ObjectPtr aBaseObject = aBaseObjectAttr->value();
539 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
542 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
543 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
545 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
546 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
548 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
549 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
550 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
551 aStartShapePoint, aLastShapePoint);
553 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
554 if (aStartShapePoint.get())
555 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
556 aStartShapePoint->y() << "]" << std::endl;
557 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
558 aStartFeaturePoint->y() << "]" << std::endl;
559 if (aLastShapePoint.get())
560 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
561 aLastShapePoint->y() << "]" << std::endl;
562 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
563 aLastFeaturePoint->y() << "]" << std::endl;
566 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
567 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
568 if (isStartPoint || isLastPoint) {
569 // result is one line: changed existing line
570 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
571 : SketchPlugin_Line::END_ID();
572 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
573 if (aStartShapePoint.get() && aLastShapePoint.get())
574 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
576 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
578 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
579 theModifiedAttributes.insert(
580 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
582 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
583 (aBaseFeature->attribute(aModifiedAttribute)));
586 // result is two lines: start line point - start shape point, last shape point - last line point
587 // create second line
588 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
589 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
590 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
592 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
593 theModifiedAttributes.insert(
594 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
595 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
598 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
600 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
601 (aBaseFeature->attribute(aModifiedAttribute)));
603 // Collinear constraint for lines
604 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
605 getFeatureResult(aBaseFeature),
606 getFeatureResult(anNewFeature));
611 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
612 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
613 std::set<AttributePoint2DPtr>& thePoints,
614 std::set<FeaturePtr>& theCreatedFeatures,
615 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
617 // Check the base objects are initialized.
618 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
619 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
620 ObjectPtr aBaseObject = aBaseObjectAttr->value();
621 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
624 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
625 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
627 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
628 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
630 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
631 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
632 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
633 aStartShapePoint, aLastShapePoint);
635 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
636 if (aStartShapePoint.get())
637 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
638 aStartShapePoint->y() << "]" << std::endl;
639 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
640 aStartArcPoint->y() << "]" << std::endl;
641 if (aLastShapePoint.get())
642 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
643 aLastShapePoint->y() << "]" << std::endl;
644 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
645 aLastArcPoint->y() << "]" << std::endl;
648 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
649 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
650 if (isStartPoint || isLastPoint) {
651 // result is one arc: changed existing arc
652 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
653 : SketchPlugin_Arc::END_ID();
654 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
655 if (aStartShapePoint.get() && aLastShapePoint.get())
656 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
658 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
660 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
661 theModifiedAttributes.insert(
662 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
664 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
665 (aBaseFeature->attribute(aModifiedAttribute)));
668 // result is two arcs: start arc point - start shape point, last shape point - last arc point
670 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
671 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
672 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
674 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
675 theModifiedAttributes.insert(
676 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
677 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
680 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
682 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
683 (aBaseFeature->attribute(aModifiedAttribute)));
685 // equal Radius constraint for arcs
686 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
687 getFeatureResult(aBaseFeature),
688 getFeatureResult(anArcFeature));
689 // coincident centers constraint
690 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
691 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
692 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
696 void SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
697 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
698 std::set<AttributePoint2DPtr>& thePoints,
699 std::set<FeaturePtr>& theCreatedFeatures,
700 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
702 // Check the base objects are initialized.
703 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
704 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
705 ObjectPtr aBaseObject = aBaseObjectAttr->value();
706 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
709 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
710 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
713 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
715 theModifiedAttributes.insert(
716 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
717 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
719 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
720 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
721 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
722 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
725 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
726 const AttributePoint2DPtr& theEndPointAttr,
727 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
728 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
730 if (!theFirstPoint.get() || !theLastPoint.get())
733 // if first point is closer to last point, swap first and last values
734 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
735 theStartPointAttr->pnt()->distance(theLastPoint)) {
736 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
737 theFirstPoint = theLastPoint;
738 theLastPoint = aTmpPoint;
742 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
743 const AttributePoint2DPtr& theStartPointAttr,
744 const AttributePoint2DPtr& theEndPointAttr,
745 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
746 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
748 if (!theFirstPoint.get() || !theSecondPoint.get())
751 static const double anAngleTol = 1.e-12;
753 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
754 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
755 bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
757 // collect directions to each point
758 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
759 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
760 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
761 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
762 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
763 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
765 // sort points by their angular values
766 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
767 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
768 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
769 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
770 aFirstPtAngle += aPeriod;
771 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
772 aSecondPtAngle += aPeriod;
774 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
775 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
776 theFirstPoint = theSecondPoint;
777 theSecondPoint = aTmpPoint;
781 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
782 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
784 std::string anAttributeType = theModifiedAttribute->attributeType();
785 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
786 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
787 theModifiedAttribute);
788 aModifiedAttribute->setValue(thePoint);
791 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
792 << thePoint->y() << "]" << std::endl;
798 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
799 const AttributePtr& theSourceAttribute)
801 std::string anAttributeType = theModifiedAttribute->attributeType();
802 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
803 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
804 theModifiedAttribute);
805 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
808 if (aModifiedAttribute.get() && aSourceAttribute.get())
809 aModifiedAttribute->setValue(aSourceAttribute->pnt());
811 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
812 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
813 theModifiedAttribute);
814 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
817 if (aModifiedAttribute.get() && aSourceAttribute.get())
818 aModifiedAttribute->setValue(aSourceAttribute->value());
820 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
821 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
822 theModifiedAttribute);
823 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
825 if (!aSourceRefAttr.get())
826 aRefAttributeToFill->setAttr(theSourceAttribute);
828 if (aSourceRefAttr->isObject())
829 aRefAttributeToFill->setObject(aSourceRefAttr->object());
831 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
836 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
837 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
838 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
841 SketchPlugin_Sketch* aSketch = sketch();
842 if (!aSketch || !theBaseFeature.get())
845 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
847 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
848 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
850 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
851 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
853 aFeature->execute(); // to obtain result
859 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
860 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
861 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
864 SketchPlugin_Sketch* aSketch = sketch();
865 if (!aSketch || !theBaseFeature.get())
868 std::string aCenterAttributeId;
869 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
870 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
871 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
872 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
874 if (aCenterAttributeId.empty())
877 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
878 // update fillet arc: make the arc correct for sure, so, it is not needed to process
879 // the "attribute updated"
880 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
881 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
883 aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
884 SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
886 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
887 theBaseFeature->attribute(aCenterAttributeId));
888 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
889 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
891 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
892 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
894 /// fill referersed state of created arc as it is on the base arc
895 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
896 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
897 aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
899 aFeature->execute(); // to obtain result
900 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
905 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
906 const AttributePtr& theFirstAttribute,
907 const AttributePtr& theSecondAttribute)
909 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
910 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
911 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
912 aRefAttr->setAttr(theFirstAttribute);
914 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
915 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
916 aRefAttr->setAttr(theSecondAttribute);
919 std::cout << "<createConstraint to attribute> :"
920 << "first attribute - " << theFirstAttribute->id()
921 << "second attribute - " << theSecondAttribute->id()
928 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
929 const AttributePtr& theFirstAttribute,
930 const ObjectPtr& theSecondObject)
932 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
933 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
934 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
935 aRefAttr->setAttr(theFirstAttribute);
937 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
938 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
939 aRefAttr->setObject(theSecondObject);
942 std::cout << "<createConstraint to attribute> :"
943 << "first attribute - " << theFirstAttribute->id()
944 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
951 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
952 const std::string& theConstraintId,
953 const ObjectPtr& theFirstObject,
954 const ObjectPtr& theSecondObject)
956 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
957 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
958 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
959 aRefAttr->setObject(theFirstObject);
961 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
962 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
963 aRefAttr->setObject(theSecondObject);
968 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
969 const std::shared_ptr<ModelAPI_Feature>& theFeature)
971 std::shared_ptr<ModelAPI_Result> aResult;
973 std::string aFeatureKind = theFeature->getKind();
974 if (aFeatureKind == SketchPlugin_Line::ID())
975 aResult = theFeature->firstResult();
976 else if (aFeatureKind == SketchPlugin_Arc::ID())
977 aResult = theFeature->lastResult();
978 else if (aFeatureKind == SketchPlugin_Circle::ID())
979 aResult = theFeature->lastResult();
984 //********************************************************************
985 bool SketchPlugin_Trim::useGraphicIntersection() const
990 //********************************************************************
991 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
993 PointToRefsMap aPointsInfo;
995 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
996 std::map<std::shared_ptr<GeomAPI_Pnt>,
997 std::list< AttributePoint2DPtr > > aPointToAttributes;
998 std::map<std::shared_ptr<GeomAPI_Pnt>,
999 std::list< ObjectPtr > > aPointToObjects;
1001 std::set<AttributePoint2DPtr > aRefAttributes;
1003 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1004 std::set<ResultPtr> anEdgeShapes;
1006 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1007 if (!anEdgeShapes.empty()) {
1008 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1010 // coincidences to the feature
1011 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1012 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1013 // layed on feature coincidences to divide it on several shapes
1014 SketchPlugin_Sketch* aSketch = sketch();
1015 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
1016 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1017 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1018 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1019 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1020 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1021 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1022 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1024 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1025 aX->dir(), aY, aPointsInfo);
1027 // intersection points
1028 if (useGraphicIntersection()) {
1029 std::list<FeaturePtr> aFeatures;
1030 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
1031 FeaturePtr aFeature = aSketch->subFeature(i);
1033 aFeatures.push_back(aFeature);
1035 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1037 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1039 myObjectToPoints[theObject] = aPointsInfo;
1040 myCashedShapes[theObject] = aShapes;
1043 //********************************************************************
1044 void SketchPlugin_Trim::attributeChanged(const std::string& theID)
1046 //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
1047 if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
1048 bool isValidAttribute = false;
1050 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
1051 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
1052 ObjectPtr aBaseObject = aBaseObjectAttr->value();
1053 if (aBaseObject.get()) {
1054 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
1056 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1057 data()->attribute(ENTITY_POINT()));
1058 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
1059 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
1060 anAttributePnt2d->y());
1062 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1063 fillObjectShapes(aBaseObject);
1065 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1066 isValidAttribute = !aShapes.empty();
1068 if (!isValidAttribute) {
1069 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1070 aBaseObjectAttr->setValue(ObjectPtr());
1071 data()->blockSendAttributeUpdated(aWasBlocked);