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); } } }
public static void test_convex_hull_2() { Random r = new Random(31337); //LocalProfiler p = new LocalProfiler(); //p.Start("Hulls"); QueryNumberType[] modes = new QueryNumberType[] { QueryNumberType.QT_DOUBLE, QueryNumberType.QT_INT64 }; foreach (var queryMode in modes) { for (int k = 0; k < 1000; ++k) { int N = 2500; double scale = (r.NextDouble() + 0.1) * 1024.0; Vector2d[] pts = TestUtil.RandomPoints2(N, r, Vector2d.Zero, scale); double eps = MathUtil.Epsilonf; ConvexHull2 hull = new ConvexHull2(pts, eps, queryMode); Polygon2d hullPoly = hull.GetHullPolygon(); foreach (Vector2d v in pts) { if (hullPoly.Contains(v)) { continue; } double d = hullPoly.DistanceSquared(v); if (d < eps) { continue; } System.Console.WriteLine("test_convex_hull: Point {0} not contained!", v); } } } //p.StopAll(); //System.Console.WriteLine(p.AllTimes()); //SVGWriter writer = new SVGWriter(); //foreach (Vector2d v in pts) { // writer.AddCircle(new Circle2d(v, 3.0), SVGWriter.Style.Outline("black", 1.0f)); //} //writer.AddPolygon(hullPoly, SVGWriter.Style.Outline("red", 2.0f)); //writer.Write(TestUtil.GetTestOutputPath("test.svg")); }
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(); }