+ std::shared_ptr<GeomAPI_Pnt> aProjectedPoint;
+ if (ModelGeomAlgo_Point2D::isPointOnEdge(aShape, aPoint, aProjectedPoint))
+ aResultForCoincidence = anAddtionalResult;
+ }
+ aCoincFeature->refattr(anAttributeId)->setObject(aResultForCoincidence);
+ }
+#ifdef DEBUG_SPLIT
+ std::cout << " -" << getFeatureInfo(aCoincFeature) << std::endl;
+#endif
+ }
+}
+
+void SketchPlugin_ConstraintSplit::updateRefFeatureConstraints(
+ const ResultPtr& theFeatureBaseResult,
+ const std::list<AttributePtr>& theRefsToFeature)
+{
+ std::list<AttributePtr>::const_iterator anIt = theRefsToFeature.begin(),
+ aLast = theRefsToFeature.end();
+ for (; anIt != aLast; anIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*anIt);
+ if (aRefAttr.get())
+ aRefAttr->setObject(theFeatureBaseResult);
+ }
+}
+
+void SketchPlugin_ConstraintSplit::updateRefAttConstraints(
+ const std::map<AttributePtr, std::list<AttributePtr> >& theBaseRefAttributes,
+ const std::set<std::pair<AttributePtr, AttributePtr> >& theModifiedAttributes)
+{
+#ifdef DEBUG_SPLIT
+ std::cout << "SketchPlugin_ConstraintSplit::updateRefAttConstraints" << std::endl;
+#endif
+
+ std::set<std::pair<AttributePtr, AttributePtr> >::const_iterator
+ anIt = theModifiedAttributes.begin(), aLast = theModifiedAttributes.end();
+ for (; anIt != aLast; anIt++) {
+ AttributePtr anAttribute = anIt->first;
+
+ /// not found in references
+ if (theBaseRefAttributes.find(anAttribute) == theBaseRefAttributes.end())
+ continue;
+ std::list<AttributePtr> aRefAttributes = theBaseRefAttributes.at(anAttribute);
+ std::list<AttributePtr>::const_iterator aRefIt = aRefAttributes.begin(),
+ aRLast = aRefAttributes.end();
+
+ AttributePtr aNewAttribute = anIt->second;
+ for (; aRefIt != aRLast; aRefIt++) {
+ AttributeRefAttrPtr aRefAttr = std::dynamic_pointer_cast<ModelAPI_AttributeRefAttr>(*aRefIt);
+ if (aRefAttr.get()) {
+ aRefAttr->setAttr(aNewAttribute);
+#ifdef DEBUG_SPLIT
+ FeaturePtr aFeature = ModelAPI_Feature::feature(aRefAttr->owner());
+ std::cout << " -" << getFeatureInfo(aFeature) << std::endl;
+#endif
+ }
+ }
+ }
+}
+
+void SketchPlugin_ConstraintSplit::splitLine(FeaturePtr& theSplitFeature,
+ FeaturePtr& theBaseFeatureModified,
+ FeaturePtr& theAfterFeature,
+ std::set<AttributePoint2DPtr>& thePoints,
+ std::set<FeaturePtr>& theCreatedFeatures,
+ std::set<std::pair<AttributePtr, AttributePtr>>& theModifiedAttributes)
+{
+ std::set<FeaturePtr> aCreatedFeatures;
+ FeaturePtr aConstraintFeature;
+ theBaseFeatureModified = FeaturePtr(); // it will contain modified base feature
+
+ SketchPlugin_Sketch* aSketch = sketch();
+ if (!aSketch)
+ return;
+
+ AttributeReferencePtr aBaseObjectAttr = std::dynamic_pointer_cast<ModelAPI_AttributeReference>(
+ data()->attribute(SketchPlugin_Constraint::VALUE()));
+ FeaturePtr aBaseFeature = ModelAPI_Feature::feature(aBaseObjectAttr->value());
+ std::string aFeatureKind = aBaseFeature->getKind();
+ if (aFeatureKind != SketchPlugin_Line::ID())
+ return;
+
+ AttributePoint2DPtr aFirstPointAttrOfSplit =
+ getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_A()));
+ AttributePoint2DPtr aSecondPointAttrOfSplit =
+ getPointOfRefAttr(data()->attribute(SketchPlugin_Constraint::ENTITY_B()));
+ AttributePoint2DPtr aStartPointAttrOfBase, anEndPointAttrOfBase;
+
+ getFeaturePoints(aBaseFeature, aStartPointAttrOfBase, anEndPointAttrOfBase);
+ if (!aStartPointAttrOfBase.get() && !anEndPointAttrOfBase.get()) {
+ setError("Error: Feature has no start and end points.");
+ return;
+ }
+
+ arrangePointsOnLine(aStartPointAttrOfBase, anEndPointAttrOfBase,
+ aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
+
+#ifdef DEBUG_SPLIT
+ std::cout << "Arranged points (to build split between 1st and 2nd points:" << std::endl;
+ std::cout << "Start point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aStartPointAttrOfBase) << std::endl;
+ std::cout << "1st point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aFirstPointAttrOfSplit) << std::endl;
+ std::cout << "2nd point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(aSecondPointAttrOfSplit) << std::endl;
+ std::cout << "End point: " <<
+ ModelGeomAlgo_Point2D::getPointAttributeInfo(anEndPointAttrOfBase) << std::endl;
+#endif
+
+ /// create a split feature
+ theSplitFeature =
+ createLineFeature(aBaseFeature, aFirstPointAttrOfSplit, aSecondPointAttrOfSplit);
+ theCreatedFeatures.insert(theSplitFeature);
+
+ // before split feature
+ if (aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) {
+ theModifiedAttributes.insert(std::make_pair(aStartPointAttrOfBase,
+ theSplitFeature->attribute(SketchPlugin_Line::START_ID())));
+ }
+ else {
+ theBaseFeatureModified = aBaseFeature; ///< use base feature to store all constraints here
+ /// move end arc point to start of split
+ }
+
+ // after split feature
+ if (!aSecondPointAttrOfSplit->pnt()->isEqual(anEndPointAttrOfBase->pnt())) {
+ FeaturePtr aFeature;
+ if (!theBaseFeatureModified.get()) {
+ aFeature = aBaseFeature; ///< use base feature to store all constraints here
+ fillAttribute(aFeature->attribute(SketchPlugin_Line::START_ID()), aSecondPointAttrOfSplit);
+ aFeature->execute(); // to update result
+ }
+ else {
+ aFeature = createLineFeature(aBaseFeature, aSecondPointAttrOfSplit, anEndPointAttrOfBase);
+ theCreatedFeatures.insert(aFeature);
+ theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase,
+ aFeature->attribute(SketchPlugin_Line::END_ID())));
+ }
+ aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+ theSplitFeature->attribute(SketchPlugin_Line::END_ID()),
+ aFeature->attribute(SketchPlugin_Line::START_ID()));
+ theCreatedFeatures.insert(aConstraintFeature);
+
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aFeature->attribute(SketchPlugin_Line::START_ID())));
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (aFeature->attribute(SketchPlugin_Line::END_ID())));
+
+ if (!theBaseFeatureModified.get())
+ theBaseFeatureModified = aFeature;
+ else
+ theAfterFeature = aFeature;
+ }
+ else {
+ thePoints.insert(std::dynamic_pointer_cast<GeomDataAPI_Point2D>
+ (theSplitFeature->attribute(SketchPlugin_Line::END_ID())));
+ theModifiedAttributes.insert(std::make_pair(anEndPointAttrOfBase,
+ theSplitFeature->attribute(SketchPlugin_Line::END_ID())));
+ }
+ // base split, that is defined before split feature should be changed at end
+ // (after the after feature creation). Otherwise modified value will be used in after feature
+ // before split feature
+ if (!aStartPointAttrOfBase->pnt()->isEqual(aFirstPointAttrOfSplit->pnt())) {
+ /// move end arc point to start of split
+ fillAttribute(theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()),
+ aFirstPointAttrOfSplit);
+ theBaseFeatureModified->execute(); // to update result
+ aConstraintFeature = createConstraint(SketchPlugin_ConstraintCoincidence::ID(),
+ theBaseFeatureModified->attribute(SketchPlugin_Line::END_ID()),
+ theSplitFeature->attribute(SketchPlugin_Line::START_ID()));
+ theCreatedFeatures.insert(aConstraintFeature);