mirror of
https://github.com/BelfrySCAD/BOSL2.git
synced 2025-01-06 04:09:47 +00:00
Merge pull request #532 from adrianVmariano/master
add search_radius, fix debug_polyhedron
This commit is contained in:
commit
7d68ee2e66
4 changed files with 63 additions and 28 deletions
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
// Default values for attachment code.
|
// Default values for attachment code.
|
||||||
$tags = "";
|
$tags = "";
|
||||||
$overlap = 0.01;
|
$overlap = 0;
|
||||||
$color = undef;
|
$color = undef;
|
||||||
|
|
||||||
$attach_to = undef;
|
$attach_to = undef;
|
||||||
|
|
28
debug.scad
28
debug.scad
|
@ -149,12 +149,14 @@ module debug_vertices(vertices, size=1, disabled=false) {
|
||||||
if (!disabled) {
|
if (!disabled) {
|
||||||
echo(vertices=vertices);
|
echo(vertices=vertices);
|
||||||
color("blue") {
|
color("blue") {
|
||||||
for (i = [0:1:len(vertices)-1]) {
|
dups = search_radius(vertices, vertices, 1e-9);
|
||||||
v = vertices[i];
|
for (ind = dups){
|
||||||
|
numstr = str_join([for(i=ind) str(i)],",");
|
||||||
|
v = vertices[ind[0]];
|
||||||
translate(v) {
|
translate(v) {
|
||||||
up(size/8) zrot($vpr[2]) xrot(90) {
|
up(size/8) zrot($vpr[2]) xrot(90) {
|
||||||
linear_extrude(height=size/10, center=true, convexity=10) {
|
linear_extrude(height=size/10, center=true, convexity=10) {
|
||||||
text(text=str(i), size=size, halign="center");
|
text(text=numstr, size=size, halign="center");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
sphere(size/10);
|
sphere(size/10);
|
||||||
|
@ -239,19 +241,18 @@ module debug_faces(vertices, faces, size=1, disabled=false) {
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Module: debug_polyhedron()
|
// Module: debug_vnf()
|
||||||
// Usage:
|
// Usage:
|
||||||
// debug_polyhedron(points, faces, <convexity=>, <txtsize=>, <disabled=>);
|
// debug_vnf(vnfs, <convexity=>, <txtsize=>, <disabled=>);
|
||||||
// Description:
|
// Description:
|
||||||
// A drop-in module to replace `polyhedron()` and help debug vertices and faces.
|
// A drop-in module to replace `vnf_polyhedron()` and help debug vertices and faces.
|
||||||
// Draws all the vertices at their 3D position, numbered in blue by their
|
// Draws all the vertices at their 3D position, numbered in blue by their
|
||||||
// position in the vertex array. Each face will have their face number drawn
|
// position in the vertex array. Each face will have its face number drawn
|
||||||
// in red, aligned with the center of face. All given faces are drawn with
|
// in red, aligned with the center of face. All given faces are drawn with
|
||||||
// transparency. All children of this module are drawn with transparency.
|
// transparency. All children of this module are drawn with transparency.
|
||||||
// Works best with Thrown-Together preview mode, to see reversed faces.
|
// Works best with Thrown-Together preview mode, to see reversed faces.
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// points = Array of point vertices.
|
// vnf = vnf to display
|
||||||
// faces = Array of faces by vertex numbers.
|
|
||||||
// ---
|
// ---
|
||||||
// convexity = The max number of walls a ray can pass through the given polygon paths.
|
// convexity = The max number of walls a ray can pass through the given polygon paths.
|
||||||
// txtsize = The size of the text used to label the faces and vertices.
|
// txtsize = The size of the text used to label the faces and vertices.
|
||||||
|
@ -259,15 +260,14 @@ module debug_faces(vertices, faces, size=1, disabled=false) {
|
||||||
// Example(EdgesMed):
|
// Example(EdgesMed):
|
||||||
// verts = [for (z=[-10,10], a=[0:120:359.9]) [10*cos(a),10*sin(a),z]];
|
// verts = [for (z=[-10,10], a=[0:120:359.9]) [10*cos(a),10*sin(a),z]];
|
||||||
// faces = [[0,1,2], [5,4,3], [0,3,4], [0,4,1], [1,4,5], [1,5,2], [2,5,3], [2,3,0]];
|
// faces = [[0,1,2], [5,4,3], [0,3,4], [0,4,1], [1,4,5], [1,5,2], [2,5,3], [2,3,0]];
|
||||||
// debug_polyhedron(points=verts, faces=faces, txtsize=1);
|
// debug_vnf([verts,faces], txtsize=2);
|
||||||
module debug_polyhedron(points, faces, convexity=6, txtsize=1, disabled=false) {
|
module debug_vnf(vnf, convexity=6, txtsize=1, disabled=false) {
|
||||||
debug_faces(vertices=points, faces=faces, size=txtsize, disabled=disabled) {
|
debug_faces(vertices=vnf[0], faces=vnf[1], size=txtsize, disabled=disabled) {
|
||||||
polyhedron(points=points, faces=faces, convexity=convexity);
|
vnf_polyhedron(vnf, convexity=convexity);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Function: standard_anchors()
|
// Function: standard_anchors()
|
||||||
// Usage:
|
// Usage:
|
||||||
// anchs = standard_anchors(<two_d>);
|
// anchs = standard_anchors(<two_d>);
|
||||||
|
|
33
joiners.scad
33
joiners.scad
|
@ -419,7 +419,7 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde
|
||||||
// Module: dovetail()
|
// Module: dovetail()
|
||||||
//
|
//
|
||||||
// Usage:
|
// Usage:
|
||||||
// dovetail(gender, w|width, h|height, slide, [slope|angle], [taper|back_width], [chamfer], [r|radius], [round], [$slop])
|
// dovetail(gender, w|width, h|height, slide, [slope|angle], [taper|back_width], [chamfer], [r|radius], [round], [extra], [$slop])
|
||||||
//
|
//
|
||||||
// Description:
|
// Description:
|
||||||
// Produces a possibly tapered dovetail joint shape to attach to or subtract from two parts you wish to join together.
|
// Produces a possibly tapered dovetail joint shape to attach to or subtract from two parts you wish to join together.
|
||||||
|
@ -429,7 +429,9 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde
|
||||||
// parallel to the Y axis and projecting upwards, so in its default orientation it will slide together with a translation
|
// parallel to the Y axis and projecting upwards, so in its default orientation it will slide together with a translation
|
||||||
// in the positive Y direction. The gender determines whether the shape is meant to be added to your model or
|
// in the positive Y direction. The gender determines whether the shape is meant to be added to your model or
|
||||||
// differenced, and it also changes the anchor and orientation. The default anchor for dovetails is BOTTOM;
|
// differenced, and it also changes the anchor and orientation. The default anchor for dovetails is BOTTOM;
|
||||||
// the default orientation depends on the gender, with male dovetails oriented UP and female ones DOWN.
|
// the default orientation depends on the gender, with male dovetails oriented UP and female ones DOWN. The dovetails by default
|
||||||
|
// have extra extension of 0.01 for unions and differences. You should ensure that attachment is done with overlap=0 to ensure that
|
||||||
|
// the sizing and positioning is correct.
|
||||||
//
|
//
|
||||||
// Arguments:
|
// Arguments:
|
||||||
// gender = A string, "male" or "female", to specify the gender of the dovetail.
|
// gender = A string, "male" or "female", to specify the gender of the dovetail.
|
||||||
|
@ -473,14 +475,14 @@ module joiner_quad(spacing1=undef, spacing2=undef, xspacing=undef, yspacing=unde
|
||||||
// diff("remove")
|
// diff("remove")
|
||||||
// cuboid([50,30,10]) {
|
// cuboid([50,30,10]) {
|
||||||
// attach(BACK) dovetail("male", slide=10, width=15, height=8, radius=1, $fn=32);
|
// attach(BACK) dovetail("male", slide=10, width=15, height=8, radius=1, $fn=32);
|
||||||
// attach(FRONT, overlap=-0.1) dovetail("female", slide=10, width=15, height=8, radius=1, $tags="remove", $fn=32);
|
// attach(FRONT) dovetail("female", slide=10, width=15, height=8, radius=1, $tags="remove", $fn=32);
|
||||||
// }
|
// }
|
||||||
// Example: Or you can make a fully rounded joint
|
// Example: Or you can make a fully rounded joint
|
||||||
// $fn=32;
|
// $fn=32;
|
||||||
// diff("remove")
|
// diff("remove")
|
||||||
// cuboid([50,30,10]){
|
// cuboid([50,30,10]){
|
||||||
// attach(BACK) dovetail("male", slide=10, width=15, height=8, radius=1.5, round=true);
|
// attach(BACK) dovetail("male", slide=10, width=15, height=8, radius=1.5, round=true);
|
||||||
// attach(FRONT,overlap=-0.1) dovetail("female", slide=10, width=15, height=8, radius=1.5, round=true, $tags="remove");
|
// attach(FRONT) dovetail("female", slide=10, width=15, height=8, radius=1.5, round=true, $tags="remove");
|
||||||
// }
|
// }
|
||||||
// Example: With a long joint like this, a taper makes the joint easy to assemble. It will go together easily and wedge tightly if you get the tolerances right. Specifying the taper with `back_width` may be easier than using a taper angle.
|
// Example: With a long joint like this, a taper makes the joint easy to assemble. It will go together easily and wedge tightly if you get the tolerances right. Specifying the taper with `back_width` may be easier than using a taper angle.
|
||||||
// cuboid([50,30,10])
|
// cuboid([50,30,10])
|
||||||
|
@ -548,8 +550,9 @@ module dovetail(gender, width, height, slide, h, w, angle, slope, taper, back_wi
|
||||||
is_def(back_width) ? (back_width-width) / 2 : 0;
|
is_def(back_width) ? (back_width-width) / 2 : 0;
|
||||||
bigend_points = move([offset,slide+2*extra,0], p=smallend_points);
|
bigend_points = move([offset,slide+2*extra,0], p=smallend_points);
|
||||||
|
|
||||||
adjustment = $overlap * (gender == "male" ? -1 : 1); // Adjustment for default overlap in attach()
|
//adjustment = $overlap * (gender == "male" ? -1 : 1); // Adjustment for default overlap in attach()
|
||||||
|
adjustment = 0; // Default overlap is assumed to be zero
|
||||||
|
|
||||||
attachable(anchor,spin,orient, size=[width+2*offset, slide, height]) {
|
attachable(anchor,spin,orient, size=[width+2*offset, slide, height]) {
|
||||||
down(height/2+adjustment) {
|
down(height/2+adjustment) {
|
||||||
skin(
|
skin(
|
||||||
|
@ -601,7 +604,8 @@ module _pin_slot(l, r, t, d, nub, depth, stretch) {
|
||||||
|
|
||||||
module _pin_shaft(r, lStraight, nub, nubscale, stretch, d, pointed)
|
module _pin_shaft(r, lStraight, nub, nubscale, stretch, d, pointed)
|
||||||
{
|
{
|
||||||
extra = 0.02;
|
extra = 0.02; // This sets the extra extension below the socket bottom
|
||||||
|
// so that difference() works without issues
|
||||||
rPoint = r / sqrt(2);
|
rPoint = r / sqrt(2);
|
||||||
down(extra) cylinder(r = r, h = lStraight + extra);
|
down(extra) cylinder(r = r, h = lStraight + extra);
|
||||||
up(lStraight) {
|
up(lStraight) {
|
||||||
|
@ -726,6 +730,8 @@ module snap_pin(size,r,radius,d,diameter, l,length, nub_depth, snap, thickness,
|
||||||
// if you add a lubricant. If `pointed` is true the socket is pointed to receive a pointed pin, otherwise it has a rounded and and
|
// if you add a lubricant. If `pointed` is true the socket is pointed to receive a pointed pin, otherwise it has a rounded and and
|
||||||
// will be shorter. If `fins` is set to true then two fins are included inside the socket to act as supports (which may help when printing tip up,
|
// will be shorter. If `fins` is set to true then two fins are included inside the socket to act as supports (which may help when printing tip up,
|
||||||
// especially when `pointed=false`). The default orientation is DOWN with anchor BOTTOM so that you can difference() the socket away from an object.
|
// especially when `pointed=false`). The default orientation is DOWN with anchor BOTTOM so that you can difference() the socket away from an object.
|
||||||
|
// The socket extends 0.02 extra below its bottom anchor point so that differences will work correctly. (You must have $overlap smaller than 0.02 in
|
||||||
|
// attach or the socket will be beneath the surface of the parent object.)
|
||||||
// .
|
// .
|
||||||
// The "large" or "standard" size pin has a length of 10.8 and diameter of 7. The "medium" pin has a length of 8 and diameter of 4.6. The "small" pin
|
// The "large" or "standard" size pin has a length of 10.8 and diameter of 7. The "medium" pin has a length of 8 and diameter of 4.6. The "small" pin
|
||||||
// has a length of 6 and diameter of 3.2. The "tiny" pin has a length of 4 and a diameter of 2.5.
|
// has a length of 6 and diameter of 3.2. The "tiny" pin has a length of 4 and a diameter of 2.5.
|
||||||
|
@ -802,13 +808,14 @@ module snap_pin_socket(size, r, radius, l,length, d,diameter,nub_depth, snap, fi
|
||||||
// make the socket with a larger depth than the clip (try 0.4 mm) to allow ease of insertion of the clip. The clearance
|
// make the socket with a larger depth than the clip (try 0.4 mm) to allow ease of insertion of the clip. The clearance
|
||||||
// value does not apply to the depth. The splinesteps parameter increases the sampling of the clip curves.
|
// value does not apply to the depth. The splinesteps parameter increases the sampling of the clip curves.
|
||||||
// .
|
// .
|
||||||
// By default clips appear with orient=UP and sockets with orient=DOWN.
|
// By default clips appear with orient=UP and sockets with orient=DOWN. The clips and sockets extend 0.02 units below
|
||||||
|
// their base so that unions and differences will work without trouble, but be sure that the attach overlap is smaller
|
||||||
|
// than 0.02.
|
||||||
// .
|
// .
|
||||||
// The first figure shows the dimensions of the rabbit clip. The second figure shows the clip in red overlayed on
|
// The first figure shows the dimensions of the rabbit clip. The second figure shows the clip in red overlayed on
|
||||||
// its socket in yellow. The left clip has a nonzero clearance, so its socket is bigger than the clip all around.
|
// its socket in yellow. The left clip has a nonzero clearance, so its socket is bigger than the clip all around.
|
||||||
// The right hand locking clip has no clearance, but it has a lock clearance, which provides some space behind
|
// The right hand locking clip has no clearance, but it has a lock clearance, which provides some space behind
|
||||||
// the lock to allow the clip to fit. (Note that depending on your printer, this can be set to zero.)
|
// the lock to allow the clip to fit. (Note that depending on your printer, this can be set to zero.)
|
||||||
//
|
|
||||||
// Figure(2DMed):
|
// Figure(2DMed):
|
||||||
// snap=1.5;
|
// snap=1.5;
|
||||||
// comp=0.75;
|
// comp=0.75;
|
||||||
|
@ -939,7 +946,8 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
||||||
} else {
|
} else {
|
||||||
anchor = default(anchor,BOTTOM);
|
anchor = default(anchor,BOTTOM);
|
||||||
is_pin = in_list(type,["pin","male"]);
|
is_pin = in_list(type,["pin","male"]);
|
||||||
default_overlap = 0.01 * (is_pin?1:-1); // Shift by this much to undo default overlap
|
//default_overlap = 0.01 * (is_pin?1:-1); // Shift by this much to undo default overlap
|
||||||
|
default_overlap = 0;
|
||||||
extra = 0.02; // Amount of extension below nominal based position for the socket, must exceed default overlap of 0.01
|
extra = 0.02; // Amount of extension below nominal based position for the socket, must exceed default overlap of 0.01
|
||||||
clearance = is_pin ? 0 : clearance;
|
clearance = is_pin ? 0 : clearance;
|
||||||
compression = is_pin ? compression : 0;
|
compression = is_pin ? compression : 0;
|
||||||
|
@ -989,8 +997,6 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
||||||
bez = path_to_bezier(path,relsize=smoothing,tangents=tangent);
|
bez = path_to_bezier(path,relsize=smoothing,tangents=tangent);
|
||||||
rounded = bezier_path(bez,splinesteps=splinesteps);
|
rounded = bezier_path(bez,splinesteps=splinesteps);
|
||||||
bounds = pointlist_bounds(rounded);
|
bounds = pointlist_bounds(rounded);
|
||||||
//kk = search([bounds[1].y], subindex(rounded,1));
|
|
||||||
//echo(rounded[kk[0]]);
|
|
||||||
extrapt = is_pin ? [] : [rounded[0] - [0,extra]];
|
extrapt = is_pin ? [] : [rounded[0] - [0,extra]];
|
||||||
finalpath = is_pin ? rounded
|
finalpath = is_pin ? rounded
|
||||||
: let(withclearance=offset(rounded, r=-clearance))
|
: let(withclearance=offset(rounded, r=-clearance))
|
||||||
|
@ -1005,6 +1011,7 @@ module rabbit_clip(type, length, width, snap, thickness, depth, compression=0.1
|
||||||
xflip_copy()
|
xflip_copy()
|
||||||
right(clearance)
|
right(clearance)
|
||||||
polygon([sidepath[1]+[-thickness/10,lock_clearance],
|
polygon([sidepath[1]+[-thickness/10,lock_clearance],
|
||||||
|
sidepath[2]-[thickness*.75,0],
|
||||||
sidepath[2],
|
sidepath[2],
|
||||||
[sidepath[2].x,sidepath[1].y+lock_clearance]]);
|
[sidepath[2].x,sidepath[1].y+lock_clearance]]);
|
||||||
if (is_pin)
|
if (is_pin)
|
||||||
|
|
28
vectors.scad
28
vectors.scad
|
@ -355,4 +355,32 @@ function vp_nearest(points, tree, p, k) =
|
||||||
subindex(_vp_nearest(points, tree, p, k),0);
|
subindex(_vp_nearest(points, tree, p, k),0);
|
||||||
|
|
||||||
|
|
||||||
|
// Function: search_radius()
|
||||||
|
// Usage:
|
||||||
|
// index_list = search_radius(points, queries, r, <leafsize>);
|
||||||
|
// Description:
|
||||||
|
// Given a list of points and a compatible list of queries, for each query
|
||||||
|
// search the points list for all points whose distance from the query
|
||||||
|
// is less than or equal to r. The return value index_list[i] lists the indices
|
||||||
|
// in points of all matches to query q[i]. This list can be in arbitrary order.
|
||||||
|
// .
|
||||||
|
// This function is advantageous to use especially when both `points` and `queries`
|
||||||
|
// are large sets. The method contructs a vantage point tree and then uses it
|
||||||
|
// to check all the queries. If you use queries=points and set r to epsilon then
|
||||||
|
// you can find all of the approximate duplicates in a large list of vectors.
|
||||||
|
// Example: Finding duplicates in a list of vectors. With exact equality the order of the output is consistent, but with small variations [2,4] could occur in one position and [4,2] in the other one.
|
||||||
|
// v = array_group(rands(0,10,5*3,seed=9),3);
|
||||||
|
// points = [v[0],v[1],v[2],v[3],v[2],v[3],v[3],v[4]];
|
||||||
|
// echo(search_radius(points,points,1e-9)); // Prints [[0],[1],[2,4],[3,5,6],[2,4],[3,5,6],[3,5,6],[7]]
|
||||||
|
//
|
||||||
|
function search_radius(points, queries, r, leafsize=25) =
|
||||||
|
assert(is_matrix(points),"Invalid points list")
|
||||||
|
assert(is_matrix(queries),"Invalid query list")
|
||||||
|
assert(len(points[0])==len(queries[0]), "Query vectors don't match length of points")
|
||||||
|
let(
|
||||||
|
vptree = vp_tree(points, leafsize)
|
||||||
|
)
|
||||||
|
[for(q=queries) vp_search(points, vptree, q, r)];
|
||||||
|
|
||||||
|
|
||||||
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
// vim: expandtab tabstop=4 shiftwidth=4 softtabstop=4 nowrap
|
||||||
|
|
Loading…
Reference in a new issue