822
823
j->retractArcHandles();
824
825
case SEGMENT_CUBIC_BEZIER:
825
if (!j->front()->isDegenerate() || !k->back()->isDegenerate())
826
if (!j->front()->isDegenerate() || !k->back()->isDegenerate()){
827
// Already a cubic bezier
830
if (!j->arc_rx()->isDegenerate() || !j->arc_ry()->isDegenerate()){
831
// This is an elliptical arc that is being converted to a cubic bezier
832
// Generate the bezier path and use it to replace the current segment
833
Geom::Path cubicbezier_path = Geom::cubicbezierpath_from_sbasis(j->getEllipticalArc().toSBasis(), 0.1);
834
replaceSegmentWithPath(j, cubicbezier_path);
827
838
// move both handles to 1/3 of the line
828
839
j->front()->move(j->position() + (k->position() - j->position()) / 3);
829
840
k->back()->move(k->position() + (j->position() - k->position()) / 3);
1164
/** Replace a segment with a path.
1165
* @param segment The segment to replace
1166
* @param newPath The path to insert in place of 'segment'
1168
* Currently, newPath must be composed only of cubic beziers, the caller must
1169
* ensure that the path only contains cubic beziers (until other segments are
1170
* implemented in this function) */
1171
void PathManipulator::replaceSegmentWithPath(NodeList::iterator segment, Geom::Path newPath)
1173
if (!segment) throw std::invalid_argument("Invalid iterator for replacement");
1174
NodeList &list = NodeList::get(segment);
1175
NodeList::iterator second = segment.next();
1176
if (!second) throw std::invalid_argument("Replace after last node in open path");
1178
// Retract all handles relating to this segment
1179
segment->retractArcHandles();
1180
segment->front()->retract();
1182
// get the insertion point
1183
NodeList::iterator insert_at = segment;
1186
// Keep the previous node handy to update its handles when needed
1187
Node *prevNode = &(*insert_at);
1189
// Path is to be inserted in reverse order
1190
Geom::Path reversedPath = newPath.reversed();
1192
// Iterate over the path
1193
for (Geom::Path::iterator i = reversedPath.begin(); i != reversedPath.end(); ++i){
1194
const Geom::Curve & thisCurve = *i;
1196
// Try converting to a bezier
1197
const Geom::BezierCurve * bezier = dynamic_cast<const Geom::BezierCurve*>(&thisCurve);
1199
// Check order of bezier (currently only cubic beziers are supported)
1200
if (bezier->order() == 3)
1202
// Create one new node
1203
Node *newNode = new Node(_multi_path_manipulator._path_data.node_data, bezier->finalPoint());
1204
// Set the control points for this node and the previous node
1205
newNode->front() ->setPosition((*bezier)[2]);
1206
prevNode->back()->setPosition((*bezier)[1]);
1207
// All new nodes are smooth
1208
newNode->setType(NODE_SMOOTH, false);
1211
list.insert(insert_at, newNode);
1212
// Move along to next node
1217
// TODO, Is there a better exception to raise here?
1218
// TODO, implement this if needed in future
1219
throw std::invalid_argument("Only cubic bezier curves are implemented in PathManipulator::replaceSegment."
1220
" newPath contains beziers with order!=3.");
1225
// TODO, Is there a better exception to raise here?
1226
// TODO, implement this if needed in future
1227
throw std::invalid_argument("Only cubic bezier curves are implemented in PathManipulator::replaceSegment."
1228
" newPath contains non-bezier segments.");
1153
1233
/** Called by the XML observer when something else than us modifies the path. */
1154
1234
void PathManipulator::_externalChange(unsigned type)