From 552e3445434c9083ec74330125cb0c33bea49b75 Mon Sep 17 00:00:00 2001 From: Ian Gulliver Date: Sat, 24 Dec 2016 23:08:34 -0700 Subject: [PATCH] Split files --- fcad.scad | 288 -------------------------------------------- fcad/cube.scad | 16 +++ fcad/cylinder.scad | 26 ++++ fcad/draw.scad | 25 ++++ fcad/fcad.scad | 9 ++ fcad/math.scad | 9 ++ fcad/obj_util.scad | 19 +++ fcad/sphere.scad | 54 +++++++++ fcad/struct.scad | 14 +++ fcad/translate.scad | 51 ++++++++ fcad/types.scad | 58 +++++++++ test.scad | 5 + 12 files changed, 286 insertions(+), 288 deletions(-) delete mode 100644 fcad.scad create mode 100644 fcad/cube.scad create mode 100644 fcad/cylinder.scad create mode 100644 fcad/draw.scad create mode 100644 fcad/fcad.scad create mode 100644 fcad/math.scad create mode 100644 fcad/obj_util.scad create mode 100644 fcad/sphere.scad create mode 100644 fcad/struct.scad create mode 100644 fcad/translate.scad create mode 100644 fcad/types.scad create mode 100644 test.scad diff --git a/fcad.scad b/fcad.scad deleted file mode 100644 index 13aba4f..0000000 --- a/fcad.scad +++ /dev/null @@ -1,288 +0,0 @@ -fDraw(fCylinder(10, r1=5, r2=2)); - -///// Data structures - -/// model: -/// kKeyPoints "points" fPoints(): [ [x, y, z], ... ] -/// kKeyFaces "faces" fFaces(): [ [ pointIdx, ... ], ... ] - -///// Drawing modules -module fDraw(model) { - polyhedron(points=fPoints(model), faces=fFaces(model)); -} - -module fDrawN(model, scales) { - fDraw(model); - points = fPoints(model); - model_max = fMaxPoint(model); - translation = - [for (axis = [0 : 2]) - scales[axis] * model_max[axis]]; - translate(translation) children(); -} - -module fDrawX(model) { - fDrawN(model, [1, 0, 0]) children(); -} - -module fDrawY(model) { - fDrawN(model, [0, 1, 0]) children(); -} - -module fDrawZ(model) { - fDrawN(model, [0, 0, 1]) children(); -} - -///// 3D object creation functions -function fCube(dims) = ( - let(x = fIsVector(dims) ? dims[0] : dims, - y = fIsVector(dims) ? dims[1] : dims, - z = fIsVector(dims) ? dims[2] : dims) - [ - [fKeyPoints, fCartesianProduct([[0, x], [0, y], [0, z]])], - [fKeyFaces, [ - [0, 2, 3, 1], // -x - [0, 1, 5, 4], // -y - [0, 4, 6, 2], // -z - [4, 5, 7, 6], // +x - [2, 6, 7, 3], // +y - [1, 3, 7, 5], // +z - ]], - ] -); - -function fCylinder(h, r, r1=undef, r2=undef, sides=36) = ( - let(degrees_per_side = 360 / sides, - side_range = [0 : sides - 1], - int_r1 = (r1 == undef) ? r : r1, - int_r2 = (r2 == undef) ? r : r2) - [ - [fKeyPoints, - [for (side = side_range) - for (params = [[int_r1, 0], [int_r2, h]]) - let (angle = side * degrees_per_side, - radius = params[0], - height = params[1]) - [radius * sin(angle), radius * cos(angle), height]], - ], - [fKeyFaces, concat( - // bottom - [[for (side = [sides : -1 : 0]) side * 2]], - // top - [[for (side = [0 : sides]) side * 2 + 1]], - // sides - [for (side = side_range) - [for (vertex = [2, 3, 1, 0]) (side * 2 + vertex) % (sides * 2)]] - )], - ] -); - -function fSphere(r, sides=36, stripes=18) = ( - let(degrees_per_slice = 180 / stripes, - degrees_per_side = 360 / sides, - top_index = (stripes - 1) * sides) - [ - [fKeyPoints, concat( - [for (stripe_index = [1 : stripes - 1]) - for (side_index = [0 : sides - 1]) - let (stripe_angle = stripe_index * degrees_per_slice, - side_angle = side_index * degrees_per_side, - stripe_radius = r * sin(stripe_angle), - stripe_z = r * cos(stripe_angle), - side_x = stripe_radius * sin(side_angle), - side_y = stripe_radius * cos(side_angle)) - [side_x, side_y, stripe_z] - ], - [ - [0, 0, r], // top - [0, 0, -r], // bottom - ] - )], - [fKeyFaces, concat( - // side squares - [for (stripe_index = [2 : stripes - 1]) - for (side_index = [0 : sides - 1]) - let (prev_side_base = (stripe_index - 2) * sides, - side_base = (stripe_index - 1) * sides) - [ - prev_side_base + (side_index + 1) % sides, - prev_side_base + side_index, - side_base + side_index, - side_base + (side_index + 1) % sides, - ] - ], - // top triangles - [for (side_index = [0 : sides - 1]) - [ - top_index, - side_index, - (side_index + 1) % sides, - ] - ], - // bottom triangles - [for (side_index = [0 : sides - 1]) - let (side_base = (stripes - 2) * sides) - [ - top_index + 1, - side_base + (side_index + 1) % sides, - side_base + side_index, - ] - ] - )], - ] -); - -///// 3D object information functions -function fMinPoint(model) = ( - [for (axis = [0 : 2]) - min([for (point = fPoints(model)) point[axis]])] -); - -function fMaxPoint(model) = ( - [for (axis = [0 : 2]) - max([for (point = fPoints(model)) point[axis]])] -); - -function fCenterPoint(model) = ( - let(model_min = fMinPoint(model), - model_max = fMaxPoint(model), - model_size = - [for (axis = [0 : 2]) - model_max[axis] - model_min[axis]]) - [for (axis = [0 : 2]) - model_min[axis] + (model_size[axis] / 2)] -); - -///// 3D object translation functions -function fTranslate(model, translation) = ( - [ - [fKeyPoints, - [for (point = fPoints(model)) - [for (axis = [0 : 2]) - point[axis] + translation[axis]] - ] - ], - [fKeyFaces, fFaces(model)], - ] -); - -function fZeroN(model, scales) = ( - let(model_min = fMinPoint(model), - translation = - [for (axis = [0 : 2]) - scales[axis] * model_min[axis]]) - fTranslate(model, translation) -); - -function fZeroX(model) = ( - fZeroN(model, [-1, 0, 0]) -); - -function fZeroY(model) = ( - fZeroN(model, [0, -1, 0]) -); - -function fZeroZ(model) = ( - fZeroN(model, [0, 0, -1]) -); - -function fCenterN(model, scales) = ( - let(model_center = fCenterPoint(model), - translation = - [for (axis = [0 : 2]) - scales[axis] * model_center[axis]]) - fTranslate(model, translation) -); - -function fCenterX(model) = ( - fCenterN(model, [-1, 0, 0]) -); - -function fCenterY(model) = ( - fCenterN(model, [0, -1, 0]) -); - -function fCenterZ(model) = ( - fCenterN(model, [0, 0, -1]) -); - -///// Constants -fKeyPoints = "points"; -fKeyFaces = "faces"; - -fTypeUndef = "undef"; -fTypeInt = "int"; -fTypeFloat = "float"; -fTypeString = "string"; -fTypeBoolean = "boolean"; -fTypeVector = "vector"; -fTypeUnknown = "unknown"; - -///// Utility functions -function fType(x) = ( - x == undef ? fTypeUndef - : floor(x) == x ? fTypeInt - : abs(x) + 1 > abs(x) ? fTypeFloat - : str(x) == x ? fTypeString - : str(x) == "false" || str(x) == "true" ? fTypeBoolean - : (x[0] == x[0]) && len(x) != undef ? fTypeVector - : fTypeUnknown -); - -function fIsVector(x) = ( - fType(x) == fTypeVector -); - -function fIsInt(x) = ( - fType(x) == fTypeInt -); - -function fIsFloat(x) = ( - fType(x) == fTypeFloat -); - -function fIsString(x) = ( - fType(x) == fTypeString -); - -function fIsBoolean(x) = ( - fType(x) == fTypeBoolean -); - -function fIsVector(x) = ( - fType(x) == fTypeVector -); - -function fMapLookup(key, model) = ( - [for (pair = model) - let (iter_key = pair[0], - iter_value = pair[1]) - if (key == iter_key) - iter_value][0] -); - -function fVectorSlice(vec, start=0, step=undef, end=undef) = ( - let(real_end = (end == undef) ? len(vec) - 1 : end, - real_step = (step == undef) ? - ((real_end > start) ? 1 : -1) - : step) - [for (i = [start : real_step : real_end]) - vec[i]] -); - -function fCartesianProduct(vecs) = ( - len(vecs) == 1 ? - vecs[0] - : - [for (val1 = vecs[0]) - for (val2 = fCartesianProduct(fVectorSlice(vecs, start=1))) - concat(val1, val2)] -); - -function fPoints(model) = ( - fMapLookup(fKeyPoints, model) -); - -function fFaces(model) = ( - fMapLookup(fKeyFaces, model) -); diff --git a/fcad/cube.scad b/fcad/cube.scad new file mode 100644 index 0000000..99ea116 --- /dev/null +++ b/fcad/cube.scad @@ -0,0 +1,16 @@ +function fCube(dims) = ( + let(x = fIsVector(dims) ? dims[0] : dims, + y = fIsVector(dims) ? dims[1] : dims, + z = fIsVector(dims) ? dims[2] : dims) + [ + [fKeyPoints, fCartesianProduct([[0, x], [0, y], [0, z]])], + [fKeyFaces, [ + [0, 2, 3, 1], // -x + [0, 1, 5, 4], // -y + [0, 4, 6, 2], // -z + [4, 5, 7, 6], // +x + [2, 6, 7, 3], // +y + [1, 3, 7, 5], // +z + ]], + ] +); diff --git a/fcad/cylinder.scad b/fcad/cylinder.scad new file mode 100644 index 0000000..30b1604 --- /dev/null +++ b/fcad/cylinder.scad @@ -0,0 +1,26 @@ +function fCylinder(h, r, r1=undef, r2=undef, sides=36) = ( + let(degrees_per_side = 360 / sides, + side_range = [0 : sides - 1], + int_r1 = (r1 == undef) ? r : r1, + int_r2 = (r2 == undef) ? r : r2) + [ + [fKeyPoints, + [for (side = side_range) + for (params = [[int_r1, 0], [int_r2, h]]) + let (angle = side * degrees_per_side, + radius = params[0], + height = params[1]) + [radius * sin(angle), radius * cos(angle), height]], + ], + [fKeyFaces, concat( + // bottom + [[for (side = [sides : -1 : 0]) side * 2]], + // top + [[for (side = [0 : sides]) side * 2 + 1]], + // sides + [for (side = side_range) + [for (vertex = [2, 3, 1, 0]) (side * 2 + vertex) % (sides * 2)]] + )], + ] +); + diff --git a/fcad/draw.scad b/fcad/draw.scad new file mode 100644 index 0000000..02d0ec5 --- /dev/null +++ b/fcad/draw.scad @@ -0,0 +1,25 @@ +module fDraw(model) { + polyhedron(points=fPoints(model), faces=fFaces(model)); +} + +module fDrawN(model, scales) { + fDraw(model); + points = fPoints(model); + model_max = fMaxPoint(model); + translation = + [for (axis = [0 : 2]) + scales[axis] * model_max[axis]]; + translate(translation) children(); +} + +module fDrawX(model) { + fDrawN(model, [1, 0, 0]) children(); +} + +module fDrawY(model) { + fDrawN(model, [0, 1, 0]) children(); +} + +module fDrawZ(model) { + fDrawN(model, [0, 0, 1]) children(); +} diff --git a/fcad/fcad.scad b/fcad/fcad.scad new file mode 100644 index 0000000..521f3f8 --- /dev/null +++ b/fcad/fcad.scad @@ -0,0 +1,9 @@ +include ; +include ; +include ; +include ; +include ; +include ; +include ; +include ; +include ; diff --git a/fcad/math.scad b/fcad/math.scad new file mode 100644 index 0000000..8d22bf6 --- /dev/null +++ b/fcad/math.scad @@ -0,0 +1,9 @@ +function fCartesianProduct(vecs) = ( + len(vecs) == 1 ? + vecs[0] + : + [for (val1 = vecs[0]) + for (val2 = fCartesianProduct(fVectorSlice(vecs, start=1))) + concat(val1, val2)] +); + diff --git a/fcad/obj_util.scad b/fcad/obj_util.scad new file mode 100644 index 0000000..917d647 --- /dev/null +++ b/fcad/obj_util.scad @@ -0,0 +1,19 @@ +function fMinPoint(model) = ( + [for (axis = [0 : 2]) + min([for (point = fPoints(model)) point[axis]])] +); + +function fMaxPoint(model) = ( + [for (axis = [0 : 2]) + max([for (point = fPoints(model)) point[axis]])] +); + +function fCenterPoint(model) = ( + let(model_min = fMinPoint(model), + model_max = fMaxPoint(model), + model_size = + [for (axis = [0 : 2]) + model_max[axis] - model_min[axis]]) + [for (axis = [0 : 2]) + model_min[axis] + (model_size[axis] / 2)] +); diff --git a/fcad/sphere.scad b/fcad/sphere.scad new file mode 100644 index 0000000..d5c537c --- /dev/null +++ b/fcad/sphere.scad @@ -0,0 +1,54 @@ +function fSphere(r, sides=36, stripes=18) = ( + let(degrees_per_slice = 180 / stripes, + degrees_per_side = 360 / sides, + top_index = (stripes - 1) * sides) + [ + [fKeyPoints, concat( + [for (stripe_index = [1 : stripes - 1]) + for (side_index = [0 : sides - 1]) + let (stripe_angle = stripe_index * degrees_per_slice, + side_angle = side_index * degrees_per_side, + stripe_radius = r * sin(stripe_angle), + stripe_z = r * cos(stripe_angle), + side_x = stripe_radius * sin(side_angle), + side_y = stripe_radius * cos(side_angle)) + [side_x, side_y, stripe_z] + ], + [ + [0, 0, r], // top + [0, 0, -r], // bottom + ] + )], + [fKeyFaces, concat( + // side squares + [for (stripe_index = [2 : stripes - 1]) + for (side_index = [0 : sides - 1]) + let (prev_side_base = (stripe_index - 2) * sides, + side_base = (stripe_index - 1) * sides) + [ + prev_side_base + (side_index + 1) % sides, + prev_side_base + side_index, + side_base + side_index, + side_base + (side_index + 1) % sides, + ] + ], + // top triangles + [for (side_index = [0 : sides - 1]) + [ + top_index, + side_index, + (side_index + 1) % sides, + ] + ], + // bottom triangles + [for (side_index = [0 : sides - 1]) + let (side_base = (stripes - 2) * sides) + [ + top_index + 1, + side_base + (side_index + 1) % sides, + side_base + side_index, + ] + ] + )], + ] +); diff --git a/fcad/struct.scad b/fcad/struct.scad new file mode 100644 index 0000000..f6c1202 --- /dev/null +++ b/fcad/struct.scad @@ -0,0 +1,14 @@ +/// model: +/// kKeyPoints "points" fPoints(): [ [x, y, z], ... ] +/// kKeyFaces "faces" fFaces(): [ [ pointIdx, ... ], ... ] + +fKeyPoints = "points"; +fKeyFaces = "faces"; + +function fPoints(model) = ( + fMapLookup(fKeyPoints, model) +); + +function fFaces(model) = ( + fMapLookup(fKeyFaces, model) +); diff --git a/fcad/translate.scad b/fcad/translate.scad new file mode 100644 index 0000000..d0cee27 --- /dev/null +++ b/fcad/translate.scad @@ -0,0 +1,51 @@ +function fTranslate(model, translation) = ( + [ + [fKeyPoints, + [for (point = fPoints(model)) + [for (axis = [0 : 2]) + point[axis] + translation[axis]] + ] + ], + [fKeyFaces, fFaces(model)], + ] +); + +function fZeroN(model, scales) = ( + let(model_min = fMinPoint(model), + translation = + [for (axis = [0 : 2]) + scales[axis] * model_min[axis]]) + fTranslate(model, translation) +); + +function fZeroX(model) = ( + fZeroN(model, [-1, 0, 0]) +); + +function fZeroY(model) = ( + fZeroN(model, [0, -1, 0]) +); + +function fZeroZ(model) = ( + fZeroN(model, [0, 0, -1]) +); + +function fCenterN(model, scales) = ( + let(model_center = fCenterPoint(model), + translation = + [for (axis = [0 : 2]) + scales[axis] * model_center[axis]]) + fTranslate(model, translation) +); + +function fCenterX(model) = ( + fCenterN(model, [-1, 0, 0]) +); + +function fCenterY(model) = ( + fCenterN(model, [0, -1, 0]) +); + +function fCenterZ(model) = ( + fCenterN(model, [0, 0, -1]) +); diff --git a/fcad/types.scad b/fcad/types.scad new file mode 100644 index 0000000..18eed53 --- /dev/null +++ b/fcad/types.scad @@ -0,0 +1,58 @@ +fTypeUndef = "undef"; +fTypeInt = "int"; +fTypeFloat = "float"; +fTypeString = "string"; +fTypeBoolean = "boolean"; +fTypeVector = "vector"; +fTypeUnknown = "unknown"; + +function fType(x) = ( + x == undef ? fTypeUndef + : floor(x) == x ? fTypeInt + : abs(x) + 1 > abs(x) ? fTypeFloat + : str(x) == x ? fTypeString + : str(x) == "false" || str(x) == "true" ? fTypeBoolean + : (x[0] == x[0]) && len(x) != undef ? fTypeVector + : fTypeUnknown +); + +function fIsVector(x) = ( + fType(x) == fTypeVector +); + +function fIsInt(x) = ( + fType(x) == fTypeInt +); + +function fIsFloat(x) = ( + fType(x) == fTypeFloat +); + +function fIsString(x) = ( + fType(x) == fTypeString +); + +function fIsBoolean(x) = ( + fType(x) == fTypeBoolean +); + +function fIsVector(x) = ( + fType(x) == fTypeVector +); + +function fMapLookup(key, model) = ( + [for (pair = model) + let (iter_key = pair[0], + iter_value = pair[1]) + if (key == iter_key) + iter_value][0] +); + +function fVectorSlice(vec, start=0, step=undef, end=undef) = ( + let(real_end = (end == undef) ? len(vec) - 1 : end, + real_step = (step == undef) ? + ((real_end > start) ? 1 : -1) + : step) + [for (i = [start : real_step : real_end]) + vec[i]] +); diff --git a/test.scad b/test.scad new file mode 100644 index 0000000..21960c1 --- /dev/null +++ b/test.scad @@ -0,0 +1,5 @@ +use ; + +fDrawX(fCylinder(10, r1=5, r2=2)) +fDrawX(fSphere(10)) +fDrawX(fCube(10));