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(), anAttributePnt2d->y());
300 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
301 fillObjectShapes(aBaseObject);
303 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
304 if (!aShapes.empty()) {
305 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
306 for (; anIt != aLast; anIt++) {
307 GeomShapePtr aBaseShape = *anIt;
308 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
309 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
312 anAIS = AISObjectPtr(new GeomAPI_AISObject);
313 anAIS->createShape(aBaseShape);
315 std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
316 aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
318 bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
320 std::vector<int> aColor;
321 aColor = Config_PropManager::color("Visualization", "operation_highlight_color",
322 OPERATION_HIGHLIGHT_COLOR());
323 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
324 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
325 if (isConstruction) {
326 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
327 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
329 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
330 // modification of width should be replaced to value 1 after highlight problem is fixed
331 anAIS->setWidth(aWidth + 2);//1);
332 anAIS->setLineStyle(aLineStyle);
342 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
343 AttributePoint2DPtr& theStartPointAttr,
344 AttributePoint2DPtr& theEndPointAttr)
346 std::string aFeatureKind = theFeature->getKind();
347 std::string aStartAttributeName, anEndAttributeName;
348 if (aFeatureKind == SketchPlugin_Line::ID()) {
349 aStartAttributeName = SketchPlugin_Line::START_ID();
350 anEndAttributeName = SketchPlugin_Line::END_ID();
352 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
353 aStartAttributeName = SketchPlugin_Arc::START_ID();
354 anEndAttributeName = SketchPlugin_Arc::END_ID();
356 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
357 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
358 theFeature->attribute(aStartAttributeName));
359 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
360 theFeature->attribute(anEndAttributeName));
364 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete,
365 std::set<FeaturePtr>& theFeaturesToUpdate)
367 std::shared_ptr<ModelAPI_Data> aData = data();
369 // Check the base objects are initialized.
370 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
371 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
372 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
373 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
375 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
376 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
377 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
379 std::set<AttributePtr>::const_iterator aIt;
380 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
381 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
382 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
383 std::string aRefFeatureKind = aRefFeature->getKind();
384 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
385 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
386 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
387 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
388 theFeaturesToDelete.insert(aRefFeature);
389 else if (aRefFeatureKind == SketchPlugin_ConstraintLength::ID())
390 theFeaturesToUpdate.insert(aRefFeature);
391 else if (aRefFeatureKind == SketchPlugin_ConstraintTangent::ID()) {
392 if (aBaseFeature->getKind() == SketchPlugin_Circle::ID()) /// TEMPORARY limitaion
393 /// until tangency between arc and line is implemented
394 theFeaturesToDelete.insert(aRefFeature);
396 std::string anAttributeToBeModified;
397 AttributePoint2DPtr aTangentPoint;
398 ObjectPtr aResult1 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_A())->object();
399 ObjectPtr aResult2 = aRefFeature->refattr(SketchPlugin_Constraint::ENTITY_B())->object();
400 if (aResult1.get() && aResult2.get()) {
401 FeaturePtr aCoincidenceFeature =
402 SketchPlugin_ConstraintCoincidence::findCoincidenceFeature
403 (ModelAPI_Feature::feature(aResult1),
404 ModelAPI_Feature::feature(aResult2));
405 // get the point not lying on the splitting feature
406 for (int i = 0; i < CONSTRAINT_ATTR_SIZE; ++i) {
407 AttributeRefAttrPtr aRefAttr = aCoincidenceFeature->refattr(SketchPlugin_Trim::BASE_OBJECT());
408 if (!aRefAttr || aRefAttr->isObject())
410 AttributePoint2DPtr aPoint =
411 std::dynamic_pointer_cast<GeomDataAPI_Point2D>(aRefAttr->attr());
414 if (aPoint->owner() != aBaseFeature) {
415 aTangentPoint = aPoint;
420 if (aTangentPoint.get()) {
421 //FeaturePtr aFeature1 = ModelAPI_Feature::feature(aResult1);
422 //std::string anAttributeToBeModified = aFeature1 == aBaseFeature
423 // ? SketchPlugin_Constraint::ENTITY_A() : SketchPlugin_Constraint::ENTITY_B();
424 //theTangentFeatures[aRefFeature] = std::make_pair(anAttributeToBeModified, aTangentPoint);
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() << ", " << 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(), anAttributePnt2d->y());
1061 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1062 fillObjectShapes(aBaseObject);
1064 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1065 isValidAttribute = !aShapes.empty();
1067 if (!isValidAttribute) {
1068 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1069 aBaseObjectAttr->setValue(ObjectPtr());
1070 data()->blockSendAttributeUpdated(aWasBlocked);