From a4ecbebfe61a27e59aeffb0b284162703095cdcb Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Sun, 15 Mar 2020 04:25:37 -0700 Subject: [PATCH] Added vnf_compact() and vnf_validate() --- version.scad | 2 +- vnf.scad | 136 +++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 137 insertions(+), 1 deletion(-) diff --git a/version.scad b/version.scad index 694c07d..05e42a0 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,190]; +BOSL_VERSION = [2,0,191]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index 6f217ee..5a37619 100644 --- a/vnf.scad +++ b/vnf.scad @@ -137,6 +137,21 @@ function vnf_merge(vnfs=[],_i=0,_acc=EMPTY_VNF) = ] ); +// Function: vnf_compact() +// Usage: +// cvnf = vnf_compact(vnf); +// Description: +// Takes a VNF and consolidates all duplicate vertices, and drops unreferenced vertices. +function vnf_compact(vnf) = + let( + verts = vnf[0], + faces = [ + for (face=vnf[1]) [ + for (i=face) verts[i] + ] + ] + ) vnf_add_faces(faces=faces); + // Function: vnf_triangulate() // Usage: @@ -310,4 +325,125 @@ module vnf_polyhedron(vnf, convexity=2) { } +// Function&Module: vnf_validate() +// Usage: As Function +// fails = vnf_validate(vnf); +// Usage: As Module +// vnf_validate(vnf); +// Description: +// When called as a function, returns a list of non-manifold errors with the given VNF. +// Each error has the format `[ERR_OR_WARN,CODE,MESG,POINTS,COLOR]`. +// When called as a module, echoes the non-manifold errors to the console, and color hilites the +// bad edges and vertices, overlaid on a transparent gray polyhedron of the VNF. +// Currently searches for these non-manifold errors: +// - HOLE_EDGE: Edge bounds Hole (magenta) +// - T_JUNC: Vertex is mid-edge on another Face (red) +// - NONPLANAR: Face vertices are not coplanar (cyan) +// +// Also checks for these warnings: +// - OPOP_EDGE: Too many faces attached at Edge (orange) +// - BIG_FACE: Face has more than 3 vertices, and may confuse CGAL (yellow) +// +// Still to implement: +// - Face intersections. +// - Overlapping coplanar faces. +// Arguments: +// vnf = The VNF to validate. +// Example: +// vnf = skin([ +// path3d(regular_ngon(n=4, d=100),0), +// path3d(regular_ngon(n=5, d=100),100) +// ], slices=0, caps=false); +// vnf_validate(vnf); +function vnf_validate(vnf) = + let( + vnf = vnf_compact(vnf), + edges = sort([ + for (face=vnf[1], edge=pair_wrap(face)) + edge[0]2) [ + "WARNING", + "OPOP_EDGE", + "Too many faces attached at Edge", + [for (i=uniq_edges[i]) vnf[0][i]], + "orange" + ] + ], + t_fails = [ + for (v=idx(vnf[0]), edge=uniq_edges) + if (v!=edge[0] && v!=edge[1]) let( + a = vnf[0][edge[0]], + b = vnf[0][v], + c = vnf[0][edge[1]], + pt = segment_closest_point([a,c],b) + ) if (approx(pt,b)) [ + "ERROR", + "T_JUNC", + "Vertex is mid-edge on another Face", + [b], + "red" + ] + ], + nonplanars = [ + for (face = vnf[1]) let( + verts = [for (i=face) vnf[0][i]] + ) if (!points_are_coplanar(verts)) [ + "ERROR", + "NONPLANAR", + "Face vertices are not coplanar", + verts, + "cyan" + ] + ], + bigfaces = [ + for (face = vnf[1]) + if (len(face) > 3) [ + "WARNING", + "BIG_FACE", + "Face has more than 3 vertices, and may confuse CGAL", + [for (i=face) vnf[0][i]], + "yellow" + ] + ] + ) concat(hole_edges, overpop_edges, t_fails, nonplanars, bigfaces); + +module vnf_validate(vnf) { + faults = vnf_validate(vnf); + for (fault = faults) { + typ = fault[0]; + err = fault[1]; + msg = fault[2]; + pts = fault[3]; + clr = fault[4]; + echo(str(typ, " ", err, ": ", msg, " at ", pts)); + color(clr) { + if (len(pts)==2) { + stroke(pts, width=2); + } else if (len(pts)>2) { + stroke(pts, width=2, closed=true); + polyhedron(pts,[[for (i=idx(pts)) i]]); + } else { + place_copies(pts) sphere(d=2); + } + } + } + color([0.5,0.5,0.5,0.5]) vnf_polyhedron(vnf); +} + + // vim: noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap