From a4ecbebfe61a27e59aeffb0b284162703095cdcb Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Sun, 15 Mar 2020 04:25:37 -0700 Subject: [PATCH 1/6] 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 From 93cdbf091d5295bbeb97e8b17cac8f6b1a141735 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Sun, 15 Mar 2020 11:20:59 -0700 Subject: [PATCH 2/6] Added size argument to vnf_validate() --- version.scad | 2 +- vnf.scad | 9 +++++---- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/version.scad b/version.scad index 05e42a0..51607a5 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,191]; +BOSL_VERSION = [2,0,192]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index 5a37619..bec67a7 100644 --- a/vnf.scad +++ b/vnf.scad @@ -349,6 +349,7 @@ module vnf_polyhedron(vnf, convexity=2) { // - Overlapping coplanar faces. // Arguments: // vnf = The VNF to validate. +// size = The width of the lines and diameter of points used to highlight edges and vertices. Module only. Default: 1 // Example: // vnf = skin([ // path3d(regular_ngon(n=4, d=100),0), @@ -422,7 +423,7 @@ function vnf_validate(vnf) = ] ) concat(hole_edges, overpop_edges, t_fails, nonplanars, bigfaces); -module vnf_validate(vnf) { +module vnf_validate(vnf, size=1) { faults = vnf_validate(vnf); for (fault = faults) { typ = fault[0]; @@ -433,12 +434,12 @@ module vnf_validate(vnf) { echo(str(typ, " ", err, ": ", msg, " at ", pts)); color(clr) { if (len(pts)==2) { - stroke(pts, width=2); + stroke(pts, width=size); } else if (len(pts)>2) { - stroke(pts, width=2, closed=true); + stroke(pts, width=size, closed=true); polyhedron(pts,[[for (i=idx(pts)) i]]); } else { - place_copies(pts) sphere(d=2); + place_copies(pts) sphere(d=size); } } } From 265db9fe5d4860cfbb446264a767c612dadefaf9 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Sun, 15 Mar 2020 11:50:41 -0700 Subject: [PATCH 3/6] Removed affine2d_apply() and affine3d_apply() --- affine.scad | 45 --------------------------------------------- involute_gears.scad | 2 +- paths.scad | 2 +- quaternions.scad | 2 +- regions.scad | 2 +- version.scad | 2 +- vnf.scad | 24 ++++++++++++------------ 7 files changed, 17 insertions(+), 62 deletions(-) diff --git a/affine.scad b/affine.scad index c7de834..5f0b248 100644 --- a/affine.scad +++ b/affine.scad @@ -118,28 +118,6 @@ function affine2d_chain(affines, _m=undef, _i=0) = affine2d_chain(affines, _m=(is_undef(_m)? affines[_i] : affines[_i] * _m), _i=_i+1); -// Function: affine2d_apply() -// Usage: -// affine2d_apply(pts, affines) -// Description: -// Given a list of 3x3 affine2d transformation matrices, applies them in order to the points in the point list. -// Arguments: -// pts = A list of 2D points to transform. -// affines = A list of 3x3 affine2d matrices to apply, in order. -// Example: -// npts = affine2d_apply( -// pts = [for (x=[0:3]) [5*x,0]], -// affines =[ -// affine2d_scale([3,1]), -// affine2d_rot(90), -// affine2d_translate([5,5]) -// ] -// ); // Returns [[5,5], [5,20], [5,35], [5,50]] -function affine2d_apply(pts, affines) = - let(m = affine2d_chain(affines)) - [for (p = pts) point2d(m * concat(point2d(p),[1]))]; - - // Section: Affine3d 4x4 Transformation Matrices @@ -399,29 +377,6 @@ function affine3d_chain(affines, _m=undef, _i=0) = affine3d_chain(affines, _m=(is_undef(_m)? affines[_i] : affines[_i] * _m), _i=_i+1); -// Function: affine3d_apply() -// Usage: -// affine3d_apply(pts, affines) -// Description: -// Given a list of affine3d transformation matrices, applies them in order to the points in the point list. -// Arguments: -// pts = A list of 3D points to transform. -// affines = A list of 4x4 matrices to apply, in order. -// Example: -// npts = affine3d_apply( -// pts = [for (x=[0:3]) [5*x,0,0]], -// affines =[ -// affine3d_scale([2,1,1]), -// affine3d_zrot(90), -// affine3d_translate([5,5,10]) -// ] -// ); // Returns [[5,5,10], [5,15,10], [5,25,10], [5,35,10]] -function affine3d_apply(pts, affines) = - let(m = affine3d_chain(affines)) - [for (p = pts) point3d(m * concat(point3d(p),[1]))]; - - - // Function: apply() // Usage: apply(transform, points) // Description: diff --git a/involute_gears.scad b/involute_gears.scad index 89c29c8..a69d8a9 100644 --- a/involute_gears.scad +++ b/involute_gears.scad @@ -516,7 +516,7 @@ module bevel_gear( ), pp = rot(theta, cp=spiral_cp, p=[0,Rm,0]), ang = atan2(pp.y,pp.x)-90, - pts = affine3d_apply(pts=profile, affines=[ + pts = apply_list(profile, [ move([0,-p,0]), rot([0,ang,0]), rot([bevelang,0,0]), diff --git a/paths.scad b/paths.scad index 00c9e10..1423a37 100644 --- a/paths.scad +++ b/paths.scad @@ -772,7 +772,7 @@ module spiral_sweep(polyline, h, r, twist=360, center, anchor, spin=0, orient=UP dx = r*cos(a), dy = r*sin(a), dz = h * (p/steps), - pts = affine3d_apply( + pts = apply_list( polyline, [ affine3d_xrot(90), affine3d_zrot(a), diff --git a/quaternions.scad b/quaternions.scad index f58f532..a8b42b7 100644 --- a/quaternions.scad +++ b/quaternions.scad @@ -289,7 +289,7 @@ module Qrot(q) { function Qrot(q,p) = is_undef(p)? Q_Matrix4(q) : is_vector(p)? Qrot(q,[p])[0] : - affine3d_apply(p,[Q_Matrix4(q)]); + apply(Q_Matrix4(q), p); // Module: Qrot_copies() diff --git a/regions.scad b/regions.scad index 4982705..9f775e2 100644 --- a/regions.scad +++ b/regions.scad @@ -285,7 +285,7 @@ function region_faces(region, transform, reverse=false, vnf=EMPTY_VNF) = if (vnf != EMPTY_VNF) vnf, for (rgn = regions) let( cleaved = _cleave_simple_region(rgn), - face = is_undef(transform)? cleaved : affine3d_apply(cleaved,[transform]), + face = is_undef(transform)? cleaved : apply(transform,cleaved), faceidxs = reverse? [for (i=[len(face)-1:-1:0]) i] : [for (i=[0:1:len(face)-1]) i] ) [face, [faceidxs]] ], diff --git a/version.scad b/version.scad index 51607a5..c65645f 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,192]; +BOSL_VERSION = [2,0,193]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index bec67a7..32179f0 100644 --- a/vnf.scad +++ b/vnf.scad @@ -197,9 +197,9 @@ function vnf_triangulate(vnf) = // vnf = vnf_vertex_array( // points=[ // for (a=[0:5:360-EPSILON]) -// affine3d_apply( -// circle(d=20), -// [xrot(90), right(30), zrot(a)] +// apply( +// zrot(a) * right(30) * xrot(90), +// circle(d=20) // ) // ], // col_wrap=true, row_wrap=true, reverse=true @@ -208,9 +208,9 @@ function vnf_triangulate(vnf) = // Example(3D): Möbius Strip. Note that `row_wrap` is not used, and the first and last profile copies are the same. // vnf = vnf_vertex_array( // points=[ -// for (a=[0:5:360]) affine3d_apply( -// square([1,10], center=true), -// [zrot(a/2+60), xrot(90), right(30), zrot(a)] +// for (a=[0:5:360]) apply( +// zrot(a) * right(30) * xrot(90) * zrot(a/2+60), +// square([1,10], center=true) // ) // ], // col_wrap=true, reverse=true @@ -218,15 +218,15 @@ function vnf_triangulate(vnf) = // vnf_polyhedron(vnf); // Example(3D): Assembling a Polyhedron from Multiple Parts // wall_points = [ -// for (a = [-90:2:90]) affine3d_apply( -// circle(d=100), -// [scale([1-0.1*cos(a*6), 1-0.1*cos((a+90)*6), 1]), up(a)] +// for (a = [-90:2:90]) apply( +// up(a) * scale([1-0.1*cos(a*6),1-0.1*cos((a+90)*6),1]), +// circle(d=100) // ) // ]; // cap = [ -// for (a = [0:0.01:1+EPSILON]) affine3d_apply( -// wall_points[0], -// [scale([a,a,1]), up(90-5*sin(a*360*2))] +// for (a = [0:0.01:1+EPSILON]) apply( +// up(90-5*sin(a*360*2)) * scale([a,a,1]), +// wall_points[0] // ) // ]; // cap1 = [for (p=cap) down(90, p=zscale(-1, p=p))]; From 3ac0be39c2a1aebbac22a192cd780370a5cd0fa7 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Sun, 15 Mar 2020 11:54:11 -0700 Subject: [PATCH 4/6] Fixed examples in vnf_vertex_array() --- version.scad | 2 +- vnf.scad | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/version.scad b/version.scad index c65645f..e46b2e1 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,193]; +BOSL_VERSION = [2,0,194]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index 32179f0..b8993b4 100644 --- a/vnf.scad +++ b/vnf.scad @@ -199,7 +199,7 @@ function vnf_triangulate(vnf) = // for (a=[0:5:360-EPSILON]) // apply( // zrot(a) * right(30) * xrot(90), -// circle(d=20) +// path3d(circle(d=20)) // ) // ], // col_wrap=true, row_wrap=true, reverse=true @@ -210,7 +210,7 @@ function vnf_triangulate(vnf) = // points=[ // for (a=[0:5:360]) apply( // zrot(a) * right(30) * xrot(90) * zrot(a/2+60), -// square([1,10], center=true) +// path3d(square([1,10], center=true)) // ) // ], // col_wrap=true, reverse=true @@ -220,7 +220,7 @@ function vnf_triangulate(vnf) = // wall_points = [ // for (a = [-90:2:90]) apply( // up(a) * scale([1-0.1*cos(a*6),1-0.1*cos((a+90)*6),1]), -// circle(d=100) +// path3d(circle(d=100)) // ) // ]; // cap = [ From 39d44cb7091d74aa7a58a0c68e720972b5d28176 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Mon, 16 Mar 2020 02:57:03 -0700 Subject: [PATCH 5/6] Improved vnf_validate() --- regions.scad | 2 +- version.scad | 2 +- vnf.scad | 208 ++++++++++++++++++++++++++++++++++++--------------- 3 files changed, 150 insertions(+), 62 deletions(-) diff --git a/regions.scad b/regions.scad index 9f775e2..ce92846 100644 --- a/regions.scad +++ b/regions.scad @@ -285,7 +285,7 @@ function region_faces(region, transform, reverse=false, vnf=EMPTY_VNF) = if (vnf != EMPTY_VNF) vnf, for (rgn = regions) let( cleaved = _cleave_simple_region(rgn), - face = is_undef(transform)? cleaved : apply(transform,cleaved), + face = is_undef(transform)? cleaved : apply(transform,path3d(cleaved)), faceidxs = reverse? [for (i=[len(face)-1:-1:0]) i] : [for (i=[0:1:len(face)-1]) i] ) [face, [faceidxs]] ], diff --git a/version.scad b/version.scad index e46b2e1..f1301e9 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,194]; +BOSL_VERSION = [2,0,195]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index b8993b4..5ed8831 100644 --- a/vnf.scad +++ b/vnf.scad @@ -335,14 +335,16 @@ module vnf_polyhedron(vnf, convexity=2) { // 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) +// Currently checks for these problems: +// Type | Color | Code | Message +// ------- | -------- | ------------ | --------------------------------- +// WARNING | Yellow | BIG_FACE | Face has more than 3 vertices, and may confuse CGAL +// ERROR | Cyan | NONPLANAR | Face vertices are not coplanar +// ERROR | Orange | OVRPOP_EDGE | Too many faces attached at edge +// ERROR | Violet | REVERSAL | Faces reverse across edge +// ERROR | Red | T_JUNCTION | Vertex is mid-edge on another Face +// ERROR | Magenta | HOLE_EDGE | Edge bounds Hole // // Still to implement: // - Face intersections. @@ -350,10 +352,55 @@ module vnf_polyhedron(vnf, convexity=2) { // Arguments: // vnf = The VNF to validate. // size = The width of the lines and diameter of points used to highlight edges and vertices. Module only. Default: 1 -// Example: +// Example: BIG_FACE Warnings; Faces with More Than 3 Vertices. CGAL often will fail to accept that a face is planar after a rotation, if it has more than 3 vertices. // vnf = skin([ -// path3d(regular_ngon(n=4, d=100),0), -// path3d(regular_ngon(n=5, d=100),100) +// path3d(regular_ngon(n=3, d=100),0), +// path3d(regular_ngon(n=5, d=100),100) +// ], slices=0, caps=true, method="tangent"); +// vnf_validate(vnf); +// Example: NONPLANAR Errors; Face Vertices are Not Coplanar +// a = [ 0, 0,-50]; +// b = [-50,-50, 50]; +// c = [-50, 50, 50]; +// d = [ 50, 50, 60]; +// e = [ 50,-50, 50]; +// vnf = vnf_add_faces(faces=[ +// [a, b, e], [a, c, b], [a, d, c], [a, e, d], [b, c, d, e] +// ]); +// vnf_validate(vnf); +// Example: OVRPOP_EDGE Errors; More Than Two Faces Attached to the Same Edge. This confuses CGAL, and can lead to failed renders. +// vnf = vnf_triangulate(linear_sweep(union(square(50), square(50,anchor=BACK+RIGHT)), height=50)); +// vnf_validate(vnf); +// Example: REVERSAL Errors; Faces Reversed Across Edge +// vnf1 = skin([ +// path3d(square(100,center=true),0), +// path3d(square(100,center=true),100), +// ], slices=0, caps=false); +// vnf = vnf_add_faces(vnf=vnf1, faces=[ +// [[-50,-50, 0], [ 50, 50, 0], [-50, 50, 0]], +// [[-50,-50, 0], [ 50,-50, 0], [ 50, 50, 0]], +// [[-50,-50,100], [-50, 50,100], [ 50, 50,100]], +// [[-50,-50,100], [ 50,-50,100], [ 50, 50,100]], +// ]); +// vnf_validate(vnf); +// Example: T_JUNCTION Errors; Vertex is Mid-Edge on Another Face. +// vnf1 = skin([ +// path3d(square(100,center=true),0), +// path3d(square(100,center=true),100), +// ], slices=0, caps=false); +// vnf = vnf_add_faces(vnf=vnf1, faces=[ +// [[-50,-50,0], [50,50,0], [-50,50,0]], +// [[-50,-50,0], [50,-50,0], [50,50,0]], +// [[-50,-50,100], [-50,50,100], [0,50,100]], +// [[-50,-50,100], [0,50,100], [0,-50,100]], +// [[0,-50,100], [0,50,100], [50,50,100]], +// [[0,-50,100], [50,50,100], [50,-50,100]], +// ]); +// vnf_validate(vnf); +// Example: HOLE_EDGE Errors; Edges Adjacent to Holes. +// 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) = @@ -365,52 +412,6 @@ function vnf_validate(vnf) = ]), edgecnts = unique_count(edges), uniq_edges = edgecnts[0], - hole_edges = [ - for (i=idx(uniq_edges)) - if (edgecnts[1][i]<2) [ - "ERROR", - "HOLE_EDGE", - "Edge bounds Hole", - [for (i=uniq_edges[i]) vnf[0][i]], - "magenta" - ] - ], - overpop_edges = [ - for (i=idx(uniq_edges)) - if (edgecnts[1][i]>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) [ @@ -420,8 +421,95 @@ function vnf_validate(vnf) = [for (i=face) vnf[0][i]], "yellow" ] - ] - ) concat(hole_edges, overpop_edges, t_fails, nonplanars, bigfaces); + ], + nonplanars = unique([ + 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" + ] + ]), + overpop_edges = unique([ + for (i=idx(uniq_edges)) + if (edgecnts[1][i]>2) [ + "ERROR", + "OVRPOP_EDGE", + "Too many faces attached at Edge", + [for (i=uniq_edges[i]) vnf[0][i]], + "#f70" + ] + ]), + reversals = unique([ + for(i = idx(vnf[1]), j = idx(vnf[1])) if(i != j) + for(edge1 = pair_wrap(vnf[1][i])) + for(edge2 = pair_wrap(vnf[1][j])) + if(edge1 == edge2) + if(_edge_not_reported(edge1, vnf, overpop_edges)) + [ + "ERROR", + "REVERSAL", + "Faces Reverse Across Edge", + [for (i=edge1) vnf[0][i]], + "violet" + ] + ]), + t_juncts = unique([ + 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_JUNCTION", + "Vertex is mid-edge on another Face", + [b], + "red" + ] + ]), + hole_edges = unique([ + for (i=idx(uniq_edges)) + if (edgecnts[1][i]<2) + if (_pts_not_reported(uniq_edges[i], vnf, t_juncts)) + [ + "ERROR", + "HOLE_EDGE", + "Edge bounds Hole", + [for (i=uniq_edges[i]) vnf[0][i]], + "magenta" + ] + ]) + ) concat( + bigfaces, + nonplanars, + overpop_edges, + reversals, + t_juncts, + hole_edges + ); + + +function _pts_not_reported(pts, vnf, reports) = + [ + for (i = pts, report = reports, pt = report[3]) + if (approx(vnf[0][i], pt)) 1 + ] == []; + + +function _edge_not_reported(edge, vnf, reports) = + let( + edge = sort([for (i=edge) vnf[0][i]]) + ) [ + for (report = reports) let( + pts = sort(report[3]) + ) if (len(pts)==2 && edge == pts) 1 + ] == []; + module vnf_validate(vnf, size=1) { faults = vnf_validate(vnf); @@ -439,11 +527,11 @@ module vnf_validate(vnf, size=1) { stroke(pts, width=size, closed=true); polyhedron(pts,[[for (i=idx(pts)) i]]); } else { - place_copies(pts) sphere(d=size); + place_copies(pts) sphere(d=size*3, $fn=18); } } } - color([0.5,0.5,0.5,0.5]) vnf_polyhedron(vnf); + color([0.33,0.33,0.33,0.5]) vnf_polyhedron(vnf); } From 9257c742364e574d06456711a116de5d88197c08 Mon Sep 17 00:00:00 2001 From: Revar Desmera Date: Mon, 16 Mar 2020 03:01:07 -0700 Subject: [PATCH 6/6] Lightened vnt_validate polyhedron ghost. --- version.scad | 2 +- vnf.scad | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/version.scad b/version.scad index f1301e9..affe347 100644 --- a/version.scad +++ b/version.scad @@ -8,7 +8,7 @@ ////////////////////////////////////////////////////////////////////// -BOSL_VERSION = [2,0,195]; +BOSL_VERSION = [2,0,196]; // Section: BOSL Library Version Functions diff --git a/vnf.scad b/vnf.scad index 5ed8831..3a9f6ad 100644 --- a/vnf.scad +++ b/vnf.scad @@ -531,7 +531,7 @@ module vnf_validate(vnf, size=1) { } } } - color([0.33,0.33,0.33,0.5]) vnf_polyhedron(vnf); + color([0.5,0.5,0.5,0.5]) vnf_polyhedron(vnf); }