public override void WriteXml(Matrix documentTrans) { Debug.Assert(iTrimmedCurves != null); Debug.Assert(iTrimmedCurves.Count > 0); string pathData = MoveTo(documentTrans * iTrimmedCurves[0].StartPoint); foreach (ITrimmedCurve curve in iTrimmedCurves) { ITrimmedCurve iTrimmedCurve = curve; Line line = iTrimmedCurve.Geometry as Line; if (line != null) { pathData += LineTo(documentTrans * iTrimmedCurve.EndPoint); continue; } if (iTrimmedCurve.Geometry is Circle || iTrimmedCurve.Geometry is Ellipse) { ITrimmedCurve iTrimmedEllipse = iTrimmedCurve.ProjectToPlane(Plane.PlaneXY); Ellipse ellipse = iTrimmedEllipse.Geometry as Ellipse; if (ellipse == null) { ellipse = ((Circle)iTrimmedEllipse.Geometry).AsEllipse(); } Debug.Assert(ellipse != null); Debug.Assert(iTrimmedEllipse.Bounds.Span > 0); // interval should always be positive for SC ellipses Debug.Assert(!iTrimmedEllipse.IsReversed); double majorRadius = documentTrans.Scale * Math.Max(ellipse.MajorRadius, ellipse.MinorRadius); double minorRadius = documentTrans.Scale * Math.Min(ellipse.MajorRadius, ellipse.MinorRadius); double x = Vector.Dot(ellipse.Frame.DirX.UnitVector, Direction.DirX.UnitVector); double y = Vector.Dot(ellipse.Frame.DirX.UnitVector, Direction.DirY.UnitVector); pathData += ArcTo( majorRadius, minorRadius, Math.Atan2(y, x) * 180 / Math.PI, iTrimmedEllipse.Bounds.Span > Math.PI, Direction.Equals(Direction.DirZ, ellipse.Frame.DirZ), documentTrans * iTrimmedEllipse.EndPoint ); continue; } NurbsCurve nurbsCurve = iTrimmedCurve.Geometry as NurbsCurve; if (nurbsCurve == null) { ProceduralCurve proceduralCurve = iTrimmedCurve.Geometry as ProceduralCurve; if (proceduralCurve != null) { nurbsCurve = proceduralCurve.AsSpline(iTrimmedCurve.Bounds); } } if (nurbsCurve != null) { Debug.Assert(nurbsCurve.Data.Degree == 3); SelectFragmentResult result = null; CurveSegment fullNurbsCurve = CurveSegment.Create(nurbsCurve); List <ITrimmedCurve> pointCurves = nurbsCurve.Data.Knots .Where(k => iTrimmedCurve.Bounds.Contains(k.Parameter)) .Select(k => ((ITrimmedCurve)(nurbsCurve.Evaluate(k.Parameter).Point.AsCurveSegment()))) .ToList <ITrimmedCurve>(); pointCurves.Insert(0, nurbsCurve.Evaluate(iTrimmedCurve.Bounds.Start).Point.AsCurveSegment()); pointCurves.Add(nurbsCurve.Evaluate(iTrimmedCurve.Bounds.End).Point.AsCurveSegment()); for (int i = 0; i < pointCurves.Count - 1; i++) { //try { result = fullNurbsCurve.SelectFragment(( nurbsCurve.ProjectPoint(pointCurves[i].StartPoint).Param + nurbsCurve.ProjectPoint(pointCurves[i + 1].StartPoint).Param ) / 2, pointCurves); //} //catch { // Debug.Assert(false, "Attempted to trim curve out of bounds."); // WriteBlock.ExecuteTask("SVG Exception Curves", () => DesignCurve.Create(Window.ActiveWindow.Scene as Part, iTrimmedCurve)); // break; //} if (result != null) { NurbsCurve fragment = result.SelectedFragment.Geometry as NurbsCurve; WriteBlock.ExecuteTask("curve", delegate { fragment.Print(); }); pathData += CubicBézierTo(documentTrans * fragment.ControlPoints[1].Position, documentTrans * fragment.ControlPoints[2].Position, documentTrans * fragment.ControlPoints[3].Position); } } continue; } PointCurve pointCurve = iTrimmedCurve.Geometry as PointCurve; if (pointCurve != null) { continue; } // Handle Polygons, which are not in the API foreach (Point point in iTrimmedCurve.Geometry.GetPolyline(iTrimmedCurve.Bounds).Skip(1)) { pathData += LineTo(documentTrans * point); } continue; // throw new NotSupportedException("Unhandled iTrimmedCurve"); } if (isClosed) { pathData += ClosePath(); } xmlWriter.WriteStartElement("path"); xmlWriter.WriteAttributeString("d", pathData); StyleAttributes(strokeColor, fillColor, strokeWidth); xmlWriter.WriteEndElement(); }