Triply-nested spiral! And more notes.
This commit is contained in:
parent
10f6128579
commit
ac022b3b9b
68
README.md
68
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
|
||||
(or an explicit stack some other way).
|
||||
- I need to figure out winding order. It is consistent through seemingly
|
||||
(or an explicit stack some other way). 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?
|
||||
- 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.
|
||||
(When there are two parallel boundaries joined with something like
|
||||
join_boundary_simple, traversing these boundaries in their actual order
|
||||
@ -10,17 +23,11 @@ To-do items, wanted features, bugs:
|
||||
opposite winding order on each. Imagine a transparent clock: seen from the
|
||||
front, it moves clockwise, but seen from the back, it moves
|
||||
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
|
||||
(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,
|
||||
despite larger numbers of them? Is it something in how I
|
||||
twist the frames?
|
||||
despite larger numbers of them? Is it something in how I
|
||||
twist the frames?
|
||||
- How can I compute the *torsion* on a quad? I think it
|
||||
comes down to this: torsion applied across the quad I'm
|
||||
triangulating leading to neither diagonal being a
|
||||
@ -29,26 +36,33 @@ twist the frames?
|
||||
quad to 4 triangles by adding the centroid) could be good
|
||||
too.
|
||||
- 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
|
||||
is preferable.
|
||||
|
||||
# Abstractions
|
||||
## Abstractions
|
||||
|
||||
- Encode the notions of "generator which transforms an
|
||||
existing list of boundaries", "generator which transforms
|
||||
another generator"
|
||||
existing list of boundaries", "generator which transforms
|
||||
another generator"
|
||||
- This has a lot of functions parametrized over a lot
|
||||
of functions. Need to work with this somehow. (e.g. should
|
||||
it subdivide this boundary? should it merge opening/closing
|
||||
boundaries?)
|
||||
of functions. Need to work with this somehow. (e.g. should
|
||||
it subdivide this boundary? should it merge opening/closing
|
||||
boundaries?)
|
||||
- Work directly with lists of boundaries. The only thing
|
||||
I ever do with them is apply transforms to all of them, or
|
||||
join adjacent ones with corresponding elements.
|
||||
I ever do with them is apply transforms to all of them, or
|
||||
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
|
||||
|
||||
import stl.mesh
|
||||
import itertools
|
||||
|
||||
import numpy
|
||||
import stl.mesh
|
||||
import trimesh
|
||||
|
||||
import meshutil
|
||||
@ -171,7 +173,9 @@ def twist_from_gen():
|
||||
b = meshutil.subdivide_boundary(b)
|
||||
b = meshutil.subdivide_boundary(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)
|
||||
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)
|
||||
bs = [b]
|
||||
# since it needs a generator:
|
||||
gen_inner = itertools.repeat(bs)
|
||||
# In order to make this line up properly:
|
||||
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)
|
||||
|
||||
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():
|
||||
fns = {
|
||||
ram_horn: "ramhorn.stl",
|
||||
@ -202,6 +249,8 @@ def main():
|
||||
twist_nonlinear: "twist_nonlinear.stl",
|
||||
twist_from_gen: "twist_from_gen.stl",
|
||||
twisty_torus: "twisty_torus.stl",
|
||||
spiral_nested_2: "spiral_nested_2.stl",
|
||||
spiral_nested_3: "spiral_nested_3.stl",
|
||||
}
|
||||
for f in fns:
|
||||
fname = fns[f]
|
||||
|
||||
21
meshgen.py
21
meshgen.py
@ -1,35 +1,34 @@
|
||||
import itertools
|
||||
|
||||
import meshutil
|
||||
import stl.mesh
|
||||
import numpy
|
||||
import trimesh
|
||||
|
||||
# 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.
|
||||
#
|
||||
# TODO: This needs to transform an existing generator, not just
|
||||
# a boundary!
|
||||
def gen_twisted_boundary(bs=None, count=4, dx0=2, dz=0.2, ang=0.1):
|
||||
if bs is None:
|
||||
# This doesn't generate usable geometry on its own.
|
||||
def gen_twisted_boundary(gen=None, count=4, dx0=2, ang=0.1):
|
||||
if gen is None:
|
||||
b = numpy.array([
|
||||
[0, 0, 0],
|
||||
[1, 0, 0],
|
||||
[1, 0, 1],
|
||||
[0, 0, 1],
|
||||
], dtype=numpy.float64) - [0.5, 0, 0.5]
|
||||
b = meshutil.subdivide_boundary(b)
|
||||
b = meshutil.subdivide_boundary(b)
|
||||
b = meshutil.subdivide_boundary(b)
|
||||
bs = [b]
|
||||
gen = itertools.repeat([b])
|
||||
# Generate 'seed' transformations:
|
||||
xfs = [meshutil.Transform().translate(dx0, 0, 0).rotate([0,1,0], numpy.pi * 2 * i / count)
|
||||
for i in range(count)]
|
||||
# (we'll increment the transforms in xfs as we go)
|
||||
while True:
|
||||
for bs in gen:
|
||||
xfs_new = []
|
||||
bs2 = []
|
||||
for i, xf in enumerate(xfs):
|
||||
# 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:
|
||||
xf2 = xf.rotate([0,1,0], ang)
|
||||
xfs_new.append(xf2)
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user