protected void GetPlanarPolys(PlanarRegion r, List <Polygon2d> polys) { try { MeshRegionBoundaryLoops loops = new MeshRegionBoundaryLoops(r.Mesh, r.Triangles); foreach (var loop in loops) { DCurve3 curve = loop.ToCurve(); Polygon2d poly = new Polygon2d(); int NV = curve.VertexCount; for (int k = 0; k < NV; k++) { poly.AppendVertex(curve[k].xy); } polys.Add(poly); } } catch (Exception) { // add each triangle as a polygon and let clipper sort it out Vector3d v0 = Vector3d.Zero, v1 = Vector3d.Zero, v2 = Vector3d.Zero; foreach (int tid in r.Triangles) { r.Mesh.GetTriVertices(tid, ref v0, ref v1, ref v2); Polygon2d p = new Polygon2d(); p.AppendVertex(v0.xy); p.AppendVertex(v1.xy); p.AppendVertex(v2.xy); polys.Add(p); } } }
static void Main() { Polygon2d poly = new Polygon2d(); poly.AppendVertex(new Vector2d(0, 0)); poly.AppendVertex(new Vector2d(100, 0)); poly.AppendVertex(new Vector2d(100, 100)); poly.AppendVertex(new Vector2d(0, 1000)); }
public static void test_tiling() { Vector2d origin = Vector2d.Zero; double radius = 22; Circle2d circ = new Circle2d(origin, radius); AxisAlignedBox2d elemBounds = circ.Bounds; //elemBounds.Max.x += radius / 2; AxisAlignedBox2d packBounds = new AxisAlignedBox2d(0, 0, 800, 400); double spacing = 5; Polygon2d boundsPoly = new Polygon2d(); for (int i = 0; i < 4; ++i) { boundsPoly.AppendVertex(packBounds.GetCorner(i)); } //List<Vector2d> packed = TilingUtil.BoundedRegularTiling2(elemBounds, packBounds, spacing); List <Vector2d> packed = TilingUtil.BoundedCircleTiling2(elemBounds, packBounds, spacing); System.Console.WriteLine("packed {0}", packed.Count); SVGWriter writer = new SVGWriter(); foreach (Vector2d t in packed) { writer.AddCircle(new Circle2d(origin + t, radius), SVGWriter.Style.Outline("black", 1.0f)); } writer.AddPolygon(boundsPoly, SVGWriter.Style.Outline("red", 2.0f)); writer.Write(TestUtil.GetTestOutputPath("test.svg")); }
public static void TestOffsetAnimation() { Window window = new Window("TestFill"); window.SetDefaultSize(600, 600); window.SetPosition(WindowPosition.Center); DMesh3 mesh = StandardMeshReader.ReadMesh("c:\\scratch\\remesh.obj"); MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh); DCurve3 curve = loops[0].ToCurve(); Polygon2d poly = new Polygon2d(); foreach (Vector3d v in curve.Vertices) { poly.AppendVertex(v.xy); } Outer = new GeneralPolygon2d(poly); DebugViewCanvas view = new DebugViewCanvas(); view.AddPolygon(Outer, Colorf.Black); DGraph2 graph = TopoOffset2d.QuickCompute(Outer, AnimOffset, AnimSpacing); view.AddGraph(graph, Colorf.Red); window.Add(view); window.ShowAll(); Active = view; }
public Polygon2d GetPolygon(bool update = true) { if (update) { Update(); } Polygon2d poly = new Polygon2d(); for (int i = 0; i < ellipse.Length; i++) { Vector2 p = ellipse[i]; if (animationEnabled) { foreach (Attractor v in attractors) { p = v.Apply(p); } p = ellipse[i] + (p - ellipse[i]) * distrStrength; float aC = Mathf.Max(0f, ceilRange - Vector2.Angle(Vector2.up, p)) / ceilRange; p.y += (Random.value - 0.5f) * aC * cNoise * noiseScale; float aF = Mathf.Max(0f, floorRange - Vector2.Angle(Vector2.down, p)) / floorRange; p.y += (Random.value - 0.5f) * aF * fNoise * noiseScale; } poly.AppendVertex(p); } //Draw(poly); return(poly); }
public List <GeneralPolygon2d> GetSolids() { Frame3f f = frameL; if (OutputSpace != CoordSpace.ObjectCoords) { f = SceneTransforms.TransformTo(f, SO, CoordSpace.ObjectCoords, OutputSpace); } PlanarComplex complex = new PlanarComplex(); foreach (DCurve3 c in localCurves.Loops) { Polygon2d poly = new Polygon2d(); for (int i = 0; i < c.VertexCount; ++i) { Vector2f uv = f.ToPlaneUV((Vector3f)c[i], 2); poly.AppendVertex(uv); } complex.Add(poly); } PlanarComplex.FindSolidsOptions options = PlanarComplex.FindSolidsOptions.SortPolygons; var info = complex.FindSolidRegions(options); return(info.Polygons); }
/// <summary> /// Construct the set of polygons-with-holes that represents the input string /// </summary> static List <GeneralPolygon2d> GetPolygons(string s, string fontName = "Consolas", FontStyle style = FontStyle.Regular, int emSize = 128) { GraphicsPath path = new GraphicsPath(); string text = s; FontFamily font = new FontFamily(fontName); Point origin = new Point(0, 0); StringFormat format = new StringFormat(); path.AddString(text, font, (int)style, emSize, origin, format); path.Flatten(); PlanarComplex complex = new PlanarComplex(); Polygon2d cur_poly = new Polygon2d(); for (int i = 0; i < path.PathPoints.Length; ++i) { PointF pt = path.PathPoints[i]; Vector2d v = new Vector2d(pt.X, pt.Y); int type = path.PathTypes[i] & 0x7; int flags = path.PathTypes[i] & 0xF8; if (type == 0) { cur_poly = new Polygon2d(); cur_poly.AppendVertex(v); } else if (type == 1) { cur_poly.AppendVertex(v); if ((flags & 0x80) != 0) { // [RMS] some characters have a duplicate start/end point after Flatten(). Some do not. Clusterfuck! int iLast = cur_poly.VertexCount - 1; if (cur_poly[0].Distance(cur_poly[iLast]) < 0.001) { cur_poly.RemoveVertex(iLast); // we just duplicated first point } complex.Add(cur_poly); } } } PlanarComplex.SolidRegionInfo solids = complex.FindSolidRegions(0.0f, false); List <GeneralPolygon2d> result = solids.Polygons; foreach (var gp in result) { gp.Transform((v) => { return(new Vector2d(v.x, emSize - v.y)); }); } return(result); }
public static void compute_distance_image() { DMesh3 mesh = StandardMeshReader.ReadMesh("c:\\scratch\\remesh.obj"); MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh); DCurve3 curve = loops[0].ToCurve(); Polygon2d poly = new Polygon2d(); foreach (Vector3d v in curve.Vertices) { poly.AppendVertex(v.xy); } int N = 1024; double cellsize = poly.Bounds.MaxDim / (double)N; Vector2d o = poly.Bounds.Min; o -= 4 * cellsize * Vector2d.One; N += 8; ShiftGridIndexer2 indexer = new ShiftGridIndexer2(poly.Bounds.Min, cellsize); double[] df = new double[N * N]; double maxd = 0; for (int yi = 0; yi < N; ++yi) { for (int xi = 0; xi < N; ++xi) { Vector2d p = indexer.FromGrid(new Vector2i(xi, yi)); double d = Math.Sqrt(poly.DistanceSquared(p)); df[yi * N + xi] = d; maxd = Math.Max(d, maxd); } } SKBitmap bmp = new SKBitmap(N, N); for (int yi = 0; yi < N; ++yi) { for (int xi = 0; xi < N; ++xi) { double d = df[yi * N + xi]; float f = (float)(d / maxd); byte b = (byte)(int)(f * 255); bmp.SetPixel(xi, yi, new SKColor(b, b, b)); } } using (var image = SKImage.FromBitmap(bmp)) using (var data = image.Encode(SKEncodedImageFormat.Png, 80)) { // save the data to a stream using (var stream = File.OpenWrite("c:\\scratch\\distances.png")) { data.SaveTo(stream); } } }
Polygon2d make_poly(DMesh3 mesh, EdgeLoop loop) { Polygon2d poly = new Polygon2d(); for (int k = 0; k < loop.VertexCount; ++k) { Vector3d v = mesh.GetVertex(loop.Vertices[k]); poly.AppendVertex(v.xy); } return(poly); }
Polygon2d to_polygon(EdgeSpan span, Frame3f polyFrame) { int NV = span.VertexCount; Polygon2d poly = new Polygon2d(); for (int k = 0; k < NV; ++k) { poly.AppendVertex(polyFrame.ToPlaneUV((Vector3f)span.GetVertex(k), 2)); } return(poly); }
public static void Restore(Polygon2d polygon, BinaryReader reader) { int count = reader.ReadInt32(); for (int i = 0; i < count; ++i) { double x = reader.ReadDouble(); double y = reader.ReadDouble(); polygon.AppendVertex(new Vector2D(x, y)); } }
public Cvt(IReadOnlyCollection <Vertex> polygon, CvtSettings settings) { if (settings == null) { throw new ArgumentException("Please, define CvtSettings object"); } Polygon = new Polygon2d(); foreach (Vertex vertex in polygon) { Polygon.AppendVertex(new Vector2d(vertex.X, vertex.Y)); } Settings = settings; }
public static Polygon2d ConvertFromClipper(CPolygon clipper_poly, double nIntScale) { double scale = 1.0 / (double)nIntScale; int N = clipper_poly.Count; Polygon2d poly = new Polygon2d(); for (int i = 0; i < N; ++i) { IntPoint p = clipper_poly[i]; Vector2d v = new Vector2d((double)p.X * scale, (double)p.Y * scale); poly.AppendVertex(v); } return(poly); }
/// <summary> /// create Polygon by projecting polygon3 into frame /// </summary> public MeshInsertProjectedPolygon(DMesh3 mesh, DCurve3 polygon3, Frame3f frame, int seedTri) { if (polygon3.Closed == false) { throw new Exception("MeshInsertPolyCurve(): only closed polygon3 supported for now"); } Mesh = mesh; ProjectFrame = frame; SeedTriangle = seedTri; Polygon = new Polygon2d(); foreach (Vector3d v3 in polygon3.Vertices) { Vector2f uv = frame.ToPlaneUV((Vector3f)v3, 2); Polygon.AppendVertex(uv); } }
static GeneralPolygon2d GetPolygonFromMesh(string sPath) { DMesh3 mesh = StandardMeshReader.ReadMesh(sPath); MeshBoundaryLoops loops = new MeshBoundaryLoops(mesh); PlanarComplex complex = new PlanarComplex(); foreach (var loop in loops) { Polygon2d poly = new Polygon2d(); DCurve3 curve = MeshUtil.ExtractLoopV(mesh, loop.Vertices); foreach (Vector3d v in curve.Vertices) { poly.AppendVertex(v.xy); } complex.Add(poly); } PlanarComplex.SolidRegionInfo solids = complex.FindSolidRegions(0.0, false); return(solids.Polygons[0]); }
public List <Polygon2d> GetPolygons() { Frame3f f = frameL; if (OutputSpace != CoordSpace.ObjectCoords) { f = SceneTransforms.TransformTo(f, SO, CoordSpace.ObjectCoords, OutputSpace); } List <Polygon2d> polygons = new List <Polygon2d>(); foreach (DCurve3 c in localCurves.Loops) { Polygon2d poly = new Polygon2d(); for (int i = 0; i < c.VertexCount; ++i) { Vector2f uv = f.ToPlaneUV((Vector3f)c[i], 2); poly.AppendVertex(uv); } polygons.Add(poly); } return(polygons); }
public static void test_uv_insert_segment() { DMesh3 mesh = TestUtil.LoadTestInputMesh("plane_250v.obj"); mesh.EnableVertexUVs(Vector2f.Zero); MeshTransforms.ConvertYUpToZUp(mesh); DMeshAABBTree3 spatial = new DMeshAABBTree3(mesh); spatial.Build(); int tid = spatial.FindNearestTriangle(Vector3d.Zero); //Polygon2d poly = Polygon2d.MakeRectangle(Vector2d.Zero, 5, 5); Polygon2d poly = Polygon2d.MakeCircle(5, 13); //PolyLine2d poly = new PolyLine2d( new Vector2d[] { -5 * Vector2d.One, 5 * Vector2d.One }); //int tri_edge0 = mesh.GetTriEdge(tid, 0); //Index2i edge0_tris = mesh.GetEdgeT(tri_edge0); //Index2i edge0_verts = mesh.GetEdgeV(tri_edge0); //Vector3d v0 = mesh.GetVertex(edge0_verts.a), v1 = mesh.GetVertex(edge0_verts.b); //Vector3d c = mesh.GetTriCentroid(tid); //Polygon2d poly = new Polygon2d(new Vector2d[] { // Vector2d.Lerp(v0.xy, v1.xy, -0.25), // Vector2d.Lerp(v0.xy, v1.xy, 1.5), // c.xy //}); MeshInsertUVPolyCurve insert = new MeshInsertUVPolyCurve(mesh, poly); insert.Apply(); Polygon2d test_poly = new Polygon2d(); List <double> distances = new List <double>(); List <int> nearests = new List <int>(); for (int i = 0; i < insert.Loops[0].VertexCount; ++i) { Vector2d v = mesh.GetVertex(insert.Loops[0].Vertices[i]).xy; test_poly.AppendVertex(v); int iNear; double fNear; distances.Add(poly.DistanceSquared(v, out iNear, out fNear)); nearests.Add(iNear); } System.Console.WriteLine("inserted loop poly has {0} edges", insert.Loops[0].EdgeCount); // find a triangle connected to loop that is inside the polygon // [TODO] maybe we could be a bit more robust about this? at least // check if triangle is too degenerate... int seed_tri = -1; for (int i = 0; i < insert.Loops[0].EdgeCount; ++i) { Index2i et = mesh.GetEdgeT(insert.Loops[0].Edges[i]); Vector3d ca = mesh.GetTriCentroid(et.a); bool in_a = poly.Contains(ca.xy); Vector3d cb = mesh.GetTriCentroid(et.b); bool in_b = poly.Contains(cb.xy); if (in_a && in_b == false) { seed_tri = et.a; break; } else if (in_b && in_a == false) { seed_tri = et.b; break; } } Util.gDevAssert(seed_tri != -1); // flood-fill inside loop HashSet <int> loopEdges = new HashSet <int>(insert.Loops[0].Edges); MeshFaceSelection sel = new MeshFaceSelection(mesh); sel.FloodFill(seed_tri, null, (eid) => { return(loopEdges.Contains(eid) == false); }); // delete inside loop MeshEditor editor = new MeshEditor(mesh); editor.RemoveTriangles(sel, true); MeshTransforms.ConvertZUpToYUp(mesh); TestUtil.WriteTestOutputMesh(mesh, "insert_uv_segment.obj"); //OBJWriter writer = new OBJWriter(); //var s = new System.IO.StreamWriter(Program.TEST_OUTPUT_PATH + "mesh_local_param.obj", false); //List<WriteMesh> wm = new List<WriteMesh>() { new WriteMesh(mesh) }; //WriteOptions opt = new WriteOptions() { // bCombineMeshes = false, bWriteGroups = false, bPerVertexColors = true, bPerVertexUVs = true, // AsciiHeaderFunc = () => { return "mttllib checkerboard.mtl\r\nusemtl checkerboard\r\n"; } //}; //writer.Write(s, wm, opt); //s.Close(); }
public static void test_tube_generator() { Polygon2d circle_path = Polygon2d.MakeCircle(50, 64); PolyLine2d arc_path = new PolyLine2d(circle_path.Vertices.Take(circle_path.VertexCount / 2)); Polygon2d irreg_path = new Polygon2d(); for (int k = 0; k < circle_path.VertexCount; ++k) { irreg_path.AppendVertex(circle_path[k]); k += k / 2; } PolyLine2d irreg_arc_path = new PolyLine2d(irreg_path.Vertices.Take(circle_path.VertexCount - 1)); Polygon2d square_profile = Polygon2d.MakeCircle(7, 32); square_profile.Translate(4 * Vector2d.One); //square_profile[0] = 20 * square_profile[0].Normalized; bool no_shared = true; WriteGeneratedMesh( new TubeGenerator(circle_path, Frame3f.Identity, square_profile) { WantUVs = true, NoSharedVertices = no_shared }, "tubegen_loop_standarduv.obj"); WriteGeneratedMesh( new TubeGenerator(irreg_path, Frame3f.Identity, square_profile) { WantUVs = true, NoSharedVertices = no_shared }, "tubegen_irregloop_standarduv.obj"); WriteGeneratedMesh( new TubeGenerator(arc_path, Frame3f.Identity, square_profile) { WantUVs = true, NoSharedVertices = no_shared }, "tubegen_arc_standarduv.obj"); WriteGeneratedMesh( new TubeGenerator(irreg_arc_path, Frame3f.Identity, square_profile) { WantUVs = true, NoSharedVertices = no_shared }, "tubegen_irregarc_standarduv.obj"); // append tube border around each hole of input mesh DMesh3 inMesh = TestUtil.LoadTestInputMesh("n_holed_bunny.obj"); Polygon2d bdrycirc = Polygon2d.MakeCircle(0.25, 6); MeshBoundaryLoops loops = new MeshBoundaryLoops(inMesh); foreach (EdgeLoop loop in loops) { DCurve3 curve = loop.ToCurve().ResampleSharpTurns(); TubeGenerator gen = new TubeGenerator(curve, bdrycirc) { NoSharedVertices = false }; MeshEditor.Append(inMesh, gen.Generate().MakeDMesh()); } TestUtil.WriteTestOutputMesh(inMesh, "boundary_tubes.obj"); }
// exports svg w/ different containments of point set (created by slicing mesh) public static void containment_demo_svg() { DMesh3 mesh = TestUtil.LoadTestInputMesh("bunny_solid.obj"); MeshTransforms.Scale(mesh, 4); AxisAlignedBox3d meshBounds = mesh.CachedBounds; Vector3d origin = meshBounds.Center; origin -= 0.2 * meshBounds.Height * Vector3d.AxisY; Frame3f plane = new Frame3f(origin, new Vector3d(1, 3, 0).Normalized); MeshPlaneCut cut = new MeshPlaneCut(mesh, plane.Origin, plane.Z); cut.Cut(); AxisAlignedBox2d polyBounds = AxisAlignedBox2d.Empty; List <Polygon2d> polys = new List <Polygon2d>(); foreach (EdgeLoop loop in cut.CutLoops) { Polygon2d poly = new Polygon2d(); foreach (int vid in loop.Vertices) { poly.AppendVertex(mesh.GetVertex(vid).xz); } poly.Rotate(new Matrix2d(90, true), Vector2d.Zero); polys.Add(poly); polyBounds.Contain(poly.Bounds); } SVGWriter svg = new SVGWriter(); var polyStyle = SVGWriter.Style.Outline("red", 1.0f); var contStyle = SVGWriter.Style.Outline("black", 1.0f); for (int k = 0; k < 3; ++k) { double shift = (k == 2) ? 1.4f : 1.1f; Vector2d tx = (k - 1) * (polyBounds.Width * shift) * Vector2d.AxisX; List <Vector2d> pts = new List <Vector2d>(); foreach (Polygon2d poly in polys) { var p2 = new Polygon2d(poly).Translate(tx); pts.AddRange(p2.Vertices); svg.AddPolygon(p2, polyStyle); } if (k == 0) { ConvexHull2 hull = new ConvexHull2(pts, 0.001, QueryNumberType.QT_DOUBLE); svg.AddPolygon(hull.GetHullPolygon(), contStyle); } else if (k == 1) { ContMinBox2 contbox = new ContMinBox2(pts, 0.001, QueryNumberType.QT_DOUBLE, false); svg.AddPolygon(new Polygon2d(contbox.MinBox.ComputeVertices()), contStyle); } else if (k == 2) { ContMinCircle2 contcirc = new ContMinCircle2(pts); svg.AddCircle(contcirc.Result, contStyle); } } svg.Write(TestUtil.GetTestOutputPath("contain_demos.svg")); }
public static void test_arrangement_demo() { DMesh3 mesh = TestUtil.LoadTestInputMesh("spheres_and_planes.obj"); MeshTransforms.Scale(mesh, 8); AxisAlignedBox3d meshBounds = mesh.CachedBounds; Vector3d origin = meshBounds.Center; double simplify_thresh = 5.0; Frame3f plane = new Frame3f(origin, Vector3d.AxisY); MeshPlaneCut cut = new MeshPlaneCut(mesh, plane.Origin, plane.Z); cut.Cut(); Arrangement2d builder = new Arrangement2d(new AxisAlignedBox2d(1024.0)); // insert all cut edges HashSet <Vector2d> srcpts = new HashSet <Vector2d>(); foreach (EdgeLoop loop in cut.CutLoops) { Polygon2d poly = new Polygon2d(); foreach (int vid in loop.Vertices) { poly.AppendVertex(mesh.GetVertex(vid).xz); } poly.Simplify(simplify_thresh, 0.01, true); foreach (Vector2d v in poly.Vertices) { srcpts.Add(v); } builder.Insert(poly); } foreach (EdgeSpan span in cut.CutSpans) { PolyLine2d pline = new PolyLine2d(); foreach (int vid in span.Vertices) { pline.AppendVertex(mesh.GetVertex(vid).xz); } pline.Simplify(simplify_thresh, 0.01, true); foreach (Vector2d v in pline) { srcpts.Add(v); } builder.Insert(pline); } SVGWriter svg = new SVGWriter(); svg.AddGraph(builder.Graph); var vtx_style = SVGWriter.Style.Outline("red", 1.0f); foreach (int vid in builder.Graph.VertexIndices()) { Vector2d v = builder.Graph.GetVertex(vid); if (srcpts.Contains(v) == false) { svg.AddCircle(new Circle2d(v, 2), vtx_style); } } svg.Write(TestUtil.GetTestOutputPath("arrangement.svg")); }