internal static double[][] PtsFromOffsetRectangle(List <Point3d> plist, double offsetdistance) { double[][] ptz = new double[4][]; for (int i = 0; i < 4; i++) { ptz[i] = new double[2]; ptz[i][0] = plist[i].X; ptz[i][1] = plist[i].Y; } double[] dblcen = Misc.Centroid(ptz); Point3d cen = new Point3d(dblcen[0], dblcen[1], 0); plist.Add(plist[0]); PolylineCurve crv = new PolylineCurve(plist); crv.MakeClosed(0.001); Curve[] offsetcr = crv.Offset(cen, Vector3d.ZAxis, offsetdistance, 0.001, CurveOffsetCornerStyle.None); PolylineCurve offsetpl = offsetcr[0].ToPolyline(0, 0, 0, System.Double.MaxValue, 0, 0.001, 0, 0, true); Point3d offsetpt0 = offsetpl.Point(0); Point3d offsetpt1 = offsetpl.Point(1); Point3d offsetpt2 = offsetpl.Point(2); Point3d offsetpt3 = offsetpl.Point(3); return(new double[][] { new double[] { offsetpt0.X, offsetpt0.Y }, new double[] { offsetpt1.X, offsetpt1.Y }, new double[] { offsetpt2.X, offsetpt2.Y }, new double[] { offsetpt3.X, offsetpt3.Y } }); }
/// <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); }
public static Dictionary <OSMTag, List <Brep> > BuildingBrepsFromCoords(ref RequestHandler result, bool outputHeighted) { var geometryResult = new Dictionary <OSMTag, List <Brep> >(); var unitScale = RhinoMath.UnitScale(UnitSystem.Meters, RhinoDoc.ActiveDoc.ModelUnitSystem); // OSM conversion assumes meters var tolerance = RhinoDoc.ActiveDoc.ModelAbsoluteTolerance; Coord lengthPerDegree = GetDegreesPerAxis(result.MinBounds, result.MaxBounds, unitScale); foreach (var entry in result.FoundData) { geometryResult[entry.Key] = new List <Brep>(); for (int i = entry.Value.Count - 1; i >= 0; i--) { var outlinePoints = new List <Point3d>(); foreach (var coord in entry.Value[i].Coords) { outlinePoints.Add(GetPointFromLatLong(coord, lengthPerDegree, result.MinBounds)); } var outline = new PolylineCurve(outlinePoints); // Creating a polylinecurve from scratch makes invalid geometry if (!outline.IsClosed) { if (outline.IsClosable(ALLOWABLE_CLOSURE)) // Force-close the curve { outline.MakeClosed(ALLOWABLE_CLOSURE); } else // Skip this curve as no valid Brep can be made { entry.Value.RemoveAt(i); continue; } } var height = GetBuildingHeights.ParseHeight(entry.Value[i].Tags, unitScale); if (outputHeighted && height > 0.0) // Output heighted buildings { var toHeight = new Vector3d(0, 0, height); var envelope = Surface.CreateExtrusion(outline, toHeight); var floor = Brep.CreatePlanarBreps(outline, tolerance); outline.Translate(toHeight); var roof = Brep.CreatePlanarBreps(outline, tolerance); var volume = Brep.JoinBreps(new Brep[] { floor[0], envelope.ToBrep(), roof[0] }, tolerance); geometryResult[entry.Key].Add(volume[0]); } else if (!outputHeighted && height == 0.0) // Output unheighted buildings { var builtSurface = Brep.CreatePlanarBreps(outline, tolerance); if (builtSurface != null && builtSurface.Length > 0) { geometryResult[entry.Key].Add(builtSurface[0]); } } else // Item wasn't matched, so should be removed from result so its metadata is not output { entry.Value.RemoveAt(i); } } geometryResult[entry.Key].Reverse(); // We iterated in reverse order, so swap list back to right direction } return(geometryResult); }