/// <summary> /// Creates outline curves from the path curves computed by Potrace. /// Also cooks up the conduit bounding box. /// </summary> private int CreateOutlineCurves() { OutlineCurves.Clear(); // The first curve is always the border curve no matter what var corners = new Point3d[] { Point3d.Origin, new Point3d(m_bitmap.Width, 0.0, 0.0), new Point3d(m_bitmap.Width, m_bitmap.Height, 0.0), new Point3d(0.0, m_bitmap.Height, 0.0), Point3d.Origin }; var border = new PolylineCurve(corners); OutlineCurves.Add(border); foreach (var path_curve in m_path_curves) { switch (GetPathCurveType(path_curve)) { case PathCurveType.LineCurve: { var curve = path_curve[0].ToLineCurve(); if (null != curve && curve.IsValid && !curve.IsShort(m_tolerance)) { OutlineCurves.Add(curve); } } break; case PathCurveType.BezierCurve: { var curve = path_curve[0].ToNurbsCurve(); if (null != curve && curve.IsValid && !curve.IsShort(m_tolerance)) { OutlineCurves.Add(curve); } } break; case PathCurveType.PolylineCurve: { var points = new List <Point3d>(); for (var i = 0; i < path_curve.Count; i++) { if (i == 0) { points.Add(path_curve[i].A.ToPoint3d()); } points.Add(path_curve[i].B.ToPoint3d()); } var curve = new PolylineCurve(points); curve.MakeClosed(m_tolerance); curve.RemoveShortSegments(m_tolerance); if (curve.IsValid && !curve.IsShort(m_tolerance)) { OutlineCurves.Add(curve); } } break; case PathCurveType.PolyCurve: { var curve = new PolyCurve(); foreach (var path in path_curve) { if (path.Kind == CurveKind.Line) { var c = path.ToLineCurve(); if (null != c && c.IsValid && !c.IsShort(m_tolerance)) { curve.Append(c); } } else { var c = path.ToNurbsCurve(); if (null != c && c.IsValid && !c.IsShort(m_tolerance)) { curve.Append(c); } } } curve.MakeClosed(m_tolerance); curve.RemoveShortSegments(m_tolerance); if (curve.IsValid && !curve.IsShort(m_tolerance)) { OutlineCurves.Add(curve); } } break; } } if (OutlineCurves.Count > 0) { // Just use the border curve m_bbox = OutlineCurves[0].GetBoundingBox(true); //for (var i = 0; i < OutlineCurves.Count; i++) // m_bbox.Union(OutlineCurves[i].GetBoundingBox(true)); } // The origin of the bitmap coordinate system is at the top-left corner of the bitmap. // So, create a mirror transformation so the output is oriented to Rhino's world xy plane. var mirror = Transform.Mirror(m_bbox.Center, Vector3d.YAxis); m_bbox.Transform(mirror); for (var i = 0; i < OutlineCurves.Count; i++) { OutlineCurves[i].Transform(mirror); } // Scale the output, per the calculation made in the command. if (m_scale != 1.0) { var scale = Transform.Scale(Point3d.Origin, m_scale); m_bbox.Transform(scale); for (var i = 0; i < OutlineCurves.Count; i++) { OutlineCurves[i].Transform(scale); } } return(OutlineCurves.Count); }