From 78a06f63ab3c71700e5434dfdaa63bcb6a8a5bd5 Mon Sep 17 00:00:00 2001 From: Alex Matulich Date: Wed, 16 Jul 2025 11:49:13 -0700 Subject: [PATCH] corrected x/y/zcyl() reorient() issue in shapes3d, commented echo and added newlines to assert messages in attachments --- attachments.scad | 270 +++++++++++++++++++++++------------------------ shapes3d.scad | 121 ++++++++++++--------- 2 files changed, 204 insertions(+), 187 deletions(-) diff --git a/attachments.scad b/attachments.scad index 9131e0c7..86db9449 100644 --- a/attachments.scad +++ b/attachments.scad @@ -509,10 +509,10 @@ module position(at,from) if (is_def(from)){ echo("'from' argument of position() has changed to 'at' and will be removed in a future version"); } - dummy0=assert(num_defined([at,from])==1, "Cannot give both `at` argument and the deprectated `from` argument to position()"); + dummy0=assert(num_defined([at,from])==1, "\nCannot give both `at` argument and the deprectated `from` argument to position()."); at = first_defined([at,from]); req_children($children); - dummy1=assert($parent_geom != undef, "No object to position relative to."); + dummy1=assert($parent_geom != undef, "\nNo object to position relative to."); anchors = (is_vector(at)||is_string(at))? [at] : at; two_d = _attach_geom_2d($parent_geom); for (anchr = anchors) { @@ -563,7 +563,7 @@ module position(at,from) module orient(anchor, spin) { req_children($children); check= - assert($parent_geom != undef, "No parent to orient from!") + assert($parent_geom != undef, "\nNo parent to orient from!") assert(is_string(anchor) || is_vector(anchor)); anch = _find_anchor(anchor, $parent_geom); two_d = _attach_geom_2d($parent_geom); @@ -700,8 +700,8 @@ module align(anchor,align=CENTER,inside=false,inset=0,shiftout=0,overlap) { req_children($children); overlap = (overlap!=undef)? overlap : $overlap; - dummy1=assert($parent_geom != undef, "No object to align to.") - assert(is_undef($attach_to), "Cannot use align() as a child of attach()"); + dummy1=assert($parent_geom != undef, "\nNo object to align to.") + assert(is_undef($attach_to), "\nCannot use align() as a child of attach()."); anchor = is_vector(anchor) ? [anchor] : anchor; align = is_vector(align) ? [align] : align; two_d = _attach_geom_2d($parent_geom); @@ -712,19 +712,19 @@ module align(anchor,align=CENTER,inside=false,inset=0,shiftout=0,overlap) $anchor=face; dummy= assert(!is_string(face), - str("Named anchor \"",face,"\" given for anchor, but align() does not support named anchors")) + str("\nNamed anchor \"",face,"\" given for anchor, but align() does not support named anchors.")) assert(is_vector(face) && (len(face)==2 || len(face)==3), - str("Invalid face ",face, ". Must be a 2-vector or 3-vector")); + str("\nInvalid face ",face, ". Must be a 2-vector or 3-vector.")); thisface = two_d? _force_anchor_2d(face) : point3d(face); for(j = idx(align)) { edge=align[j]; $idx = j+len(align)*i; $align=edge; dummy1=assert(is_vector(edge) && (len(edge)==2 || len(edge)==3), - "align direction must be a 2-vector or 3-vector"); + "\nalign direction must be a 2-vector or 3-vector."); thisedge = two_d? _force_anchor_2d(edge) : point3d(edge); dummy=assert(all_zero(v_mul(thisedge,thisface)), - str("align (",thisedge,") cannot include component parallel to anchor ",thisface)); + str("\nalign (",thisedge,") cannot include component parallel to anchor ",thisface,".")); thisface_anch = _find_anchor(thisface, $parent_geom); inset_dir = two_d ? -thisface : unit(thisface_anch[1]-_find_anchor([thisedge.x,0,0]+thisface, $parent_geom)[1],CTR) @@ -931,10 +931,10 @@ function _make_anchor_legal(anchor,geom) = module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, inside=false, from, to) { dummy3= - assert(num_defined([to,child])<2, "Cannot combine deprecated 'to' argument with 'child' parameter") - assert(num_defined([from,parent])<2, "Cannot combine deprecated 'from' argument with 'parent' parameter") - assert(spin!="align" || is_def(align), "Can only set spin to \"align\" when the 'align' parameter is given") - assert(is_finite(spin) || spin=="align", "Spin must be a number (unless align is given)") + assert(num_defined([to,child])<2, "\nCannot combine deprecated 'to' argument with 'child' parameter.") + assert(num_defined([from,parent])<2, "\nCannot combine deprecated 'from' argument with 'parent' parameter.") + assert(spin!="align" || is_def(align), "\nCan only set spin to \"align\" when the 'align' parameter is given.") + assert(is_finite(spin) || spin=="align", "\nSpin must be a number (unless align is given).") assert((is_undef(overlap) || is_finite(overlap)) && (is_def(overlap) || is_undef($overlap) || is_finite($overlap)), str("Provided ",is_def(overlap)?"":"$","overlap is not valid.")); removetag = inside; @@ -947,10 +947,10 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, echo("The 'norot' option to attach() is deprecated and will be removed in the future. Use position() instead."); req_children($children); - dummy=assert($parent_geom != undef, "No object to attach to!") + dummy=assert($parent_geom != undef, "\nNo object to attach to!") assert(is_undef(child) || is_string(child) || (is_vector(child) && (len(child)==2 || len(child)==3)), - "child must be a named anchor (a string) or a 2-vector or 3-vector") - assert(is_undef(align) || !is_string(child), "child is a named anchor. Named anchors are not supported with align="); + "\nChild must be a named anchor (a string) or a 2-vector or 3-vector.") + assert(is_undef(align) || !is_string(child), "\nChild is a named anchor. Named anchors are not supported with align=."); two_d = _attach_geom_2d($parent_geom); basegeom = $parent_geom[0]=="conoid" ? attach_geom(r=2,h=2,axis=$parent_geom[5]) @@ -963,22 +963,22 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, anchors = is_vector(parent) || is_string(parent) ? [parent] : parent; align_list = is_undef(align) ? [undef] : is_vector(align) || is_string(align) ? [align] : align; - dummy4 = assert(is_string(parent) || is_list(parent), "Invalid parent anchor or anchor list") - assert(spin==0 || (!two_d || is_undef(child)), "spin is not allowed for 2d objects when 'child' is given"); + dummy4 = assert(is_string(parent) || is_list(parent), "\nInvalid parent anchor or anchor list.") + assert(spin==0 || (!two_d || is_undef(child)), "\nspin is not allowed for 2d objects when 'child' is given."); child_temp = first_defined([child,to]); child = two_d ? _force_anchor_2d(child_temp) : child_temp; - dummy2=assert(align_list==[undef] || is_def(child), "Cannot use 'align' without 'child'") - assert(!inside || is_def(child), "Cannot use 'inside' without 'child'") - assert(inset==0 || is_def(child), "Cannot specify 'inset' without 'child'") - assert(inset==0 || is_def(align), "Cannot specify 'inset' without 'align'") - assert(shiftout==0 || is_def(child), "Cannot specify 'shiftout' without 'child'"); + dummy2=assert(align_list==[undef] || is_def(child), "\nCannot use 'align' without 'child'.") + assert(!inside || is_def(child), "\nCannot use 'inside' without 'child'.") + assert(inset==0 || is_def(child), "\nCannot specify 'inset' without 'child'.") + assert(inset==0 || is_def(align), "\nCannot specify 'inset' without 'align'.") + assert(shiftout==0 || is_def(child), "\nCannot specify 'shiftout' without 'child'."); factor = inside?-1:1; $attach_to = child; for (anch_ind = idx(anchors)) { dummy=assert(is_string(anchors[anch_ind]) || (is_vector(anchors[anch_ind]) && (len(anchors[anch_ind])==2 || len(anchors[anch_ind])==3)), - str("parent[",anch_ind,"] is ",anchors[anch_ind]," but it must be a named anchor (string) or a 2-vector or 3-vector")) + str("\nParent[",anch_ind,"] is ",anchors[anch_ind]," but it must be a named anchor (string), a 2-vector, or 3-vector.")) assert(align_list==[undef] || !is_string(anchors[anch_ind]), - str("parent[",anch_ind,"] is a named anchor (",anchors[anch_ind],"), but named anchors are not supported with align=")); + str("\nParent[",anch_ind,"] is a named anchor (",anchors[anch_ind],"), but named anchors are not supported with align=.")); anchor = is_string(anchors[anch_ind])? anchors[anch_ind] : two_d?_force_anchor_2d(anchors[anch_ind]) : point3d(anchors[anch_ind]); @@ -995,7 +995,7 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, parent_abstract_anchor = is_vector(anchor) && !two_d ? _find_anchor(_make_anchor_legal(anchor,basegeom),basegeom) : undef; for(align_ind = idx(align_list)){ align = is_undef(align_list[align_ind]) ? undef - : assert(is_vector(align_list[align_ind],2) || is_vector(align_list[align_ind],3), "align direction must be a 2-vector or 3-vector") + : assert(is_vector(align_list[align_ind],2) || is_vector(align_list[align_ind],3), "\nAlign direction must be a 2-vector or 3-vector.") two_d ? _force_anchor_2d(align_list[align_ind]) : point3d(align_list[align_ind]); spin = is_num(spin) ? spin @@ -1024,10 +1024,10 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, badcorner = !in_list($parent_geom[0],["conoid","spheroid"]) && !is_undef(align) && align!=CTR && sum(v_abs(anchor))==3; badsphere = $parent_geom[0]=="spheroid" && !is_undef(align) && align!=CTR; dummy=assert(is_undef(align) || all_zero(v_mul(anchor,align)), - str("Invalid alignment: align value (",align,") includes component parallel to parent anchor (",anchor,")")) - assert(goodcyl, str("Cannot use align with an anchor on a curved edge or surface of a cylinder at parent anchor (",anchor,")")) - assert(!badcorner, str("Cannot use align at a corner anchor (",anchor,")")) - assert(!badsphere, "Cannot use align on spheres."); + str("\nInvalid alignment: align value (",align,") includes component parallel to parent anchor (",anchor,").")) + assert(goodcyl, str("\nCannot use align with an anchor on a curved edge or surface of a cylinder at parent anchor (",anchor,").")) + assert(!badcorner, str("\nCannot use align at a corner anchor (",anchor,").")) + assert(!badsphere, "\nCannot use align on spheres."); // Now compute position on the parent (including alignment but not inset) where the child will be anchored pos = is_undef(align) ? anchor_data[1] : _find_anchor(anchor+align, $parent_geom)[1]; $attach_anchor = list_set(anchor_data, 1, pos); // Never used; For user informational use? Should this be set at all? @@ -1100,9 +1100,9 @@ module attach(parent, child, overlap, align, spin=0, norot, inset=0, shiftout=0, module attach_part(name) { req_children($children); - dummy=assert(!is_undef($parent_parts), "Parent does not exist or does not have any parts"); + dummy=assert(!is_undef($parent_parts), "\nParent does not exist or does not have any parts."); ind = search([name], $parent_parts, 1,0)[0]; - dummy2 = assert(ind!=[], str("Parent does not have a part named ",name)); + dummy2 = assert(ind!=[], str("\nParent does not have a part named \"",name,"\".")); $parent_geom = $parent_parts[ind][1]; $anchor_inside = $parent_parts[ind][2]; T = $parent_parts[ind][3]; @@ -1145,8 +1145,8 @@ module tag(tag) { req_children($children); check= - assert(is_string(tag),"tag must be a string") - assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed")); + assert(is_string(tag),"\n'tag' must be a string.") + assert(undef==str_find(tag," "),str("\nTag string \"",tag,"\" contains a space, which is not allowed.")); $tag = str($tag_prefix,tag); children(); } @@ -1178,8 +1178,8 @@ module tag_this(tag) { req_children($children); check= - assert(is_string(tag),"tag must be a string") - assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed")); + assert(is_string(tag),"\n'tag' must be a string.") + assert(undef==str_find(tag," "),str("\nTag string \"",tag,"\" contains a space, which is not allowed.")); $save_tag=default($tag,""); $tag = str($tag_prefix,tag); children(); @@ -1239,9 +1239,9 @@ module tag_this(tag) module force_tag(tag) { req_children($children); - check1=assert(is_undef(tag) || is_string(tag),"tag must be a string"); + check1=assert(is_undef(tag) || is_string(tag),"\n'tag' must be a string."); $tag = str($tag_prefix,default(tag,$tag)); - assert(undef==str_find($tag," "),str("Tag string \"",$tag,"\" contains a space, which is not allowed")); + assert(undef==str_find($tag," "),str("\nTag string \"",$tag,"\" contains a space, which is not allowed.")); if(_is_shown()) show_all() children(); @@ -1382,8 +1382,8 @@ module default_tag(tag,do_tag=true) module tag_scope(scope){ req_children($children); scope = is_undef(scope) ? rand_str(20) : scope; - assert(is_string(scope), "scope must be a string"); - assert(undef==str_find(scope," "),str("Scope string \"",scope,"\" contains a space, which is not allowed")); + assert(is_string(scope), "\n'scope' must be a string."); + assert(undef==str_find(scope," "),str("\nScope string \"",scope,"\" contains a space, which is not allowed.")); $tag_prefix=scope; children(); } @@ -1569,8 +1569,8 @@ module tag_scope(scope){ module diff(remove="remove", keep="keep") { req_children($children); - assert(is_string(remove),"remove must be a string of tags"); - assert(is_string(keep),"keep must be a string of tags"); + assert(is_string(remove),"\n'remove' must be a string of tags."); + assert(is_string(keep),"\n'keep' must be a string of tags."); if (_is_shown()) { difference() { @@ -1637,10 +1637,10 @@ module diff(remove="remove", keep="keep") module tag_diff(tag="",remove="remove", keep="keep") { req_children($children); - assert(is_string(remove),"remove must be a string of tags"); - assert(is_string(keep),"keep must be a string of tags"); - assert(is_string(tag),"tag must be a string"); - assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed")); + assert(is_string(remove),"\n'remove' must be a string of tags."); + assert(is_string(keep),"\n'keep' must be a string of tags."); + assert(is_string(tag),"\n'tag' must be a string."); + assert(undef==str_find(tag," "),str("\nTag string \"",tag,"\" contains a space, which is not allowed.")); $tag=str($tag_prefix,tag); if (_is_shown()) show_all(){ @@ -1715,8 +1715,8 @@ module tag_diff(tag="",remove="remove", keep="keep") // } module intersect(intersect="intersect",keep="keep") { - assert(is_string(intersect),"intersect must be a string of tags"); - assert(is_string(keep),"keep must be a string of tags"); + assert(is_string(intersect),"\n'intersect' must be a string of tags."); + assert(is_string(keep),"\n'keep' must be a string of tags."); intersection(){ show_only(intersect) children(); hide(str(intersect," ",keep)) children(); @@ -1765,10 +1765,10 @@ module intersect(intersect="intersect",keep="keep") // } module tag_intersect(tag="",intersect="intersect",keep="keep") { - assert(is_string(intersect),"intersect must be a string of tags"); - assert(is_string(keep),"keep must be a string of tags"); - assert(is_string(tag),"tag must be a string"); - assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed")); + assert(is_string(intersect),"\n'intersect' must be a string of tags."); + assert(is_string(keep),"\n'keep' must be a string of tags."); + assert(is_string(tag),"\n'tag' must be a string."); + assert(undef==str_find(tag," "),str("\nTag string \"",tag,"\" contains a space, which is not allowed.")); $tag=str($tag_prefix,tag); if (_is_shown()) show_all(){ @@ -1813,7 +1813,7 @@ module tag_intersect(tag="",intersect="intersect",keep="keep") module conv_hull(keep="keep") { req_children($children); - assert(is_string(keep),"keep must be a string of tags"); + assert(is_string(keep),"\n'keep' must be a string of tags."); if (_is_shown()) hull() hide(keep) children(); show_int(keep) children(); @@ -1860,9 +1860,9 @@ module conv_hull(keep="keep") module tag_conv_hull(tag="",keep="keep") { req_children($children); - assert(is_string(keep),"keep must be a string of tags"); - assert(is_string(tag),"tag must be a string"); - assert(undef==str_find(tag," "),str("Tag string \"",tag,"\" contains a space, which is not allowed")); + assert(is_string(keep),"\n'keep' must be a string of tags."); + assert(is_string(tag),"\n'tag' must be a string."); + assert(undef==str_find(tag," "),str("\nTag string \"",tag,"\" contains a space, which is not allowed.")); $tag=str($tag_prefix,tag); if (_is_shown()) show_all(){ @@ -1900,7 +1900,7 @@ module tag_conv_hull(tag="",keep="keep") module hide(tags) { req_children($children); - dummy=assert(is_string(tags), "tags must be a string"); + dummy=assert(is_string(tags), "\n'tags' must be a string."); taglist = [for(s=str_split(tags," ",keep_nulls=false)) str($tag_prefix,s)]; $tags_hidden = concat($tags_hidden,taglist); children(); @@ -1961,7 +1961,7 @@ module hide_this() module show_only(tags) { req_children($children); - dummy=assert(is_string(tags), str("tags must be a string",tags)); + dummy=assert(is_string(tags), str("\n'tags' must be a string.",tags)); taglist = [for(s=str_split(tags," ",keep_nulls=false)) str($tag_prefix,s)]; $tags_shown = taglist; children(); @@ -2004,7 +2004,7 @@ module show_all() module show_int(tags) { req_children($children); - dummy=assert(is_string(tags), str("tags must be a string",tags)); + dummy=assert(is_string(tags), str("\n'tags' must be a string.",tags)); taglist = [for(s=str_split(tags," ",keep_nulls=false)) str($tag_prefix,s)]; $tags_shown = $tags_shown == "ALL" ? taglist : set_intersection($tags_shown,taglist); children(); @@ -2049,8 +2049,8 @@ module show_int(tags) module face_mask(faces=[LEFT,RIGHT,FRONT,BACK,BOT,TOP]) { req_children($children); faces = is_vector(faces)? [faces] : faces; - assert(all([for (face=faces) is_vector(face) && sum([for (x=face) x!=0? 1 : 0])==1]), "Vector in faces doesn't point at a face."); - assert($parent_geom != undef, "No object to attach to!"); + assert(all([for (face=faces) is_vector(face) && sum([for (x=face) x!=0? 1 : 0])==1]), "\nVector in faces doesn't point at a face."); + assert($parent_geom != undef, "\nNo object to attach to!"); attach(faces) { default_tag("remove") children(); } @@ -2094,7 +2094,7 @@ module face_mask(faces=[LEFT,RIGHT,FRONT,BACK,BOT,TOP]) { // rounding_edge_mask(l=71,r=10); module edge_mask(edges=EDGES_ALL, except=[]) { req_children($children); - assert($parent_geom != undef, "No object to attach to!"); + assert($parent_geom != undef, "\nNo object to attach to!"); edges = _edges(edges, except=except); vecs = [ for (i = [0:3], axis=[0:2]) @@ -2104,7 +2104,7 @@ module edge_mask(edges=EDGES_ALL, except=[]) { for ($idx = idx(vecs)) { vec = vecs[$idx]; vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0); - dummy=assert(vcount == 2, "Not an edge vector!"); + dummy=assert(vcount == 2, "\nNot an edge vector!"); anch = _find_anchor(vec, $parent_geom); $edge_angle = len(anch)==5 ? struct_val(anch[4],"edge_angle") : undef; $edge_length = len(anch)==5 ? struct_val(anch[4],"edge_length") : undef; @@ -2151,13 +2151,13 @@ module edge_mask(edges=EDGES_ALL, except=[]) { // } module corner_mask(corners=CORNERS_ALL, except=[]) { req_children($children); - assert($parent_geom != undef, "No object to attach to!"); + assert($parent_geom != undef, "\nNo object to attach to!"); corners = _corners(corners, except=except); vecs = [for (i = [0:7]) if (corners[i]>0) CORNER_OFFSETS[i]]; for ($idx = idx(vecs)) { vec = vecs[$idx]; vcount = (vec.x?1:0) + (vec.y?1:0) + (vec.z?1:0); - dummy=assert(vcount == 3, "Not an edge vector!"); + dummy=assert(vcount == 3, "\nNot an edge vector!"); anch = _find_anchor(vec, $parent_geom); $attach_to = undef; $attach_anchor = anch; @@ -2202,7 +2202,7 @@ module corner_mask(corners=CORNERS_ALL, except=[]) { module face_profile(faces=[], r, d, excess=0.01, convexity=10) { req_children($children); faces = is_vector(faces)? [faces] : faces; - assert(all([for (face=faces) is_vector(face) && sum([for (x=face) x!=0? 1 : 0])==1]), "Vector in faces doesn't point at a face."); + assert(all([for (face=faces) is_vector(face) && sum([for (x=face) x!=0? 1 : 0])==1]), "\nVector in faces doesn't point at a face."); r = get_radius(r=r, d=d, dflt=undef); assert(is_num(r) && r>=0); edge_profile(faces, excess=excess) children(); @@ -2256,11 +2256,11 @@ module face_profile(faces=[], r, d, excess=0.01, convexity=10) { module edge_profile(edges=EDGES_ALL, except=[], excess=0.01, convexity=10) { req_children($children); - check1 = assert($parent_geom != undef, "No object to attach to!"); + check1 = assert($parent_geom != undef, "\nNo object to attach to!"); conoid = $parent_geom[0] == "conoid"; edges = !conoid? _edges(edges, except=except) : edges==EDGES_ALL? [TOP,BOT] : - assert(all([for (e=edges) in_list(e,[TOP,BOT])]), "Invalid conoid edge spec.") + assert(all([for (e=edges) in_list(e,[TOP,BOT])]), "\nInvalid conoid edge spec.") edges; vecs = conoid ? [for (e=edges) e+FWD] @@ -2270,7 +2270,7 @@ module edge_profile(edges=EDGES_ALL, except=[], excess=0.01, convexity=10) { EDGE_OFFSETS[axis][i] ]; all_vecs_are_edges = all([for (vec = vecs) sum(v_abs(vec))==2]); - check2 = assert(all_vecs_are_edges, "All vectors must be edges."); + check2 = assert(all_vecs_are_edges, "\nAll vectors must be edges."); default_tag("remove") for ($idx = idx(vecs)) { vec = vecs[$idx]; @@ -2452,7 +2452,7 @@ module edge_profile_asym( [BACK+RIGHT, [TOP+BACK, BOT+BACK]], ], i = search([from], flip_edges, num_returns_per_match=1)[0], - check = assert(i!=[], "Bad edge vector.") + check = assert(i!=[], "\nBad edge vector.") ) in_list(to,flip_edges[i][1]); function _edge_corner_numbers(vec) = @@ -2467,7 +2467,7 @@ module edge_profile_asym( function _gather_contiguous_edges(edge_corners) = let( no_tri_corners = all([for(cn = [0:7]) len([for (ec=edge_corners) if(in_list(cn,ec[1])) 1])<3]), - check = assert(no_tri_corners, "Cannot have three edges that meet at the same corner.") + check = assert(no_tri_corners, "\nCannot have three edges that meet at the same corner.") ) _gather_contiguous_edges_r( [for (i=idx(edge_corners)) if(i) edge_corners[i]], @@ -2552,7 +2552,7 @@ module edge_profile_asym( [for (i=[0:2]) if (abs(e1[i])==1 && e1[i]==e2[i]) -e1[i] else 0]; req_children($children); - check1 = assert($parent_geom != undef, "No object to attach to!") + check1 = assert($parent_geom != undef, "\nNo object to attach to!") assert(in_list(corner_type, ["none", "round", "chamfer", "sharp"])) assert(is_bool(flip)); edges = _edges(edges, except=except); @@ -2562,7 +2562,7 @@ module edge_profile_asym( EDGE_OFFSETS[axis][i] ]; all_vecs_are_edges = all([for (vec = vecs) sum(v_abs(vec))==2]); - check2 = assert(all_vecs_are_edges, "All vectors must be edges."); + check2 = assert(all_vecs_are_edges, "\nAll vectors must be edges."); edge_corners = [for (vec = vecs) [vec, _edge_corner_numbers(vec)]]; edge_strings = _gather_contiguous_edges(edge_corners); default_tag("remove") @@ -2688,13 +2688,13 @@ module edge_profile_asym( // mask2d_teardrop(r=10, angle=40); // } module corner_profile(corners=CORNERS_ALL, except=[], r, d, convexity=10) { - check1 = assert($parent_geom != undef, "No object to attach to!"); + check1 = assert($parent_geom != undef, "\nNo object to attach to!"); r = max(0.01, get_radius(r=r, d=d, dflt=undef)); - check2 = assert(is_num(r), "Bad r/d argument."); + check2 = assert(is_num(r), "\nBad r/d argument."); corners = _corners(corners, except=except); vecs = [for (i = [0:7]) if (corners[i]>0) CORNER_OFFSETS[i]]; all_vecs_are_corners = all([for (vec = vecs) sum(v_abs(vec))==3]); - check3 = assert(all_vecs_are_corners, "All vectors must be corners."); + check3 = assert(all_vecs_are_corners, "\nAll vectors must be corners."); for ($idx = idx(vecs)) { vec = vecs[$idx]; anch = _find_anchor(vec, $parent_geom); @@ -3121,11 +3121,11 @@ module attachable( expose_tags=false, keep_color=false ) { dummy1 = - assert($children==2, "attachable() expects exactly two children; the shape to manage, and the union of all attachment candidates.") + assert($children==2, "\nattachable() expects exactly two children: the shape to manage, and the union of all attachment candidates.") assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor)) - assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin)) - assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient)); - assert(in_list(v_abs(axis),[UP,RIGHT,BACK]), "axis must be a coordinate direction"); + assert(is_undef(spin) || is_finite(spin), str("\nInvalid spin: ",spin)) + assert(is_undef(orient) || is_vector(orient,3), str("\nInvalid orient: ",orient)); + assert(in_list(v_abs(axis),[UP,RIGHT,BACK]), "\n'axis' must be a coordinate direction."); anchor = default(anchor,CENTER); spin = default(spin,0); orient = is_def($anchor_override)? UP : default(orient, UP); @@ -3300,9 +3300,9 @@ function reorient( geom, p=undef ) = - assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor)) - assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin)) - assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient)) + assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("\nInvalid anchor: ",anchor)) + assert(is_undef(spin) || is_finite(spin), str("\nInvalid spin: ",spin)) + assert(is_undef(orient) || is_vector(orient,3), str("\nInvalid orient: ",orient)) let( anchor = default(anchor, CENTER), spin = default(spin, 0), @@ -3348,15 +3348,15 @@ function reorient( // rot = A 4x4 rotations matrix, which may include a translation // flip = If true, flip the anchor the opposite direction. Default: false function named_anchor(name, pos, orient, spin, rot, flip, info) = - assert(num_defined([orient,spin])==0 || num_defined([rot,flip])==0, "Cannot mix orient or spin with rot or flip") - assert(num_defined([pos,rot])>0, "Must give pos or rot") + assert(num_defined([orient,spin])==0 || num_defined([rot,flip])==0, "\nCannot mix orient or spin with rot or flip.") + assert(num_defined([pos,rot])>0, "\nMust give pos or rot") is_undef(rot) ? [name, pos, default(orient,UP), default(spin,0), if (info) info] : let( flip = default(flip,false), pos = default(pos,apply(rot,CTR)), rotpart = _force_rot(rot), - dummy = assert(approx(det4(rotpart),1), "Input rotation is not a rotation matrix"), + dummy = assert(approx(det4(rotpart),1), "\nInput rotation is not a rotation matrix."), dir = flip ? apply(rotpart,DOWN) : apply(rotpart,UP), rot = flip? affine3d_rot_by_axis(apply(rotpart,BACK),180)*rot @@ -3540,11 +3540,11 @@ function attach_geom( assert(is_region(region),2) let( l = default(l, h) ) two_d==true - ? assert(is_undef(l), "Cannot give l/h with region anchor types (when two_d is set)") + ? assert(is_undef(l), "\nCannot give l/h with region anchor types (when two_d is set).") extent==true ? ["rgn_extent", region, cp, offset, anchors] : ["rgn_isect", region, cp, offset, anchors] - : assert(is_finite(l), "Must give l/h with extrusion anchor types (did you forget to set two_d?)") + : assert(is_finite(l), "\nMust give l/h with extrusion anchor types (did you forget to set two_d?).") let( shift = default(shift, [0,0]), scale = is_num(scale)? [scale,scale] : default(scale, [1,1]), @@ -3623,10 +3623,10 @@ function attach_geom( // } function define_part(name, geom, inside=false, T=IDENT) = - assert(is_string(name), "name must be a string") - assert(_is_geometry(geom), "geometry appears invalid") - assert(is_bool(inside), "inside must be boolean") - assert(is_matrix(T,4), "T must be a 4x4 transformation matrix") + assert(is_string(name), "\n'name' must be a string.") + assert(_is_geometry(geom), "\ngeometry appears invalid.") + assert(is_bool(inside), "\n'inside' must be boolean.") + assert(is_matrix(T,4), "\nT must be a 4×4 transformation matrix.") [name, geom, inside, T]; @@ -3714,7 +3714,7 @@ function _attach_geom_size(geom) = delt = mm[1]-mm[0] ) [delt.x, delt.y] ) : - assert(false, "Unknown attachment geometry type."); + assert(false, "\nUnknown attachment geometry type."); @@ -3727,7 +3727,7 @@ function _attach_geom_size(geom) = /// Returns the path and post-transform matrix of the indicated edge. /// If the edge is invalid for the geometry, returns `undef`. function _attach_geom_edge_path(geom, edge) = - assert(is_vector(edge),str("Invalid edge: edge=",edge)) + assert(is_vector(edge),str("\nInvalid edge: ",edge)) let( type = geom[0], cp = _get_cp(geom), @@ -3737,9 +3737,9 @@ function _attach_geom_edge_path(geom, edge) = ) type == "prismoid"? ( //size, size2, shift, axis let(all_comps_good = [for (c=edge) if (c!=sign(c)) 1]==[]) - assert(all_comps_good, "All components of an edge for a cuboid/prismoid must be -1, 0, or 1") + assert(all_comps_good, "\nAll components of an edge for a cuboid/prismoid must be -1, 0, or 1.") let(edge_good = len([for (c=edge) if(c) 1])==2) - assert(edge_good, "Invalid edge.") + assert(edge_good, "\nInvalid edge.") let( size = geom[1], size2 = geom[2], @@ -3776,7 +3776,7 @@ function _attach_geom_edge_path(geom, edge) = m = rot(from=UP,to=axis) * move(offset) ) [path, [vecs], m] ) : type == "conoid"? ( //r1, r2, l, shift, axis - assert(edge.z && edge.z == sign(edge.z), "The Z component of an edge for a cylinder/cone must be -1 or 1") + assert(edge.z && edge.z == sign(edge.z), "\nThe Z component of an edge for a cylinder/cone must be -1 or 1.") let( rr1 = geom[1], rr2 = geom[2], @@ -3830,9 +3830,9 @@ function _attach_geom_edge_path(geom, edge) = /// p = If given as a VNF, path, or point, applies the affine3d transformation matrix to it and returns the result. function _attach_transform(anchor, spin, orient, geom, p) = - assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("Invalid anchor: ",anchor)) - assert(is_undef(spin) || is_finite(spin), str("Invalid spin: ",spin)) - assert(is_undef(orient) || is_vector(orient,3), str("Invalid orient: ",orient)) + assert(is_undef(anchor) || is_vector(anchor) || is_string(anchor), str("\nInvalid anchor: ",anchor)) + assert(is_undef(spin) || is_finite(spin), str("\nInvalid spin: ",spin)) + assert(is_undef(orient) || is_vector(orient,3), str("\nInvalid orient: ",orient)) let( anchor=default(anchor,CENTER), spin=default(spin,0), @@ -3888,7 +3888,7 @@ function _get_cp(geom) = : in_list(geom[0],["extrusion_extent","extrusion_isect"]) ? "xpath" : "other" ) - assert(type!="other", "Invalid cp value") + assert(type!="other", "\nInvalid cp value.") cp=="centroid" ? ( type=="vnf" && (len(geom[1][0])==0 || len(geom[1][1])==0) ? [0,0,0] : [each centroid(geom[1]), if (type=="xpath") 0] @@ -3896,7 +3896,7 @@ function _get_cp(geom) = : let(points = type=="vnf"?geom[1][0]:flatten(force_region(geom[1]))) cp=="mean" ? [each mean(points), if (type=="xpath") 0] : cp=="box" ?[each mean(pointlist_bounds(points)), if (type=="xpath") 0] - : assert(false,"Invalid cp specification"); + : assert(false,"\nInvalid cp specification."); function _get_cp(geom) = @@ -3913,7 +3913,7 @@ function _get_cp(geom) = : let(points = is_vnf?geom[1][0]:flatten(force_region(geom[1]))) cp=="mean" ? mean(points) : cp=="box" ? mean(pointlist_bounds(points)) - : assert(false,"Invalid cp specification"); + : assert(false,"\nInvalid cp specification."); @@ -3949,7 +3949,7 @@ function _find_anchor(anchor, geom)= anchors = last(geom), found = search([anchor], anchors, num_returns_per_match=1)[0] ) - assert(found!=[], str("Unknown anchor: ",anchor)) + assert(found!=[], str("\nUnknown anchor: ",anchor)) anchors[found] ) : let( @@ -3958,7 +3958,7 @@ function _find_anchor(anchor, geom)= offset = [for (i=[0:2]) anchor[i]==0? 0 : offset_raw[i]], // prevents bad centering. type = geom[0] ) - assert(is_vector(anchor),str("Invalid anchor: anchor=",anchor)) + assert(is_vector(anchor),str("\nInvalid anchor: ",anchor)) let( anchor = point3d(anchor), oang = ( @@ -3968,7 +3968,7 @@ function _find_anchor(anchor, geom)= ) type == "prismoid"? ( //size, size2, shift, axis let(all_comps_good = [for (c=anchor) if (c!=sign(c)) 1]==[]) - assert(all_comps_good, "All components of an anchor for a cuboid/prismoid must be -1, 0, or 1") + assert(all_comps_good, "\nAll components of an anchor for a cuboid/prismoid must be -1, 0, or 1.") let( size=geom[1], size2=geom[2], @@ -4059,7 +4059,7 @@ function _find_anchor(anchor, geom)= : axis==RIGHT ? "X" : axis==BACK ? "Y" : "", - dummy = assert(anch.z == sign(anch.z), str("The ",axisname," component of an anchor for the cylinder/cone must be -1, 0, or 1")), + dummy = assert(anch.z == sign(anch.z), str("\nThe ",axisname," component of an anchor for the cylinder/cone must be -1, 0, or 1.")), offset = rot(from=axis, to=UP, p=offset), u = (anch.z+1)/2, // Returns [point,tangent_dir] @@ -4144,7 +4144,7 @@ function _find_anchor(anchor, geom)= for(pt=ptlist) [anchor * (pt-cp), n, pt] ] ) - assert(len(hits)>0, "Anchor vector does not intersect with the shape. Attachment failed.") + assert(len(hits)>0, "\nAnchor vector does not intersect with the shape. Attachment failed.") let( furthest = max_index(column(hits,0)), dist = hits[furthest][0], @@ -4169,8 +4169,8 @@ function _find_anchor(anchor, geom)= let( vnf=geom[1], override = geom[2](anchor) - ,fd=echo(cp=cp) - ) // CENTER anchors anchor on cp, "origin" anchors on [0,0] + //,fd=echo(cp=cp) + ) // CENTER anchors anchor on cp, "origin" anchors on [0,0] approx(anchor,CTR)? [anchor, default(override[0],cp),default(override[1],UP),default(override[2], 0)] : vnf==EMPTY_VNF? [anchor, [0,0,0], unit(anchor,UP), 0] : let( @@ -4236,7 +4236,7 @@ function _find_anchor(anchor, geom)= center = mean(plist) ) [center,anchor,basic_spin] - : len(vlist)==0 ? assert(false,"Cannot find anchor on the VNF") + : len(vlist)==0 ? assert(false,"\nCannot find anchor on the VNF.") : let( vlist = flatten(vlist), uind = unique_approx_indexed(select(vnf[0],vlist)), @@ -4266,7 +4266,7 @@ function _find_anchor(anchor, geom)= ) [anchor, default(override[0],res[0]),default(override[1],res[1]),default(override[2],res[2]),if (len(res)==3) res[2]] ) : type == "trapezoid"? ( //size, size2, shift, override let(all_comps_good = [for (c=anchor) if (c!=sign(c)) 1]==[]) - assert(all_comps_good, "All components of an anchor for a rectangle/trapezoid must be -1, 0, or 1") + assert(all_comps_good, "\nAll components of an anchor for a rectangle/trapezoid must be -1, 0, or 1.") let( anchor=_force_anchor_2d(anchor), size=geom[1], size2=geom[2], shift=geom[3], @@ -4318,7 +4318,7 @@ function _find_anchor(anchor, geom)= if(!is_undef(isect) && !approx(isect,t[0])) [norm(isect), isect, n2] ] ) - assert(len(isects)>0, "Anchor vector does not intersect with the shape. Attachment failed.") + assert(len(isects)>0, "\nAnchor vector does not intersect with the shape. Attachment failed.") let( maxidx = max_index(column(isects,0)), isect = isects[maxidx], @@ -4347,7 +4347,7 @@ function _find_anchor(anchor, geom)= [is_polygon_clockwise(path) ? -normal : normal, vector_angle(corner)] ) [anchor, pos, dir[0], 0, if(len(dir)>1) [["corner_angle",dir[1]]]] ) : type=="extrusion_extent" || type=="extrusion_isect" ? ( // extruded region - assert(in_list(anchor.z,[-1,0,1]), "The Z component of an anchor for an extruded 2D shape must be -1, 0, or 1.") + assert(in_list(anchor.z,[-1,0,1]), "\nThe Z component of an anchor for an extruded 2D shape must be -1, 0, or 1.") let( anchor_xy = point2d(anchor), rgn = geom[1], @@ -4379,7 +4379,7 @@ function _find_anchor(anchor, geom)= ) [anchor, pos, vec, oang] ) : - assert(false, "Unknown attachment geometry type."); + assert(false, "\nUnknown attachment geometry type."); /// Internal Function: _is_shown() @@ -4396,8 +4396,8 @@ function _is_shown() = dummy=is_undef($tags) ? 0 : echo("Use tag() instead of $tags for specifying an object's tag."), $tag = default($tag,$tags) ) - assert(is_string($tag), str("Tag value (",$tag,") is not a string")) - assert(undef==str_find($tag," "),str("Tag string \"",$tag,"\" contains a space, which is not allowed")) + assert(is_string($tag), str("\nTag value (",$tag,") is not a string")) + assert(undef==str_find($tag," "),str("\nTag string \"",$tag,"\" contains a space, which is not allowed.")) let( shown = $tags_shown=="ALL" || in_list($tag,$tags_shown), hidden = in_list($tag, $tags_hidden) @@ -4822,7 +4822,7 @@ function _edge_set(v) = let(valid_values = ["X", "Y", "Z", "ALL", "NONE"]) assert( in_list(v, valid_values), - str(v, " must be a vector, edge array, or one of ", valid_values) + str("\n", v, " must be a vector, edge array, or one of ", valid_values, ".") ) v ) : let(nonz = sum(v_abs(v))) @@ -4983,7 +4983,7 @@ function _corner_set(v) = let(valid_values = ["ALL", "NONE"]) assert( in_list(v, valid_values), - str(v, " must be a vector, corner array, or one of ", valid_values) + str("\n", v, " must be a vector, corner array, or one of ", valid_values, ".") ) v ) : all([for (i=[0:2]) !v[i] || (v[i]==v2[i])]) @@ -5114,14 +5114,14 @@ function _force_rot(T) = : 0]]; function _local_struct_val(struct, key)= - assert(is_def(key),"key is missing") + assert(is_def(key),"\nkey is missing.") let(ind = search([key],struct)[0]) ind == [] ? undef : struct[ind][1]; function _force_anchor_2d(anchor) = is_undef(anchor) || len(anchor)==2 || is_string(anchor) ? anchor : - assert(anchor.y==0 || anchor.z==0, "Anchor for a 2D shape cannot be fully 3D. It must have either Y or Z component equal to zero.") + assert(anchor.y==0 || anchor.z==0, "\nAnchor for a 2D shape cannot be fully 3D. It must have either Y or Z component equal to zero.") anchor.y==0 ? [anchor.x,anchor.z] : point2d(anchor); // Compute spin angle based on a anchor direction and desired spin direction @@ -5132,7 +5132,7 @@ function _compute_spin(anchor_dir, spin_dir) = let( native_dir = rot(from=UP, to=anchor_dir, p=BACK), spin_dir = spin_dir - (spin_dir*anchor_dir)*anchor_dir, // component of spin_dir perpendicular to anchor_dir - dummy = assert(!approx(spin_dir,[0,0,0]),"spin direction is parallel to anchor"), + dummy = assert(!approx(spin_dir,[0,0,0]),"\nSpin direction is parallel to anchor."), angle = vector_angle(native_dir,spin_dir), sign = cross(native_dir,spin_dir)*anchor_dir<0 ? -1 : 1 ) @@ -5216,11 +5216,11 @@ function parent() = // fillet=1); function parent_part(name) = - assert(!is_undef($parent_parts), "Parent does not exist or does not have any parts") + assert(!is_undef($parent_parts), "\nParent does not exist or does not have any parts.") let( ind = search([name], $parent_parts, 1,0)[0] ) - assert(ind!=[], str("Parent does not have a part named ",name)) + assert(ind!=[], str("\nParent does not have a part named \"",name,"\".")) [$transform * $parent_parts[ind][3], $parent_parts[ind][1]]; @@ -5251,7 +5251,7 @@ module restore(desc) multmatrix(T) children(); } else{ - check=assert(is_description(desc), "Invalid description"); + check=assert(is_description(desc), "\nInvalid description."); T = linear_solve($transform, desc[0]); $parent_geom = desc[1]; multmatrix(T) children(); @@ -5286,13 +5286,13 @@ module restore(desc) // stroke([[0,0,0], desc_point(desc,anchor=TOP+FWD+RIGHT)],width=.5,color="red"); function desc_point(desc, p, anchor) = is_undef(desc) ? - assert(is_undef(anchor), "Cannot give anchor withot desc") + assert(is_undef(anchor), "\nCannot give 'anchor' withot 'desc'.") let( T = matrix_inverse($transform) ) apply(T, default(p,UP)) - : assert(is_description(desc), "Invalid description") - assert(num_defined([anchor,p])<2, "Cannot give both anchor and p") + : assert(is_description(desc), "\nInvalid description.") + assert(num_defined([anchor,p])<2, "\nCannot give both anchor and p") let ( T = linear_solve($transform, desc[0]), p = is_def(p) ? p @@ -5328,14 +5328,14 @@ function desc_point(desc, p, anchor) = // position(TOP) cyl(d=2,h=15,orient=desc_dir(pris,anchor=FWD),anchor=LEFT); function desc_dir(desc, dir, anchor) = is_undef(desc) ? - assert(is_undef(anchor), "Cannot give anchor without desc") + assert(is_undef(anchor), "\nCannot give 'anchor' without 'desc'.") let( T = matrix_inverse($transform) ) move(-apply(T,CENTER), apply(T, default(dir,UP))) : assert(is_description(desc), "Invalid description") - assert(num_defined([dir,anchor])<2, "Cannot give both dir and anchor") + assert(num_defined([dir,anchor])<2, "\nCannot give both dir and anchor.") let( T = linear_solve($transform, desc[0]), dir = is_def(dir) ? dir @@ -5347,7 +5347,7 @@ function desc_dir(desc, dir, anchor) = move(-apply(T,CENTER),apply(T, dir)); function desc_attach(desc, anchor=UP, p, reverse=false) = - assert(is_description(desc), "Invalid description") + assert(is_description(desc), "\nInvalid description.") let( T = linear_solve($transform, desc[0]), anch = _find_anchor(anchor,desc[1]), @@ -5385,8 +5385,8 @@ function desc_attach(desc, anchor=UP, p, reverse=false) = // } function desc_dist(desc1,anchor1=CENTER, desc2, anchor2=CENTER)= - assert(is_description(desc1),"Invalid description: desc1") - assert(is_description(desc2),"Invalid description: desc2") + assert(is_description(desc1),str("\nInvalid description: desc1=",desc1)) + assert(is_description(desc2),str("\nInvalid description: desc2=",desc2)) let( anch1 = _find_anchor(anchor1, desc1[1]), anch2 = _find_anchor(anchor2, desc2[1]), @@ -5415,10 +5415,10 @@ function desc_dist(desc1,anchor1=CENTER, desc2, anchor2=CENTER)= // desc = description to transform function transform_desc(T,desc) = - assert(is_description(desc), "Invalid description") + assert(is_description(desc), "\nInvalid description.") is_consistent(T, ident(4)) ? [for(t=T) [t*desc[0], desc[1]]] : is_matrix(T,4,4) ? [T*desc[0], desc[1]] - : assert(false,"T must be a 4x4 matrix or list of 4x4 matrices"); + : assert(false,"\nT must be a 4×4 matrix or list of 4×4 matrices."); // Module: desc_copies() diff --git a/shapes3d.scad b/shapes3d.scad index d42d17a7..aa0fe99b 100644 --- a/shapes3d.scad +++ b/shapes3d.scad @@ -2544,22 +2544,27 @@ function xcyl( tex_taper, style, tex_style, extra, extra1, extra2, anchor, spin=0 -) = cyl(h=h, r=r, center=center, - l=l, r1=r1, r2=r2, - d=d, d1=d1, d2=d2, - length=length, height=height, - chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, - chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, - rounding=rounding, rounding1=rounding1, rounding2=rounding2, - circum=circum, realign=realign, shift=shift, - teardrop=teardrop, clip_angle=clip_angle, - from_end=from_end, from_end1=from_end1, from_end2=from_end2, - texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, - tex_inset=tex_inset, tex_rot=tex_rot, - tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, - tex_taper=tex_taper, style=style, tex_style=tex_style, - extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=RIGHT); +) = let( + r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), + r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), + l = one_defined([l,h,length,height],"l,h,length,height",1), + vnf=cyl(h=h, r=r, center=center, + l=l, r1=r1, r2=r2, + d=d, d1=d1, d2=d2, + length=length, height=height, + chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, + chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, + rounding=rounding, rounding1=rounding1, rounding2=rounding2, + circum=circum, realign=realign, shift=shift, + teardrop=teardrop, clip_angle=clip_angle, + from_end=from_end, from_end1=from_end1, from_end2=from_end2, + texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, + tex_inset=tex_inset, tex_rot=tex_rot, + tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, + tex_taper=tex_taper, style=style, tex_style=tex_style, + extra=extra, extra1=extra1, extra2=extra2, + anchor=CENTER, spin=0, orient=RIGHT) + ) reorient(anchor, spin, UP, p=vnf, r1=r1, r2=r2, l=l, axis=RIGHT); module xcyl( h, r, center, @@ -2577,7 +2582,7 @@ module xcyl( tex_scale, tex_depth, tex_samples, tex_taper, style, tex_style, extra, extra1, extra2, - anchor, spin=0 + anchor=CENTER, spin=0 ) { r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1); r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1); @@ -2597,7 +2602,7 @@ module xcyl( tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, tex_taper=tex_taper, style=style, tex_style=tex_style, extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=RIGHT + anchor=CENTER, spin=0, orient=RIGHT ); children(); } @@ -2650,22 +2655,28 @@ function ycyl( tex_taper, style, tex_style, extra, extra1, extra2, anchor, spin=0 -) = cyl(h=h, r=r, center=center, - l=l, r1=r1, r2=r2, - d=d, d1=d1, d2=d2, - length=length, height=height, - chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, - chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, - rounding=rounding, rounding1=rounding1, rounding2=rounding2, - circum=circum, realign=realign, shift=shift, - teardrop=teardrop, clip_angle=clip_angle, - from_end=from_end, from_end1=from_end1, from_end2=from_end2, - texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, - tex_inset=tex_inset, tex_rot=tex_rot, - tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, - tex_taper=tex_taper, style=style, tex_style=tex_style, - extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=BACK); +) = let( + r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), + r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), + l = one_defined([l,h,length,height],"l,h,length,height",1), + vnf=cyl(h=h, r=r, center=center, + l=l, r1=r1, r2=r2, + d=d, d1=d1, d2=d2, + length=length, height=height, + chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, + chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, + rounding=rounding, rounding1=rounding1, rounding2=rounding2, + circum=circum, realign=realign, shift=shift, + teardrop=teardrop, clip_angle=clip_angle, + from_end=from_end, from_end1=from_end1, from_end2=from_end2, + texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, + tex_inset=tex_inset, tex_rot=tex_rot, + tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, + tex_taper=tex_taper, style=style, tex_style=tex_style, + extra=extra, extra1=extra1, extra2=extra2, + anchor=CENTER, spin=0, orient=BACK) + ) reorient(anchor, spin, UP, p=vnf, r1=r1, r2=r2, l=l, axis=BACK); + module ycyl( @@ -2704,7 +2715,7 @@ module ycyl( tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, tex_taper=tex_taper, style=style, tex_style=tex_style, extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=BACK + anchor=CENTER, spin=0, orient=BACK ); children(); } @@ -2753,22 +2764,28 @@ function zcyl( tex_taper, style, tex_style, extra, extra1, extra2, anchor, spin=0 -) = cyl(h=h, r=r, center=center, - l=l, r1=r1, r2=r2, - d=d, d1=d1, d2=d2, - length=length, height=height, - chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, - chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, - rounding=rounding, rounding1=rounding1, rounding2=rounding2, - circum=circum, realign=realign, shift=shift, - teardrop=teardrop, clip_angle=clip_angle, - from_end=from_end, from_end1=from_end1, from_end2=from_end2, - texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, - tex_inset=tex_inset, tex_rot=tex_rot, - tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, - tex_taper=tex_taper, style=style, tex_style=tex_style, - extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=UP); +) = let( + r1 = get_radius(r1=r1, r=r, d1=d1, d=d, dflt=1), + r2 = get_radius(r1=r2, r=r, d1=d2, d=d, dflt=1), + l = one_defined([l,h,length,height],"l,h,length,height",1), + vnf=cyl(h=h, r=r, center=center, + l=l, r1=r1, r2=r2, + d=d, d1=d1, d2=d2, + length=length, height=height, + chamfer=chamfer, chamfer1=chamfer1, chamfer2=chamfer2, + chamfang=chamfang, chamfang1=chamfang1, chamfang2=chamfang2, + rounding=rounding, rounding1=rounding1, rounding2=rounding2, + circum=circum, realign=realign, shift=shift, + teardrop=teardrop, clip_angle=clip_angle, + from_end=from_end, from_end1=from_end1, from_end2=from_end2, + texture=texture, tex_size=tex_size, tex_reps=tex_reps, tex_counts=tex_counts, + tex_inset=tex_inset, tex_rot=tex_rot, + tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, + tex_taper=tex_taper, style=style, tex_style=tex_style, + extra=extra, extra1=extra1, extra2=extra2, + anchor=CENTER, spin=0, orient=UP) + ) reorient(anchor, spin, UP, p=vnf, r1=r1, r2=r2, l=l, axis=UP); + module zcyl( h, r, center, @@ -2805,7 +2822,7 @@ module zcyl( tex_scale=tex_scale, tex_depth=tex_depth, tex_samples=tex_samples, tex_taper=tex_taper, style=style, tex_style=tex_style, extra=extra, extra1=extra1, extra2=extra2, - anchor=anchor, spin=spin, orient=UP + anchor=CENTER, spin=0, orient=UP ); children(); }