├── .gitignore
├── README.md
├── bevel.scad
├── box-pcb.scad
├── box-shell.scad
├── bsf-screw.scad
├── bsf-thread.scad
├── bspp-screw.scad
├── bspp-thread.scad
├── bsw-screw.scad
├── bsw-thread.scad
├── cable-gland.scad
├── canvas.scad
├── design
├── octree.svg
└── thread-extrapolation.ods
├── electronic.scad
├── extensions.scad
├── extrude.scad
├── geometry.scad
├── glue.scad
├── hardware.scad
├── hirth-joint.scad
├── lib-screw.scad
├── lib-spiral.scad
├── mesh.scad
├── morph.scad
├── mx-knob.scad
├── mx-screw.scad
├── mx-thread.scad
├── mxf-screw.scad
├── mxf-thread.scad
├── polyhedron
└── rhombicosidodecahedron.scad
├── printing.scad
├── screw-stand.scad
├── sew.scad
├── snap-joint.scad
├── test
├── images
│ ├── clipart-library-penguin.jpg
│ ├── clipart-library-penguin.scad
│ ├── pixabay-morris-minor.png
│ └── pixabay-morris-minor.scad
├── screws
│ ├── test-bsf-screw-anim.scad
│ ├── test-bsf-screw-tutorial.scad
│ ├── test-bsf-screw-wall.scad
│ ├── test-bspp-screw-wall.scad
│ ├── test-bsw-screw-anim.scad
│ ├── test-bsw-screw-tutorial.scad
│ ├── test-bsw-screw-wall.scad
│ ├── test-lib-screw-profiles.scad
│ ├── test-lib-screw.scad
│ ├── test-mx-screw-anim.scad
│ ├── test-mx-screw-tutorial.scad
│ ├── test-mx-screw-wall.scad
│ ├── test-mxf-screw-anim.scad
│ ├── test-mxf-screw-tutorial.scad
│ ├── test-mxf-screw-wall.scad
│ ├── test-unc-screw-anim.scad
│ ├── test-unc-screw-tutorial.scad
│ ├── test-unc-screw-wall.scad
│ ├── test-unf-screw-anim.scad
│ ├── test-unf-screw-tutorial.scad
│ └── test-unf-screw-wall.scad
├── test-canvas-tutorial.scad
├── test-canvas.scad
├── test-extensions.scad
├── test-extrude.scad
├── test-geometry.scad
├── test-glue.scad
├── test-hardware.scad
├── test-hirth-joint.scad
├── test-mx-knob.scad
├── test-pixeled.scad
├── test-sew.scad
├── test-snap-joint-tutorial.scad
├── test-snap-joint.scad
└── threads
│ ├── test-bsf-thread.scad
│ ├── test-bspp-thread.scad
│ ├── test-bsw-thread.scad
│ ├── test-mx-thread.scad
│ ├── test-mxf-thread.scad
│ ├── test-thread-comparison.scad
│ ├── test-unc-thread.scad
│ └── test-unf-thread.scad
├── things
├── 2.5-3.5-to-525-drive-adapter.scad
├── AaaD-puzzle.scad
├── box-pcb_HW-411_LM2596.scad
├── box-pcb_SM-GPN30E.scad
├── box-pcb_ZC255800+MP1584EN.scad
├── confusing-pyramid.scad
├── minecraft
│ ├── creeper-lamp
│ │ ├── cable_path_svg.scad
│ │ ├── cable_path_svg.svg
│ │ ├── creeper-body.scad
│ │ ├── creeper-cable.scad
│ │ ├── creeper-const.scad
│ │ ├── creeper-foot.scad
│ │ ├── creeper-ground.scad
│ │ ├── creeper-head.scad
│ │ ├── creeper-lib.scad
│ │ ├── creeper-polygons.scad
│ │ ├── creeper.scad
│ │ ├── creeper_svg.scad
│ │ └── creeper_svg.svg
│ └── pickaxe
│ │ ├── pickaxe.scad
│ │ └── pickaxe_design.svg
├── office-tree-branch-beds.scad
├── office-tree.scad
├── pixeled
│ ├── cap.scad
│ ├── const.scad
│ ├── layout.scad
│ ├── nail.scad
│ └── pixel.scad
├── snap-star.scad
├── tas-wrench-stand.scad
└── tools
│ └── ER-collet
│ ├── ER-collet-handle.scad
│ ├── ER-collet-handle.svg
│ └── ER-collet-handle.svg.scad
├── unc-screw.scad
├── unc-thread.scad
├── unf-screw.scad
├── unf-thread.scad
└── wrench.scad
/.gitignore:
--------------------------------------------------------------------------------
1 | stl/
2 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # agentscad
2 | My utilities for OpenSCAD
3 |
4 | # Prerequisites
5 |
6 | [Follow these instructions to use the library](https://github.com/GillesBouissac/agentscad/wiki/Prerequisites)
7 |
8 | # Canvas and Lithophanes
9 |
10 | 
11 |
12 |
13 | Tutorial for canvas here
14 |
15 |
16 | # Snap Joint
17 |
18 | 
19 |
20 |
21 | Tutorial for Snap Joint here
22 |
23 |
24 | # Screws, Bolts and Nuts shapes and passages
25 |
26 | 
27 |
28 |
29 | Tutorial for screws here
30 |
31 |
32 | # Threaded Screws, Bolts and Nuts (3D Printable)
33 |
34 | 
35 |
36 |
37 | Tutorial for threaded bolts
38 |
39 |
40 | # Hirth Joint
41 |
42 | 
43 |
44 |
45 | Tutorial for Hirth Joint here
46 |
47 |
48 | # Metric screw knobs
49 |
50 | 
51 |
52 |
53 | Tutorial for screw knobs here
54 |
55 |
56 | # Beveling library
57 |
58 | 
59 |
60 |
61 | Tutorial for beveling here
62 |
63 |
64 | # Glue shapes library
65 |
66 | 
67 |
68 |
69 | Tutorial for glue shapes here
70 |
71 |
--------------------------------------------------------------------------------
/bsf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSF thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module bsfThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module bsfThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module bsfNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module bsfNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module bsfBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module bsfBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/bspp-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSPPP thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module bsppThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module bsppThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module bsppNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module bsppNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module bsppBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module bsppBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/bsw-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSW thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module bswThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module bswThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module bswNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module bswNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module bswBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module bswBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/design/thread-extrapolation.ods:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/GillesBouissac/agentscad/d146a7e2b9cdc87eaee0589c107d81b24fb9ce29/design/thread-extrapolation.ods
--------------------------------------------------------------------------------
/extrude.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Vigibot
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Mesh manipulations
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 | use
19 |
20 | //
21 | // Generates a extrusion of given profile:
22 | //
23 | // @param profile the profile to extrude
24 | // @param height the z height of the generated end profile
25 | // @param caps true to generate start and end caps
26 | // @param vanishLineX vanishing line parallel to x axis
27 | // @param vanishLineY vanishing line parallel to y axis
28 | // @returns a mesh made of the initial profile and the extruded profile
29 | //
30 | module extrude(profile, height, caps=true, vanishLineX=undef, vanishLineY=undef, convexity=undef) {
31 | meshPolyhedron(extrudeProfile(profile, height, caps=caps, vanishLineX=vanishLineX, vanishLineY=vanishLineY), convexity=convexity);
32 | }
33 |
34 | //
35 | // Generates an extrusion of given profile
36 | //
37 | // @param profile the profile to extrude
38 | // @param height the z height of the generated end profile
39 | // @param caps true to generate start and end caps
40 | // @param vanishLineX vanishing line parallel to x axis
41 | // @param vanishLineY vanishing line parallel to y axis
42 | // @returns a mesh made of the initial profile and the extruded profile
43 | //
44 | function extrudeProfile(profile, height, caps=true, vanishLineX=undef, vanishLineY=undef) =
45 | sewMesh( [ profile, projectProfile(profile, height, vanishLineX=vanishLineX, vanishLineY=vanishLineY) ], caps=caps );
46 |
47 |
48 | //
49 | // make a prism mesh from a polygon
50 | //
51 | // @param poly polygon to extrude
52 | // @param height prism height
53 | // @returns a mesh made of the initial profile and the extruded profile
54 | //
55 | module prism(poly, height=1, caps=true) {
56 | meshPolyhedron( prismMesh(poly=poly, height=height, caps=caps ));
57 | }
58 |
59 | function prismMesh(poly, height=1, caps=true) =
60 | extrudeProfile ( transform(translation([0,0,-height/2]), getMeshVertices(poly)), height=height, caps=caps );
61 |
62 | //
63 | // make a frustum mesh from a polygon
64 | //
65 | // @param poly polygon to extrude
66 | // @param height frustum height
67 | // @param a frustum angle (0 = vertical)
68 | // @returns a mesh made of the initial profile and the extruded profile
69 | //
70 | module frustum(poly, height=1, angle=-45, caps=true) {
71 | meshPolyhedron(frustumMesh(poly=poly,height=height,angle=angle,caps=caps));
72 | }
73 |
74 | function frustumMesh(poly, height=1, angle=-45, caps=true) =
75 | let( vertices=getMeshVertices(poly) )
76 | let( faces=getMeshFaces(poly) )
77 | let( n=len(vertices) )
78 | newMesh (flatten([
79 | for ( i=[0:n-1] )
80 | let( v=vertices[i] )
81 | let( i=atan2(v.y,v.x) )
82 | let( dr=(height/2)*tan(angle) )
83 | let( dx=dr*cos(i) )
84 | let( dy=dr*sin(i) )
85 | [ [v.x-dx,v.y-dy,-height/2], [v.x+dx,v.y+dy,+height/2] ]
86 | ]),
87 | [
88 | if (caps) [ for ( i=[0:n-1] ) 2*faces[0][i] ],
89 | for( i=[0:2:2*(n-2)] ) [i,i+1,i+3,i+2],
90 | [2*n-2,2*n-1,1,0],
91 | if (caps) [ for ( i=[n-1:-1:0] ) 2*faces[0][i]+1 ]
92 | ]
93 | );
94 |
95 | //
96 | // Scales a profile (list of points) along vectors directed to vanishing lines
97 | //
98 | // input profile is assumed to be in z=0 plane
99 | // 2 vanishing lines can be used:
100 | // - vanishLineX: [undef,y,z] position of the vanishing line parallel to x axis
101 | // Result is a scaling of the projected profile on y
102 | // - vanishLineY: [x,undef,z] position of the vanishing line parallel to y axis
103 | // Result is a scaling of the projected profile on x
104 | //
105 | // for a vanishing point:
106 | // - vanishLineX.z == vanishLineY.z
107 | // - the vanishing point coordinates are [vanishLineY.x, vanishLineX.y, vanishLineX.z]
108 | //
109 | // for a vertical scaling:
110 | // - only on x: vanishLineX == undef
111 | // - only on y: vanishLineY == undef
112 | // - no scaling: vanishLineX == vanishLineY == undef
113 | //
114 | // @param profile: list of 2D (x,y) points
115 | // @param height the projection stops at specified height
116 | // @returns the projected profile
117 | //
118 | function projectProfile(profile, height, vanishLineX=undef, vanishLineY=undef) =
119 | let (
120 | vy = is_undef(vanishLineY) ? [0,0,0] : [ vanishLineY.x, 0, vanishLineY.z ],
121 | vx = is_undef(vanishLineX) ? [0,0,0] : [ 0, vanishLineX.y, vanishLineX.z ],
122 |
123 | try = is_undef(vanishLineX) ? identity4() :
124 | translation(+vx) * scaling([1, (vx.z - height)/vx.z, 1]) * translation(-vx),
125 | trx = is_undef(vanishLineY) ? identity4() :
126 | translation(+vy) * scaling([(vy.z - height)/vy.z, 1, 1]) * translation(-vy)
127 | ) transform(translation([0,0,height]) * try * trx, profile);
128 |
--------------------------------------------------------------------------------
/geometry.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Some geometrical functions
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 | use
16 |
17 |
18 | // ----------------------------------------
19 | // 3D Geometry
20 | // ----------------------------------------
21 |
22 | // Normalise a plane defined this way
23 | // [
24 | // [px, py, pz], // mandatory: any point on the plane
25 | // [nx, ny, nz], // mandatory: vector normal to the plane
26 | // [ox, oy, oz] // optional: vector origin (default [0,0,0])
27 | // ]
28 | function plane3(plane) =
29 | let( _p = vec3(plane[0]) )
30 | let( _o = len(plane)>2 ? vec3(plane[2]) : [0,0,0] )
31 | let( _n = vec3(plane[1])-_o)
32 | [ _p, _n, [0,0,0] ];
33 |
34 | // Normalise a line defined this way
35 | // [
36 | // [px, py, pz], // mandatory: any point on the line
37 | // [vx, vy, vz], // mandatory: vector parallel to the line
38 | // [ox, oy, oz] // optional: vector origin (default [0,0,0])
39 | // ]
40 | function line3(line) =
41 | let( _p = vec3(line[0]) )
42 | let( _o = len(line)>2 ? vec3(line[2]) : [0,0,0] )
43 | let( _v = vec3(line[1])-_o)
44 | [ _p, _v, [0,0,0] ];
45 |
46 | // ----------------------------------------
47 | // 3D Operations
48 | // ----------------------------------------
49 |
50 | // Intersection of three planes (Graphics Gems 1 - V.4)
51 | // - PInt={(P1.N1)(V2xV3)+(P2.V2)(V3xV1)+(P3.V3)(V1xV2)}/Det(V1,V2,V3).
52 | // Params:
53 | // - p1,p2,p3: 3 plane3
54 | // Returns:
55 | // - undef if 2 of the 3 planes are parallels
56 | // - otherwise: a 3D point
57 | function intersec_planes_3(p1,p2,p3) =
58 | let( _pl1=plane3(p1) )
59 | let( _pl2=plane3(p2) )
60 | let( _pl3=plane3(p3) )
61 | let( _p1=_pl1[0], _p2=_pl2[0], _p3=_pl3[0] )
62 | let( _n1=_pl1[1], _n2=_pl2[1], _n3=_pl3[1] )
63 | let( d=det([_n1,_n2,_n3]) )
64 | d==0 ? undef : (
65 | (_p1*_n1)*cross(_n2,_n3)+
66 | (_p2*_n2)*cross(_n3,_n1)+
67 | (_p3*_n3)*cross(_n1,_n2)
68 | )/d;
69 |
70 | // Intersection of two planes
71 | // - computation derived from intersec_planes_3
72 | // we create the 3rd plane with:
73 | // - point [0,0,0]
74 | // - normal computed as the normal to input planes normal
75 | // this give the common points to the 3 planes
76 | // Params:
77 | // - p1,p2: 2 plane3
78 | // Returns:
79 | // - undef if 2 planes are parallels
80 | // - otherwise: a 3D line defined this way:
81 | // [
82 | // [px, py, pz], // one point on the line
83 | // [vx, vy, vz] // direction vector of the line
84 | // ]
85 | function intersec_planes_2(p1,p2) =
86 | let( _pl1=plane3(p1) )
87 | let( _pl2=plane3(p2) )
88 | let( _p1=_pl1[0], _p2=_pl2[0] )
89 | let( _n1=_pl1[1], _n2=_pl2[1] )
90 | let( _n3=cross(_n1,_n2) )
91 | let( _p3=intersec_planes_3(p1,p2,[[0,0,0],_n3]) )
92 | is_undef(_p3) ? undef : [_p3,_n3,[0,0,0]];
93 |
94 |
95 | // ----------------------------------------
96 | // Useful tools to show basic 3D objects
97 | // ----------------------------------------
98 |
99 | module renderPoint(point) {
100 | let( pt=vec3(point) )
101 | translate(pt)
102 | sphere( 0.1 );
103 | }
104 | module renderPoints(points) {
105 | for ( p=points ) renderPoint(p);
106 | }
107 | module renderPlane(plane, size=10) {
108 | let( _pl=plane3(plane) )
109 | let( pt=_pl[0], vn=_pl[1] )
110 | let( a=angle_vector(vn,[0,0,1]) )
111 | let( c=cross(vn,[0,0,1]) )
112 | {
113 | renderPoints([pt]);
114 | translate(pt)
115 | rotate(-a,c)
116 | cube( [size,size,0.01], center=true );
117 | }
118 | }
119 | module renderPlanes(planes, size=10) {
120 | for ( p=planes ) renderPlane(p,size);
121 | }
122 | module renderLine(line, length=undef) {
123 | let( pt=vec3(line[0]), vc=vec3(line[1]) )
124 | let( _l=is_undef(length) ? norm(vc) : length )
125 | let( a=angle_vector(vc,[0,0,1]) )
126 | let( c=cross(vc,[0,0,1]) )
127 | {
128 | renderPoints([pt]);
129 | translate(pt)
130 | rotate(-a,c)
131 | cylinder( r=0.05, h=_l, center=true );
132 | }
133 | }
134 | module renderLines(lines) {
135 | for ( l=lines ) renderLine(l);
136 | }
137 |
138 |
139 |
--------------------------------------------------------------------------------
/glue.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Vigibot
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Shapes designed to glue parts avoiding supports
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | // API
18 | // ----------------------------------------
19 | module glue_circle ( d=CIRCLE_D, h=GLUE_H, g=GLUE_GRID, t=THICKNESS ) {
20 | ncircle = floor( d/(2*g) );
21 | diff_d = d/ncircle;
22 | for ( i=[0:ncircle-1] )
23 | difference() {
24 | cylinder( r=diff_d/2+(i*diff_d)/2+t/2, h=h, center=true );
25 | cylinder( r=diff_d/2+(i*diff_d)/2-t/2, h=h+mfg(), center=true );
26 | }
27 |
28 | nradius = floor( PI*d/(2*g) );
29 | diff_a = 360/nradius;
30 | step = d / (is_undef($fn) ? 10: $fn) ;
31 | radius_profile = [
32 | for ( x=[0:step:d/2-diff_d/2] )
33 | [ diff_d/2+x, g/6*sin(x*180/(diff_d/2))+t/2 ],
34 | for ( x=[d/2-diff_d/2:-step:0] )
35 | [ diff_d/2+x, g/6*sin(x*180/(diff_d/2))-t/2 ]
36 | ];
37 | for ( i=[0:nradius] )
38 | rotate( [0,0,i*diff_a] )
39 | translate( [0,0,-h/2] )
40 | linear_extrude( height=h )
41 | polygon(radius_profile);
42 | }
43 |
44 | module glue_circle_receiver ( d=CIRCLE_D, h=GLUE_H, g=GLUE_GRID, t=THICKNESS ) {
45 | glue_circle( d, h+2*gap(), g, t+2*gap() );
46 | }
47 |
48 | // ----------------------------------------
49 | // Implementation
50 | // ----------------------------------------
51 | CIRCLE_D = 50;
52 | GLUE_GRID = CIRCLE_D/6;
53 | GLUE_H = 4;
54 | THICKNESS = 3*nozzle()+0.05;
55 |
56 | // ----------------------------------------
57 | // Showcase
58 | // ----------------------------------------
59 | GLUE_D = 50;
60 | GLUE_T = 1.6 ;
61 |
62 | color( "gold" )
63 | glue_circle ( GLUE_D, GLUE_T, $fn=200 );
64 |
65 | translate( [0,0,20] )
66 | rotate( [-30,0,0] )
67 | difference() {
68 | translate( [0,0,5/2] )
69 | cube( [ 70, 70, 5 ], center=true );
70 | # glue_circle_receiver ( GLUE_D, GLUE_T, $fn=200 );
71 | }
72 |
73 | translate( [0,0,-20] )
74 | rotate( [+30,0,0] )
75 | difference() {
76 | translate( [0,0,-5/2] )
77 | cube( [ 70, 70, 5 ], center=true );
78 | glue_circle_receiver ( GLUE_D, GLUE_T, $fn=200 );
79 | }
80 |
81 |
--------------------------------------------------------------------------------
/mesh.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Vigibot
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Mesh manipulations
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 |
19 | // ----------------------------------------
20 | // Base API
21 | // ----------------------------------------
22 |
23 | function classMesh() = "mesh";
24 |
25 | //
26 | // Converts a mesh to a polyhedron module
27 | //
28 | module meshPolyhedron ( mesh, convexity=undef ) {
29 | class = assertClass(mesh,classMesh());
30 | convexity = is_undef(convexity) ? 2 : convexity;
31 | polyhedron ( points=getMeshVertices(mesh), faces=getMeshFaces(mesh), convexity=convexity );
32 | }
33 |
34 | //
35 | // Creates a new mesh from a list of vertices and faces
36 | //
37 | function newMesh( vertices, faces ) = [ classMesh(), vertices, faces ];
38 |
39 | // Accessor to the list of vertices in a mesh
40 | // @return the list of 3D points
41 | function getMeshVertices( mesh ) = let(class = assertClass(mesh,classMesh())) mesh[1];
42 |
43 | // Accessor to the list of faces in a mesh
44 | // @return the list of vertex indices in the mesh
45 | function getMeshFaces( mesh ) = let(class = assertClass(mesh,classMesh())) mesh[2];
46 |
47 |
48 | // ----------------------------------------
49 | // Simple Polygons
50 | // ----------------------------------------
51 |
52 | // make a regular polygon mesh
53 | // - n: number of edges in the polygon
54 | // - r: radius of the circumscribed circle
55 | function meshRegularPolygon(n,r=1) = let()
56 | newMesh (
57 | regularPolygon(n,r),
58 | [ [ for( i=[0:n-1] ) i ] ]
59 | );
60 |
61 | // make a regular polygon profile
62 | // - n: number of edges in the polygon
63 | // - r: radius of the circumscribed circle
64 | function regularPolygon(n,r=1) = flatten([
65 | for ( i=[0:n-1] ) transform(rotation([0,0,i*360/n]),[[r,0,0]])
66 | ]);
67 |
--------------------------------------------------------------------------------
/morph.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Vigibot
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Adaptation of morph function from openscad/list-comprehension-demos
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 | use
16 | use
17 |
18 | // ----------------------------------------
19 | // API
20 | // ----------------------------------------
21 |
22 | // Morph two profile: Generates a succession of 'slices' profiles (=list of 3D points):
23 | // - The first one in the list is 'profile1'
24 | // - The last one in the list is 'profile2'
25 | // speed: power factor of the x^speed curve: >1 we reach profile2 faster, <1 we reach profile2 slowlier
26 | function morph ( profile1, profile2, slices=1, speed=1 ) =
27 | let (
28 | profilelen = max(len(profile1),len(profile2)),
29 | profile1 = augment_profile(to_3d(profile1),profilelen),
30 | profile2 = augment_profile(to_3d(profile2),profilelen)
31 | )[
32 | for(index = [0:slices-1])
33 | interpolateProfile( profile1, profile2, index/(slices-1), speed )
34 | ];
35 |
36 | // Morph two profile: Generates a succession of 'slices' profiles (=list of 3D points):
37 | // The number of slices is the length of path_transforms
38 | // Each slice is transformed using the current path_transforms[]
39 | // This is a mix between morph and sweep
40 | // - The first one in the list is 'profile1'
41 | // - The last one in the list is 'profile2'
42 | function morphpath(profile1, profile2, path_transforms, speed=1) = let(
43 | slices = len(path_transforms),
44 | profilelen = max(len(profile1),len(profile2)),
45 | profile1 = augment_profile(to_3d(profile1),profilelen),
46 | profile2 = augment_profile(to_3d(profile2),profilelen)
47 | )[
48 | for (index = [0:slices-1])
49 | transform(path_transforms[index], interpolateProfile(profile1, profile2, index/(slices-1),speed))
50 | ];
51 |
52 |
--------------------------------------------------------------------------------
/mx-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module mxThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module mxThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module mxNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module mxNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module mxBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module mxBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/mxf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric fine screw thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module mxfThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module mxfThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module mxfNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module mxfNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module mxfBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module mxfBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/printing.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Tools and constants for 3D printing
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | // ----------------------------------------
14 | //
15 | // API
16 | //
17 | // ----------------------------------------
18 |
19 | // Default values
20 | GAP = 0.2;
21 | NOZZLE = 0.4;
22 | LAYER = 0.2;
23 | OVERHANG = 70;
24 |
25 | VOLUME_MK3S = [250,210,210];
26 |
27 | // Distance between 2 parts that must touch be not be stuck
28 | function gap(mult=1) = is_undef($gap) ? mult*GAP : mult*$gap;
29 |
30 | // The printer nozzle diameter
31 | function nozzle(mult=1) = is_undef($nozzle) ? mult*NOZZLE : mult*$nozzle;
32 |
33 | // The layer height
34 | function layer(mult=1) = is_undef($layer) ? mult*LAYER : mult*$layer;
35 |
36 | // The maximum overhang angle the printer can print from vertical
37 | function overhang() = is_undef($overhang) ? OVERHANG : $overhang;
38 |
39 | // The print volume available
40 | function printVolume() = is_undef($bed) ? getPrintVolumePrusaMk3s() : $bed;
41 |
42 | // Known volume sizes
43 | function getPrintVolumePrusaMk3s() = VOLUME_MK3S;
44 |
45 |
--------------------------------------------------------------------------------
/sew.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: OpenSCAD extensions to scad language
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 | use
14 | use
15 | use
16 |
17 | //
18 | // Joint n profiles (list of 2D or 3D points) with triangles
19 | //
20 | // @param profiles the list of profiles to joint
21 | // @param caps true to generate start and end caps
22 | // @param convexity convexity for visualisation before rendering
23 | // @return a polyhedron
24 | //
25 | module sew(profiles,caps=true,convexity=undef) {
26 | mesh = sewMesh(profiles,caps);
27 | meshPolyhedron(mesh,convexity=convexity);
28 | }
29 |
30 | //
31 | // Joint n profiles (list of 2D or 3D points) with triangles
32 | //
33 | // @param profiles the list of profiles to joint
34 | // @param caps true to generate start and end caps
35 | // @return a list of faces
36 | //
37 | function sewMesh(profiles,caps=true) = let(
38 | n = len(profiles),
39 | lengths = concat([ for (p=profiles) len(p)],[0]),
40 | o = [ for (i=[0:len(lengths)-1]) [columnSum(lengths,start=0,end=i-1), lengths[i]] ],
41 | vertexes = flatten(profiles),
42 | faces = flatten([
43 | for (i=[0:n-2])
44 | sewSelf (vertexes,o[i][0],o[i+1][0],o[i][1],o[i+1][1])
45 | ]),
46 | scap = caps ? [range([ 0 : +1 : o[ 1][0]-1])] : [],
47 | ecap = caps ? [range([o[n][0]-1 : -1 : o[n-1][0]])] : []
48 | ) newMesh(vertexes, caps ? concat(scap,faces,ecap) : faces) ;
49 |
50 | //
51 | // Joint 2 list of point from the same input profile (list of 2D or 3D points) with triangles
52 | //
53 | // @param points list of points to sew in a continuous list
54 | // @param s1 index of the first point of the first list
55 | // @param s2 index of the first point of the second list
56 | // @param l1 number of points in the first list
57 | // @param l2 number of points in the second list
58 | // @return a list of faces made with 3 indexes of points from input list of points
59 | //
60 | function sewSelf (points,s1,s2,l1=2,l2=2) = (l1<2 || l2<2) ? [] : _sewSelfFrom (points,s1,s2,l1,l2,0,0);
61 | function _sewSelfFrom (points,s1,s2,l1,l2,i1,i2) = let(
62 | // Candidates for next move
63 | c1 = i1
13 | use
14 |
15 | // ----------------------------------------
16 | // Animation params:
17 | // fps: 10
18 | // steps: 100
19 | // ----------------------------------------
20 |
21 | ALL_SCREW = [for ( idx=[0:bsfGetDataLength()-1] ) bsfData( idx ) ];
22 |
23 | // Modulo
24 | function mod(a,m) = a - m*floor(a/m);
25 | module showcaseAnimated() {
26 |
27 | translate( [0,0,0] ) {
28 |
29 | idx=floor($t*len(ALL_SCREW));
30 | screw = ALL_SCREW[idx];
31 |
32 | translate( [1.5*screwGetHeadDP(screw),0,4*screwGetHeadLP(screw)] )
33 | color( "gold" )
34 | rotate( $vpr )
35 | linear_extrude(1)
36 | text( screwGetName(screw), halign="center", valign="center", size=screwGetThreadD(screw) );
37 | rotate( [180,0,0] )
38 | translate( [0,screwGetHeadDP(screw)/1.5,0] ) {
39 | translate( [3*screwGetHeadDP(screw),0,0] ) {
40 | color( "red", 0.5 )
41 | bsfBoltPassage( bsfClone(screw,tlp=3) );
42 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
43 | color( "silver", 0.5 )
44 | bsfNutPassage( screw );
45 | }
46 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
47 | color( "red", 0.5 )
48 | bsfBoltAllenPassage( bsfClone(screw,tlp=3) );
49 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
50 | color( "silver", 0.5 )
51 | bsfNutPassage( screw );
52 | }
53 | bsfBoltAllen( screw );
54 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
55 | color( "cyan", 0.5 )
56 | bsfNutSquare( screw );
57 | }
58 | rotate( [180,0,0] )
59 | translate( [0,-screwGetHeadDP(screw)/1.5,0] ) {
60 | translate( [3*screwGetHeadDP(screw),0,0] ) {
61 | color( "red", 0.5 )
62 | bsfBoltPassage( bsfClone(screw,tlp=3) );
63 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
64 | color( "silver", 0.5 )
65 | bsfNutPassage( screw );
66 | }
67 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
68 | color( "red", 0.5 )
69 | bsfBoltHexagonalPassage( bsfClone(screw,tlp=3) );
70 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
71 | color( "silver", 0.5 )
72 | bsfNutPassage( screw );
73 | }
74 | bsfBoltHexagonal( screw );
75 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
76 | color( "cyan", 0.5 )
77 | bsfNutHexagonal( screw );
78 | }
79 | }
80 | }
81 |
82 | showcaseAnimated ($fn=100);
83 |
84 |
--------------------------------------------------------------------------------
/test/screws/test-bsf-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = BSF3_16(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | bsfBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = BSF3_16(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | bsfBoltPassage (screw);
53 | }
54 | %bsfBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = BSF3_16(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | bsfBoltPassage (screw);
63 | }
64 | %bsfBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = BSF3_16(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | bsfBoltAllenPassage (screw);
73 | }
74 | %bsfBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = BSF3_16(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | bsfBoltHexagonalPassage (screw);
83 | }
84 | %bsfBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = BSF3_16(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | bsfBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | bsfNutPassage (screw);
95 | }
96 | %bsfBoltHexagonal (bsfClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = BSF3_16(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | bsfBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | bsfNutPassage (screw);
107 | }
108 | %bsfBoltHexagonal (bsfClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %bsfNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = BSF3_16(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | bsfBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | bsfNutPassage (screw);
121 | }
122 | %bsfBoltHexagonal (bsfClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %bsfNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = BSF3_16(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | bsfBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | bsfNutHexagonalPassage (screw);
135 | }
136 | %bsfBoltHexagonal (bsfClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %bsfNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = BSF3_16(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | bsfBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | bsfNutSquarePassage (screw);
150 | }
151 | %bsfBoltHexagonal (bsfClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %bsfNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-bsf-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:bsfGetDataLength()-1] ) screwGetHeadDP ( bsfData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:bsfGetDataLength()-1] ) bsfData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=160;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=bsfGetDataLength()-1 )+(bsfGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | bsfBoltPassage ( bsfClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( screwGetIdx(t)%2 ) {
40 | bsfBoltAllen ( t );
41 | }
42 | else {
43 | bsfBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/screws/test-bspp-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSPP (British Standard Pipe) screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:bsppGetDataLength()-1] ) screwGetHeadDP ( bsppData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:bsppGetDataLength()-1] ) bsppData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=160;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=bsppGetDataLength()-1 )+(bsppGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | bsppBoltPassage ( bsppClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | difference() {
40 | bsppBoltHexagonal ( t );
41 | cylinder(r=bsppGetPipeD(t)/2, h=1000, center=true);
42 | }
43 | }
44 | color( "gold" )
45 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
46 | rotate ( [90,0,0] )
47 | linear_extrude(1)
48 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
49 | }
50 | }
51 |
52 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
53 | translate ( [0,wp/2,0] ) {
54 | color( "LightSkyBlue" )
55 | translate ( [0,0,+(wh2+wh1)/2] )
56 | cube( [ww,wp,wh2], center=true );
57 | color( "DodgerBlue" )
58 | translate ( [0,0,0] )
59 | cube( [ww,wp,wh1], center=true );
60 | }
61 | }
62 |
63 | module showcaseBigWall() {
64 | HLP = WALL1_H+10;
65 | difference() {
66 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
67 | for ( screw=ALL_SCREW ) {
68 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
69 | }
70 | }
71 | for ( screw=ALL_SCREW ) {
72 | showcaseScrew( screw );
73 | }
74 | }
75 |
76 | dumpScrewsData(ALL_SCREW);
77 | showcaseBigWall ($fn=50);
78 |
--------------------------------------------------------------------------------
/test/screws/test-bsw-screw-anim.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSW screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | // Animation params:
17 | // fps: 10
18 | // steps: 100
19 | // ----------------------------------------
20 |
21 | ALL_SCREW = [for ( idx=[0:bswGetDataLength()-1] ) bswData( idx ) ];
22 |
23 | // Modulo
24 | function mod(a,m) = a - m*floor(a/m);
25 | module showcaseAnimated() {
26 |
27 | translate( [0,0,0] ) {
28 |
29 | idx=floor($t*len(ALL_SCREW));
30 | screw = ALL_SCREW[idx];
31 |
32 | translate( [1.5*screwGetHeadDP(screw),0,4*screwGetHeadLP(screw)] )
33 | color( "gold" )
34 | rotate( $vpr )
35 | linear_extrude(1)
36 | text( screwGetName(screw), halign="center", valign="center", size=screwGetThreadD(screw) );
37 | rotate( [180,0,0] )
38 | translate( [0,screwGetHeadDP(screw)/1.5,0] ) {
39 | translate( [3*screwGetHeadDP(screw),0,0] ) {
40 | color( "red", 0.5 )
41 | bswBoltPassage( bswClone(screw,tlp=3) );
42 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
43 | color( "silver", 0.5 )
44 | bswNutPassage( screw );
45 | }
46 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
47 | color( "red", 0.5 )
48 | bswBoltAllenPassage( bswClone(screw,tlp=3) );
49 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
50 | color( "silver", 0.5 )
51 | bswNutPassage( screw );
52 | }
53 | bswBoltAllen( screw );
54 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
55 | color( "cyan", 0.5 )
56 | bswNutSquare( screw );
57 | }
58 | rotate( [180,0,0] )
59 | translate( [0,-screwGetHeadDP(screw)/1.5,0] ) {
60 | translate( [3*screwGetHeadDP(screw),0,0] ) {
61 | color( "red", 0.5 )
62 | bswBoltPassage( bswClone(screw,tlp=3) );
63 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
64 | color( "silver", 0.5 )
65 | bswNutPassage( screw );
66 | }
67 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
68 | color( "red", 0.5 )
69 | bswBoltHexagonalPassage( bswClone(screw,tlp=3) );
70 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
71 | color( "silver", 0.5 )
72 | bswNutPassage( screw );
73 | }
74 | bswBoltHexagonal( screw );
75 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
76 | color( "cyan", 0.5 )
77 | bswNutHexagonal( screw );
78 | }
79 | }
80 | }
81 |
82 | showcaseAnimated ($fn=100);
83 |
84 |
--------------------------------------------------------------------------------
/test/screws/test-bsw-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSW screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = BSW5_32(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | bswBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = BSW5_32(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | bswBoltPassage (screw);
53 | }
54 | %bswBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = BSW5_32(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | bswBoltPassage (screw);
63 | }
64 | %bswBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = BSW5_32(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | bswBoltAllenPassage (screw);
73 | }
74 | %bswBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = BSW5_32(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | bswBoltHexagonalPassage (screw);
83 | }
84 | %bswBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = BSW5_32(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | bswBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | bswNutPassage (screw);
95 | }
96 | %bswBoltHexagonal (bswClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = BSW5_32(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | bswBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | bswNutPassage (screw);
107 | }
108 | %bswBoltHexagonal (bswClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %bswNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = BSW5_32(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | bswBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | bswNutPassage (screw);
121 | }
122 | %bswBoltHexagonal (bswClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %bswNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = BSW5_32(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | bswBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | bswNutHexagonalPassage (screw);
135 | }
136 | %bswBoltHexagonal (bswClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %bswNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = BSW5_32(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | bswBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | bswNutSquarePassage (screw);
150 | }
151 | %bswBoltHexagonal (bswClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %bswNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-bsw-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSW screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:bswGetDataLength()-1] ) screwGetHeadDP ( bswData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:bswGetDataLength()-1] ) bswData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=160;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=bswGetDataLength()-1 )+(bswGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | bswBoltPassage ( bswClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( screwGetIdx(t)%2 ) {
40 | bswBoltAllen ( t );
41 | }
42 | else {
43 | bswBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/screws/test-lib-screw-profiles.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: lib-screw testing
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | PRECISION = 50;
16 | PART_TO_SHOW = 0; // [0:Profile,1:Complex structure]
17 | SHOW_HOLLOW = true;
18 |
19 | // ----------------------------------------
20 | //
21 | // Showcase
22 | //
23 | // ----------------------------------------
24 | function profile_m() = "M"; // Metric or UTS profile
25 | function profile_w() = "W"; // Whitworth profile
26 |
27 | module showName( d, dy=0 ) {
28 | translate( [screwGetPitch(d),dy,0.1] )
29 | linear_extrude(1)
30 | text( screwGetName(d), halign="center", valign="center", size=1 );
31 | }
32 |
33 | // Thread profiles visualisation
34 | module showParts( part=0 ) {
35 | if ( part==0 ) {
36 | screw_w = libScrewDataCompletion([["Profile BSW / BSF", 6,12,1]],0,prf=profile_w());
37 | screw_m = libScrewDataCompletion([["Profile M / UNC / UNF", 6,12,1]],0,prf=profile_m());
38 | !union() {
39 | color("white")
40 | union() {
41 | intersection() {
42 | rotate( [90,0,90] )
43 | union() {
44 | libThreadExternal(screw_m,l=2*screwGetPitch(screw_m),f=true);
45 | libThreadInternal(screw_m,l=2*screwGetPitch(screw_m),f=true,t=1);
46 | }
47 | cube( [100,100,0.01], center=true );
48 | }
49 | showName(screw_m,-0.6);
50 | }
51 | translate( [0,0,-2] )
52 | color("lightblue")
53 | union() {
54 | intersection() {
55 | rotate( [90,0,90] )
56 | union() {
57 | libThreadExternal(screw_w,l=2*screwGetPitch(screw_m),f=true);
58 | libThreadInternal(screw_w,l=2*screwGetPitch(screw_m),f=true,t=1);
59 | }
60 | cube( [100,100,0.01], center=true );
61 | }
62 | showName(screw_w,-0.6);
63 | }
64 | }
65 | }
66 |
67 | // Complex structure
68 | if ( part==1 ) {
69 | screw_w = libScrewDataCompletion([["Profile BSW / BSF",inch2mm(1/16),inch2mm(3/8),1]],0,prf=profile_w());
70 | screw_hole = libScrewDataCompletion([["B",2,6,1]],0,prf=profile_w());
71 |
72 | difference() {
73 | render(convexity=20)
74 | union() {
75 | libThreadExternal( screw_w, 10, f=false );
76 | libThreadInternal( screw_w, 10, f=false, t=1 );
77 | }
78 | if (SHOW_HOLLOW) {
79 | #negative_parts(screw_hole);
80 | }
81 | else {
82 | negative_parts(screw_hole);
83 | }
84 | }
85 | }
86 | }
87 |
88 | module negative_parts(screw_hole) {
89 | render(convexity=20)
90 | union() {
91 | translate( [-1,0,9] )
92 | rotate( [ 60, 20, -60 ] )
93 | translate( [0,0,-10] )
94 | libThreadExternal( screw_hole, 16 );
95 | rotate( [ 0, 0, -90 ] )
96 | translate( [5,5,3] )
97 | cylinder( r=4.5,10 );
98 | }
99 | }
100 |
101 | showParts(PART_TO_SHOW, $fn=PRECISION);
102 |
103 |
--------------------------------------------------------------------------------
/test/screws/test-mx-screw-anim.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 |
14 | // ----------------------------------------
15 | // Animation params:
16 | // fps: 10
17 | // steps: 100
18 | // ----------------------------------------
19 |
20 | ALL_SCREW = [for ( idx=[0:mxGetDataLength()-1] ) mxData( idx ) ];
21 |
22 | // Modulo
23 | function mod(a,m) = a - m*floor(a/m);
24 | module showcaseAnimated() {
25 |
26 | translate( [0,0,0] ) {
27 |
28 | idx=floor($t*len(ALL_SCREW));
29 | screw = ALL_SCREW[idx];
30 |
31 | translate( [1.5*mxGetHeadDP(screw),0,4*mxGetHeadLP(screw)] )
32 | color( "gold" )
33 | rotate( $vpr )
34 | linear_extrude(1)
35 | text( mxGetName(screw), halign="center", valign="center", size=mxGetThreadD(screw) );
36 | rotate( [180,0,0] )
37 | translate( [0,mxGetHeadDP(screw)/1.5,0] ) {
38 | translate( [3*mxGetHeadDP(screw),0,0] ) {
39 | color( "red", 0.5 )
40 | mxBoltPassage( mxClone(screw,tlp=3) );
41 | translate( [0,0,+mxGetThreadL(screw)-mxGetHeadLP(screw)/2] )
42 | color( "silver", 0.5 )
43 | mxNutPassage( screw );
44 | }
45 | translate( [1.5*mxGetHeadDP(screw),0,0] ) {
46 | color( "red", 0.5 )
47 | mxBoltAllenPassage( mxClone(screw,tlp=3) );
48 | translate( [0,0,+mxGetThreadL(screw)-mxGetHeadLP(screw)/2] )
49 | color( "silver", 0.5 )
50 | mxNutPassage( screw );
51 | }
52 | mxBoltAllen( screw );
53 | translate( [0,0,+mxGetThreadL(screw)-mxGetSquareHeadL(screw)/2] )
54 | color( "cyan", 0.5 )
55 | mxNutSquare( screw );
56 | }
57 | rotate( [180,0,0] )
58 | translate( [0,-mxGetHeadDP(screw)/1.5,0] ) {
59 | translate( [3*mxGetHeadDP(screw),0,0] ) {
60 | color( "red", 0.5 )
61 | mxBoltPassage( mxClone(screw,tlp=3) );
62 | translate( [0,0,+mxGetThreadL(screw)-mxGetHeadLP(screw)/2] )
63 | color( "silver", 0.5 )
64 | mxNutPassage( screw );
65 | }
66 | translate( [1.5*mxGetHeadDP(screw),0,0] ) {
67 | color( "red", 0.5 )
68 | mxBoltHexagonalPassage( mxClone(screw,tlp=3) );
69 | translate( [0,0,+mxGetThreadL(screw)-mxGetHeadLP(screw)/2] )
70 | color( "silver", 0.5 )
71 | mxNutPassage( screw );
72 | }
73 | mxBoltHexagonal( screw );
74 | translate( [0,0,+mxGetThreadL(screw)-mxGetSquareHeadL(screw)/2] )
75 | color( "cyan", 0.5 )
76 | mxNutHexagonal( screw );
77 | }
78 | }
79 | }
80 |
81 | showcaseAnimated ($fn=100);
82 |
83 |
--------------------------------------------------------------------------------
/test/screws/test-mx-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = M3(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | mxBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = M3(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | mxBoltPassage (screw);
53 | }
54 | %mxBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = M3(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | mxBoltPassage (screw);
63 | }
64 | %mxBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = M3(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | mxBoltAllenPassage (screw);
73 | }
74 | %mxBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = M3(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | mxBoltHexagonalPassage (screw);
83 | }
84 | %mxBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = M3(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | mxBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | mxNutPassage (screw);
95 | }
96 | %mxBoltHexagonal (mxClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = M3(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | mxBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | mxNutPassage (screw);
107 | }
108 | %mxBoltHexagonal (mxClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %mxNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = M3(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | mxBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | mxNutPassage (screw);
121 | }
122 | %mxBoltHexagonal (mxClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %mxNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = M3(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | mxBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | mxNutHexagonalPassage (screw);
135 | }
136 | %mxBoltHexagonal (mxClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %mxNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = M3(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | mxBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | mxNutSquarePassage (screw);
150 | }
151 | %mxBoltHexagonal (mxClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %mxNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-mx-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:mxGetDataLength()-1] ) mxGetHeadDP ( mxData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:mxGetDataLength()-1] ) mxData( idx ) ];
24 | SCREW_DISTANCE=3;
25 |
26 | WALL1_H=4;
27 | WALL2_H=136;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=mxGetDataLength()-1 )+(mxGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | mxBoltPassage ( mxClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( mxGetIdx(t)%2 ) {
40 | mxBoltAllen ( t );
41 | }
42 | else {
43 | mxBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+mxGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/screws/test-mxf-screw-anim.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: MXF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | // Animation params:
17 | // fps: 10
18 | // steps: 100
19 | // ----------------------------------------
20 |
21 | ALL_SCREW = [for ( idx=[0:mxfGetDataLength()-1] ) mxfData( idx ) ];
22 |
23 | // Modulo
24 | function mod(a,m) = a - m*floor(a/m);
25 | module showcaseAnimated() {
26 |
27 | translate( [0,0,0] ) {
28 |
29 | idx=floor($t*len(ALL_SCREW));
30 | screw = ALL_SCREW[idx];
31 |
32 | translate( [1.5*screwGetHeadDP(screw),0,4*screwGetHeadLP(screw)] )
33 | color( "gold" )
34 | rotate( $vpr )
35 | linear_extrude(1)
36 | text( screwGetName(screw), halign="center", valign="center", size=screwGetThreadD(screw) );
37 | rotate( [180,0,0] )
38 | translate( [0,screwGetHeadDP(screw)/1.5,0] ) {
39 | translate( [3*screwGetHeadDP(screw),0,0] ) {
40 | color( "red", 0.5 )
41 | mxfBoltPassage( mxfClone(screw,tlp=3) );
42 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
43 | color( "silver", 0.5 )
44 | mxfNutPassage( screw );
45 | }
46 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
47 | color( "red", 0.5 )
48 | mxfBoltAllenPassage( mxfClone(screw,tlp=3) );
49 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
50 | color( "silver", 0.5 )
51 | mxfNutPassage( screw );
52 | }
53 | mxfBoltAllen( screw );
54 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
55 | color( "cyan", 0.5 )
56 | mxfNutSquare( screw );
57 | }
58 | rotate( [180,0,0] )
59 | translate( [0,-screwGetHeadDP(screw)/1.5,0] ) {
60 | translate( [3*screwGetHeadDP(screw),0,0] ) {
61 | color( "red", 0.5 )
62 | mxfBoltPassage( mxfClone(screw,tlp=3) );
63 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
64 | color( "silver", 0.5 )
65 | mxfNutPassage( screw );
66 | }
67 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
68 | color( "red", 0.5 )
69 | mxfBoltHexagonalPassage( mxfClone(screw,tlp=3) );
70 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
71 | color( "silver", 0.5 )
72 | mxfNutPassage( screw );
73 | }
74 | mxfBoltHexagonal( screw );
75 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
76 | color( "cyan", 0.5 )
77 | mxfNutHexagonal( screw );
78 | }
79 | }
80 | }
81 |
82 | showcaseAnimated ($fn=100);
83 |
84 |
--------------------------------------------------------------------------------
/test/screws/test-mxf-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: MXF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = MF3(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | mxfBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = MF3(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | mxfBoltPassage (screw);
53 | }
54 | %mxfBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = MF3(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | mxfBoltPassage (screw);
63 | }
64 | %mxfBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = MF3(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | mxfBoltAllenPassage (screw);
73 | }
74 | %mxfBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = MF3(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | mxfBoltHexagonalPassage (screw);
83 | }
84 | %mxfBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = MF3(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | mxfBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | mxfNutPassage (screw);
95 | }
96 | %mxfBoltHexagonal (mxfClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = MF3(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | mxfBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | mxfNutPassage (screw);
107 | }
108 | %mxfBoltHexagonal (mxfClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %mxfNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = MF3(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | mxfBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | mxfNutPassage (screw);
121 | }
122 | %mxfBoltHexagonal (mxfClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %mxfNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = MF3(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | mxfBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | mxfNutHexagonalPassage (screw);
135 | }
136 | %mxfBoltHexagonal (mxfClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %mxfNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = MF3(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | mxfBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | mxfNutSquarePassage (screw);
150 | }
151 | %mxfBoltHexagonal (mxfClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %mxfNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-mxf-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: MXF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:mxfGetDataLength()-1] ) screwGetHeadDP ( mxfData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:mxfGetDataLength()-1] ) mxfData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=150;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=mxfGetDataLength()-1 )+(mxfGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | mxfBoltPassage ( mxfClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( screwGetIdx(t)%2 ) {
40 | mxfBoltAllen ( t );
41 | }
42 | else {
43 | mxfBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/screws/test-unc-screw-anim.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNC screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | // Animation params:
17 | // fps: 10
18 | // steps: 100
19 | // ----------------------------------------
20 |
21 | ALL_SCREW = [for ( idx=[0:uncGetDataLength()-1] ) uncData( idx ) ];
22 |
23 | // Modulo
24 | function mod(a,m) = a - m*floor(a/m);
25 | module showcaseAnimated() {
26 |
27 | translate( [0,0,0] ) {
28 |
29 | idx=floor($t*len(ALL_SCREW));
30 | screw = ALL_SCREW[idx];
31 |
32 | translate( [1.5*screwGetHeadDP(screw),0,4*screwGetHeadLP(screw)] )
33 | color( "gold" )
34 | rotate( $vpr )
35 | linear_extrude(1)
36 | text( screwGetName(screw), halign="center", valign="center", size=screwGetThreadD(screw) );
37 | rotate( [180,0,0] )
38 | translate( [0,screwGetHeadDP(screw)/1.5,0] ) {
39 | translate( [3*screwGetHeadDP(screw),0,0] ) {
40 | color( "red", 0.5 )
41 | uncBoltPassage( uncClone(screw,tlp=3) );
42 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
43 | color( "silver", 0.5 )
44 | uncNutPassage( screw );
45 | }
46 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
47 | color( "red", 0.5 )
48 | uncBoltAllenPassage( uncClone(screw,tlp=3) );
49 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
50 | color( "silver", 0.5 )
51 | uncNutPassage( screw );
52 | }
53 | uncBoltAllen( screw );
54 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
55 | color( "cyan", 0.5 )
56 | uncNutSquare( screw );
57 | }
58 | rotate( [180,0,0] )
59 | translate( [0,-screwGetHeadDP(screw)/1.5,0] ) {
60 | translate( [3*screwGetHeadDP(screw),0,0] ) {
61 | color( "red", 0.5 )
62 | uncBoltPassage( uncClone(screw,tlp=3) );
63 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
64 | color( "silver", 0.5 )
65 | uncNutPassage( screw );
66 | }
67 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
68 | color( "red", 0.5 )
69 | uncBoltHexagonalPassage( uncClone(screw,tlp=3) );
70 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
71 | color( "silver", 0.5 )
72 | uncNutPassage( screw );
73 | }
74 | uncBoltHexagonal( screw );
75 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
76 | color( "cyan", 0.5 )
77 | uncNutHexagonal( screw );
78 | }
79 | }
80 | }
81 |
82 | showcaseAnimated ($fn=100);
83 |
84 |
--------------------------------------------------------------------------------
/test/screws/test-unc-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNC screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = UNC_N5(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | uncBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = UNC_N5(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | uncBoltPassage (screw);
53 | }
54 | %uncBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = UNC_N5(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | uncBoltPassage (screw);
63 | }
64 | %uncBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = UNC_N5(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | uncBoltAllenPassage (screw);
73 | }
74 | %uncBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = UNC_N5(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | uncBoltHexagonalPassage (screw);
83 | }
84 | %uncBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = UNC_N5(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | uncBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | uncNutPassage (screw);
95 | }
96 | %uncBoltHexagonal (uncClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = UNC_N5(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | uncBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | uncNutPassage (screw);
107 | }
108 | %uncBoltHexagonal (uncClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %uncNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = UNC_N5(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | uncBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | uncNutPassage (screw);
121 | }
122 | %uncBoltHexagonal (uncClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %uncNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = UNC_N5(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | uncBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | uncNutHexagonalPassage (screw);
135 | }
136 | %uncBoltHexagonal (uncClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %uncNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = UNC_N5(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | uncBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | uncNutSquarePassage (screw);
150 | }
151 | %uncBoltHexagonal (uncClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %uncNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-unc-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNC screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:uncGetDataLength()-1] ) screwGetHeadDP ( uncData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:uncGetDataLength()-1] ) uncData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=160;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=uncGetDataLength()-1 )+(uncGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | uncBoltPassage ( uncClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( screwGetIdx(t)%2 ) {
40 | uncBoltAllen ( t );
41 | }
42 | else {
43 | uncBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/screws/test-unf-screw-anim.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | // Animation params:
17 | // fps: 10
18 | // steps: 100
19 | // ----------------------------------------
20 |
21 | ALL_SCREW = [for ( idx=[0:unfGetDataLength()-1] ) unfData( idx ) ];
22 |
23 | // Modulo
24 | function mod(a,m) = a - m*floor(a/m);
25 | module showcaseAnimated() {
26 |
27 | translate( [0,0,0] ) {
28 |
29 | idx=floor($t*len(ALL_SCREW));
30 | screw = ALL_SCREW[idx];
31 |
32 | translate( [1.5*screwGetHeadDP(screw),0,4*screwGetHeadLP(screw)] )
33 | color( "gold" )
34 | rotate( $vpr )
35 | linear_extrude(1)
36 | text( screwGetName(screw), halign="center", valign="center", size=screwGetThreadD(screw) );
37 | rotate( [180,0,0] )
38 | translate( [0,screwGetHeadDP(screw)/1.5,0] ) {
39 | translate( [3*screwGetHeadDP(screw),0,0] ) {
40 | color( "red", 0.5 )
41 | unfBoltPassage( unfClone(screw,tlp=3) );
42 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
43 | color( "silver", 0.5 )
44 | unfNutPassage( screw );
45 | }
46 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
47 | color( "red", 0.5 )
48 | unfBoltAllenPassage( unfClone(screw,tlp=3) );
49 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
50 | color( "silver", 0.5 )
51 | unfNutPassage( screw );
52 | }
53 | unfBoltAllen( screw );
54 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
55 | color( "cyan", 0.5 )
56 | unfNutSquare( screw );
57 | }
58 | rotate( [180,0,0] )
59 | translate( [0,-screwGetHeadDP(screw)/1.5,0] ) {
60 | translate( [3*screwGetHeadDP(screw),0,0] ) {
61 | color( "red", 0.5 )
62 | unfBoltPassage( unfClone(screw,tlp=3) );
63 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
64 | color( "silver", 0.5 )
65 | unfNutPassage( screw );
66 | }
67 | translate( [1.5*screwGetHeadDP(screw),0,0] ) {
68 | color( "red", 0.5 )
69 | unfBoltHexagonalPassage( unfClone(screw,tlp=3) );
70 | translate( [0,0,+screwGetThreadL(screw)-screwGetHeadLP(screw)/2] )
71 | color( "silver", 0.5 )
72 | unfNutPassage( screw );
73 | }
74 | unfBoltHexagonal( screw );
75 | translate( [0,0,+screwGetThreadL(screw)-screwGetSquareHeadL(screw)/2] )
76 | color( "cyan", 0.5 )
77 | unfNutHexagonal( screw );
78 | }
79 | }
80 | }
81 |
82 | showcaseAnimated ($fn=100);
83 |
84 |
--------------------------------------------------------------------------------
/test/screws/test-unf-screw-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // Showcase
18 | //
19 | // ----------------------------------------
20 |
21 | module showcaseWalls( wh1, wh2, ww=200, wp=20 ) {
22 | translate ( [0,wp/2,0] ) {
23 | color( "LightSkyBlue" )
24 | translate ( [0,0,+(wh2+wh1)/2] )
25 | cube( [ww,wp,wh2], center=true );
26 | color( "DodgerBlue" )
27 | translate ( [0,0,0] )
28 | cube( [ww,wp,wh1], center=true );
29 | }
30 | }
31 |
32 | module showCase() {
33 | translate ( [+100,0,0] ) {
34 | // 1: Some walls
35 | showcaseWalls (3,10,15);
36 | }
37 |
38 | translate ( [+80,0,0] ) {
39 | // 2: Bolt passage
40 | screw = UNF_N5(10,3);
41 | difference() {
42 | showcaseWalls (3,10,15);
43 | unfBoltPassage (screw);
44 | }
45 | }
46 |
47 | translate ( [+60,0,0] ) {
48 | // 3: Allen bolt
49 | screw = UNF_N5(10,3);
50 | difference() {
51 | showcaseWalls (3,10,15);
52 | unfBoltPassage (screw);
53 | }
54 | %unfBoltAllen (screw);
55 | }
56 |
57 | translate ( [40,0,0] ) {
58 | // 4: Hexagonal bolt
59 | screw = UNF_N5(10,3);
60 | difference() {
61 | showcaseWalls (3,10,15);
62 | unfBoltPassage (screw);
63 | }
64 | %unfBoltHexagonal (screw);
65 | }
66 |
67 | translate ( [+20,0,0] ) {
68 | // 5: Tight passage allen
69 | screw = UNF_N5(10,3);
70 | difference() {
71 | showcaseWalls (3,10,15);
72 | unfBoltAllenPassage (screw);
73 | }
74 | %unfBoltAllen (screw);
75 | }
76 |
77 | translate ( [-0,0,0] ) {
78 | // 6: Tight passage hexagonal
79 | screw = UNF_N5(10,3);
80 | difference() {
81 | showcaseWalls (3,10,15);
82 | unfBoltHexagonalPassage (screw);
83 | }
84 | %unfBoltHexagonal (screw);
85 | }
86 |
87 | translate ( [-20,0,0] ) {
88 | // 7: Nut passage
89 | screw = UNF_N5(10,3);
90 | difference() {
91 | showcaseWalls (3,10,15);
92 | unfBoltHexagonalPassage (screw);
93 | translate( [0,0,screwGetThreadL(screw)] )
94 | unfNutPassage (screw);
95 | }
96 | %unfBoltHexagonal (unfClone(screw,12));
97 | }
98 |
99 | translate ( [-40,0,0] ) {
100 | // 8: Hexagonal nut
101 | screw = UNF_N5(10,3);
102 | difference() {
103 | showcaseWalls (3,10,15);
104 | unfBoltHexagonalPassage (screw);
105 | translate( [0,0,screwGetThreadL(screw)] )
106 | unfNutPassage (screw);
107 | }
108 | %unfBoltHexagonal (unfClone(screw,12));
109 | translate( [0,0,screwGetThreadL(screw)] )
110 | %unfNutHexagonal (screw);
111 | }
112 |
113 | translate ( [-60,0,0] ) {
114 | // 9: Square nut
115 | screw = UNF_N5(10,3);
116 | difference() {
117 | showcaseWalls (3,10,15);
118 | unfBoltHexagonalPassage (screw);
119 | translate( [0,0,screwGetThreadL(screw)] )
120 | unfNutPassage (screw);
121 | }
122 | %unfBoltHexagonal (unfClone(screw,12));
123 | translate( [0,0,screwGetThreadL(screw)] )
124 | %unfNutSquare (screw);
125 | }
126 |
127 | translate ( [-80,0,0] ) {
128 | // 10: Hexagonal nut passage
129 | screw = UNF_N5(10,3);
130 | difference() {
131 | showcaseWalls (3,10,15);
132 | unfBoltHexagonalPassage (screw);
133 | translate( [0,0,screwGetThreadL(screw)] )
134 | unfNutHexagonalPassage (screw);
135 | }
136 | %unfBoltHexagonal (unfClone(screw,12));
137 | translate( [0,0,screwGetThreadL(screw)] )
138 | %unfNutHexagonal (screw);
139 | }
140 |
141 | translate ( [-100,0,0] ) {
142 | // 11: Square nut passage
143 | screw = UNF_N5(10,3);
144 | difference() {
145 | translate ( [0,-screwGetSquareToolSize(screw)/2,0] )
146 | showcaseWalls (3,10,15);
147 | unfBoltPassage (screw);
148 | translate( [0,0,screwGetThreadL(screw)-4] )
149 | unfNutSquarePassage (screw);
150 | }
151 | %unfBoltHexagonal (unfClone(screw,12));
152 | translate( [0,0,screwGetThreadL(screw)-3.8] )
153 | %unfNutSquare (screw);
154 | }
155 | }
156 | rotate( [0,180,0] )
157 | showCase( $fn=100 );
158 |
--------------------------------------------------------------------------------
/test/screws/test-unf-screw-wall.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNF screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | SCREWS_HDP = [ for ( idx=[0:unfGetDataLength()-1] ) screwGetHeadDP ( unfData( idx ) ) ];
23 | ALL_SCREW = [for ( idx=[0:unfGetDataLength()-1] ) unfData( idx ) ];
24 | SCREW_DISTANCE=7;
25 |
26 | WALL1_H=4;
27 | WALL2_H=70;
28 | WALL_W=100+columnSum( SCREWS_HDP, end=unfGetDataLength()-1 )+(unfGetDataLength()-1)*SCREW_DISTANCE;
29 | WALL_P=100;
30 |
31 | module showcaseScrewPassage ( t, tlp ) {
32 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
33 | unfBoltPassage ( unfClone(t, tlp=tlp) );
34 | }
35 | }
36 | module showcaseScrew ( t ) {
37 | translate( [ t[0]*SCREW_DISTANCE + columnSum( SCREWS_HDP, end=t[0] )-WALL_W/2,0,0] ) {
38 | color( "silver", 0.7 ) {
39 | if ( screwGetIdx(t)%2 ) {
40 | unfBoltAllen ( t );
41 | }
42 | else {
43 | unfBoltHexagonal ( t );
44 | }
45 | }
46 | color( "gold" )
47 | translate( [0,-t[8]/2-1.5,-t[9]/2] )
48 | rotate ( [90,0,0] )
49 | linear_extrude(1)
50 | text( t[1], halign="center", valign="center", size=2, $fn=100 );
51 | }
52 | }
53 |
54 | module showcaseWalls( wh1, wh2, ww=WALL_W, wp=WALL_P ) {
55 | translate ( [0,wp/2,0] ) {
56 | color( "LightSkyBlue" )
57 | translate ( [0,0,+(wh2+wh1)/2] )
58 | cube( [ww,wp,wh2], center=true );
59 | color( "DodgerBlue" )
60 | translate ( [0,0,0] )
61 | cube( [ww,wp,wh1], center=true );
62 | }
63 | }
64 |
65 | module showcaseBigWall() {
66 | HLP = WALL1_H+10;
67 | difference() {
68 | showcaseWalls (WALL1_H,WALL2_H,WALL_W);
69 | for ( screw=ALL_SCREW ) {
70 | showcaseScrewPassage( screw, 2+screwGetThreadL(screw)*0.3 );
71 | }
72 | }
73 | for ( screw=ALL_SCREW ) {
74 | showcaseScrew( screw );
75 | }
76 | }
77 |
78 | dumpScrewsData(ALL_SCREW);
79 | showcaseBigWall ($fn=50);
80 |
--------------------------------------------------------------------------------
/test/test-canvas.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Vigibot
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Test canvas manipulations and rendering
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 |
18 | // rendering precision tuning
19 | $fn=80;
20 |
21 | //
22 | // Images sources:
23 | // Penguin: http://clipart-library.com/clipart/709738.htm
24 | // Morris Minor: https://pixabay.com/fr/photos/morris-minor-limousine-oldtimer-4754082/
25 | //
26 | use
27 | use
28 |
29 | penguin = levels_clipartlibrarypenguin();
30 | module showPlane(preserve=true, moved=false, resized=false) {
31 | canvas = newCanvas( [200,100], [2*$fn,$fn] );
32 | image = drawImage ( penguin, canvas,
33 | size=resized?[100,50]:undef, start=moved?[90,40]:undef, preserve=preserve );
34 | mesh = canvas2mesh( image, skin=false, minlayer=2, thickness=5 );
35 | projected = getMeshVertices(mesh);
36 | lithophane = newMesh(projected,getMeshFaces(mesh));
37 | render()
38 | meshPolyhedron ( lithophane );
39 | }
40 | module showSphereFull( skin=true, positive=true, resized=false ) {
41 | // If image size is reduced we need more pixels in the canvas
42 | canvas = newCanvas( [2,1], resized?[4*$fn,2*$fn]:[2*$fn,$fn] );
43 | image = drawImage ( penguin, canvas, size=resized?[undef,0.5]:undef );
44 | mesh = canvas2mesh( image, skin=skin, positive=positive, thickness=10 );
45 | projected = projectSphereCylindrical( getMeshVertices(mesh), 100 );
46 | lithophane = newMesh(projected,getMeshFaces(mesh));
47 | render()
48 | meshPolyhedron ( lithophane );
49 | }
50 | module showSphereCrop(preserve=true) {
51 | levels = imageCrop(penguin, [40,40], [43,66]);
52 | canvas = newCanvas( [2,1], [2*$fn,$fn] );
53 | image = drawImage ( levels, canvas, size=[1,0.5], preserve=preserve );
54 | mesh = canvas2mesh( image, skin=true, thickness=10 );
55 | projected = projectSphereCylindrical( getMeshVertices(mesh), 100 );
56 | lithophane = newMesh(projected,getMeshFaces(mesh));
57 | render()
58 | meshPolyhedron ( lithophane );
59 | }
60 | module showCylinder() {
61 | canvas = newCanvas( [2,1], [2*$fn,$fn] );
62 | image = drawImage ( penguin, canvas );
63 | mesh = canvas2mesh( image, skin=false, thickness=10 );
64 | projected = projectCylinder( getMeshVertices(mesh), 100, 314 );
65 | lithophane = newMesh(projected,getMeshFaces(mesh));
66 | render()
67 | meshPolyhedron ( lithophane );
68 | }
69 | module showBigShere() {
70 | levels = levels_pixabaymorrisminor();
71 | canvas = newCanvas( [2,1], [6*$fn,3*$fn] );
72 | image = drawImage ( levels, canvas, size=[undef,0.4] );
73 | mesh = canvas2mesh( image, skin=true, thickness=5 );
74 | projected = projectSphereCylindrical( getMeshVertices(mesh), 100 );
75 | lithophane = newMesh(projected,getMeshFaces(mesh));
76 | render()
77 | meshPolyhedron ( lithophane );
78 | }
79 | module showText( t ) {
80 | %
81 | for ( i=[0:len(t)-1] )
82 | translate( [0,0,-150-i*40] )
83 | rotate( [90,0,0] )
84 | color( "gold" )
85 | linear_extrude ( height=1 )
86 | text( t[i], halign="center", size=30-i*3 );
87 | }
88 | /*
89 | */
90 | translate ( [000,0,0] ) {
91 | rotate( [90,0,0] )
92 | translate ( [-100,-50,0] )
93 | showPlane();
94 | showText( [ "Plane", "thick", "positive", "preserve on" ] );
95 | }
96 | translate ( [300,0,0] ) {
97 | rotate( [90,0,0] )
98 | translate ( [-100,-50,0] )
99 | showPlane(resized=true,moved=true,preserve=false);
100 | showText( [ "Plane", "resize", "move", "preserve off", "thick", "positive" ] );
101 | }
102 | translate ( [600,0,0] ) {
103 | rotate( [0,0,90] )
104 | scale( 0.7 )
105 | showCylinder();
106 | showText( [ "Cylinder", "thick", "positive", "preserve on" ] );
107 | }
108 | translate ( [900,0,0] ) {
109 | rotate( [0,0,90] )
110 | showSphereFull(skin=true);
111 | showText( [ "Sphere", "positive", "preserve on", "skin" ] );
112 | }
113 | translate ( [1200,0,0] ) {
114 | rotate( [0,0,90] )
115 | showSphereFull(skin=true,positive=false);
116 | showText( [ "Sphere", "negative", "preserve on", "skin" ] );
117 | }
118 | translate ( [1500,0,0] ) {
119 | rotate( [0,0,90] )
120 | showSphereFull(skin=true,resized=true);
121 | showText( [ "Sphere", "resize", "preserve on", "skin", "positive" ] );
122 | }
123 | translate ( [1800,0,0] ) {
124 | rotate( [0,0,90] )
125 | showSphereCrop();
126 | showText( [ "Sphere", "crop", "resize", "preserve on", "skin", "positive" ] );
127 | }
128 | translate ( [2100,0,0] ) {
129 | rotate( [0,0,90] )
130 | showSphereCrop(preserve=false);
131 | showText( [ "Sphere", "preserve off", "crop", "resize", "skin", "positive" ] );
132 | }
133 | translate ( [1000,1500,800] ) {
134 | scale( [10,10,10] )
135 | rotate( [0,0,90] )
136 | showBigShere();
137 | }
138 | /*
139 | */
140 |
141 |
--------------------------------------------------------------------------------
/test/test-extrude.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2022, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: OpenSCAD extensions to scad language
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 |
17 | translate([+4.5,0,0])
18 | extrude(regularPolygon(100), 1, false, [undef,2,2], [0,undef,4] );
19 |
20 | translate([+4.5,3,0])
21 | extrude(regularPolygon(100), 1, true, [undef,0,4], [2,undef,2] );
22 |
23 | translate([+1.5,0,0])
24 | extrude(regularPolygon(12), 1, true, [undef,1,1] );
25 |
26 | translate([+1.5,3,0])
27 | extrude(regularPolygon(12), 1, true, undef, [1,undef,1] );
28 |
29 | translate([-1.5,0,0])
30 | extrude(regularPolygon(8), 1, true, [undef,1,1], [0,undef,1.3] );
31 |
32 | translate([-1.5,3,0])
33 | extrude(regularPolygon(8), 1, true, [undef,0,1.3], [1,undef,1] );
34 |
35 | translate([-4.5,3,0])
36 | extrude(regularPolygon(3), 1 );
37 |
38 | translate([-4.5,0,0])
39 | extrude(regularPolygon(3), 1, true, [undef,0,1], [0,undef,1] );
40 |
41 | translate([-1.5,6,0])
42 | prism(meshRegularPolygon(6));
43 |
44 | translate([-4.5,6,0])
45 | prism(meshRegularPolygon(12), caps=false);
46 |
47 | translate([1.5,6,0])
48 | frustum(meshRegularPolygon(7), 1, 30);
49 |
50 | translate([4.5,6,0])
51 | frustum(meshRegularPolygon(7), 1, 30, caps=false);
52 |
--------------------------------------------------------------------------------
/test/test-geometry.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Some geometrical functions
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 | use
16 |
17 |
18 | // ----------------------------------------
19 | // TEST intersec_planes_3
20 | // ----------------------------------------
21 |
22 | test_ip3_0_planes = [
23 | [ [-3,4,0], [0,0,2] ],
24 | [ [-4,0,4], [0,3,0] ],
25 | [ [0,1,-2], [4,0,0] ] ];
26 | test_ip3_0 = intersec_planes_3(
27 | test_ip3_0_planes[0],
28 | test_ip3_0_planes[1],
29 | test_ip3_0_planes[2]
30 | );
31 | color("yellow") renderPlanes(test_ip3_0_planes);
32 | color("red") renderPoints([test_ip3_0]);
33 | echo("test_ip3_0=",roundDownList(test_ip3_0));
34 | assert(roundDownList(test_ip3_0)==[0,0,0],
35 | "ERROR intersec_planes_3 test 0");
36 |
37 | test_ip3_1_planes = [
38 | [ [25,-2,0], [0,2,2] ],
39 | [ [25,-1,4], [0,3,-10] ],
40 | [ [23,-3,2], [4,8,0] ] ];
41 | test_ip3_1 = intersec_planes_3(
42 | test_ip3_1_planes[0],
43 | test_ip3_1_planes[1],
44 | test_ip3_1_planes[2]
45 | );
46 | color("blue") renderPlanes(test_ip3_1_planes);
47 | color("red") renderPoints([test_ip3_1]);
48 | echo("test_ip3_1=",roundDownList(test_ip3_1));
49 | assert(roundDownList(test_ip3_1)==[26.69,-4.85,2.84],
50 | "ERROR intersec_planes_3 test 1");
51 |
52 | test_ip3_2 = intersec_planes_3(
53 | [ [1,2,0], [0,0,2] ],
54 | [ [4,2,0], [0,0,2] ],
55 | [ [0,5,6], [4,0,0] ]
56 | );
57 | echo("test_ip3_2=",test_ip3_2);
58 | assert(is_undef(test_ip3_2),
59 | "ERROR intersec_planes_3 test 2");
60 |
61 |
62 | // ----------------------------------------
63 | // TEST intersec_planes_2
64 | // ----------------------------------------
65 |
66 | test_ip2_0_planes = [
67 | [ [9,2,0], [4,1,-1] ],
68 | [ [9,5,4], [-2,3,1] ] ];
69 | test_ip2_0 = intersec_planes_2(
70 | test_ip2_0_planes[0],
71 | test_ip2_0_planes[1]
72 | );
73 | color("green") renderPlanes(test_ip2_0_planes);
74 | color("red") renderLines([test_ip2_0]);
75 | test_ip2_0_check=roundDownList(test_ip2_0);
76 | echo("test_ip2_0=",test_ip2_0_check);
77 | assert(test_ip2_0_check== [[7.68,5.9,-1.36],[4,-2,14],[0,0,0]],
78 | "ERROR intersec_planes_2 test 0");
79 |
80 | test_ip2_1 = intersec_planes_2(
81 | [ [1,2,0], [2,2,1] ],
82 | [ [3,5,4], [60,60,30] ]
83 | );
84 | echo("test_ip2_1=",test_ip2_1);
85 | assert(is_undef(test_ip2_1),
86 | "ERROR intersec_planes_2 test 1");
87 |
88 |
89 |
90 | // ----------------------------------------
91 | // Utilities
92 | // ----------------------------------------
93 | $fn=10;
94 |
95 | function roundDownList(val) = [ for (v=val)
96 | if ( is_list(v) )
97 | [ for (c=v) roundDown(c,0.01) ]
98 | else
99 | roundDown(v,0.01)
100 | ];
101 |
--------------------------------------------------------------------------------
/test/test-glue.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Glue shapes library test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 |
14 | color( "gold" )
15 | glue_circle ( $fn=200 );
16 |
17 | translate( [0,0,20] )
18 | rotate( [-30,0,0] )
19 | difference() {
20 | translate( [0,0,5/2] )
21 | cube( [ 70, 70, 5 ], center=true );
22 | # glue_circle_receiver ( $fn=200 );
23 | }
24 |
25 | translate( [0,0,-20] )
26 | rotate( [+30,0,0] )
27 | difference() {
28 | translate( [0,0,-5/2] )
29 | cube( [ 70, 70, 5 ], center=true );
30 | glue_circle_receiver ( $fn=200 );
31 | }
32 |
33 |
--------------------------------------------------------------------------------
/test/test-hardware.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Test hardware modules
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 |
16 |
17 | PRECISION = 200;
18 | SEPARATION = 0;
19 |
20 | module show_er() {
21 | collets_min = [ // Minimum printable dimensions with default prinable settings
22 | newER8(1), newER11(1), newER16(1), newER20(1),
23 | newER25(1), newER32(2), newER40(3), newER50(6)
24 | ];
25 | collets_max = [ // Maximum printable dimensions with default prinable settings
26 | newER8(4), newER11(6.5), newER16(10), newER20(13),
27 | newER25(16), newER32(20), newER40(26), newER50(34)
28 | ];
29 |
30 | YER = -50;
31 | YERMAX = -110;
32 | YPASS = 10;
33 | offsetx = columnSum(collets_min,3)/2;
34 | for ( i=[0:len(collets_min)-1] ) let(
35 | x = columnSum(collets_min,3,0,i),
36 | col = collets_min[i],
37 | colmax = collets_max[i]
38 | ) {
39 | translate([x-offsetx,YER,0])
40 | ERCollet(col);
41 | translate([x-offsetx,YERMAX,0])
42 | ERCollet(colmax);
43 | color( "gold" )
44 | translate([x-offsetx,YER,ERColletGetL(col)+5])
45 | rotate ( [90,0,0] )
46 | linear_extrude(1)
47 | text(ERColletGetName(col), halign="center", valign="center", size=3, $fn=100 );
48 | color("lime")
49 | translate([x-offsetx,YPASS,0]) ERColletPassage(col);
50 | color("blue")
51 | translate([x-offsetx,YER,0]) ERColletExtractorRing(col);
52 | }
53 | }
54 |
55 | module show_parts( part=0, cut=undef, cut_rotation=undef ) {
56 | zip = newZipTie2_5();
57 | zipu1 = makeZipU( zip, 20 );
58 | zipu2 = makeZipU( zip, 10, 5 );
59 | zipo1 = makeZipOblong( zip, 1.5, 3 );
60 |
61 | if ( part==0 ) {
62 | intersection () {
63 | union() {
64 | zipShape ( zipu1 );
65 | rotate( [0,90,0] )
66 | zipShape ( zipo1 );
67 | translate( [0, 0, 2])
68 | difference() {
69 | zipConduitShape ( zipu2 );
70 | zipConduitHollow( zipu2 );
71 | }
72 | }
73 | color ( "#fff",0.1 )
74 | rotate( [0,0,is_undef(cut_rotation)?0:cut_rotation] )
75 | translate( [-500,is_undef(cut)?-500:cut,-500] )
76 | cube( [1000,1000,1000] );
77 | }
78 | color( "#fff" )
79 | translate( [0, 0, 2])
80 | zipShape ( zipu2 );
81 | show_er();
82 | }
83 |
84 | if ( part==1 ) {
85 | #zipShapePassage ( zipu2, $gap=1 );
86 | zipShape ( zipu2 );
87 | }
88 | if ( part==2 ) {
89 | #zipShapePassage ( zipo1 );
90 | zipShape ( zipo1 );
91 | }
92 | if ( part==3 ) {
93 | difference() {
94 | zipConduitShape( zipu2 );
95 | zipConduitHollow( zipu2 );
96 | }
97 | zipShape ( zipu2 );
98 | }
99 | if ( part==4 ) {
100 | show_er();
101 | }
102 | }
103 |
104 | // 0: all
105 | // 1: zip U shape
106 | // 2: zip Obblong shape
107 | // 3: zip U shape conduit
108 | // 4: ER Collets
109 | show_parts ( 4, 0, -90, $fn=PRECISION );
110 |
111 |
112 |
--------------------------------------------------------------------------------
/test/test-hirth-joint.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw modelisation
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use <../hirth-joint.scad>
14 |
15 | MARGIN = 0.2;
16 |
17 | // ----------------------------------------
18 | //
19 | // Showcase
20 | //
21 | // ----------------------------------------
22 | module hirthJointShow( part=0 ) {
23 | INTER = 10;
24 |
25 | RADIUS = 10;
26 | TOOTH = 21;
27 | HEIGHT = 1.2;
28 | SHOULDER = 0;
29 | INLAY = 2;
30 |
31 | if ( part==0 || part==1 ) {
32 | color( "YellowGreen" )
33 | translate( [0,0,+SHOULDER+HEIGHT/2+INTER/2] )
34 | rotate( [180,0,0] )
35 | rotate( [0,0,180] )
36 | hirthJointSinus( RADIUS, TOOTH, HEIGHT, SHOULDER, INLAY );
37 | }
38 |
39 | if ( part==0 || part==2 ) {
40 | color( "Lime" )
41 | translate( [0,0,-SHOULDER-HEIGHT/2-INTER/2] )
42 | hirthJointSinus( RADIUS, TOOTH, HEIGHT, SHOULDER, INLAY );
43 | }
44 |
45 | if ( part==0 || part==3 ) {
46 | color( "SkyBlue" )
47 | translate( [0,3*RADIUS,-SHOULDER-HEIGHT/2-INTER/2] )
48 | hirthJointTriangle( RADIUS, TOOTH, HEIGHT, SHOULDER, INLAY );
49 | }
50 |
51 | if ( part==0 || part==4 ) {
52 | color( "Khaki" )
53 | translate( [2.5*RADIUS,1.5*RADIUS,-SHOULDER-HEIGHT/2-INTER/2] )
54 | hirthJointRectangle( RADIUS, TOOTH, HEIGHT, SHOULDER, INLAY );
55 | }
56 |
57 | if ( part==0 || part==5 ) {
58 | translate( [0,0,-1.5*INTER-SHOULDER-HEIGHT] ) {
59 | difference() {
60 | color( "DarkGreen" )
61 | translate( [0,0,-2] )
62 | cylinder( r=(RADIUS+2)/cos(30), h=4, center=true );
63 | hirthJointPassage( RADIUS, HEIGHT, SHOULDER, INLAY );
64 | }
65 | }
66 | }
67 |
68 | if ( part==0 || part==6 )
69 | translate( [0,50,0] ) {
70 | translate( [0,0,0] ) {
71 | hirthJointSinus( 5, 11, 2, 1, 1, shift=0.5, rmin=0 );
72 | %hirthJointPassage( 5, 2, 1, 1 );
73 | }
74 |
75 | translate( [15,0,0] ) {
76 | hirthJointRectangle( 5, 11, 1, 1, 1, shift=0, rmin=2.5 );
77 | %hirthJointPassage( 5, 1, 1, 1 );
78 | }
79 | translate( [30,0,0] ) {
80 | hirthJointTriangle( 5, 11, 1, 1, 1, shift=0, rmin=4 );
81 | %hirthJointPassage( 5, 1, 1, 1 );
82 | }
83 |
84 | translate( [0,15,0] ) {
85 | difference() {
86 | union() {
87 | // Automatic rmin
88 | hirthJointSinus( 5, 11, 1, 1, 1, shift=0.5 );
89 | translate( [0,0,3+0.01] )
90 | rotate([0,180,0])
91 | hirthJointSinus( 5, 11, 1, 1, 1, shift=0.5 );
92 | }
93 | translate( [0,-500,0] )
94 | cube( 1000, center=true );
95 | }
96 | }
97 | translate( [15,15,0] ) {
98 | difference() {
99 | union() {
100 | hirthJointRectangle( 5, 11, 1, 1, 1, shift=0.5 );
101 | translate( [0,0,3+0.01] )
102 | rotate([0,180,0])
103 | hirthJointRectangle( 5, 11, 1, 1, 1, shift=0.5 );
104 | }
105 | cylinder(r=2.5,h=10, center=true);
106 | }
107 | }
108 | translate( [30,15,0] ) {
109 | difference() {
110 | union() {
111 | hirthJointTriangle( 5, 11, 1, 1, 1, shift=0.5 );
112 | translate( [0,0,3+0.01] )
113 | rotate([0,180,0])
114 | hirthJointTriangle( 5, 11, 1, 1, 1, shift=0.5 );
115 | }
116 | cylinder(r=2.5,h=10, center=true);
117 | }
118 | }
119 |
120 | echo ("test=", hirthJointProfileSinus(1) );
121 | }
122 |
123 | }
124 |
125 | $fn=50;
126 |
127 | difference() {
128 | hirthJointShow( 0 );
129 | cylinder( r=1.5+MARGIN/2, h=100, center=true );
130 | }
131 |
--------------------------------------------------------------------------------
/test/test-mx-knob.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Knob modelisation
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use <../mx-knob.scad>
14 | use <../mx-screw.scad>
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module mxKnobTest() {
23 | translate([+60,+30,0]) {
24 | mxKnob ( M12(), 50, 100, cap_height=30 );
25 | rotate( [180,0,0] )
26 | %mxBoltHexagonal ( M12() );
27 | }
28 | translate([+15,+50,0])
29 | rotate( [90,0,0] ) {
30 | mxKnob ( M6(), 25, 20, part=0 );
31 | rotate( [180,0,0] )
32 | #mxBoltHexagonal ( M6() );
33 | }
34 | translate([-15,+30,0]) {
35 | mxKnob ( M1_6(tlp=3), 15, 15, part=0 );
36 | rotate( [180,0,0] )
37 | %mxBoltHexagonal ( M1_6() );
38 | }
39 |
40 | translate([+60,-30,0]) {
41 | mxKnob ( M12() );
42 | rotate( [180,0,0] )
43 | %mxBoltHexagonal ( M12() );
44 | }
45 | translate([+15,-30,0]) {
46 | mxKnob ( M6(), part=1 );
47 | mxKnob ( M6(), part=3 );
48 | rotate( [180,0,0] )
49 | %mxBoltHexagonal ( M6() );
50 | }
51 | translate([-15,-30,0]) {
52 | mxKnob ( M1_6(tlp=3) );
53 | rotate( [180,0,0] )
54 | %mxBoltHexagonal ( M1_6() );
55 | }
56 | }
57 | mxKnobTest($fn=50);
58 |
--------------------------------------------------------------------------------
/test/test-pixeled.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2_21, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Pickaxe - test layout
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 |
17 | /**
18 | * $part:
19 | * ALL()
20 | * 0: Cells only
21 | * 1: Caps only
22 | * 2: Nails only
23 | *
24 | * 3: Cells for printing
25 | * 4: Caps for printing
26 | * 5: Nails for printing
27 | *
28 | * $subpart:
29 | * ALL()
30 | * 0: part 0
31 | * 1: part 1
32 | * etc...
33 | *
34 | * $cut:
35 | * true: cut the figure to see internal structure (debug purpose)
36 | * false: normal display (default)
37 | *
38 | */
39 |
40 | // Custom sizes
41 | $pixel_w = 30;
42 | $pixel_h = 20;
43 |
44 | // Selection of what to display
45 | $part = ALL();
46 | $subpart = ALL();
47 |
48 | // Beveling is essentially to counter first layer overextrusion
49 | // set this value to 0 to disable beveling
50 | $bevel = 0.3;
51 |
52 | layoutPixeledObject(TEST_CELLS(), TEST_NAILS(), TEST_COLORS());
53 |
54 |
55 |
56 | VAL_PART1 = VAL_UNICOLOR_CELL(1);
57 | VAL_PART1_SHINE = VAL_BICOLOR_CELL(2);
58 | VAL_PART2 = VAL_UNICOLOR_CELL(3);
59 | VAL_PART2_SHINE = VAL_BICOLOR_CELL(4);
60 |
61 | COLOR_DARK_BROWN = "#513c1a";
62 | COLOR_LIGHT_BROWN = "#a3752d";
63 | COLOR_DARK_TURQUOISE = "#20594b";
64 | COLOR_LIGHT_TURQUOISE = "#32e8bf";
65 |
66 | /**
67 | * Mapping from layout values to colors
68 | */
69 | function TEST_COLORS() = [
70 | [ // Cell color mapping: IDX_COLOR_CELL() array
71 | [ VAL_PART1, COLOR_DARK_BROWN ],
72 | [ VAL_PART1_SHINE, COLOR_DARK_BROWN ],
73 | [ VAL_PART2, COLOR_DARK_TURQUOISE ],
74 | [ VAL_PART2_SHINE, COLOR_DARK_TURQUOISE ]
75 | ],[ // Cap color mapping: IDX_COLOR_CAP() array
76 | [ VAL_PART1_SHINE, COLOR_LIGHT_BROWN ],
77 | [ VAL_PART2_SHINE, COLOR_LIGHT_TURQUOISE ]
78 | ]];
79 |
80 | function TEST_CELLS() =
81 | let (
82 | _ = VAL_EMPTY(),
83 | z = VAL_PART1,
84 | x = VAL_PART1_SHINE,
85 | m = VAL_PART2,
86 | o = VAL_PART2_SHINE
87 | )
88 | [[
89 | [ o,_ ],
90 | [ o,o ],
91 | ],[
92 | [ _,x ],
93 | [ _,_ ],
94 | ]];
95 |
96 | function TEST_NAILS() =
97 | let (
98 | _ = VAL_EMPTY(),
99 | r = VAL_NAIL_RGT(),
100 | x = VAL_NAIL_LFT() + VAL_NAIL_BOT(),
101 | I = VAL_NAIL_TOP() + VAL_NAIL_BOT()
102 | )
103 | [[
104 | [ r,_ ],
105 | [ _,I ],
106 | ],[
107 | [ _,x ],
108 | [ _,_ ],
109 | ]];
110 |
--------------------------------------------------------------------------------
/test/test-sew.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: OpenSCAD extensions to scad language
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 | use
14 | use
15 | use
16 |
17 |
18 |
19 | unevenSurface = [
20 | [ [0,1,0], [3,0,0], [6,1,0] ],
21 | [ [0,1,1], [2,0,1], [4,0,1], [6,1,1] ],
22 | [ [0,1,2], [1,0,2], [2,0,2], [3,-0.5,2], [4,0,2], [5,0,2], [6,1,2] ],
23 | [ [0,1,3], [2,0,3], [4,0,3], [6,1,3] ],
24 | [ [0,1,4], [3,0,4], [6,1,4] ],
25 | ];
26 | color("lime")
27 | translate( [10,0,0] )
28 | sew(unevenSurface);
29 |
30 |
31 | radius = 5;
32 | height = 14;
33 | layers = 10;
34 | candleSurface = [
35 | for (i=[0:layers-1])
36 | transform(
37 | translation([0,0,i*height/layers]) * rotation([0,0,-30*i]),
38 | circle($fn=6,r=radius))
39 | ];
40 | color("lightblue")
41 | difference() {
42 | sew(candleSurface,convexity=10);
43 | cylinder(r=1, h=1000, $fn=50);
44 | }
45 |
46 |
47 |
48 |
49 |
50 |
--------------------------------------------------------------------------------
/test/test-snap-joint-tutorial.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Snap Joint tutorial
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use <../snap-joint.scad>
14 |
15 | // ----------------------------------------
16 | // API
17 | // ----------------------------------------
18 | $fn=50;
19 | showCase() {
20 | step_01();
21 | step_02();
22 | step_03();
23 | step_04();
24 | step_05();
25 | step_06();
26 | step_07();
27 | step_08();
28 | step_09();
29 | step_10();
30 | step_11();
31 | step_12();
32 | };
33 |
34 | // ----------------------------------------
35 | // Showcase
36 | // ----------------------------------------
37 | SHOW_ITV_H = 30;
38 |
39 | // 1: Simple Joint internal part
40 | module step_01() {
41 | joint = newSnapCircleInt ();
42 | snapJoint(joint);
43 | }
44 |
45 | // 2: Same with external part
46 | module step_02() {
47 | joint = newSnapCircleInt();
48 | snapJoint(joint);
49 | joint_e = newSnapCircleExt(source=joint);
50 | snapJoint(joint_e);
51 | }
52 |
53 | // 3: Gap
54 | module step_03() {
55 | $gap = 1;
56 |
57 | joint = newSnapCircleInt();
58 | snapJoint(joint);
59 | joint_e = newSnapCircleExt(source=joint);
60 | snapJoint(joint_e);
61 | }
62 |
63 | // 4: Springs/Cutter
64 | module step_04() {
65 | joint = newSnapCircleInt(springs=true);
66 | snapJoint(joint);
67 | joint_e = newSnapCircleExt(source=joint);
68 | snapJoint(joint_e);
69 | }
70 |
71 | // 5: Polygon 5
72 | module step_05() {
73 | joint = newSnapPolygonInt(springs=true);
74 | snapJoint(joint);
75 | joint_e = newSnapPolygonExt(source=joint);
76 | snapJoint(joint_e);
77 | }
78 |
79 | // 6: Polygon 4
80 | module step_06() {
81 | joint = newSnapPolygonInt (
82 | leaves=4,
83 | springs=true );
84 | snapJoint(joint);
85 | joint_e = newSnapPolygonExt(source=joint);
86 | snapJoint(joint_e);
87 | }
88 |
89 | // 7: Cut external: one time joint
90 | module step_07() {
91 | joint = newSnapCircleInt ();
92 | snapJoint(joint);
93 | joint_e = newSnapCircleExt (
94 | source=joint,
95 | springs=true );
96 | snapJoint(joint_e);
97 | }
98 |
99 | // 8: Height/Thickness
100 | module step_08() {
101 | joint = newSnapCircleInt (
102 | height = 10,
103 | thickness = 3,
104 | springs = true );
105 | snapJoint(joint);
106 | }
107 |
108 | // 9: Hook
109 | module step_09() {
110 | joint = newSnapCircleInt (
111 | height = 10,
112 | springs = true,
113 | hook_h = 5,
114 | hook_w = 1.6 );
115 | snapJoint(joint);
116 | }
117 |
118 | // 10: Spring width
119 | module step_10() {
120 | joint = newSnapCircleInt (
121 | height = 10,
122 | springs = true,
123 | hook_h = 5,
124 | hook_w = 1.6,
125 | spring_w = 5 );
126 | snapJoint(joint);
127 | }
128 |
129 | // 11: Spring angle
130 | module step_11() {
131 | joint = newSnapCircleInt (
132 | height = 10,
133 | springs = true,
134 | hook_h = 5,
135 | hook_w = 1.6,
136 | spring_w = 5,
137 | spring_a = 33 );
138 | snapJoint(joint);
139 | }
140 |
141 | // 12: Cut
142 | module step_12() {
143 | joint = newSnapCircleInt (
144 | springs = true,
145 | cutwidth = 2,
146 | cutdistance = 7
147 | );
148 | snapJoint(joint);
149 | }
150 |
151 | // ----------------------------------------
152 | // Implementation
153 | // ----------------------------------------
154 |
155 | module showOneStep ( x=0 ) {
156 | translate([x,SHOW_ITV_H,0])
157 | children();
158 | translate([x,0,0])
159 | children();
160 | }
161 |
162 | module showCase( only_one=undef ) {
163 | range = SHOW_ITV_H*($children-1);
164 | intersection () {
165 | union() {
166 | if ( is_undef(only_one) )
167 | for ( i=[0:$children-1] )
168 | showOneStep(-range/2+i*SHOW_ITV_H)
169 | children(i);
170 | else
171 | showOneStep()
172 | children(only_one-1);
173 | }
174 | color ( "#fff",0.1 )
175 | translate( [-500,0,-500] )
176 | cube( [1000,1000,1000] );
177 | }
178 | }
179 |
180 |
181 |
182 |
183 |
184 |
--------------------------------------------------------------------------------
/test/threads/test-bsf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSF thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | // Showcase
18 | // ----------------------------------------
19 |
20 | module showName( d, z ) {
21 | %color( "gold" )
22 | translate( [0,-7,z] )
23 | rotate( [90,0,0] )
24 | linear_extrude(0.1)
25 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
26 | }
27 |
28 | module showParts( part=0 ) {
29 | IX=20;
30 | color( "silver" )
31 | translate( [50,7,-20] )
32 | rotate( [90,0,0] )
33 | linear_extrude(0.1)
34 | text( "BSW BSF",halign="center",valign="center",size=10,$fn=100 );
35 |
36 | if ( part==0 ) {
37 | s1 = BSF3_16();
38 | s2 = BSF7_32();
39 | s3 = BSF1_4(tl=20);
40 | s4 = BSF3_8(tl=30);
41 | s5 = BSF1_2();
42 | s6 = BSF7_8();
43 | translate([0,0,0]) {
44 | bsfNutHexagonalThreaded(s1, $fn=50);
45 | showName(s1, -2);
46 | }
47 | translate([15,0,0]) {
48 | bsfNutSquareThreaded(s2, $fn=50);
49 | showName(s2, -2);
50 | }
51 | translate([30,0,0]) {
52 | bsfBoltHexagonalThreaded(s3, $fn=50);
53 | showName(s3, -7);
54 | }
55 | translate([50,0,0]) {
56 | bsfBoltAllenThreaded(s4, $fn=50);
57 | showName(s4, -11);
58 | }
59 | translate([70,0,0]) {
60 | bsfThreadInternal(s5, $fn=50);
61 | showName(s5, -2);
62 | }
63 | translate([90,0,0]) {
64 | bsfThreadExternal(bsfClone(s6,16),$fn=50);
65 | showName(s6, -4);
66 | }
67 | }
68 | if ( part==1 ) {
69 | s1 = BSF1_4(tl=20);
70 | translate([0*IX,0,0]) {
71 | bsfNutHexagonalThreaded(s1, $fn=50);
72 | showName(s1, -2);
73 | }
74 | translate([1*IX,0,0]) {
75 | bsfNutSquareThreaded(s1, $fn=50);
76 | showName(s1, -2);
77 | }
78 | translate([2*IX,0,0]) {
79 | bsfBoltHexagonalThreaded(s1, $fn=50);
80 | showName(s1, -7);
81 | }
82 | translate([3*IX,0,0]) {
83 | bsfBoltAllenThreaded(s1, $fn=50);
84 | showName(s1, -9);
85 | }
86 | }
87 | if ( part==2 ) {
88 | s1 = BSF3_8(tl=20);
89 | translate([0*IX,0,0]) {
90 | bsfNutHexagonalThreaded(s1, $fn=50);
91 | showName(s1, -2);
92 | }
93 | translate([1*IX,0,0]) {
94 | bsfNutSquareThreaded(s1, $fn=50);
95 | showName(s1, -2);
96 | }
97 | translate([2*IX,0,0]) {
98 | bsfBoltHexagonalThreaded(s1, $fn=50);
99 | showName(s1, -9);
100 | }
101 | translate([3*IX,0,0]) {
102 | bsfBoltAllenThreaded(s1, $fn=50);
103 | showName(s1, -11);
104 | }
105 | }
106 | }
107 |
108 | showParts(0);
109 |
--------------------------------------------------------------------------------
/test/threads/test-bspp-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSPP thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 | use
16 | use
17 |
18 | // ----------------------------------------
19 | //
20 | // Showcase
21 | //
22 | // ----------------------------------------
23 | $fn=50;
24 |
25 | module showVerticalText(t, z) {
26 | %color( "gold" )
27 | translate( [0,-7,z] )
28 | rotate( [90,0,0] )
29 | linear_extrude(0.1)
30 | text( t, halign="center", valign="center", size=2 );
31 | }
32 |
33 | module showName( d, z ) {
34 | showVerticalText(screwGetName(d), z);
35 | }
36 |
37 | module showParts( part=0 ) {
38 | IX=20;
39 | color( "silver" )
40 | translate( [40,7,-20] )
41 | rotate( [90,0,0] )
42 | linear_extrude(0.1)
43 | text( "BSPP",halign="center",valign="center",size=10 );
44 |
45 | if ( part==0 ) {
46 | translate([00,0,0]) {
47 | screw = BSPP1_4();
48 | difference() {
49 | bsppBoltHexagonalThreaded(screw);
50 | cylinder(r=bsppGetPipeD(screw)/2, h=1000, center=true);
51 | }
52 | showName(screw, -12);
53 | }
54 | translate([40,0,0]) {
55 | screw = BSPP1_2();
56 | difference() {
57 | bsppThreadExternal(screw);
58 | cylinder(r=bsppGetPipeD(screw)/2, h=1000, center=true);
59 | }
60 | showName(screw, -2);
61 | }
62 | translate([80,0,0]) {
63 | screw1 = BSPP1_8(tl=7.26);
64 | screw2 = BSW3_8(tl=5.15);
65 | difference() {
66 | union() {
67 | bsppThreadExternal(screw1);
68 | translate([0,0,-screwGetHexagonalHeadL(screw2)])
69 | rotate([180,0,0])
70 | bswBoltHexagonalThreaded(screw2);
71 | }
72 | cylinder(r=bsppGetPipeD(screw1)/2, h=1000, center=true);
73 | }
74 | showVerticalText("BSPP 1/8 to BSW 3/8 adapter", -22);
75 | }
76 | }
77 | }
78 |
79 | showParts(0);
80 |
81 |
--------------------------------------------------------------------------------
/test/threads/test-bsw-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: BSW thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module showName( d, z ) {
23 | %color( "gold" )
24 | translate( [0,-7,z] )
25 | rotate( [90,0,0] )
26 | linear_extrude(0.1)
27 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
28 | }
29 |
30 | module showParts( part=0 ) {
31 | IX=20;
32 | color( "silver" )
33 | translate( [50,7,-20] )
34 | rotate( [90,0,0] )
35 | linear_extrude(0.1)
36 | text( "BSW BSF",halign="center",valign="center",size=10,$fn=100 );
37 |
38 | if ( part==0 ) {
39 | s1 = BSW1_16();
40 | s2 = BSW5_32();
41 | s3 = BSW1_4(tl=20);
42 | s4 = BSW3_8(tl=30); // AKA: Congrès thread
43 | s5 = BSW1_2();
44 | s6 = BSW7_8();
45 | translate([0,0,0]) {
46 | bswNutHexagonalThreaded(s1, $fn=50);
47 | showName(s1, -2);
48 | }
49 | translate([15,0,0]) {
50 | bswNutSquareThreaded(s2, $fn=50);
51 | showName(s2, -2);
52 | }
53 | translate([30,0,0]) {
54 | bswBoltHexagonalThreaded(s3, $fn=50);
55 | showName(s3, -7);
56 | }
57 | translate([50,0,0]) {
58 | bswBoltAllenThreaded(s4, $fn=50);
59 | showName(s4, -11);
60 | }
61 | translate([70,0,0]) {
62 | bswThreadInternal(screw=s5,$fn=50);
63 | showName(s5, -2);
64 | }
65 | translate([90,0,0]) {
66 | bswThreadExternal(bswClone(s6,16),$fn=50);
67 | showName(s6, -4);
68 | }
69 | }
70 | if ( part==1 ) {
71 | s1 = BSW1_4(tl=20);
72 | translate([0*IX,0,0]) {
73 | bswNutHexagonalThreaded(s1, $fn=100);
74 | showName(s1, -2);
75 | }
76 | translate([1*IX,0,0]) {
77 | bswNutSquareThreaded(s1, $fn=100);
78 | showName(s1, -2);
79 | }
80 | translate([2*IX,0,0]) {
81 | bswBoltHexagonalThreaded(s1, $fn=100);
82 | showName(s1, -7);
83 | }
84 | translate([3*IX,0,0]) {
85 | bswBoltAllenThreaded(s1, $fn=100);
86 | showName(s1, -9);
87 | }
88 | }
89 | if ( part==2 ) {
90 | s1 = BSW3_8(tl=20);
91 | translate([0*IX,0,0]) {
92 | bswNutHexagonalThreaded(s1, $fn=100);
93 | showName(s1, -2);
94 | }
95 | translate([1*IX,0,0]) {
96 | bswNutSquareThreaded(s1, $fn=100);
97 | showName(s1, -2);
98 | }
99 | translate([2*IX,0,0]) {
100 | bswBoltHexagonalThreaded(s1, $fn=100);
101 | showName(s1, -9);
102 | }
103 | translate([3*IX,0,0]) {
104 | bswBoltAllenThreaded(s1, $fn=100);
105 | showName(s1, -11);
106 | }
107 | }
108 | }
109 |
110 | showParts(0);
111 |
112 |
--------------------------------------------------------------------------------
/test/threads/test-mx-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric screw thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module showName( d, z ) {
23 | %color( "gold" )
24 | translate( [0,-7,z] )
25 | rotate( [90,0,0] )
26 | linear_extrude(0.1)
27 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
28 | }
29 |
30 | module showParts( part=0 ) {
31 | IX=20;
32 | color( "DodgerBlue" )
33 | translate( [50,7,-20] )
34 | rotate( [90,0,0] )
35 | linear_extrude(0.1)
36 | text( "MC MF",halign="center",valign="center",size=10,$fn=100 );
37 |
38 | if ( part==0 ) {
39 | s1 = M1_6();
40 | s2 = M5();
41 | s3 = M6(tl=20);
42 | s4 = M10(tl=30);
43 | s5 = M12();
44 | s6 = M22();
45 | translate([0,0,0]) {
46 | mxNutHexagonalThreaded(s1, $fn=50);
47 | showName(s1, -2);
48 | }
49 | translate([15,0,0]) {
50 | mxNutSquareThreaded(s2, $fn=50);
51 | showName(s2, -2);
52 | }
53 | translate([30,0,0]) {
54 | mxBoltHexagonalThreaded(s3, $fn=50);
55 | showName(s3, -7);
56 | }
57 | translate([50,0,0]) {
58 | mxBoltAllenThreaded(s4, $fn=50);
59 | showName(s4, -11);
60 | }
61 | translate([70,0,0]) {
62 | mxThreadInternal(s5, $fn=50);
63 | showName(s5, -2);
64 | }
65 | translate([90,0,0]) {
66 | mxThreadExternal(mxClone(s6,16),$fn=50);
67 | showName(s6, -4);
68 | }
69 | }
70 | if ( part==1 ) {
71 | s1 = M5(tl=20);
72 | translate([0*IX,0,0]) {
73 | mxNutHexagonalThreaded(s1, $fn=100);
74 | showName(s1, -2);
75 | }
76 | translate([1*IX,0,0]) {
77 | mxNutSquareThreaded(s1, $fn=100);
78 | showName(s1, -2);
79 | }
80 | translate([2*IX,0,0]) {
81 | mxBoltHexagonalThreaded(s1, $fn=100);
82 | showName(s1, -7);
83 | }
84 | translate([3*IX,0,0]) {
85 | mxBoltAllenThreaded(s1, $fn=100);
86 | showName(s1, -9);
87 | }
88 | }
89 | if ( part==2 ) {
90 | s1 = M6(tl=20);
91 | translate([0*IX,0,0]) {
92 | mxNutHexagonalThreaded(s1, $fn=100);
93 | showName(s1, -2);
94 | }
95 | translate([1*IX,0,0]) {
96 | mxNutSquareThreaded(s1, $fn=100);
97 | showName(s1, -2);
98 | }
99 | translate([2*IX,0,0]) {
100 | mxBoltHexagonalThreaded(s1, $fn=100);
101 | showName(s1, -9);
102 | }
103 | translate([3*IX,0,0]) {
104 | mxBoltAllenThreaded(s1, $fn=100);
105 | showName(s1, -11);
106 | }
107 | }
108 | }
109 |
110 | showParts(0);
111 |
--------------------------------------------------------------------------------
/test/threads/test-mxf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Metric fine screw thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module showName( d, z ) {
23 | %color( "gold" )
24 | translate( [0,-7,z] )
25 | rotate( [90,0,0] )
26 | linear_extrude(0.1)
27 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
28 | }
29 |
30 | module showParts( part=0 ) {
31 | IX=20;
32 | color( "DodgerBlue" )
33 | translate( [50,7,-20] )
34 | rotate( [90,0,0] )
35 | linear_extrude(0.1)
36 | text( "MC MF",halign="center",valign="center",size=10,$fn=100 );
37 |
38 | if ( part==0 ) {
39 | s1 = MF1_6();
40 | s2 = MF5();
41 | s3 = MF6(tl=20);
42 | s4 = MF10(tl=30);
43 | s5 = MF12();
44 | s6 = MF22();
45 | translate([0,0,0]) {
46 | mxfNutHexagonalThreaded(s1, $fn=50);
47 | showName(s1, -2);
48 | }
49 | translate([15,0,0]) {
50 | mxfNutSquareThreaded(s2, $fn=50);
51 | showName(s2, -2);
52 | }
53 | translate([30,0,0]) {
54 | mxfBoltHexagonalThreaded(s3, $fn=50);
55 | showName(s3, -7);
56 | }
57 | translate([50,0,0]) {
58 | mxfBoltAllenThreaded(s4, $fn=50);
59 | showName(s4, -11);
60 | }
61 | translate([70,0,0]) {
62 | mxfThreadInternal(s5, $fn=50);
63 | showName(s5, -2);
64 | }
65 | translate([90,0,0]) {
66 | mxfThreadExternal(mxfClone(s6,16),$fn=50);
67 | showName(s6, -4);
68 | }
69 | }
70 | if ( part==1 ) {
71 | s1 = MF5(tl=20);
72 | translate([0*IX,0,0]) {
73 | mxfNutHexagonalThreaded(s1, $fn=100);
74 | showName(s1, -2);
75 | }
76 | translate([1*IX,0,0]) {
77 | mxfNutSquareThreaded(s1, $fn=100);
78 | showName(s1, -2);
79 | }
80 | translate([2*IX,0,0]) {
81 | mxfBoltHexagonalThreaded(s1, $fn=100);
82 | showName(s1, -7);
83 | }
84 | translate([3*IX,0,0]) {
85 | mxfBoltAllenThreaded(s1, $fn=100);
86 | showName(s1, -9);
87 | }
88 | }
89 | if ( part==2 ) {
90 | s1 = MF6(tl=20);
91 | translate([0*IX,0,0]) {
92 | mxfNutHexagonalThreaded(s1, $fn=100);
93 | showName(s1, -2);
94 | }
95 | translate([1*IX,0,0]) {
96 | mxfNutSquareThreaded(s1, $fn=100);
97 | showName(s1, -2);
98 | }
99 | translate([2*IX,0,0]) {
100 | mxfBoltHexagonalThreaded(s1, $fn=100);
101 | showName(s1, -9);
102 | }
103 | translate([3*IX,0,0]) {
104 | mxfBoltAllenThreaded(s1, $fn=100);
105 | showName(s1, -11);
106 | }
107 | }
108 | }
109 |
110 | showParts(0);
111 |
--------------------------------------------------------------------------------
/test/threads/test-thread-comparison.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Thread standards comparison
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 | use
16 | use
17 | use
18 | use
19 |
20 | // ----------------------------------------
21 | //
22 | // Showcase
23 | //
24 | // ----------------------------------------
25 | XI=15;
26 | ZI=-25;
27 | module renderThread ( d, x, z ) {
28 | translate( [x*XI,0,z*ZI] ) {
29 | libBoltHexagonalThreaded (d);
30 | color( "gold" )
31 | translate( [0,0,-6] )
32 | rotate( [90,0,0] )
33 | linear_extrude(1)
34 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
35 | }
36 | }
37 |
38 | module showcase() {
39 | renderThread ( M6 ( tl=15 ), 0, 0);
40 | renderThread ( MF6 ( tl=15 ), 0, 1);
41 | renderThread ( UNC1_4 ( tl=15 ), 1, 0);
42 | renderThread ( UNF1_4 ( tl=15 ), 1, 1);
43 | renderThread ( BSW1_4 ( tl=15 ), 2, 0);
44 | renderThread ( BSF1_4 ( tl=15 ), 2, 1);
45 | }
46 |
47 | showcase ($fn=50);
48 |
49 | echo("========== Metric thread data ==========");
50 | mxdata = [ for ( i=[0:mxGetDataLength()-1] )
51 | mxData(i)
52 | ];
53 | dumpScrewsData(mxdata);
54 |
55 | echo("========== Metric fine thread data ==========");
56 | mxfdata = [ for ( i=[0:mxfGetDataLength()-1] )
57 | mxfData(i)
58 | ];
59 | dumpScrewsData(mxfdata);
60 |
61 | echo("========== UNC thread data ==========");
62 | uncdata = [ for ( i=[0:uncGetDataLength()-1] )
63 | uncData(i)
64 | ];
65 | dumpScrewsData(uncdata);
66 |
67 | echo("========== UNC fine thread data ==========");
68 | unfdata = [ for ( i=[0:unfGetDataLength()-1] )
69 | unfData(i)
70 | ];
71 | dumpScrewsData(unfdata);
72 |
73 | echo("========== BSW thread data ==========");
74 | bswdata = [ for ( i=[0:bswGetDataLength()-1] )
75 | bswData(i)
76 | ];
77 | dumpScrewsData(bswdata);
78 |
79 | echo("========== BSW fine thread data ==========");
80 | bsfdata = [ for ( i=[0:bsfGetDataLength()-1] )
81 | bsfData(i)
82 | ];
83 | dumpScrewsData(bsfdata);
84 |
--------------------------------------------------------------------------------
/test/threads/test-unc-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNC thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module showName( d, z ) {
23 | %color( "gold" )
24 | translate( [0,-7,z] )
25 | rotate( [90,0,0] )
26 | linear_extrude(0.1)
27 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
28 | }
29 |
30 | module showParts( part=0 ) {
31 | IX=20;
32 | color( "gold" )
33 | translate( [50,7,-20] )
34 | rotate( [90,0,0] )
35 | linear_extrude(0.1)
36 | text( "UNC UNF",halign="center",valign="center",size=10,$fn=100 );
37 |
38 | if ( part==0 ) {
39 | s1 = UNC_N1();
40 | s2 = UNC_N5();
41 | s3 = UNC1_4(tl=20);
42 | s4 = UNC3_8(tl=30);
43 | s5 = UNC1_2();
44 | s6 = UNC7_8();
45 | translate([2,0,0]) {
46 | uncNutHexagonalThreaded(s1, $fn=50);
47 | showName(s1, -2);
48 | }
49 | translate([15,0,0]) {
50 | uncNutSquareThreaded(s2, $fn=50);
51 | showName(s2, -2);
52 | }
53 | translate([30,0,0]) {
54 | uncBoltHexagonalThreaded(s3, $fn=50);
55 | showName(s3, -7);
56 | }
57 | translate([50,0,0]) {
58 | uncBoltAllenThreaded(s4, $fn=50);
59 | showName(s4, -11);
60 | }
61 | translate([70,0,0]) {
62 | uncThreadInternal(s5, $fn=50);
63 | showName(s5, -2);
64 | }
65 | translate([90,0,0]) {
66 | uncThreadExternal(uncClone(s6,16),$fn=50);
67 | showName(s6, -4);
68 | }
69 | }
70 | if ( part==1 ) {
71 | s1 = UNC1_4(tl=20);
72 | translate([0*IX,0,0]) {
73 | uncNutHexagonalThreaded(s1, $fn=100);
74 | showName(s1, -2);
75 | }
76 | translate([1*IX,0,0]) {
77 | uncNutSquareThreaded(s1, $fn=100);
78 | showName(s1, -2);
79 | }
80 | translate([2*IX,0,0]) {
81 | uncBoltHexagonalThreaded(s1, $fn=100);
82 | showName(s1, -7);
83 | }
84 | translate([3*IX,0,0]) {
85 | uncBoltAllenThreaded(s1, $fn=100);
86 | showName(s1, -9);
87 | }
88 | }
89 | if ( part==2 ) {
90 | s1 = UNC3_8(tl=20);
91 | translate([0*IX,0,0]) {
92 | uncNutHexagonalThreaded(s1, $fn=100);
93 | showName(s1, -2);
94 | }
95 | translate([1*IX,0,0]) {
96 | uncNutSquareThreaded(s1, $fn=100);
97 | showName(s1, -2);
98 | }
99 | translate([2*IX,0,0]) {
100 | uncBoltHexagonalThreaded(s1, $fn=100);
101 | showName(s1, -9);
102 | }
103 | ! translate([3*IX,0,0]) {
104 | uncBoltAllenThreaded(s1, $fn=100);
105 | showName(s1, -11);
106 | }
107 | }
108 | }
109 |
110 | showParts(0);
111 |
--------------------------------------------------------------------------------
/test/threads/test-unf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNF thread test
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 | use
15 |
16 | // ----------------------------------------
17 | //
18 | // Showcase
19 | //
20 | // ----------------------------------------
21 |
22 | module showName( d, z ) {
23 | %color( "gold" )
24 | translate( [0,-7,z] )
25 | rotate( [90,0,0] )
26 | linear_extrude(0.1)
27 | text( screwGetName(d), halign="center", valign="center", size=2, $fn=100 );
28 | }
29 |
30 | module showParts( part=0 ) {
31 | IX=20;
32 | color( "gold" )
33 | translate( [50,7,-20] )
34 | rotate( [90,0,0] )
35 | linear_extrude(0.1)
36 | text( "UNC UNF",halign="center",valign="center",size=10,$fn=100 );
37 |
38 | if ( part==0 ) {
39 | s1 = UNF_N0();
40 | s2 = UNF_N5();
41 | s3 = UNF1_4(tl=20);
42 | s4 = UNF3_8(tl=30);
43 | s5 = UNF1_2();
44 | s6 = UNF7_8();
45 | translate([2,0,0]) {
46 | unfNutHexagonalThreaded(s1, $fn=50);
47 | showName(s1, -2);
48 | }
49 | translate([15,0,0]) {
50 | unfNutSquareThreaded(s2, $fn=50);
51 | showName(s2, -2);
52 | }
53 | translate([30,0,0]) {
54 | unfBoltHexagonalThreaded(s3, $fn=50);
55 | showName(s3, -7);
56 | }
57 | translate([50,0,0]) {
58 | unfBoltAllenThreaded(s4, $fn=50);
59 | showName(s4, -11);
60 | }
61 | translate([70,0,0]) {
62 | unfThreadInternal(s5, $fn=50);
63 | showName(s5, -2);
64 | }
65 | translate([90,0,0]) {
66 | unfThreadExternal(unfClone(s6,16),$fn=50);
67 | showName(s6, -4);
68 | }
69 | }
70 | if ( part==1 ) {
71 | s1 = UNF1_4(tl=20);
72 | translate([0*IX,0,0]) {
73 | unfNutHexagonalThreaded(s1, $fn=50);
74 | showName(s1, -2);
75 | }
76 | translate([1*IX,0,0]) {
77 | unfNutSquareThreaded(s1, $fn=50);
78 | showName(s1, -2);
79 | }
80 | translate([2*IX,0,0]) {
81 | unfBoltHexagonalThreaded(s1, $fn=50);
82 | showName(s1, -7);
83 | }
84 | translate([3*IX,0,0]) {
85 | unfBoltAllenThreaded(s1, $fn=50);
86 | showName(s1, -9);
87 | }
88 | }
89 | if ( part==2 ) {
90 | s1 = UNF3_8(tl=20);
91 | translate([0*IX,0,0]) {
92 | unfNutHexagonalThreaded(s1, $fn=50);
93 | showName(s1, -2);
94 | }
95 | translate([1*IX,0,0]) {
96 | unfNutSquareThreaded(s1, $fn=50);
97 | showName(s1, -2);
98 | }
99 | translate([2*IX,0,0]) {
100 | unfBoltHexagonalThreaded(s1, $fn=50);
101 | showName(s1, -9);
102 | }
103 | translate([3*IX,0,0]) {
104 | unfBoltAllenThreaded(s1, $fn=50);
105 | showName(s1, -11);
106 | }
107 | }
108 | }
109 |
110 | showParts(0);
111 |
--------------------------------------------------------------------------------
/things/box-pcb_HW-411_LM2596.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Box for HW411 pcb module (LM2596 DC-DC step down)
10 | * http://tpelectronic.ir/datasheets/20150123144301750.pdf
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 | use
19 | use
20 |
21 | // ----------------------------------------
22 | // Implementation
23 | // ----------------------------------------
24 | PRECISION = 100;
25 | SEPARATION = 0;
26 | CABLE_D = 3;
27 |
28 | SCREW = M2_5(tl=16, ahd=5) ;
29 | HW411 = newPcb (
30 | sx=44, sy=22,
31 | holes=[
32 | [-15, +7.5, SCREW ],
33 | [+15, -7.5, SCREW ]
34 | ]
35 | );
36 | ZIP_TIE_CABLE = newZipTie2_5();
37 | ZIP_TIE_BOX = makeZipU(newZipTie2_5(),7.4,4);
38 |
39 | module show_parts( part=0, cut=undef, cut_rotation=undef ) {
40 | draftbox = newBoxShell ( bsz=8 );
41 | cables = [
42 | newCable ( CABLE_D/2, CABLE_D, c=[0,0,0], v=[+1,0,0] )
43 | ,newCable ( CABLE_D/2, CABLE_D, c=[0,0,0], v=[-1,0,0] )
44 | ];
45 | box = newPcbBox (
46 | pcb = HW411,
47 | shell = draftbox,
48 | cables = cables,
49 | cablezip = ZIP_TIE_CABLE,
50 | boxzip = ZIP_TIE_BOX,
51 | margin = nozzle(),
52 | incrustation = 3
53 | );
54 |
55 | if ( part==0 ) {
56 | intersection () {
57 | union() {
58 | translate( [0,0,+SEPARATION] )
59 | pcbBoxTop( box );
60 | translate( [0,0,-SEPARATION] )
61 | pcbBoxBottom( box );
62 | %
63 | translate ( getPcbBoxPcbTranslation(box) )
64 | pcbShape ( getPcbBoxPcb(box) );
65 | }
66 | color ( "#fff",0.1 )
67 | rotate( [0,0,is_undef(cut_rotation)?0:cut_rotation] )
68 | translate( [-500,is_undef(cut)?-500:cut,-500] )
69 | cube( [1000,1000,1000] );
70 | }
71 | }
72 |
73 | if ( part==1 ) {
74 | pcbBoxBottom( box );
75 | }
76 | if ( part==2 ) {
77 | rotate( [180,0,0] ) {
78 | pcbBoxTop( box );
79 | }
80 | }
81 | if ( part==3 ) {
82 | translate( [0,30,0])
83 | pcbBoxBottom( box );
84 | translate( [0,-30,0])
85 | rotate( [180,0,0] ) {
86 | pcbBoxTop( box );
87 | }
88 | }
89 | }
90 |
91 | // 0: all cut to see inside
92 | // 1: bottom
93 | // 2: top
94 | // 3: top+bottom printables
95 | show_parts ( 3, 0, 0, $fn=PRECISION );
96 |
97 |
--------------------------------------------------------------------------------
/things/box-pcb_SM-GPN30E.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Box for SM-GPN30E pcb module (AC-DC power supply 30W / 5-36V)
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 | use
16 | use
17 | use
18 | use
19 |
20 | // ----------------------------------------
21 | // Implementation
22 | // ----------------------------------------
23 | PRECISION = 50;
24 | SEPARATION = 0;
25 | CABLE_D = 3.5;
26 |
27 | SCREW = M3(tl=20, ahd=5) ;
28 | PCB = newPcb (
29 | sx=100, sy=50, below=4, above=26,
30 | holes=[
31 | [-81/2, +20, SCREW ],
32 | [-81/2, -20, SCREW ],
33 | [+81/2, -20, SCREW ],
34 | [+81/2, +20, SCREW ]
35 | ]
36 | );
37 | ZIP_TIE_CABLE = newZipTie2_5();
38 |
39 | module vents ( sx, sy, wt=0.8, sp=1.2 ) {
40 | int = wt+sp;
41 | nb = floor((sy-wt)/int);
42 | aw = nb*int + wt;
43 | off = (sy-aw+wt)/2;
44 |
45 | for ( i=[0:nb] )
46 | translate( [0,-sy/2+off+i*int,500] ) {
47 | efsx = i==0 ? sx-2*int : i==nb ? sx-2*int : sx;
48 | cube( [efsx-wt,wt,1000], center=true );
49 | translate( [-efsx/2+wt/2,0,0] )
50 | cylinder ( r=wt/2, h=1000, center=true );
51 | translate( [+efsx/2-wt/2,0,0] )
52 | cylinder ( r=wt/2, h=1000, center=true );
53 | }
54 | }
55 |
56 | module top_with_vents ( box ) {
57 | difference() {
58 | pcbBoxTop( box );
59 |
60 | // Vent for 7N65C Mosfet heatsink
61 | translate ( [50-40,0,0] ) {
62 | translate ( [0,0,5.5] )
63 | rotate( [90,90,0] )
64 | vents( 16, 18 );
65 | translate ( [0,-25+11,0] )
66 | vents( 18, 18 );
67 | }
68 |
69 | // Vent for MBR20100F Schottky Barrier heatsink
70 | translate ( [-50+28,0,0] ) {
71 | translate ( [0,0,5.5] )
72 | rotate( [90,90,0] )
73 | vents( 16, 22 );
74 | translate ( [0,-25+12,0] )
75 | vents( 22, 20 );
76 | }
77 | }
78 | }
79 |
80 | module show_box() {
81 | // The draft controls the base parameters of the enclosing box shell
82 | // bsz forced to have the box joint at 10mm height, ie not in components
83 | // t forced because this is a relative big box, one more layer bot and top is better
84 | draftbox = newBoxShell ( bsz=10, t=1.2 );
85 | cables = [
86 | newCable ( CABLE_D/2, CABLE_D, c=[0,0,-5], v=[+1,0,0] )
87 | ,newCable ( CABLE_D/2, CABLE_D, c=[0,0,+5], v=[-1,0,0] )
88 | ];
89 | box = newPcbBox (
90 | pcb = PCB,
91 | shell = draftbox,
92 | cables = cables,
93 | cablezip = ZIP_TIE_CABLE,
94 | boxzip = undef,
95 | margin = nozzle(),
96 | incrustation = 3
97 | );
98 | translate( [0,30,0])
99 | pcbBoxBottom( box );
100 | translate( [0,-30,0])
101 | rotate( [180,0,0] ) {
102 | top_with_vents( box );
103 | }
104 | }
105 |
106 | show_box ( $fn=PRECISION );
107 |
108 |
--------------------------------------------------------------------------------
/things/confusing-pyramid.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Not so easy pyramid puzzle
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | // ----------------------------------------
14 | // API
15 | // ----------------------------------------
16 |
17 | /* [Global] */
18 |
19 | // Height of the pyramid
20 | PYRAMID_HEIGHT = 60; // [0:250]
21 |
22 | // Beveling around shapes
23 | BEVEL = 0.5; // [0:5]
24 |
25 |
26 | // ----------------------------------------
27 | // Implementation
28 | // ----------------------------------------
29 |
30 | /* [Hidden] */
31 |
32 | PYRAMID_H = PYRAMID_HEIGHT-2*BEVEL;
33 |
34 | ALPHA = 2*asin( 1/(2*sin(60)) );
35 |
36 | FACE_H = PYRAMID_H/sin(ALPHA);
37 |
38 | SIDE_L = FACE_H/sin(60);
39 | SIDE_l = SIDE_L/2;
40 |
41 | FACE_HS = SIDE_l*tan(30);
42 | FACE_HL = FACE_H-FACE_HS;
43 |
44 | PYRAMID_HS = FACE_HS*tan(ALPHA/2);
45 | PYRAMID_HL = PYRAMID_H-PYRAMID_HS;
46 |
47 | module cutter() {
48 | cut_w = PYRAMID_H*10;
49 | rotate( [-(180-ALPHA)/2,0,0] )
50 | translate( [0,0,cut_w/2] )
51 | cube( [cut_w,cut_w,cut_w], center=true );
52 | }
53 |
54 | module pyramid() {
55 | // [0,0,0] is the center of the pyramid
56 | translate( [0,0,-PYRAMID_HS] )
57 | linear_extrude ( height=PYRAMID_H, scale=0 )
58 | polygon( [
59 | [ 0, FACE_HL],
60 | [+SIDE_l, -FACE_HS],
61 | [-SIDE_l, -FACE_HS]
62 | ]);
63 | }
64 |
65 | module pyramidPart() {
66 | translate( [0,-PYRAMID_HS-BEVEL,PYRAMID_HS+BEVEL] )
67 | minkowski() {
68 | difference() {
69 | pyramid();
70 | // Beveling with minkowski adds a thickness we must remove
71 | translate( [0,-BEVEL*cos(45),-BEVEL*cos(45)] )
72 | cutter();
73 | }
74 | sphere(BEVEL);
75 | }
76 | }
77 |
78 | // ----------------------------------------
79 | // Final rendering
80 | // ----------------------------------------
81 | pyramidPart( $fn=100 );
82 | translate( [0,PYRAMID_HL+2*BEVEL,0] )
83 | pyramidPart( $fn=100 );
84 |
--------------------------------------------------------------------------------
/things/minecraft/creeper-lamp/cable_path_svg.scad:
--------------------------------------------------------------------------------
1 | // Generated by inkscape 1.0.2 (394de47547, 2021-03-26) + inkscape-paths2openscad 0.27
2 | // Sat May 15 21:48:06 2021 from "cable_path_svg.svg"
3 |
4 | // Module names are of the form poly_(). As a result,
5 | // you can associate a polygon in this OpenSCAD program with the corresponding
6 | // SVG element in the Inkscape document by looking for the XML element with
7 | // the attribute id="inkscape-path-id".
8 |
9 | // fudge value is used to ensure that subtracted solids are a tad taller
10 | // in the z dimension than the polygon being subtracted from. This helps
11 | // keep the resulting .stl file manifold.
12 | fudge = 0.1;
13 | user_unit_scale_x = 1.0;
14 | user_unit_scale_y = 1.0;
15 | custom_scale_x = 1;
16 | custom_scale_y = 1;
17 | zsize = 5;
18 | line_fn = 8;
19 | min_line_width = 0.20000000298023224;
20 | line_width_scale = 1.0;
21 | function min_line_mm(w) = max(min_line_width, w * line_width_scale) * 1;
22 |
23 |
24 | rect5579_0_center = [0.000000,0.000000];
25 | rect5579_0_points = [[-145.000000,-150.000000],[145.000000,-150.000000],[145.000000,150.000000],[-145.000000,150.000000],[-145.000000,-150.000000]];
26 | module poly_rect5579(h, w, s, res=line_fn)
27 | {
28 | scale([custom_scale_x, -custom_scale_y, 1]) union()
29 | {
30 | translate (rect5579_0_center) linear_extrude(height=h, convexity=10, scale=0.01*s)
31 | translate (-rect5579_0_center) polygon(rect5579_0_points);
32 | }
33 | }
34 |
35 | cablePathFront_0_center = [-59.500527,68.995320];
36 | cablePathFront_0_points = [[-56.305871,123.193530],[-56.392101,110.096780],[-56.388525,108.084985],[-56.434420,105.922474],[-56.614721,103.642701],[-57.014362,101.279115],[-57.322976,100.076346],[-57.718276,98.865169],[-58.210878,97.649764],[-58.811398,96.434313],[-59.530455,95.222998],[-60.378663,94.020000],[-61.366641,92.829500],[-62.505005,91.655680],[-64.395804,89.741023],[-66.296353,87.599563],[-68.155037,85.273097],[-69.920242,82.803419],[-71.540355,80.232323],[-72.963762,77.601605],[-74.138849,74.953059],[-74.617143,73.635161],[-75.014002,72.328480],[-75.658086,69.492806],[-76.144376,66.366558],[-76.495038,62.978396],[-76.732237,59.356979],[-76.878141,55.530967],[-76.954914,51.529020],[-76.989733,43.111960],[-77.001053,27.909810],[-76.964570,26.459907],[-76.854381,25.076883],[-76.669377,23.764418],[-76.408451,22.526189],[-76.070493,21.365877],[-75.654395,20.287160],[-75.159047,19.293717],[-74.583342,18.389228],[-73.926171,17.577370],[-73.186425,16.861824],[-72.362996,16.246269],[-71.454774,15.734382],[-70.460652,15.329844],[-69.379520,15.036333],[-68.210270,14.857529],[-66.951793,14.797110],[-42.000000,14.823710]];
37 | module poly_cablePathFront(h, w, s, res=line_fn)
38 | {
39 | scale([custom_scale_x, -custom_scale_y, 1]) union()
40 | {
41 | for (t = [0: len(cablePathFront_0_points)-2]) {
42 | hull() {
43 | translate(cablePathFront_0_points[t])
44 | cylinder(h=h, r=w/2, $fn=res);
45 | translate(cablePathFront_0_points[t + 1])
46 | cylinder(h=h, r=w/2, $fn=res);
47 | }
48 | }
49 | }
50 | }
51 |
52 | cableProfile_0_center = [-56.000001,131.500000];
53 | cableProfile_0_points = [[-58.000001,134.000000],[-58.000001,129.000000],[-57.959509,128.595945],[-57.843313,128.220063],[-57.415501,127.584500],[-56.779939,127.156687],[-56.404056,127.040492],[-56.000001,127.000000],[-55.595946,127.040492],[-55.220063,127.156687],[-54.584501,127.584500],[-54.156689,128.220063],[-54.040493,128.595945],[-54.000001,129.000000],[-54.000001,134.000000],[-54.040493,134.404055],[-54.156689,134.779937],[-54.584501,135.415500],[-55.220063,135.843313],[-55.595946,135.959508],[-56.000001,136.000000],[-56.404056,135.959508],[-56.779939,135.843313],[-57.415501,135.415500],[-57.843313,134.779937],[-57.959509,134.404055],[-58.000001,134.000000],[-58.000001,134.000000]];
54 | module poly_cableProfile(h, w, s, res=line_fn)
55 | {
56 | scale([custom_scale_x, -custom_scale_y, 1]) union()
57 | {
58 | translate (cableProfile_0_center) linear_extrude(height=h, convexity=10, scale=0.01*s)
59 | translate (-cableProfile_0_center) polygon(cableProfile_0_points);
60 | }
61 | }
62 |
63 | cablePathSide_0_center = [63.750010,31.000000];
64 | cablePathSide_0_points = [[60.000000,140.000000],[60.138360,86.921770],[60.199281,83.467833],[60.372676,80.545805],[60.644490,78.075894],[61.000671,75.978306],[61.427165,74.173249],[61.909919,72.580930],[62.987990,69.715330],[64.323138,66.636213],[65.069395,64.844765],[65.797955,62.839241],[66.456202,60.585027],[66.991522,58.047509],[67.351299,55.192075],[67.482920,51.984110],[67.500020,-78.000001]];
65 | module poly_cablePathSide(h, w, s, res=line_fn)
66 | {
67 | scale([custom_scale_x, -custom_scale_y, 1]) union()
68 | {
69 | for (t = [0: len(cablePathSide_0_points)-2]) {
70 | hull() {
71 | translate(cablePathSide_0_points[t])
72 | cylinder(h=h, r=w/2, $fn=res);
73 | translate(cablePathSide_0_points[t + 1])
74 | cylinder(h=h, r=w/2, $fn=res);
75 | }
76 | }
77 | }
78 | }
79 |
80 | module cable_path_svg(h)
81 | {
82 | difference()
83 | {
84 | union()
85 | {
86 | translate ([0,0,0]) poly_rect5579(h, min_line_mm(0.1), 100.0);
87 | translate ([0,0,0]) poly_cablePathFront(h, min_line_mm(4.0), 100.0);
88 | translate ([0,0,0]) poly_cableProfile(h, min_line_mm(4.0), 100.0);
89 | translate ([0,0,0]) poly_cablePathSide(h, min_line_mm(9.0), 100.0);
90 | }
91 | union()
92 | {
93 | }
94 | }
95 | }
96 |
97 | //cable_path_svg(zsize);
98 |
--------------------------------------------------------------------------------
/things/minecraft/creeper-lamp/creeper-cable.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Creeper Lamp - cable passage
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | include
17 | include
18 |
19 |
20 | /**
21 | * Cable passage
22 | */
23 | module cablePassage() {
24 | rotate( [0,0,90] )
25 | sweep(normalizedCableProfile, path_transforms);
26 | }
27 |
28 | /**
29 | * Cable cut to show the inside
30 | */
31 | module cableCut() {
32 | rotate( [0,0,90] )
33 | sweep(cutProfile, path_transforms);
34 | }
35 |
36 | cutProfile = [
37 | [0, 0],
38 | [0, -HEAD_W],
39 | [-HEAD_W, -HEAD_W],
40 | [-HEAD_W, 0],
41 | ];
42 |
43 | normalizedCablePathSide = [
44 | for(pt = cablePathSide_0_points)
45 | [pt.x - 67.5, 0, 142 - pt.y]
46 | ];
47 | normalizedCablePathFront = [
48 | for(pt = cablePathFront_0_points)
49 | [77 + pt.x, 0, 142 - pt.y]
50 | ];
51 | normalizedCableProfile = [
52 | for(pt = cableProfile_0_points)
53 | [ pt.x - cableProfile_0_center.x, cableProfile_0_center.y - pt.y]
54 | ];
55 |
56 | /**
57 | * assume line is such that:
58 | * len(list) >= 2
59 | * list[i].z <= list[i+1].z
60 | */
61 | function indexForZ ( line, z, _i=-1 ) =
62 | _i>=len(line)-1 ? _i :
63 | line[_i+1].z >= z ? _i :
64 | indexForZ( line, z, _i+1 )
65 | ;
66 |
67 | function interpolatey(pt0, pt1, z) =
68 | let(
69 | n = (pt1.z-pt0.z)/(z-pt0.z)
70 | ) (pt1.x-pt0.x)/n + pt0.x
71 | ;
72 |
73 | function interpolatexFromPathSide(z) =
74 | let(
75 | i = indexForZ(normalizedCablePathSide, z)
76 | ) interpolatey( normalizedCablePathSide[i], normalizedCablePathSide[i+1], z )
77 | ;
78 |
79 | function cablePath() = [
80 | for(pt = normalizedCablePathFront)
81 | [pt.x,interpolatexFromPathSide(pt.z),pt.z]
82 | ];
83 |
84 | path_transforms = construct_transform_path ( cablePath() );
85 |
--------------------------------------------------------------------------------
/things/minecraft/creeper-lamp/creeper-const.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Creeper Lamp - constants
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | SHADER_T = 1.2;
15 |
16 | CGREEN1 = "#005500";
17 | CGREEN2 = "#00d400";
18 | CGREEN3 = "#66ff00";
19 | CBROWN1 = "#784212";
20 | CBROWN2 = "#b7950b";
21 | CBROWN3 = "#fad7a0";
22 | CGREY = "#b3b3b3";
23 | CBLACK = "#202020";
24 |
25 | HEAD_W = 120;
26 | HEAD_L = HEAD_W;
27 | HEAD_H = HEAD_W;
28 |
29 | WALL_THIN = 2;
30 | WALL_THICK = 4;
31 |
32 | LED_RING_D = 50;
33 |
34 | PLUG_D = 10.5;
35 |
36 | SPRING_DEXT = 20;
37 | SPRING_DINT = SPRING_DEXT-2*1.2;
38 | SPRING_PD = LED_RING_D-2*WALL_THICK;
39 | SPRING_L = 50;
40 | SPRING_GAP = 10;
41 | SPRING_GRIP_H = (SPRING_L-SPRING_GAP)/2;
42 |
43 | BODY_H = 56;
44 | BODY_L = 64;
45 | BODY_W = 32;
46 | BODY_BDH = 16;
47 | BODY_HDH = 10;
48 |
49 | FOOT_H = 24;
50 | FOOT_L = 32;
51 | FOOT_W = 24;
52 |
53 | GROUND_H = 32;
54 | GROUND_L = 136;
55 | GROUND_W = 136;
56 |
57 | FOOT_BH = GROUND_H;
58 | BODY_BH = FOOT_BH+BODY_BDH;
59 | HEAD_BH = BODY_BH+BODY_H-BODY_HDH;
60 |
61 | LED_RING_H = HEAD_W/2;
62 |
63 | BEVEL = 0.6;
64 |
65 | // Head face selector
66 | FACE_ALL = 0;
67 | FACE_FRONT = 1;
68 | FACE_RIGHT = 2;
69 | FACE_BACK = 3;
70 | FACE_LEFT = 4;
71 | FACE_TOP = 5;
72 |
--------------------------------------------------------------------------------
/things/minecraft/creeper-lamp/creeper-lib.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Creeper Lamp - tools
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 |
19 | module bevelCube( length, width=undef, height=undef, nobot=false ) {
20 | w = is_undef(width) ? length : width;
21 | th = is_undef(height) ? length : height;
22 | h = nobot ? th*2 : th;
23 | dh = nobot ? -th/2 : 0;
24 | translate( [length/2,-w/2,dh] )
25 | bevelCutLinear(w, h, -1);
26 | translate( [-length/2,+w/2,dh] )
27 | rotate( [0,0,180] )
28 | bevelCutLinear(w, h, -1);
29 | translate( [+length/2,w/2,dh] )
30 | rotate( [0,0,90] )
31 | bevelCutLinear(length, h, -1);
32 | translate( [-length/2,-w/2,dh] )
33 | rotate( [0,0,-90] )
34 | bevelCutLinear(length, h, -1);
35 | translate( [0,0,0] )
36 | rotate( [90,0,0] )
37 | translate( [length/2,-h/2,0] )
38 | bevelCutLinear(h, w, -1);
39 | translate( [0,0,0] )
40 | rotate( [90,0,180] )
41 | translate( [length/2,-h/2,0] )
42 | bevelCutLinear(h, w, -1);
43 | }
44 |
45 | //
46 | // Extrudes polygons following vectors from points to vaninsing lines
47 | //
48 | // polygons in a plane paralel to [x,y] plane:
49 | // - polys: list of polygons of 2D (x,y) points
50 | // - polysz: z distance of polygons plane
51 | //
52 | // polygons will be extruded along vectors to vanishing lines
53 | // - width: width of the required slice between polygons plane and image plane
54 | //
55 | // vanishing lines imply scaling of polygons on image plane:
56 | // - vanishLineX: [-,y,z] position of the vanishing line parallel to x axis
57 | // - vanishLineY: [x,-,z] position of the vanishing line parallel to y axis
58 | //
59 | // for a vanishing point:
60 | // - vanishLineX: [x,y,z] position of the vanishing point
61 | // - vanishLineY: undef
62 | //
63 | module extrudePolygons ( polys, polysz, width, vanishLineX, vanishLineY=undef ) {
64 | vx = [ 0, vanishLineX.y, vanishLineX.z ];
65 | vy = is_undef(vanishLineY) ? [ vanishLineX.x, 0, vanishLineX.z ] : [ vanishLineY.x, 0, vanishLineY.z ];
66 |
67 | // p: polygon plane
68 | // lyp: distance from vy to polygon plane
69 | // lxp: distance from vx to polygon plane
70 | // dxp: x distance from vy to polygon point
71 | // dyp: y distance from vx to polygon point
72 | lyp = polysz - vy.z;
73 | lxp = polysz - vx.z;
74 |
75 | // i: image plane closer to [0,0,0] by slice width
76 | // lyi: distance from vy to image plane
77 | // lxi: distance from vx to image plane
78 | // dxi: x distance from vy to image point
79 | // dyi: y distance from vx to image point
80 | lyi = lyp - width;
81 | lxi = lxp - width;
82 |
83 | // rx: dxi/dxp
84 | // ry: dyi/dyp
85 | rx = lyi/lyp;
86 | ry = lxi/lxp;
87 |
88 | for ( p=polys )
89 | let(
90 | p1 = transform(translation([0,0,polysz]),p),
91 | p2 = transform(
92 | translation([0,0,-width])
93 | *
94 | translation(+vx) * scaling([1,ry,1]) * translation(-vx)
95 | *
96 | translation(+vy) * scaling([rx,1,1]) * translation(-vy)
97 | ,p1)
98 | )
99 | skin( [ p2, p1 ] );
100 | }
101 |
102 |
--------------------------------------------------------------------------------
/things/office-tree-branch-beds.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Render beds for printing branches
10 | * Author: Gilles Bouissac
11 | */
12 |
13 | use
14 | use
15 | use
16 |
17 | // ----------------------------------------
18 | // API
19 | // ----------------------------------------
20 |
21 | // part: bed number [0-9]
22 | // $layer: will be printed with 0.3mm layers
23 | showCase ( part=3, $fn=PRECISION, $layer=0.3 );
24 |
25 |
26 | // ----------------------------------------
27 | // Showcase
28 | // ----------------------------------------
29 | PRECISION = 100;
30 |
31 | BEDS = [
32 | [ // BED 0
33 | [ 00, [ -65, -20], 0 ],
34 | [ 44, [ 102, -42], -60 ],
35 | [ 43, [ 60, -42], -60 ],
36 | [ 42, [ 10, -42], -60 ],
37 | [ 41, [ 30, -92], 165 ],
38 | [ 40, [ 74, 27], 60 ],
39 | [ 39, [ -33, -88], 90 ],
40 | [ 38, [ -68, -51], -90 ],
41 | [ 37, [-100, -76], 90 ],
42 | [ 36, [ 98, 80], 182 ],
43 | [ 35, [ 18, 8], 75 ],
44 | [ 34, [ 15, 80], 184 ],
45 | [ 33, [ -10, 30],-170 ],
46 | [ 32, [-100, 20], 70 ],
47 | ],
48 | [ // BED 1
49 | [ 01, [ -60, -01], 0 ],
50 | [ 31, [ 19, -25], -80 ],
51 | [ 30, [ -35, -23], -80 ],
52 | [ 29, [ -95, -15], -80 ],
53 | [ 28, [ 52, 80],-170 ],
54 | [ 27, [-110, 90], -52 ],
55 | ],
56 | [ // BED 2
57 | [ 02, [ -50, -85], 30 ],
58 | [ 03, [ 50, 85],-150 ],
59 | ],
60 | [ // BED 3
61 | [ 04, [ -50, -85], 30 ],
62 | [ 05, [ 50, 85],-150 ],
63 | ],
64 | [ // BED 4
65 | [ 06, [ -40, -85], 30 ],
66 | [ 07, [ 45, 75],-150 ],
67 | ],
68 | [ // BED 5
69 | [ 08, [ -30, -90], 30 ],
70 | [ 09, [ 25, 50],-150 ],
71 | [ 26, [ 25, 85], -25 ],
72 | ],
73 | [ // BED 6
74 | [ 10, [ -22, -90], 30 ],
75 | [ 11, [ 20, 20],-150 ],
76 | [ 25, [ 22, 85], -20 ],
77 | [ 24, [ 7, 60],-177 ],
78 | ],
79 | [ // BED 7
80 | [ 12, [ -22, -85], 26 ],
81 | [ 13, [ 18, 18],-150 ],
82 | [ 23, [ 15, 70], -10 ],
83 | [ 22, [ -10, 90],-145 ],
84 | ],
85 | [ // BED 8
86 | [ 14, [ -18, -90], 26 ],
87 | [ 15, [ 10, -23],-174 ],
88 | [ 21, [ 12, 68], -10 ],
89 | [ 20, [ 27, 00], 145 ],
90 | ],
91 | [ // BED 9
92 | [ 16, [ -10, -90], 26 ],
93 | [ 17, [ 3, -30],-174 ],
94 | [ 19, [ 3, 75], -17 ],
95 | [ 18, [ 30, -8], 145 ],
96 | ],
97 | ];
98 |
99 | BRANCH_NB = getBranchNb();
100 |
101 | module showCase ( part ) {
102 | // Checks that:
103 | // we missed no branch
104 | // we didn't ask to print a branch twice
105 | // we didn't ask to print an unexisting branch
106 | branches = [ for ( i=[0:BRANCH_NB-1] ) i ];
107 | declared = sortNum([
108 | for ( bed=BEDS )
109 | for ( b=bed )
110 | b[0]
111 | ]);
112 | missing = [
113 | for ( b=branches )
114 | let(
115 | found = search ( b, declared )
116 | ) if ( len(found)==0) b
117 | ];
118 | if ( len(missing)>0 ) {
119 | error = str("WARNING - branches not declared in any bed: ", missing);
120 | translate( [-printVolume().x/2,printVolume().y/2+5,0] ) text( error );
121 | }
122 | unknown = [
123 | for ( d=declared )
124 | let(
125 | found = search ( d, branches )
126 | ) if ( len(found)==0) d
127 | ];
128 | if ( len(unknown)>0 ) {
129 | error = str("WARNING - unknown branches declared: ", unknown);
130 | translate( [-printVolume().x/2,printVolume().y/2+25,0] ) text( error );
131 | }
132 | duplicates = [
133 | for ( b=branches )
134 | let(
135 | found = search ( b, declared, 0 )
136 | ) if ( len(found)>1) b
137 | ];
138 | if ( len(duplicates)>0 ) {
139 | error = str("WARNING - duplicates branches declared: ", duplicates);
140 | translate( [-printVolume().x/2,printVolume().y/2+45,0] ) text( error );
141 | }
142 |
143 | // Print beds for branches, sub_parts are bed numbers
144 | % translate([0,0,-1])
145 | cube( [ printVolume().x, printVolume().y, 1 ], center=true );
146 |
147 | // Print required bed
148 | for ( b=BEDS[part] )
149 | translate( b[1] ) {
150 | %translate( [0,0,40] )
151 | color( "yellow" )
152 | text( str(b[0]), halign="center" );
153 | rotate( [0,0,is_undef(b[2])?0:b[2]] )
154 | branch( b[0] );
155 | }
156 | }
157 |
--------------------------------------------------------------------------------
/things/pixeled/cap.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Pickaxe - cell caps for minecraft tool
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 | use
19 | use
20 |
21 | function getMinWidth() = (nozzle()+0.1);
22 | function getCapW() = getPixelW()-2*getMinWidth()-2*getRadiusBevel();
23 | function getCapInsert() = 2*layer();
24 | function getCapT() = 1;
25 |
26 | function getSnapR() = getCapW()/(2*sin(45));
27 | function getSnapH() = getPixelH()/2 - getCapInsert();
28 | function getSnapA() = 50;
29 |
30 | function getJointQuadI() = newSnapPolygonInt ( height=getSnapH(), radius=getSnapR(), spring_w=getPixelW()/5, cutdistance=getPixelW()/3, spring_a=getSnapA(), leaves=4, springs=true );
31 | function getJointQuadE() = newSnapPolygonExt ( source=getJointQuadI() );
32 | function getJointElevation() = getSnapJointVGap(getJointQuadE())+mfg();
33 |
34 | function drad() = getSnapJointSpringW(getJointQuadE())-getSnapJointHGap(getJointQuadI());
35 | function getCapGripWidth() = getCapW() - 2*drad();
36 |
37 | module cap() {
38 | elevation = getJointElevation();
39 | jointI = getJointQuadI();
40 | gap = 2*gap();
41 | translate( [0,0,elevation] ) {
42 | intersection() {
43 | snapJoint( jointI );
44 | translate( [0,0,-500+getSnapH()] )
45 | cube ( [getCapW()-gap,getCapW()-gap,1000], center=true );
46 | }
47 | }
48 | intersection() {
49 | translate( [0,0,elevation] )
50 | snapJointShape ( jointI );
51 | translate( [0,0,getPixelH()/2-getCapT()/2+elevation/2] )
52 | cube ( [ getCapW()-gap, getCapW()-gap, getCapT()-elevation], center=true );
53 | }
54 | }
55 |
56 | module capPassage() {
57 | elevation = getJointElevation();
58 | jointE = getJointQuadE();
59 | translate( [0,0,+elevation] )
60 | snapJointHollow( jointE );
61 | translate( [0,0,getPixelH()/2-getCapInsert()/2] )
62 | cube ( [ getCapW(), getCapW(), getCapInsert()+mfg()], center=true );
63 | }
64 |
65 | module partCaps( part_layout, colors=[[],[]] ) {
66 | hy = floor(len(part_layout)/2);
67 | hx = floor(len(part_layout[0])/2);
68 | for ( i = [0:len(part_layout)-1] ) {
69 | for ( j = [0:len(part_layout[i])-1] ) {
70 | let ( val = part_layout[i][j] )
71 | if ( val>=0 ) {
72 | translate( [ (j-hx)*getPixelW(), (hy-i)*getPixelW(), 0 ] )
73 | color( getCapColor(colors, val) )
74 | if ( isCellBicolor(val) ) {
75 | cap();
76 | rotate( [180,0,0] )
77 | cap();
78 | }
79 | }
80 | }
81 | }
82 | }
83 |
--------------------------------------------------------------------------------
/things/pixeled/const.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2_21, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Pickaxe - constants for minecraft tool
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 |
15 | function getPixelW() = is_undef($pixel_w) ? 25 : $pixel_w;
16 | function getPixelH() = is_undef($pixel_h) ? 20 : $pixel_h;
17 | function getNailH() = getPixelW()/2;
18 |
19 | // Used to render all parts or subparts
20 | function ALL() = -1;
21 |
22 | // Empty value in any layout
23 | function VAL_EMPTY() = -1;
24 |
25 | // Offset in layouts to specify one color cell (ie no cap)
26 | VAL_UNICOLOR_CELL_FIRST = 000;
27 | VAL_UNICOLOR_CELL_LAST = 099;
28 | function VAL_UNICOLOR_CELL(v) = VAL_UNICOLOR_CELL_FIRST+v;
29 | function isCellUnicolor(v) = VAL_UNICOLOR_CELL_FIRST<=v && v<=VAL_UNICOLOR_CELL_LAST;
30 |
31 | // Offset in layouts to specify bi color cell (ie with colored cap)
32 | VAL_BICOLOR_CELL_FIRST = 100;
33 | VAL_BICOLOR_CELL_LAST = 199;
34 | function VAL_BICOLOR_CELL(v) = VAL_BICOLOR_CELL_FIRST+v;
35 | function isCellBicolor(v) = VAL_BICOLOR_CELL_FIRST<=v && v<=VAL_BICOLOR_CELL_LAST;
36 |
37 | // Value in nails layout to tell there is a nail
38 | function VAL_NAIL_TOP() = 8;
39 | function VAL_NAIL_LFT() = 4;
40 | function VAL_NAIL_BOT() = 2;
41 | function VAL_NAIL_RGT() = 1;
42 |
43 | // Values ordered from higher to lower
44 | function NAIL_VALS() = [
45 | VAL_NAIL_TOP(),
46 | VAL_NAIL_LFT(),
47 | VAL_NAIL_BOT(),
48 | VAL_NAIL_RGT()
49 | ];
50 |
51 | // Index in color mapping arrays
52 | function IDX_COLOR_CELL() = 0;
53 | function IDX_COLOR_CAP() = 1;
54 |
55 | function getLayoutColor( mapping, v, _i=0 ) =
56 | mapping[_i][0]==v ? mapping[_i][1] :
57 | _i
15 | use
16 | use
17 | use
18 | use
19 |
20 | function getNailGap() = 0.15;
21 | function getNailW() = getPixelH()/8-2*getNailGap();
22 | function getNailProfile() = meshRegularPolygon(8, getNailW()/(2*cos(45/2)));
23 | function getNailPassageProfile() = newMesh(wrinkle(getMeshVertices(getNailProfile()), -getNailGap(), true), getMeshFaces(getNailProfile()));
24 |
25 | // Horizontal and Vertical nail never cross each other
26 | function getNailMarginH() = 0.1;
27 | function getNailMaxH() = getPixelH()/4-getNailMarginH();
28 | function getNailVH() = [+(getNailMaxH()-getNailW()-2*layer()), -getNailMaxH()];
29 | function getNailHH() = [-(getNailMaxH()-getNailW()-2*layer()), +getNailMaxH()];
30 |
31 | // Index in nails layouts arrays
32 | IDX_TOP_NAILS = 0;
33 | IDX_LFT_NAILS = 1;
34 | IDX_BOT_NAILS = 2;
35 | IDX_RGT_NAILS = 3;
36 |
37 | module nail( l=getNailH() ) {
38 | rotate( [-90,0,0] )
39 | rotate( [0,0,45/2] )
40 | extrude( getMeshVertices(getNailProfile()), l );
41 | }
42 | module nailPassage( l=getNailH() ) {
43 | rotate( [-90,0,0] )
44 | rotate( [0,0,45/2] )
45 | extrude( getMeshVertices(getNailPassageProfile()), l+2*gap() );
46 | }
47 | module locateNailInLayer() {
48 | x = getPixelW()/2 - getNailW()/2 - 2*(nozzle()+0.1);
49 | translate ( [+x, 0, 0 ] )
50 | children();
51 | translate ( [-x, 0, 0 ] )
52 | children();
53 | }
54 | module nailPassagesLayer( l=getNailH() ) {
55 | locateNailInLayer()
56 | nailPassage(l);
57 | }
58 | module nailsLayer( l=getNailH() ) {
59 | locateNailInLayer()
60 | nail(l);
61 | }
62 |
63 | function decomposeValues ( val, values, _i=0 ) = let (
64 | i = floor ( val / values[_i] ),
65 | r = val % values[_i],
66 | cr = concat ( [ i>0 ], _i<(len(values)-1) ? decomposeValues(r, values, _i+1) : [])
67 | ) cr;
68 |
69 | module locateNailInCell( val ) {
70 | values = decomposeValues ( val, NAIL_VALS() );
71 | if ( values[IDX_TOP_NAILS] ) {
72 | translate ( [0, 0, getNailVH()[0] ] )
73 | children();
74 | translate ( [0, 0, getNailVH()[1] ] )
75 | children();
76 | }
77 | if ( values[IDX_LFT_NAILS] ) {
78 | translate ( [0, 0, getNailHH()[0] ] )
79 | rotate ( [0, 0, +90] ) children();
80 | translate ( [0, 0, getNailHH()[1] ] )
81 | rotate ( [0, 0, +90] ) children();
82 | }
83 | if ( values[IDX_BOT_NAILS] ) {
84 | translate ( [0, 0, getNailVH()[0] ] )
85 | rotate ( [0, 0, 180] ) children();
86 | translate ( [0, 0, getNailVH()[1] ] )
87 | rotate ( [0, 0, 180] ) children();
88 | }
89 | if ( values[IDX_RGT_NAILS] ) {
90 | translate ( [0, 0, getNailHH()[0] ] )
91 | rotate ( [0, 0, -90] ) children();
92 | translate ( [0, 0, getNailHH()[1] ] )
93 | rotate ( [0, 0, -90] ) children();
94 | }
95 | }
96 |
97 | module partNails( part_layout, nails_layout, colors=[[],[]] ) {
98 | hy = floor(len(part_layout)/2);
99 | hx = floor(len(part_layout[0])/2);
100 | for ( i = [0:len(part_layout)-1] ) {
101 | for ( j = [0:len(part_layout[i])-1] ) {
102 | let ( val = part_layout[i][j] )
103 | if ( val>=0 ) {
104 | translate( [ (j-hx)*getPixelW(), (hy-i)*getPixelW(), 0 ] ) {
105 | color( getPixelColor(colors, val) )
106 | locateNailInCell(nails_layout[i][j])
107 | nailsLayer();
108 | }
109 | }
110 | }
111 | }
112 | }
113 |
114 | module partNailPassages( part_layout, nails_layout ) {
115 | hy = floor(len(part_layout)/2);
116 | hx = floor(len(part_layout[0])/2);
117 | for ( i = [0:len(part_layout)-1] ) {
118 | for ( j = [0:len(part_layout[i])-1] ) {
119 | let ( val = part_layout[i][j] )
120 | if ( val>=0 ) {
121 | translate( [ (j-hx)*getPixelW(), (hy-i)*getPixelW(), 0 ] ) {
122 | locateNailInCell(nails_layout[i][j])
123 | nailPassagesLayer();
124 | }
125 | }
126 | }
127 | }
128 | }
129 |
--------------------------------------------------------------------------------
/things/pixeled/pixel.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2021, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: Minecraft Pickaxe - cells for minecraft tool
10 | * Design: Gilles Bouissac
11 | * Author: Gilles Bouissac
12 | */
13 |
14 | use
15 | use
16 | use
17 | use
18 |
19 | use
20 | use
21 | use
22 |
23 | module unicolorCell() {
24 | cube ( [ getPixelW(), getPixelW(), getPixelH() ], center=true );
25 | }
26 |
27 | module bicolorCell() {
28 | difference() {
29 | cube ( [ getPixelW(), getPixelW(), getPixelH() ], center=true );
30 |
31 | rotate ( [0,0,0] )
32 | capPassage();
33 | rotate ( [180,0,0] )
34 | capPassage();
35 |
36 | cube ( [ getCapGripWidth(), getCapGripWidth(), getPixelW()], center=true );
37 | }
38 | }
39 |
40 | module partCells( part_layout, nails_layout, colors=[[],[]] ) {
41 | hy = floor(len(part_layout)/2);
42 | hx = floor(len(part_layout[0])/2);
43 | for ( i = [0:len(part_layout)-1] ) {
44 | for ( j = [0:len(part_layout[i])-1] ) {
45 | let ( val = part_layout[i][j] )
46 | if ( val>=0 ) {
47 | translate( [ (j-hx)*getPixelW(), (hy-i)*getPixelW(), 0 ] ) {
48 | difference() {
49 | color( getPixelColor(colors, val) )
50 | if ( isCellUnicolor(val) )
51 | unicolorCell();
52 | else
53 | bicolorCell();
54 | locateNailInCell(nails_layout[i][j])
55 | nailPassagesLayer();
56 | }
57 | }
58 | }
59 | }
60 | }
61 | }
62 |
63 | module bevelEdge() {
64 | BEVEL_PROFILE = [
65 | [ +getPixelW()/2, 0 ],
66 | [ +getPixelW()/2, +getRadiusBevel() ],
67 | [ -getPixelW()/2, +getRadiusBevel() ],
68 | [ -getPixelW()/2, 0 ]
69 | ];
70 |
71 | rotate( [-90,0,0] )
72 | extrude(BEVEL_PROFILE, getRadiusBevel(), true, [undef, 0, getRadiusBevel()], [0, undef, -getPixelW()/2]);
73 | }
74 |
75 | module bevelCellSide() {
76 | translate( [0,-getPixelW()/2,+getPixelH()/2] )
77 | bevelEdge();
78 | translate( [0,-getPixelW()/2,-getPixelH()/2] )
79 | rotate( [0,180,0] )
80 | bevelEdge();
81 | }
82 |
83 | module bevelCell(data, i, j) {
84 |
85 | // top cell bevel
86 | if ( i==0 || data[i-1][j]==VAL_EMPTY() ) {
87 | rotate( [0,0,180] )
88 | bevelCellSide();
89 | }
90 |
91 | // bottom cell bevel
92 | if ( i==len(data)-1 || data[i+1][j]==VAL_EMPTY() ) {
93 | bevelCellSide();
94 | }
95 |
96 | // right cell bevel
97 | if ( j==len(data[i])-1 || data[i][j+1]==VAL_EMPTY() ) {
98 | rotate( [0,0,+90] )
99 | bevelCellSide();
100 | }
101 |
102 | // left cell bevel
103 | if ( j==0 || data[i][j-1]==VAL_EMPTY() ) {
104 | rotate( [0,0,-90] )
105 | bevelCellSide();
106 | }
107 | }
108 |
109 | module partBevel( part_layout, i, j) {
110 | if ( bevelActive() ) {
111 | hy = floor(len(part_layout)/2);
112 | hx = floor(len(part_layout[0])/2);
113 | for ( i = [0:len(part_layout)-1] )
114 | for ( j = [0:len(part_layout[i])-1] )
115 | if (part_layout[i][j]!=VAL_EMPTY())
116 | translate( [ (j-hx)*getPixelW(), (hy-i)*getPixelW(), 0 ] )
117 | bevelCell(part_layout, i, j);
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/unc-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNC thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module uncThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module uncThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module uncNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module uncNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module uncBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module uncBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------
/unf-thread.scad:
--------------------------------------------------------------------------------
1 | /*
2 | * Copyright (c) 2019, Gilles Bouissac
3 | * All rights reserved.
4 | *
5 | * Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met:
6 | * * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer.
7 | * * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution.
8 | *
9 | * Description: UNF thread modelisation
10 | * Author: Gilles Bouissac
11 | */
12 | use
13 | use
14 |
15 | // ----------------------------------------
16 | //
17 | // API
18 | //
19 | // ----------------------------------------
20 |
21 | // Renders an external thread (for bolts)
22 | module unfThreadExternal ( screw, l=undef, f=true ) { libThreadExternal(screw,l,f); }
23 |
24 | // Renders an internal thread (for nuts)
25 | module unfThreadInternal ( screw, l=undef, f=true, t=undef ) { libThreadInternal(screw,l,f,t); }
26 |
27 | // Nut with Hexagonal head
28 | module unfNutHexagonalThreaded( screw, bt=true, bb=true ) { libNutHexagonalThreaded(screw,bt,bb); }
29 |
30 | // Nut with Square head
31 | module unfNutSquareThreaded( screw, bt=true, bb=true ) { libNutSquareThreaded(screw,bt,bb); }
32 |
33 | // Bolt with Hexagonal head
34 | module unfBoltHexagonalThreaded( screw, bt=true, bb=true ) { libBoltHexagonalThreaded(screw,bt,bb); }
35 |
36 | // Bolt with Allen head
37 | module unfBoltAllenThreaded( screw, bt=true ) { libBoltAllenThreaded(screw,bt); }
38 |
--------------------------------------------------------------------------------