mirror of
https://github.com/JustinSDK/dotSCAD.git
synced 2025-08-19 13:01:37 +02:00
rewrite polyhedra
This commit is contained in:
@@ -1,82 +1,55 @@
|
||||
use <../../__comm__/_pt3_hash.scad>;
|
||||
use <../../util/map/hashmap.scad>;
|
||||
use <../../util/map/hashmap_put.scad>;
|
||||
use <../../util/map/hashmap_get.scad>;
|
||||
use <../../util/sum.scad>;
|
||||
|
||||
function _tri_subdivide(points) =
|
||||
let(
|
||||
p0 = points[0],
|
||||
p1 = points[1],
|
||||
p2 = points[2],
|
||||
m0 = (p0 + p1) / 2,
|
||||
m1 = (p1 + p2) / 2,
|
||||
m2 = (p2 + p0) / 2
|
||||
)
|
||||
[
|
||||
[p0, m0, m2],
|
||||
[m0, p1, m1],
|
||||
[m1, p2, m2],
|
||||
[m0, m1, m2]
|
||||
];
|
||||
function _tri_subdivide(points, detail) =
|
||||
let(
|
||||
rows = detail + 1,
|
||||
vc = points[2] - points[0],
|
||||
vr = points[1] - points[0],
|
||||
dr = vr / (detail + 1),
|
||||
dc = vc / (detail + 1),
|
||||
pts = [
|
||||
for(ri = [0:rows])
|
||||
let(cols = rows - ri)
|
||||
for(ci = [0:cols])
|
||||
points[0] + ci * dc + ri * dr
|
||||
],
|
||||
pre_n = concat([0], [for(ri = [0:rows]) rows - ri + 1]),
|
||||
idx = function(ci, ri) ci + sum([for(i = [0:ri]) pre_n[i]]),
|
||||
faces = [
|
||||
for(ri = [0:rows - 1])
|
||||
let(cols = rows - ri - 1)
|
||||
for(ci = [0:cols])
|
||||
let(pre = 0)
|
||||
each (ci == cols ?
|
||||
[
|
||||
[idx(ci, ri), idx(ci, ri + 1), idx(ci + 1, ri)]
|
||||
] :
|
||||
[
|
||||
[idx(ci, ri), idx(ci, ri + 1), idx(ci + 1, ri)],
|
||||
[idx(ci + 1, ri), idx(ci, ri + 1), idx(ci + 1, ri + 1)]
|
||||
]
|
||||
)
|
||||
]
|
||||
)
|
||||
[pts, faces];
|
||||
|
||||
function tri_subdivide(points, n = 1) =
|
||||
n == 1 ? _tri_subdivide(points) :
|
||||
[for(tri = tri_subdivide(points, n - 1)) each _tri_subdivide(tri)];
|
||||
|
||||
function _geom_prj2sphere(t, r) = [for(p = t) p / norm(p) * r];
|
||||
|
||||
function _pimap_pts(radius, points, leng, hash, m, deduped_pts = [], n = -1, i = 0) =
|
||||
i == leng ? [m, deduped_pts] :
|
||||
let(v = hashmap_get(m, points[i], hash = hash))
|
||||
is_undef(v) ?
|
||||
_pimap_pts(radius, points, leng, hash, hashmap_put(m, points[i], n + 1, hash = hash), concat(deduped_pts, [points[i] / norm(points[i]) * radius]), n + 1, i + 1) :
|
||||
_pimap_pts(radius, points, leng, hash, m, deduped_pts, n, i + 1);
|
||||
|
||||
function _geom_pts_faces(points, radius) =
|
||||
function _subdivide_project(points, faces, radius, detail) =
|
||||
let(
|
||||
number_of_buckets = ceil(sqrt(len(points)) * 1.5),
|
||||
hash = function(p) _pt3_hash(p),
|
||||
leng = len(points),
|
||||
m_pts = _pimap_pts(
|
||||
radius,
|
||||
points,
|
||||
leng,
|
||||
hash,
|
||||
hashmap(number_of_buckets = number_of_buckets)
|
||||
),
|
||||
faces = [
|
||||
for(i = [0:3:leng - 3])
|
||||
[
|
||||
hashmap_get(m_pts[0], points[i], hash = hash),
|
||||
hashmap_get(m_pts[0], points[i + 1], hash = hash),
|
||||
hashmap_get(m_pts[0], points[i + 2], hash = hash)
|
||||
]
|
||||
]
|
||||
)
|
||||
[m_pts[1], faces];
|
||||
|
||||
function _geom_info(tris, radius, detail) =
|
||||
_geom_pts_faces([
|
||||
for(tri = tris)
|
||||
each [for(t = tri_subdivide(tri, detail)) each t]
|
||||
], radius);
|
||||
|
||||
function _geom_info_quick(tris, radius, detail) =
|
||||
let(
|
||||
points = [
|
||||
for(tri = tris)
|
||||
each [for(t = tri_subdivide(tri, detail)) each _geom_prj2sphere(t, radius)]
|
||||
],
|
||||
faces = [for(i = [0:3:len(points) - 3]) [i, i + 1, i + 2]]
|
||||
)
|
||||
[points, faces];
|
||||
|
||||
function _geom_platonic_polyhedra(points, faces, radius, detail, quick_mode) =
|
||||
detail == 0 ? [_geom_prj2sphere(points, radius), faces] :
|
||||
let(
|
||||
tris = [
|
||||
for(face = faces)
|
||||
[for(i = face) points[i]]
|
||||
]
|
||||
)
|
||||
quick_mode ? _geom_info_quick(tris, radius, detail) : _geom_info(tris, radius, detail);
|
||||
subdivided_all = [
|
||||
for(face = faces)
|
||||
_tri_subdivide([for(i = face) points[i]], detail)
|
||||
],
|
||||
pts_number_per_tri = len(subdivided_all[0][0]),
|
||||
flatten_points = [
|
||||
for(pts_faces = subdivided_all)
|
||||
for(p = pts_faces[0])
|
||||
p / norm(p) * radius
|
||||
],
|
||||
flatten_faces = [
|
||||
for(i = [0:len(subdivided_all) - 1])
|
||||
let(faces = subdivided_all[i][1])
|
||||
for(face = faces)
|
||||
face + [i, i, i] * pts_number_per_tri
|
||||
]
|
||||
)
|
||||
[flatten_points, flatten_faces];
|
@@ -1,6 +1,6 @@
|
||||
use <geom_dodecahedron.scad>;
|
||||
|
||||
module dodecahedron(radius, detail = 0, quick_mode = true) {
|
||||
points_faces = geom_dodecahedron(radius, detail, quick_mode);
|
||||
module dodecahedron(radius, detail = 0) {
|
||||
points_faces = geom_dodecahedron(radius, detail);
|
||||
polyhedron(points_faces[0], points_faces[1]);
|
||||
}
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use <_impl/_geom_platonic_polyhedra.scad>;
|
||||
|
||||
function geom_dodecahedron(radius, detail = 0, quick_mode = true) =
|
||||
function geom_dodecahedron(radius, detail = 0) =
|
||||
let(
|
||||
t = (1 + sqrt(5)) / 2,
|
||||
r = 1 / t,
|
||||
@@ -38,4 +38,4 @@ function geom_dodecahedron(radius, detail = 0, quick_mode = true) =
|
||||
[14, 12, 1], [5, 14, 1], [9, 5, 1]
|
||||
]
|
||||
)
|
||||
_geom_platonic_polyhedra(dodecahedron_points, dodecahedron_faces, radius, detail, quick_mode);
|
||||
_subdivide_project(dodecahedron_points, dodecahedron_faces, radius, detail);
|
@@ -1,6 +1,6 @@
|
||||
use <_impl/_geom_platonic_polyhedra.scad>;
|
||||
|
||||
function geom_hexahedron(radius, detail = 0, quick_mode = true) =
|
||||
function geom_hexahedron(radius, detail = 0) =
|
||||
let(
|
||||
t = 1 / sqrt(3),
|
||||
hexahedron_points = [
|
||||
@@ -16,4 +16,4 @@ function geom_hexahedron(radius, detail = 0, quick_mode = true) =
|
||||
[5, 6, 7], [5, 7, 4]
|
||||
]
|
||||
)
|
||||
_geom_platonic_polyhedra(hexahedron_points, hexahedron_faces, radius, detail, quick_mode);
|
||||
_subdivide_project(hexahedron_points, hexahedron_faces, radius, detail);
|
@@ -1,6 +1,6 @@
|
||||
use <_impl/_geom_platonic_polyhedra.scad>;
|
||||
|
||||
function geom_icosahedron(radius, detail = 0, quick_mode = true) =
|
||||
function geom_icosahedron(radius, detail = 0) =
|
||||
let(
|
||||
t = (1 + sqrt(5)) / 2 ,
|
||||
icosahedron_points = [
|
||||
@@ -15,5 +15,5 @@ function geom_icosahedron(radius, detail = 0, quick_mode = true) =
|
||||
[5, 9, 4], [11, 4, 2], [10, 2, 6], [7, 6, 8], [1, 8, 9]
|
||||
]
|
||||
)
|
||||
_geom_platonic_polyhedra(icosahedron_points, icosahedron_faces, radius, detail, quick_mode);
|
||||
_subdivide_project(icosahedron_points, icosahedron_faces, radius, detail);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use <_impl/_geom_platonic_polyhedra.scad>;
|
||||
|
||||
function geom_octahedron(radius, detail = 0, quick_mode = true) =
|
||||
function geom_octahedron(radius, detail = 0) =
|
||||
let(
|
||||
octahedron_points = [
|
||||
[1, 0, 0], [-1, 0, 0], [0, 1, 0],
|
||||
@@ -12,5 +12,5 @@ function geom_octahedron(radius, detail = 0, quick_mode = true) =
|
||||
[4, 3, 1], [2, 4, 1]
|
||||
]
|
||||
)
|
||||
_geom_platonic_polyhedra(octahedron_points, octahedron_faces, radius, detail, quick_mode);
|
||||
_subdivide_project(octahedron_points, octahedron_faces, radius, detail);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use <_impl/_geom_platonic_polyhedra.scad>;
|
||||
|
||||
function geom_tetrahedron(radius, detail = 0, quick_mode = true) =
|
||||
function geom_tetrahedron(radius, detail = 0) =
|
||||
let(
|
||||
t = (1 + sqrt(5)) / 2 ,
|
||||
tetrahedron_points = [
|
||||
@@ -10,5 +10,5 @@ function geom_tetrahedron(radius, detail = 0, quick_mode = true) =
|
||||
[0, 1, 2], [2, 3, 0], [0, 3, 1], [1, 3, 2]
|
||||
]
|
||||
)
|
||||
_geom_platonic_polyhedra(tetrahedron_points, tetrahedron_faces, radius, detail, quick_mode);
|
||||
_subdivide_project(tetrahedron_points, tetrahedron_faces, radius, detail);
|
||||
|
@@ -1,6 +1,6 @@
|
||||
use <geom_hexahedron.scad>;
|
||||
|
||||
module hexahedron(radius, detail = 0, quick_mode = true) {
|
||||
points_faces = geom_hexahedron(radius, detail, quick_mode);
|
||||
module hexahedron(radius, detail = 0) {
|
||||
points_faces = geom_hexahedron(radius, detail);
|
||||
polyhedron(points_faces[0], points_faces[1]);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
use <geom_icosahedron.scad>;
|
||||
|
||||
module icosahedron(radius, detail = 0, quick_mode = true) {
|
||||
points_faces = geom_icosahedron(radius, detail, quick_mode);
|
||||
module icosahedron(radius, detail = 0) {
|
||||
points_faces = geom_icosahedron(radius, detail);
|
||||
polyhedron(points_faces[0], points_faces[1]);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
use <geom_octahedron.scad>;
|
||||
|
||||
module octahedron(radius, detail = 0, quick_mode = true) {
|
||||
points_faces = geom_octahedron(radius, detail, quick_mode);
|
||||
module octahedron(radius, detail = 0) {
|
||||
points_faces = geom_octahedron(radius, detail);
|
||||
polyhedron(points_faces[0], points_faces[1]);
|
||||
}
|
@@ -1,6 +1,6 @@
|
||||
use <geom_tetrahedron.scad>;
|
||||
|
||||
module tetrahedron(radius, detail = 0, quick_mode = true) {
|
||||
points_faces = geom_tetrahedron(radius, detail, quick_mode);
|
||||
module tetrahedron(radius, detail = 0) {
|
||||
points_faces = geom_tetrahedron(radius, detail);
|
||||
polyhedron(points_faces[0], points_faces[1]);
|
||||
}
|
Reference in New Issue
Block a user