Triply-nested spiral! And more notes.
This commit is contained in:
parent
10f6128579
commit
ac022b3b9b
48
README.md
48
README.md
@ -1,8 +1,21 @@
|
|||||||
To-do items, wanted features, bugs:
|
# To-do items, wanted features, bugs:
|
||||||
|
|
||||||
|
## Cool
|
||||||
- Examples of branching. This will probably need recursion via functions
|
- Examples of branching. This will probably need recursion via functions
|
||||||
(or an explicit stack some other way).
|
(or an explicit stack some other way). If I simply
|
||||||
- I need to figure out winding order. It is consistent through seemingly
|
split a boundary into sub-boundaries per the rules I already
|
||||||
|
have in my notes, then this still lets me split any way I want
|
||||||
|
to without having to worry about joining N boundaries instead
|
||||||
|
of 2, doesn't it?
|
||||||
|
- More complicated: Examples of *merging*. I'm not sure on the theory
|
||||||
|
behind this.
|
||||||
|
|
||||||
|
## Annoying
|
||||||
|
- I really need to standardize some of the behavior of fundamental
|
||||||
|
operations (with regard to things like sizes they generate). This
|
||||||
|
is behavior that, if it changes, will change a lot of things that I'm
|
||||||
|
trying to keep consistent so that my examples still work.
|
||||||
|
- Winding order. It is consistent through seemingly
|
||||||
everything, except for reflection and close_boundary_simple.
|
everything, except for reflection and close_boundary_simple.
|
||||||
(When there are two parallel boundaries joined with something like
|
(When there are two parallel boundaries joined with something like
|
||||||
join_boundary_simple, traversing these boundaries in their actual order
|
join_boundary_simple, traversing these boundaries in their actual order
|
||||||
@ -10,14 +23,8 @@ To-do items, wanted features, bugs:
|
|||||||
opposite winding order on each. Imagine a transparent clock: seen from the
|
opposite winding order on each. Imagine a transparent clock: seen from the
|
||||||
front, it moves clockwise, but seen from the back, it moves
|
front, it moves clockwise, but seen from the back, it moves
|
||||||
counter-clockwise.)
|
counter-clockwise.)
|
||||||
- Make it easier to build up meshes a bit at a time?
|
|
||||||
- Factor out recursive/iterative stuff to be a bit more concise
|
|
||||||
- Embed this in Blender?
|
|
||||||
- File that bug that I've seen in trimesh/three.js
|
- File that bug that I've seen in trimesh/three.js
|
||||||
(see trimesh_fail.ipynb)
|
(see trimesh_fail.ipynb)
|
||||||
|
|
||||||
- Parametrize gen_twisted_boundary over boundaries and
|
|
||||||
do my nested spiral
|
|
||||||
- Why do I get the weird zig-zag pattern on the triangles,
|
- Why do I get the weird zig-zag pattern on the triangles,
|
||||||
despite larger numbers of them? Is it something in how I
|
despite larger numbers of them? Is it something in how I
|
||||||
twist the frames?
|
twist the frames?
|
||||||
@ -29,18 +36,11 @@ twist the frames?
|
|||||||
quad to 4 triangles by adding the centroid) could be good
|
quad to 4 triangles by adding the centroid) could be good
|
||||||
too.
|
too.
|
||||||
- Facets/edges are just oriented the wrong way...
|
- Facets/edges are just oriented the wrong way...
|
||||||
- I need an actual example of branching/forking. If I simply
|
|
||||||
split a boundary into sub-boundaries per the rules I already
|
|
||||||
have in my notes, then this still lets me split any way I want
|
|
||||||
to without having to worry about joining N boundaries instead
|
|
||||||
of 2, doesn't it?
|
|
||||||
|
|
||||||
Other notes:
|
|
||||||
- Picking at random the diagonal on the quad to triangulate with
|
- Picking at random the diagonal on the quad to triangulate with
|
||||||
does seem to turn 'error' just to noise, and in its own way this
|
does seem to turn 'error' just to noise, and in its own way this
|
||||||
is preferable.
|
is preferable.
|
||||||
|
|
||||||
# Abstractions
|
## Abstractions
|
||||||
|
|
||||||
- Encode the notions of "generator which transforms an
|
- Encode the notions of "generator which transforms an
|
||||||
existing list of boundaries", "generator which transforms
|
existing list of boundaries", "generator which transforms
|
||||||
@ -52,3 +52,17 @@ boundaries?)
|
|||||||
- Work directly with lists of boundaries. The only thing
|
- Work directly with lists of boundaries. The only thing
|
||||||
I ever do with them is apply transforms to all of them, or
|
I ever do with them is apply transforms to all of them, or
|
||||||
join adjacent ones with corresponding elements.
|
join adjacent ones with corresponding elements.
|
||||||
|
|
||||||
|
- Some generators produce boundaries that can be directly merged
|
||||||
|
and produce sensible geometry. Some generators produce
|
||||||
|
boundaries that are only usable when they are further
|
||||||
|
transformed (and would produce degenerate geometry). What sort
|
||||||
|
of nomenclature captures this?
|
||||||
|
|
||||||
|
- How can I capture the idea of a group of parameters which, if
|
||||||
|
they are all scaled in the correct way (some linearly, others
|
||||||
|
inversely perhaps), generated geometry that is more or less
|
||||||
|
identical except that it is higher-resolution?
|
||||||
|
## ????
|
||||||
|
- Embed this in Blender?
|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
55
examples.py
55
examples.py
@ -1,7 +1,9 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
import stl.mesh
|
import itertools
|
||||||
|
|
||||||
import numpy
|
import numpy
|
||||||
|
import stl.mesh
|
||||||
import trimesh
|
import trimesh
|
||||||
|
|
||||||
import meshutil
|
import meshutil
|
||||||
@ -171,7 +173,9 @@ def twist_from_gen():
|
|||||||
b = meshutil.subdivide_boundary(b)
|
b = meshutil.subdivide_boundary(b)
|
||||||
b = meshutil.subdivide_boundary(b)
|
b = meshutil.subdivide_boundary(b)
|
||||||
bs = [b]
|
bs = [b]
|
||||||
gen = meshgen.gen_inc_y(meshgen.gen_twisted_boundary(bs))
|
# since it needs a generator:
|
||||||
|
gen_inner = itertools.repeat(bs)
|
||||||
|
gen = meshgen.gen_inc_y(meshgen.gen_twisted_boundary(gen_inner))
|
||||||
mesh = meshgen.gen2mesh(gen, 100, True)
|
mesh = meshgen.gen2mesh(gen, 100, True)
|
||||||
return mesh
|
return mesh
|
||||||
|
|
||||||
@ -189,11 +193,54 @@ def twisty_torus(frames = 200, turns = 4, count = 4, rad = 4):
|
|||||||
b = meshutil.subdivide_boundary(b)
|
b = meshutil.subdivide_boundary(b)
|
||||||
b = meshutil.subdivide_boundary(b)
|
b = meshutil.subdivide_boundary(b)
|
||||||
bs = [b]
|
bs = [b]
|
||||||
|
# since it needs a generator:
|
||||||
|
gen_inner = itertools.repeat(bs)
|
||||||
# In order to make this line up properly:
|
# In order to make this line up properly:
|
||||||
angle = numpy.pi * 2 * turns / frames
|
angle = numpy.pi * 2 * turns / frames
|
||||||
gen = meshgen.gen_torus_xy(meshgen.gen_twisted_boundary(bs=bs, count=count, ang=angle), rad=rad, frames=frames)
|
gen = meshgen.gen_torus_xy(meshgen.gen_twisted_boundary(gen=gen_inner, count=count, ang=angle), rad=rad, frames=frames)
|
||||||
return meshgen.gen2mesh(gen, 0, flip_order=True, loop=True)
|
return meshgen.gen2mesh(gen, 0, flip_order=True, loop=True)
|
||||||
|
|
||||||
|
def spiral_nested_2():
|
||||||
|
# Slow.
|
||||||
|
b = numpy.array([
|
||||||
|
[0, 0, 0],
|
||||||
|
[1, 0, 0],
|
||||||
|
[1, 0, 1],
|
||||||
|
[0, 0, 1],
|
||||||
|
], dtype=numpy.float64) - [0.5, 0, 0.5]
|
||||||
|
b *= 0.3
|
||||||
|
b = meshutil.subdivide_boundary(b)
|
||||||
|
b = meshutil.subdivide_boundary(b)
|
||||||
|
bs = [b]
|
||||||
|
# since it needs a generator:
|
||||||
|
gen1 = itertools.repeat(bs)
|
||||||
|
gen2 = meshgen.gen_twisted_boundary(gen1, ang=-0.2, dx0=0.5)
|
||||||
|
gen3 = meshgen.gen_twisted_boundary(gen2, ang=0.05, dx0=1)
|
||||||
|
gen = meshgen.gen_inc_y(gen3, dy=0.1)
|
||||||
|
return meshgen.gen2mesh(
|
||||||
|
gen, count=250, flip_order=True, close_first=True, close_last=True)
|
||||||
|
|
||||||
|
def spiral_nested_3():
|
||||||
|
# Slower.
|
||||||
|
b = numpy.array([
|
||||||
|
[0, 0, 0],
|
||||||
|
[1, 0, 0],
|
||||||
|
[1, 0, 1],
|
||||||
|
[0, 0, 1],
|
||||||
|
], dtype=numpy.float64) - [0.5, 0, 0.5]
|
||||||
|
b *= 0.3
|
||||||
|
b = meshutil.subdivide_boundary(b)
|
||||||
|
b = meshutil.subdivide_boundary(b)
|
||||||
|
bs = [b]
|
||||||
|
# since it needs a generator:
|
||||||
|
gen1 = itertools.repeat(bs)
|
||||||
|
gen2 = meshgen.gen_twisted_boundary(gen1, ang=-0.2, dx0=0.5)
|
||||||
|
gen3 = meshgen.gen_twisted_boundary(gen2, ang=0.07, dx0=1)
|
||||||
|
gen4 = meshgen.gen_twisted_boundary(gen3, ang=-0.03, dx0=3)
|
||||||
|
gen = meshgen.gen_inc_y(gen4, dy=0.1)
|
||||||
|
return meshgen.gen2mesh(
|
||||||
|
gen, count=500, flip_order=True, close_first=True, close_last=True)
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
fns = {
|
fns = {
|
||||||
ram_horn: "ramhorn.stl",
|
ram_horn: "ramhorn.stl",
|
||||||
@ -202,6 +249,8 @@ def main():
|
|||||||
twist_nonlinear: "twist_nonlinear.stl",
|
twist_nonlinear: "twist_nonlinear.stl",
|
||||||
twist_from_gen: "twist_from_gen.stl",
|
twist_from_gen: "twist_from_gen.stl",
|
||||||
twisty_torus: "twisty_torus.stl",
|
twisty_torus: "twisty_torus.stl",
|
||||||
|
spiral_nested_2: "spiral_nested_2.stl",
|
||||||
|
spiral_nested_3: "spiral_nested_3.stl",
|
||||||
}
|
}
|
||||||
for f in fns:
|
for f in fns:
|
||||||
fname = fns[f]
|
fname = fns[f]
|
||||||
|
|||||||
21
meshgen.py
21
meshgen.py
@ -1,35 +1,34 @@
|
|||||||
|
import itertools
|
||||||
|
|
||||||
import meshutil
|
import meshutil
|
||||||
import stl.mesh
|
import stl.mesh
|
||||||
import numpy
|
import numpy
|
||||||
import trimesh
|
import trimesh
|
||||||
|
|
||||||
# Generate a frame with 'count' boundaries in the XZ plane.
|
# Generate a frame with 'count' boundaries in the XZ plane.
|
||||||
# Each one rotates by 'ang' as it moves by 'dz'.
|
# Each one rotates by 'ang' at each step.
|
||||||
# dx0 is center-point distance from each to the origin.
|
# dx0 is center-point distance from each to the origin.
|
||||||
#
|
#
|
||||||
# TODO: This needs to transform an existing generator, not just
|
# This doesn't generate usable geometry on its own.
|
||||||
# a boundary!
|
def gen_twisted_boundary(gen=None, count=4, dx0=2, ang=0.1):
|
||||||
def gen_twisted_boundary(bs=None, count=4, dx0=2, dz=0.2, ang=0.1):
|
if gen is None:
|
||||||
if bs is None:
|
|
||||||
b = numpy.array([
|
b = numpy.array([
|
||||||
[0, 0, 0],
|
[0, 0, 0],
|
||||||
[1, 0, 0],
|
[1, 0, 0],
|
||||||
[1, 0, 1],
|
[1, 0, 1],
|
||||||
[0, 0, 1],
|
[0, 0, 1],
|
||||||
], dtype=numpy.float64) - [0.5, 0, 0.5]
|
], dtype=numpy.float64) - [0.5, 0, 0.5]
|
||||||
b = meshutil.subdivide_boundary(b)
|
gen = itertools.repeat([b])
|
||||||
b = meshutil.subdivide_boundary(b)
|
|
||||||
b = meshutil.subdivide_boundary(b)
|
|
||||||
bs = [b]
|
|
||||||
# Generate 'seed' transformations:
|
# Generate 'seed' transformations:
|
||||||
xfs = [meshutil.Transform().translate(dx0, 0, 0).rotate([0,1,0], numpy.pi * 2 * i / count)
|
xfs = [meshutil.Transform().translate(dx0, 0, 0).rotate([0,1,0], numpy.pi * 2 * i / count)
|
||||||
for i in range(count)]
|
for i in range(count)]
|
||||||
# (we'll increment the transforms in xfs as we go)
|
# (we'll increment the transforms in xfs as we go)
|
||||||
while True:
|
for bs in gen:
|
||||||
xfs_new = []
|
xfs_new = []
|
||||||
|
bs2 = []
|
||||||
for i, xf in enumerate(xfs):
|
for i, xf in enumerate(xfs):
|
||||||
# Generate a boundary from running transform:
|
# Generate a boundary from running transform:
|
||||||
bs2 = [xf.apply_to(b) for b in bs]
|
bs2 += [xf.apply_to(b) for b in bs]
|
||||||
# Increment transform i:
|
# Increment transform i:
|
||||||
xf2 = xf.rotate([0,1,0], ang)
|
xf2 = xf.rotate([0,1,0], ang)
|
||||||
xfs_new.append(xf2)
|
xfs_new.append(xf2)
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user