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;
180 getConstraints(aFeaturesToDelete);
182 std::map<AttributePtr, std::list<AttributePtr> > aBaseRefAttributes;
183 std::list<AttributePtr> aRefsToFeature;
184 getRefAttributes(aBaseFeature, aBaseRefAttributes, aRefsToFeature);
187 // coincidence to result points
188 // find coincidences to the base object, it should be used when attribute is found
189 // in myObjectToPoints
190 std::map<AttributePtr, FeaturePtr> aCoincidencesToBaseFeature;
191 getCoincidencesToObject(aBaseObject, aCoincidencesToBaseFeature);
193 std::set<AttributePoint2DPtr> aFurtherCoincidences;
194 std::set<std::pair<AttributePtr, AttributePtr>> aModifiedAttributes;
195 const std::string& aKind = aBaseFeature->getKind();
196 FeaturePtr aReplacingFeature;
197 if (aKind == SketchPlugin_Circle::ID()) {
198 aReplacingFeature = trimCircle(aStartShapePoint2d, aLastShapePoint2d,
199 aFurtherCoincidences, aModifiedAttributes);
201 aFeaturesToDelete.insert(aBaseFeature);
202 // as circle is removed, temporary fill this attribute
203 aBaseObjectAttr->setObject(ResultPtr());
205 else if (aKind == SketchPlugin_Line::ID()) {
206 trimLine(aStartShapePoint2d, aLastShapePoint2d,
207 aFurtherCoincidences, aModifiedAttributes);
209 else if (aKind == SketchPlugin_Arc::ID()) {
210 trimArc(aStartShapePoint2d, aLastShapePoint2d,
211 aFurtherCoincidences, aModifiedAttributes);
215 const PointToRefsMap& aRefsMap = myObjectToPoints.at(aBaseObject);
216 std::set<AttributePoint2DPtr>::const_iterator anIt = aFurtherCoincidences.begin(),
217 aLast = aFurtherCoincidences.end();
218 for (; anIt != aLast; anIt++) {
219 AttributePoint2DPtr aPointAttribute = (*anIt);
220 std::shared_ptr<GeomAPI_Pnt2d> aPoint2d = aPointAttribute->pnt();
222 std::shared_ptr<GeomAPI_Pnt> aPoint;
223 if (aStartShapePoint2d.get() && aPoint2d->isEqual(aStartShapePoint2d))
224 aPoint = aStartShapePoint;
225 else if (aLastShapePoint2d.get() && aPoint2d->isEqual(aLastShapePoint2d))
226 aPoint = aLastShapePoint;
231 std::pair<std::list<AttributePoint2DPtr >, std::list<ObjectPtr > > anInfo;
232 for (PointToRefsMap::const_iterator aRefIt = aRefsMap.begin(); aRefIt != aRefsMap.end();
235 if (aRefIt->first->isEqual(aPoint)) {
236 anInfo = aRefIt->second;
240 const std::list<AttributePoint2DPtr >& anAttributes = anInfo.first;
241 for (std::list<AttributePoint2DPtr>::const_iterator anAttrIt = anAttributes.begin();
242 anAttrIt != anAttributes.end(); anAttrIt++) {
243 AttributePtr anAttribute = *anAttrIt;
244 if (aCoincidencesToBaseFeature.find(anAttribute) != aCoincidencesToBaseFeature.end())
246 FeaturePtr anAttrFeature = aCoincidencesToBaseFeature.at(anAttribute);
247 AttributePtr anOtherAttribute;
248 if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
249 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()))->attr() == anAttribute)
250 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
251 else if (std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
252 (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()))->attr() == anAttribute)
253 anOtherAttribute = anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
256 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
259 aRefAttr->setAttr(aPointAttribute);
263 const std::list<ObjectPtr>& anObjects = anInfo.second;
264 for (std::list<ObjectPtr>::const_iterator anObjectIt = anObjects.begin();
265 anObjectIt != anObjects.end(); anObjectIt++) {
266 createConstraintToObject(SketchPlugin_ConstraintCoincidence::ID(), aPointAttribute,
271 // move constraints from base feature to replacing feature: ignore coincidences to feature
272 // if attributes of coincidence participated in split
273 if (aReplacingFeature.get()) {
274 ResultPtr aReplacingResult = getFeatureResult(aReplacingFeature);
275 std::list<AttributePtr>::const_iterator anIt = aRefsToFeature.begin(),
276 aLast = aRefsToFeature.end();
277 for (; anIt != aLast; anIt++) {
278 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
281 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(aRefAttr->owner());
282 if (anAttrFeature.get() &&
283 anAttrFeature->getKind() == SketchPlugin_ConstraintCoincidence::ID())
285 if (anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_A()) == aRefAttr ||
286 anAttrFeature->attribute(SketchPlugin_Constraint::ENTITY_B()) == aRefAttr)
289 aRefAttr->setObject(aReplacingResult);
293 // Wait all constraints being created, then send update events
294 static Events_ID anUpdateEvent = Events_Loop::eventByName(EVENT_OBJECT_UPDATED);
295 bool isUpdateFlushed = Events_Loop::loop()->isFlushed(anUpdateEvent);
297 Events_Loop::loop()->setFlushed(anUpdateEvent, false);
299 updateRefAttConstraints(aBaseRefAttributes, aModifiedAttributes, aFeaturesToDelete);
301 // delete constraints
303 std::cout << "remove features and references:" << std::endl;
304 std::set<FeaturePtr>::const_iterator aDIt = aFeaturesToDelete.begin(),
305 aDLast = aFeaturesToDelete.end();
306 for (; aDIt != aDLast; aDIt++) {
307 //std::cout << getFeatureInfo(*aDIt, false) << std::endl;
308 //std::cout << std::endl;
311 ModelAPI_Tools::removeFeaturesAndReferences(aFeaturesToDelete);
312 Events_Loop::loop()->flush(Events_Loop::eventByName(EVENT_OBJECT_DELETED));
314 // Send events to update the sub-features by the solver.
315 if(isUpdateFlushed) {
316 Events_Loop::loop()->setFlushed(anUpdateEvent, true);
320 std::cout << "SketchPlugin_Trim::done" << std::endl;
324 bool SketchPlugin_Trim::isMacro() const
329 AISObjectPtr SketchPlugin_Trim::getAISObject(AISObjectPtr thePrevious)
331 AISObjectPtr anAIS = thePrevious;
333 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
334 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
335 ObjectPtr aBaseObject = aBaseObjectAttr->value();
336 if (!aBaseObject.get())
338 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
341 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
342 data()->attribute(ENTITY_POINT()));
343 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
344 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
345 anAttributePnt2d->y());
347 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
348 fillObjectShapes(aBaseObject);
350 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
351 if (!aShapes.empty()) {
352 std::set<GeomShapePtr>::const_iterator anIt = aShapes.begin(), aLast = aShapes.end();
353 for (; anIt != aLast; anIt++) {
354 GeomShapePtr aBaseShape = *anIt;
355 std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
356 if (ModelGeomAlgo_Point2D::isPointOnEdge(aBaseShape, anAttributePnt, aProjectedPoint)) {
359 anAIS = AISObjectPtr(new GeomAPI_AISObject);
360 anAIS->createShape(aBaseShape);
362 std::shared_ptr<ModelAPI_AttributeBoolean> anAuxiliaryAttr =
363 aBaseFeature->data()->boolean(SketchPlugin_SketchEntity::AUXILIARY_ID());
365 bool isConstruction = anAuxiliaryAttr.get() != NULL && anAuxiliaryAttr->value();
367 std::vector<int> aColor;
368 aColor = Config_PropManager::color("Visualization", "operation_highlight_color",
369 OPERATION_HIGHLIGHT_COLOR());
370 double aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH();
371 int aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE();
372 if (isConstruction) {
373 aWidth = SketchPlugin_SketchEntity::SKETCH_LINE_WIDTH_AUXILIARY();
374 aLineStyle = SketchPlugin_SketchEntity::SKETCH_LINE_STYLE_AUXILIARY();
376 anAIS->setColor(aColor[0], aColor[1], aColor[2]);
377 // modification of width should be replaced to value 1 after highlight problem is fixed
378 anAIS->setWidth(aWidth + 2);//1);
379 anAIS->setLineStyle(aLineStyle);
389 void SketchPlugin_Trim::getFeaturePoints(const FeaturePtr& theFeature,
390 AttributePoint2DPtr& theStartPointAttr,
391 AttributePoint2DPtr& theEndPointAttr)
393 std::string aFeatureKind = theFeature->getKind();
394 std::string aStartAttributeName, anEndAttributeName;
395 if (aFeatureKind == SketchPlugin_Line::ID()) {
396 aStartAttributeName = SketchPlugin_Line::START_ID();
397 anEndAttributeName = SketchPlugin_Line::END_ID();
399 else if (aFeatureKind == SketchPlugin_Arc::ID()) {
400 aStartAttributeName = SketchPlugin_Arc::START_ID();
401 anEndAttributeName = SketchPlugin_Arc::END_ID();
403 if (!aStartAttributeName.empty() && !anEndAttributeName.empty()) {
404 theStartPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
405 theFeature->attribute(aStartAttributeName));
406 theEndPointAttr = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
407 theFeature->attribute(anEndAttributeName));
411 void SketchPlugin_Trim::getConstraints(std::set<FeaturePtr>& theFeaturesToDelete)
413 std::shared_ptr<ModelAPI_Data> aData = data();
415 // Check the base objects are initialized.
416 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
417 aData->attribute(SketchPlugin_Trim::BASE_OBJECT()));
418 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
419 ResultPtr aBaseFeatureResult = getFeatureResult(aBaseFeature);
421 std::set<AttributePtr> aRefsList = aBaseFeatureResult->data()->refsToMe();
422 std::set<AttributePtr> aFRefsList = aBaseFeature->data()->refsToMe();
423 aRefsList.insert(aFRefsList.begin(), aFRefsList.end());
425 std::set<AttributePtr>::const_iterator aIt;
426 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
427 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
428 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
429 std::string aRefFeatureKind = aRefFeature->getKind();
430 if (aRefFeatureKind == SketchPlugin_ConstraintMirror::ID() ||
431 aRefFeatureKind == SketchPlugin_MultiRotation::ID() ||
432 aRefFeatureKind == SketchPlugin_MultiTranslation::ID() ||
433 aRefFeatureKind == SketchPlugin_ConstraintMiddle::ID())
434 theFeaturesToDelete.insert(aRefFeature);
438 void SketchPlugin_Trim::getRefAttributes(const FeaturePtr& theFeature,
439 std::map<AttributePtr, std::list<AttributePtr> >& theRefs,
440 std::list<AttributePtr>& theRefsToFeature)
444 std::list<AttributePtr> aPointAttributes =
445 theFeature->data()->attributes(GeomDataAPI_Point2D::typeId());
446 std::set<AttributePtr> aPointAttributesSet;
448 std::list<AttributePtr>::const_iterator aPIt =
449 aPointAttributes.begin(), aPLast = aPointAttributes.end();
450 for (; aPIt != aPLast; aPIt++)
451 aPointAttributesSet.insert(*aPIt);
453 std::set<AttributePtr> aRefsAttributes = getFeatureResult(theFeature)->data()->refsToMe();
454 std::set<AttributePtr> aFRefsList = theFeature->data()->refsToMe();
455 aRefsAttributes.insert(aFRefsList.begin(), aFRefsList.end());
457 std::set<AttributePtr>::const_iterator aIt;
458 for (aIt = aRefsAttributes.cbegin(); aIt != aRefsAttributes.cend(); ++aIt) {
459 AttributePtr anAttr = (*aIt);
460 FeaturePtr anAttrFeature = ModelAPI_Feature::feature(anAttr->owner());
461 if (anAttrFeature.get() != this &&
462 anAttr.get() && anAttr->attributeType() == ModelAPI_AttributeRefAttr::typeId()) {
463 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(anAttr);
464 if (!aRefAttr->isObject()) { /// find attributes referenced to feature point attributes
465 AttributePtr anAttrInRef = aRefAttr->attr();
466 if (anAttrInRef.get() &&
467 aPointAttributesSet.find(anAttrInRef) != aPointAttributesSet.end()) {
468 if (theRefs.find(anAttrInRef) != theRefs.end())
469 theRefs[anAttrInRef].push_back(aRefAttr);
471 std::list<AttributePtr> anAttrList;
472 anAttrList.push_back(aRefAttr);
473 theRefs[anAttrInRef] = anAttrList;
477 else { /// find attributes referenced to feature itself
478 theRefsToFeature.push_back(anAttr);
484 void SketchPlugin_Trim::getCoincidencesToObject(const ObjectPtr& theObject,
485 std::map<AttributePtr, FeaturePtr>& theCoincidencesToBaseFeature)
487 const std::set<AttributePtr>& aRefsList = theObject->data()->refsToMe();
488 std::set<AttributePtr>::const_iterator aIt;
489 for (aIt = aRefsList.cbegin(); aIt != aRefsList.cend(); ++aIt) {
490 std::shared_ptr<ModelAPI_Attribute> aAttr = (*aIt);
491 FeaturePtr aRefFeature = std::dynamic_pointer_cast<ModelAPI_Feature>(aAttr->owner());
492 if (aRefFeature->getKind() != SketchPlugin_ConstraintCoincidence::ID())
494 AttributePtr anAttribute;
495 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
496 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A()));
497 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
499 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B());
502 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
503 (aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_B()));
504 if (aRefAttr->isObject() && aRefAttr->object() == theObject)
506 anAttribute = aRefFeature->attribute(SketchPlugin_Constraint::ENTITY_A());
508 if (anAttribute.get())
510 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>
512 anAttribute = aRefAttr->attr();
513 if (anAttribute.get())
514 theCoincidencesToBaseFeature[anAttribute] = aRefFeature;
520 void SketchPlugin_Trim::updateRefAttConstraints(
521 const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
522 const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes,
523 std::set<FeaturePtr>& theFeaturesToDelete)
526 std::cout << "SketchPlugin_Trim::updateRefAttConstraints" << std::endl;
529 std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
530 anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
531 for (; anIt != aLast; anIt++) {
532 AttributePtr anAttribute = anIt->first;
534 /// not found in references
535 if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
537 std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
538 std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
539 aRLast = aRefAttributes.end();
541 AttributePtr aNewAttribute = anIt->second;
542 for (; aRefIt != aRLast; aRefIt++) {
543 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
544 if (aRefAttr.get()) {
545 if (aNewAttribute.get())
546 aRefAttr->setAttr(aNewAttribute);
548 theFeaturesToDelete.insert(ModelAPI_Feature::feature(aRefAttr->owner()));
550 //FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
551 //std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
558 void SketchPlugin_Trim::trimLine(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
559 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
560 std::set<AttributePoint2DPtr>& thePoints,
561 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
563 // Check the base objects are initialized.
564 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
565 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
566 ObjectPtr aBaseObject = aBaseObjectAttr->value();
567 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
570 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
571 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
573 std::shared_ptr<GeomAPI_Pnt2d> aStartFeaturePoint = aStartPointAttrOfBase->pnt();
574 std::shared_ptr<GeomAPI_Pnt2d> aLastFeaturePoint = anEndPointAttrOfBase->pnt();
576 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
577 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
578 arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
579 aStartShapePoint, aLastShapePoint);
581 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
582 if (aStartShapePoint.get())
583 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
584 aStartShapePoint->y() << "]" << std::endl;
585 std::cout << "1st point: [" << aStartFeaturePoint->x() << ", " <<
586 aStartFeaturePoint->y() << "]" << std::endl;
587 if (aLastShapePoint.get())
588 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
589 aLastShapePoint->y() << "]" << std::endl;
590 std::cout << "End point: [" << aLastFeaturePoint->x() << ", " <<
591 aLastFeaturePoint->y() << "]" << std::endl;
594 bool isStartPoint = !aStartShapePoint.get() || aStartFeaturePoint->isEqual(aStartShapePoint);
595 bool isLastPoint = !aLastShapePoint.get() || aLastFeaturePoint->isEqual(aLastShapePoint);
596 if (isStartPoint || isLastPoint) {
597 // result is one line: changed existing line
598 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Line::START_ID()
599 : SketchPlugin_Line::END_ID();
600 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
601 if (aStartShapePoint.get() && aLastShapePoint.get())
602 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
604 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
606 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
607 theModifiedAttributes.insert(
608 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
610 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
611 (aBaseFeature->attribute(aModifiedAttribute)));
614 // result is two lines: start line point - start shape point, last shape point - last line point
615 // create second line
616 FeaturePtr anNewFeature = createLineFeature(aBaseFeature, aLastShapePoint, aLastFeaturePoint);
617 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
618 (anNewFeature->attribute(SketchPlugin_Line::START_ID())));
620 std::string aModifiedAttribute = SketchPlugin_Line::END_ID();
621 theModifiedAttributes.insert(
622 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
623 anNewFeature->attribute(SketchPlugin_Line::END_ID())));
626 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
628 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
629 (aBaseFeature->attribute(aModifiedAttribute)));
631 // Collinear constraint for lines
632 createConstraintForObjects(SketchPlugin_ConstraintCollinear::ID(),
633 getFeatureResult(aBaseFeature),
634 getFeatureResult(anNewFeature));
639 void SketchPlugin_Trim::trimArc(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
640 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
641 std::set<AttributePoint2DPtr>& thePoints,
642 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
644 // Check the base objects are initialized.
645 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
646 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
647 ObjectPtr aBaseObject = aBaseObjectAttr->value();
648 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
651 AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
652 getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
654 std::shared_ptr<GeomAPI_Pnt2d> aStartArcPoint = aStartPointAttrOfBase->pnt();
655 std::shared_ptr<GeomAPI_Pnt2d> aLastArcPoint = anEndPointAttrOfBase->pnt();
657 std::shared_ptr<GeomAPI_Pnt2d> aStartShapePoint = theStartShapePoint;
658 std::shared_ptr<GeomAPI_Pnt2d> aLastShapePoint = theLastShapePoint;
659 arrangePointsOnArc(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase,
660 aStartShapePoint, aLastShapePoint);
662 std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
663 if (aStartShapePoint.get())
664 std::cout << "Start point: [" << aStartShapePoint->x() << ", " <<
665 aStartShapePoint->y() << "]" << std::endl;
666 std::cout << "1st point: [" << aStartArcPoint->x() << ", " <<
667 aStartArcPoint->y() << "]" << std::endl;
668 if (aLastShapePoint.get())
669 std::cout << "2st point: [" << aLastShapePoint->x() << ", " <<
670 aLastShapePoint->y() << "]" << std::endl;
671 std::cout << "End point: [" << aLastArcPoint->x() << ", " <<
672 aLastArcPoint->y() << "]" << std::endl;
675 bool isStartPoint = !aStartShapePoint.get() || aStartArcPoint->isEqual(aStartShapePoint);
676 bool isLastPoint = !aLastShapePoint.get() || aLastArcPoint->isEqual(aLastShapePoint);
677 if (isStartPoint || isLastPoint) {
678 // result is one arc: changed existing arc
679 std::string aModifiedAttribute = isStartPoint ? SketchPlugin_Arc::START_ID()
680 : SketchPlugin_Arc::END_ID();
681 std::shared_ptr<GeomAPI_Pnt2d> aPoint;
682 if (aStartShapePoint.get() && aLastShapePoint.get())
683 aPoint = isStartPoint ? aLastShapePoint : aStartShapePoint;
685 aPoint = aStartShapePoint.get() ? aStartShapePoint : aLastShapePoint;
687 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aPoint);
688 theModifiedAttributes.insert(
689 std::make_pair(aBaseFeature->attribute(aModifiedAttribute), AttributePtr()));
691 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
692 (aBaseFeature->attribute(aModifiedAttribute)));
695 // result is two arcs: start arc point - start shape point, last shape point - last arc point
697 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, aLastShapePoint, aLastArcPoint);
698 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
699 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
701 std::string aModifiedAttribute = SketchPlugin_Arc::END_ID();
702 theModifiedAttributes.insert(
703 std::make_pair(aBaseFeature->attribute(aModifiedAttribute),
704 anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
707 fillPointAttribute(aBaseFeature->attribute(aModifiedAttribute), aStartShapePoint);
709 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
710 (aBaseFeature->attribute(aModifiedAttribute)));
712 // equal Radius constraint for arcs
713 createConstraintForObjects(SketchPlugin_ConstraintEqual::ID(),
714 getFeatureResult(aBaseFeature),
715 getFeatureResult(anArcFeature));
716 // coincident centers constraint
717 createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
718 aBaseFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
719 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID()));
723 FeaturePtr SketchPlugin_Trim::trimCircle(const std::shared_ptr<GeomAPI_Pnt2d>& theStartShapePoint,
724 const std::shared_ptr<GeomAPI_Pnt2d>& theLastShapePoint,
725 std::set<AttributePoint2DPtr>& thePoints,
726 std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
728 // Check the base objects are initialized.
729 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
730 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
731 ObjectPtr aBaseObject = aBaseObjectAttr->value();
732 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
735 //AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
736 //getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
739 FeaturePtr anArcFeature = createArcFeature(aBaseFeature, theStartShapePoint, theLastShapePoint);
741 theModifiedAttributes.insert(
742 std::make_pair(aBaseFeature->attribute(SketchPlugin_Circle::CENTER_ID()),
743 anArcFeature->attribute(SketchPlugin_Arc::CENTER_ID())));
745 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
746 (anArcFeature->attribute(SketchPlugin_Arc::START_ID())));
747 thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
748 (anArcFeature->attribute(SketchPlugin_Arc::END_ID())));
753 void SketchPlugin_Trim::arrangePointsOnLine(const AttributePoint2DPtr& theStartPointAttr,
754 const AttributePoint2DPtr& theEndPointAttr,
755 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
756 std::shared_ptr<GeomAPI_Pnt2d>& theLastPoint) const
758 if (!theFirstPoint.get() || !theLastPoint.get())
761 // if first point is closer to last point, swap first and last values
762 if (theStartPointAttr->pnt()->distance(theFirstPoint) >
763 theStartPointAttr->pnt()->distance(theLastPoint)) {
764 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
765 theFirstPoint = theLastPoint;
766 theLastPoint = aTmpPoint;
770 void SketchPlugin_Trim::arrangePointsOnArc(const FeaturePtr& theArc,
771 const AttributePoint2DPtr& theStartPointAttr,
772 const AttributePoint2DPtr& theEndPointAttr,
773 std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
774 std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint) const
776 if (!theFirstPoint.get() || !theSecondPoint.get())
779 static const double anAngleTol = 1.e-12;
781 std::shared_ptr<GeomAPI_Pnt2d> aCenter = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
782 theArc->attribute(SketchPlugin_Arc::CENTER_ID()))->pnt();
783 bool isReversed = theArc->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
785 // collect directions to each point
786 std::shared_ptr<GeomAPI_Dir2d> aStartDir(
787 new GeomAPI_Dir2d(theStartPointAttr->pnt()->xy()->decreased(aCenter->xy())));
788 std::shared_ptr<GeomAPI_Dir2d> aFirstPtDir(
789 new GeomAPI_Dir2d(theFirstPoint->xy()->decreased(aCenter->xy())));
790 std::shared_ptr<GeomAPI_Dir2d> aSecondPtDir(
791 new GeomAPI_Dir2d(theSecondPoint->xy()->decreased(aCenter->xy())));
793 // sort points by their angular values
794 double aFirstPtAngle = aStartDir->angle(aFirstPtDir);
795 double aSecondPtAngle = aStartDir->angle(aSecondPtDir);
796 double aPeriod = isReversed ? -2.0 * PI : 2.0 * PI;
797 if (fabs(aFirstPtAngle) > anAngleTol && isReversed == (aFirstPtAngle > 0.))
798 aFirstPtAngle += aPeriod;
799 if (fabs(aSecondPtAngle) > anAngleTol && isReversed == (aSecondPtAngle > 0.))
800 aSecondPtAngle += aPeriod;
802 if (fabs(aFirstPtAngle) > fabs(aSecondPtAngle)) {
803 std::shared_ptr<GeomAPI_Pnt2d> aTmpPoint = theFirstPoint;
804 theFirstPoint = theSecondPoint;
805 theSecondPoint = aTmpPoint;
809 void SketchPlugin_Trim::fillPointAttribute(const AttributePtr& theModifiedAttribute,
810 const std::shared_ptr<GeomAPI_Pnt2d>& thePoint)
812 std::string anAttributeType = theModifiedAttribute->attributeType();
813 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
814 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
815 theModifiedAttribute);
816 aModifiedAttribute->setValue(thePoint);
819 std::cout << "<fillPointAttribute> => Pnt2d - [" << thePoint->x() << ", "
820 << thePoint->y() << "]" << std::endl;
826 void SketchPlugin_Trim::fillAttribute(const AttributePtr& theModifiedAttribute,
827 const AttributePtr& theSourceAttribute)
829 std::string anAttributeType = theModifiedAttribute->attributeType();
830 if (anAttributeType == GeomDataAPI_Point2D::typeId()) {
831 AttributePoint2DPtr aModifiedAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
832 theModifiedAttribute);
833 AttributePoint2DPtr aSourceAttribute = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
836 if (aModifiedAttribute.get() && aSourceAttribute.get())
837 aModifiedAttribute->setValue(aSourceAttribute->pnt());
839 else if (anAttributeType == ModelAPI_AttributeBoolean::typeId()) {
840 AttributeBooleanPtr aModifiedAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
841 theModifiedAttribute);
842 AttributeBooleanPtr aSourceAttribute = std::dynamic_pointer_cast<ModelAPI_AttributeBoolean>(
845 if (aModifiedAttribute.get() && aSourceAttribute.get())
846 aModifiedAttribute->setValue(aSourceAttribute->value());
848 else if (anAttributeType == ModelAPI_AttributeRefAttr::typeId()) {
849 AttributeRefAttrPtr aRefAttributeToFill = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
850 theModifiedAttribute);
851 AttributeRefAttrPtr aSourceRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
853 if (!aSourceRefAttr.get())
854 aRefAttributeToFill->setAttr(theSourceAttribute);
856 if (aSourceRefAttr->isObject())
857 aRefAttributeToFill->setObject(aSourceRefAttr->object());
859 aRefAttributeToFill->setAttr(aSourceRefAttr->attr());
864 FeaturePtr SketchPlugin_Trim::createLineFeature(const FeaturePtr& theBaseFeature,
865 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
866 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
869 SketchPlugin_Sketch* aSketch = sketch();
870 if (!aSketch || !theBaseFeature.get())
873 aFeature = aSketch->addFeature(SketchPlugin_Line::ID());
875 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), theFirstPoint);
876 fillPointAttribute(aFeature->attribute(SketchPlugin_Line::END_ID()), theSecondPoint);
878 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
879 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
881 aFeature->execute(); // to obtain result
887 FeaturePtr SketchPlugin_Trim::createArcFeature(const FeaturePtr& theBaseFeature,
888 const std::shared_ptr<GeomAPI_Pnt2d>& theFirstPoint,
889 const std::shared_ptr<GeomAPI_Pnt2d>& theSecondPoint)
892 SketchPlugin_Sketch* aSketch = sketch();
893 if (!aSketch || !theBaseFeature.get())
896 std::string aCenterAttributeId;
897 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID())
898 aCenterAttributeId = SketchPlugin_Arc::CENTER_ID();
899 else if (theBaseFeature->getKind() == SketchPlugin_Circle::ID())
900 aCenterAttributeId = SketchPlugin_Circle::CENTER_ID();
902 if (aCenterAttributeId.empty())
905 aFeature = aSketch->addFeature(SketchPlugin_Arc::ID());
906 // update fillet arc: make the arc correct for sure, so, it is not needed to process
907 // the "attribute updated"
908 // by arc; moreover, it may cause cyclicity in hte mechanism of updater
909 bool aWasBlocked = aFeature->data()->blockSendAttributeUpdated(true);
911 aFeature->string(SketchPlugin_Arc::ARC_TYPE())->setValue(
912 SketchPlugin_Arc::ARC_TYPE_CENTER_START_END());
914 fillAttribute(aFeature->attribute(SketchPlugin_Arc::CENTER_ID()),
915 theBaseFeature->attribute(aCenterAttributeId));
916 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::START_ID()), theFirstPoint);
917 fillPointAttribute(aFeature->attribute(SketchPlugin_Arc::END_ID()), theSecondPoint);
919 fillAttribute(aFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()),
920 theBaseFeature->attribute(SketchPlugin_SketchEntity::AUXILIARY_ID()));
922 /// fill referersed state of created arc as it is on the base arc
923 if (theBaseFeature->getKind() == SketchPlugin_Arc::ID()) {
924 bool aReversed = theBaseFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->value();
925 aFeature->boolean(SketchPlugin_Arc::INVERSED_ID())->setValue(aReversed);
927 aFeature->execute(); // to obtain result
928 aFeature->data()->blockSendAttributeUpdated(aWasBlocked);
933 FeaturePtr SketchPlugin_Trim::createConstraint(const std::string& theConstraintId,
934 const AttributePtr& theFirstAttribute,
935 const AttributePtr& theSecondAttribute)
937 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
938 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
939 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
940 aRefAttr->setAttr(theFirstAttribute);
942 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
943 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
944 aRefAttr->setAttr(theSecondAttribute);
947 std::cout << "<createConstraint to attribute> :"
948 << "first attribute - " << theFirstAttribute->id()
949 << "second attribute - " << theSecondAttribute->id()
956 FeaturePtr SketchPlugin_Trim::createConstraintToObject(const std::string& theConstraintId,
957 const AttributePtr& theFirstAttribute,
958 const ObjectPtr& theSecondObject)
960 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
961 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
962 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
963 aRefAttr->setAttr(theFirstAttribute);
965 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
966 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
967 aRefAttr->setObject(theSecondObject);
970 std::cout << "<createConstraint to attribute> :"
971 << "first attribute - " << theFirstAttribute->id()
972 << "second object - " << ModelAPI_Feature::feature(theSecondObject)->getKind()
979 FeaturePtr SketchPlugin_Trim::createConstraintForObjects(
980 const std::string& theConstraintId,
981 const ObjectPtr& theFirstObject,
982 const ObjectPtr& theSecondObject)
984 FeaturePtr aConstraint = sketch()->addFeature(theConstraintId);
985 AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
986 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_A()));
987 aRefAttr->setObject(theFirstObject);
989 aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(
990 aConstraint->attribute(SketchPlugin_Constraint::ENTITY_B()));
991 aRefAttr->setObject(theSecondObject);
996 std::shared_ptr<ModelAPI_Result> SketchPlugin_Trim::getFeatureResult(
997 const std::shared_ptr<ModelAPI_Feature>& theFeature)
999 std::shared_ptr<ModelAPI_Result> aResult;
1001 std::string aFeatureKind = theFeature->getKind();
1002 if (aFeatureKind == SketchPlugin_Line::ID())
1003 aResult = theFeature->firstResult();
1004 else if (aFeatureKind == SketchPlugin_Arc::ID())
1005 aResult = theFeature->lastResult();
1006 else if (aFeatureKind == SketchPlugin_Circle::ID())
1007 aResult = theFeature->lastResult();
1012 //********************************************************************
1013 bool SketchPlugin_Trim::useGraphicIntersection() const
1018 //********************************************************************
1019 void SketchPlugin_Trim::fillObjectShapes(const ObjectPtr& theObject)
1021 PointToRefsMap aPointsInfo;
1023 std::set<std::shared_ptr<GeomAPI_Shape> > aShapes;
1024 std::map<std::shared_ptr<GeomAPI_Pnt>,
1025 std::list< AttributePoint2DPtr > > aPointToAttributes;
1026 std::map<std::shared_ptr<GeomAPI_Pnt>,
1027 std::list< ObjectPtr > > aPointToObjects;
1029 std::set<AttributePoint2DPtr > aRefAttributes;
1031 FeaturePtr aFeature = ModelAPI_Feature::feature(theObject);
1032 std::set<ResultPtr> anEdgeShapes;
1034 ModelAPI_Tools::shapesOfType(aFeature, GeomAPI_Shape::EDGE, anEdgeShapes);
1035 if (!anEdgeShapes.empty()) {
1036 GeomShapePtr aFeatureShape = (*anEdgeShapes.begin())->shape();
1038 // coincidences to the feature
1039 ModelGeomAlgo_Point2D::getPointsOfReference(aFeature, SketchPlugin_ConstraintCoincidence::ID(),
1040 aRefAttributes, SketchPlugin_Point::ID(), SketchPlugin_Point::COORD_ID());
1041 // layed on feature coincidences to divide it on several shapes
1042 SketchPlugin_Sketch* aSketch = sketch();
1043 std::shared_ptr<ModelAPI_Data> aData = aSketch->data();
1044 std::shared_ptr<GeomDataAPI_Point> aC = std::dynamic_pointer_cast<GeomDataAPI_Point>(
1045 aData->attribute(SketchPlugin_Sketch::ORIGIN_ID()));
1046 std::shared_ptr<GeomDataAPI_Dir> aX = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1047 aData->attribute(SketchPlugin_Sketch::DIRX_ID()));
1048 std::shared_ptr<GeomDataAPI_Dir> aNorm = std::dynamic_pointer_cast<GeomDataAPI_Dir>(
1049 aData->attribute(SketchPlugin_Sketch::NORM_ID()));
1050 std::shared_ptr<GeomAPI_Dir> aY(new GeomAPI_Dir(aNorm->dir()->cross(aX->dir())));
1052 ModelGeomAlgo_Point2D::getPointsInsideShape(aFeatureShape, aRefAttributes, aC->pnt(),
1053 aX->dir(), aY, aPointsInfo);
1055 // intersection points
1056 if (useGraphicIntersection()) {
1057 std::list<FeaturePtr> aFeatures;
1058 for (int i = 0; i < aSketch->numberOfSubs(); i++) {
1059 FeaturePtr aFeature = aSketch->subFeature(i);
1061 aFeatures.push_back(aFeature);
1063 ModelGeomAlgo_Point2D::getPointsIntersectedShape(aFeature, aFeatures, aPointsInfo);
1065 GeomAlgoAPI_ShapeTools::splitShape(aFeatureShape, aPointsInfo, aShapes);
1067 myObjectToPoints[theObject] = aPointsInfo;
1068 myCashedShapes[theObject] = aShapes;
1071 //********************************************************************
1072 void SketchPlugin_Trim::attributeChanged(const std::string& theID)
1074 //data()->addAttribute(SketchPlugin_Trim::BASE_OBJECT(), ModelAPI_AttributeReference::typeId());
1075 if (theID == SketchPlugin_Trim::BASE_OBJECT()) {
1076 bool isValidAttribute = false;
1078 AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
1079 data()->attribute(SketchPlugin_Trim::BASE_OBJECT()));
1080 ObjectPtr aBaseObject = aBaseObjectAttr->value();
1081 if (aBaseObject.get()) {
1082 FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
1084 AttributePoint2DPtr aPoint = std::dynamic_pointer_cast<GeomDataAPI_Point2D>(
1085 data()->attribute(ENTITY_POINT()));
1086 std::shared_ptr<GeomAPI_Pnt2d> anAttributePnt2d = aPoint->pnt();
1087 std::shared_ptr<GeomAPI_Pnt> anAttributePnt = sketch()->to3D(anAttributePnt2d->x(),
1088 anAttributePnt2d->y());
1090 if (myCashedShapes.find(aBaseObject) == myCashedShapes.end())
1091 fillObjectShapes(aBaseObject);
1093 const std::set<GeomShapePtr>& aShapes = myCashedShapes[aBaseObject];
1094 isValidAttribute = !aShapes.empty();
1096 if (!isValidAttribute) {
1097 bool aWasBlocked = data()->blockSendAttributeUpdated(true);
1098 aBaseObjectAttr->setValue(ObjectPtr());
1099 data()->blockSendAttributeUpdated(aWasBlocked);