/// <summary> /// Triangulates the given object and parses the result to the builder. /// </summary> /// <param name="autoOptimize">Determine weather or not to use grid refinement, lazy cube evaluation and another sized grid - based on the given SDF.</param> /// <returns></returns> public virtual IPolygon Run(SDF obj, IPolygonBuilder builder, bool autoOptimize) { /// Setup! if (autoOptimize) { Optimize(obj); } _obj = obj; _builder = builder; if (builder is GridLog) { _log = builder as GridLog; _useLogging = true; } if (useRefinement) { GridRefinement(); } else { _halfStep = new Vec3(_step / 2, _step / 2, _step / 2); _lazy = _halfStep.Magnitude() * 1.001f; Initialize(); GridLoop(); } return(_builder.Build()); }
public static bool Import(string filename, IPolygonBuilder builder) { var verts = new List <Vec3>(); using (StreamReader _stream = new StreamReader(filename)) { while (!_stream.EndOfStream) { string[] subString = _stream.ReadLine().Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries); if (subString.Count() == 0) { continue; } switch (subString[0]) { case "v": float x, y, z; if (float.TryParse(subString[1], out x) && float.TryParse(subString[2], out y) && float.TryParse(subString[3], out z)) { verts.Add(new Vec3(x, y, z)); } break; case "f": if (subString.Count() > 5) { throw new NotImplementedException("Only triangles and squares supported"); } int f1, f2, f3, f4; if (int.TryParse(subString[1].Split('/')[0], out f1) && int.TryParse(subString[2].Split('/')[0], out f2) && int.TryParse(subString[3].Split('/')[0], out f3)) { if (subString.Length == 5 && int.TryParse(subString[4].Split('/')[0], out f4)) { builder.Append(verts[f1 - 1], verts[f2 - 1], verts[f3 - 1]); builder.Append(verts[f3 - 1], verts[f4 - 1], verts[f1 - 1]); } else { builder.Append(verts[f1 - 1], verts[f2 - 1], verts[f3 - 1]); } } break; } } } return(true); }
/// <summary> /// Runs Polychop on the given mesh until the cost of removing a vertex exceeds the tolerance. /// Cost is calculated as curvature * length of edge to collapse. /// </summary> /// <param name="mesh">The Polygon to run the algorithm on.</param> /// <param name="builder">Preferred builder.</param> /// <param name="iterations">Number of iterations to run.</param> /// <returns></returns> public IPolygon Run(IPolygon mesh, IPolygonBuilder builder, int iterations) { Import(mesh); // Run algorithm var useless = _pq.Count > 0 ? _pq.Dequeue() : null; for (int i = 0; i < iterations; i++) { useless.Collapse(); useless = _pq.Count > 0 ? _pq.Dequeue() : null; } // Build foreach (T tris in _triangles) { if (tris.normal != Vec3.zero) { builder.Append(tris.vert[0].position, tris.vert[1].position, tris.vert[2].position); } } return(builder.Build()); }
/// <summary> /// Runs Polychop on the given mesh until the cost of removing a vertex exceeds the tolerance. /// Cost is calculated as curvature * length of edge to collapse. /// </summary> /// <param name="mesh">The Polygon to run the algorithm on.</param> /// <param name="builder">Preferred builder.</param> /// <param name="tolerance">Negative tolerance will result in unwanted behavior.</param> /// <returns></returns> public IPolygon Run(IPolygon mesh, IPolygonBuilder builder, float tolerance = 0.00001f) { Import(mesh); // Run algorithm var useless = _pq.Count > 0 ? _pq.Dequeue() : null; while (useless != null && useless.objDist <= tolerance) { useless.Collapse(); useless = _pq.Count > 0 ? _pq.Dequeue() : null; } // Build foreach (T tris in _triangles) { if (tris.normal != Vec3.zero) { builder.Append(tris.vert[0].position, tris.vert[1].position, tris.vert[2].position); } } return(builder.Build()); }
public static IPolygonBuilder AddVertices(this IPolygonBuilder builder, params int[] vertices) { return(builder.AddVertices((IEnumerable <int>)vertices)); }
/// <summary> /// Triangulates the given object and parses the result to the builder. /// This will optimize the current ITriangulator to use grid refinement, /// lazy cube evaluation and a correct sized grid - if possible. /// </summary> public virtual IPolygon Run(SDF obj, IPolygonBuilder builder) { return(Run(obj, builder, true)); }