Merge branch 'master' of github.com:Hodapp87/automata_scratch

This commit is contained in:
Chris Hodapp 2021-07-02 18:10:48 -04:00
commit 8457ef2043
3 changed files with 63 additions and 18 deletions

View File

@ -8,6 +8,8 @@
- https://en.wikipedia.org/wiki/Polygon_triangulation - do this to - https://en.wikipedia.org/wiki/Polygon_triangulation - do this to
fix my wave example! fix my wave example!
- http://www.polygontriangulation.com/2018/07/triangulation-algorithm.html - http://www.polygontriangulation.com/2018/07/triangulation-algorithm.html
- Clean up examples.ram_horn_branch(). The way I clean it up might
help inform some cleaner designs.
- I really need to standardize some of the behavior of fundamental - I really need to standardize some of the behavior of fundamental
operations (with regard to things like sizes they generate). This 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 is behavior that, if it changes, will change a lot of things that I'm
@ -58,6 +60,7 @@
identical except that it is higher-resolution? identical except that it is higher-resolution?
- Use mixins to extend 3D transformations to things (matrices, - Use mixins to extend 3D transformations to things (matrices,
cages, meshes, existing transformations) cages, meshes, existing transformations)
- I can transform a Cage. Why not a CageGen?
## ???? ## ????
- Embed this in Blender? - Embed this in Blender?
@ -75,3 +78,7 @@
- Current system is very "generative". Could I do basically L-system - Current system is very "generative". Could I do basically L-system
if I have rules for how a much is *refined*? What about IFS? if I have rules for how a much is *refined*? What about IFS?
- Do this in Rust once I understand WTF I am doing - Do this in Rust once I understand WTF I am doing
## Other thoughts
- Why do I never use the term "extruding" to describe what I'm doing?

14
cage.py
View File

@ -67,6 +67,20 @@ class Cage(object):
trans_verts[2*i+1] = m trans_verts[2*i+1] = m
trans_edges = [[7, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7]] trans_edges = [[7, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7]]
return cages, trans_verts, trans_edges return cages, trans_verts, trans_edges
def subdivide_x_deprecated(self):
mids = (self.verts + numpy.roll(self.verts, -1, axis=0)) / 2
centroid = numpy.mean(self.verts, axis=0)
arrs = [
[self.verts[0,:], mids[0,:], mids[2,:], self.verts[3,:]],
[mids[0,:], self.verts[1,:], self.verts[2,:], mids[2,:]],
]
cages = [Cage(numpy.array(a), self.splits) for a in arrs]
trans_verts = numpy.zeros((2*len(self.verts),3), dtype=self.verts.dtype)
for i,(v,m) in enumerate(zip(self.verts, mids)):
trans_verts[2*i] = v
trans_verts[2*i+1] = m
trans_edges = [[7, 0, 1], [1, 2, 3], [3, 4, 5], [5, 6, 7]]
return cages, trans_verts, trans_edges
def is_fork(self): def is_fork(self):
return False return False
def transform(self, xform): def transform(self, xform):

View File

@ -2,6 +2,7 @@
import itertools import itertools
import math
import numpy import numpy
import stl.mesh import stl.mesh
import trimesh import trimesh
@ -148,22 +149,13 @@ def ram_horn_branch():
for i in range(count): for i in range(count):
if i > 0: if i > 0:
c = cage1.transform(xf) c = cage1.transform(xf)
#print("DEBUG: recur, i={}, yield {}".format(i, c.verts))
yield c yield c
xf0 = xf xf0 = xf
xf = incr.compose(xf) xf = incr.compose(xf)
# .compose(opening_boundary(i))
def xf_sub(i): def xf_sub(i):
# yes, I can do this in a one-liner # (dx,dy) should be normalized, but I reused from something else
# yes, it should be normalized, but I reused from something else dx = 1 if i == 0 or i == 1 else -1
if i == 0: dy = 1 if i == 0 or i == 3 else -1
dx, dy = 1, 1
elif i == 1:
dx, dy = -1, 1
elif i == 2:
dx, dy = -1, -1
elif i == 3:
dx, dy = 1, -1
return meshutil.Transform().translate(0, 0, 0.5).rotate([-dy,dx,0], -numpy.pi/6) return meshutil.Transform().translate(0, 0, 0.5).rotate([-dy,dx,0], -numpy.pi/6)
subdiv, trans_vs, trans_es = cage1.subdivide_deprecated() subdiv, trans_vs, trans_es = cage1.subdivide_deprecated()
gens = [cage.CageGen(itertools.chain( gens = [cage.CageGen(itertools.chain(
@ -172,12 +164,6 @@ def ram_horn_branch():
for i,cage_sub in for i,cage_sub in
enumerate(subdiv)] enumerate(subdiv)]
yield cage.CageFork(gens, xf.apply_to(trans_vs), trans_es) yield cage.CageFork(gens, xf.apply_to(trans_vs), trans_es)
# TODO: The starting cage needs to be one iteration *earlier*, and the
# subdivided cage is fine, but the generators likewise need to start
# one iteration earlier. Look closely in Blender at the mesh,
# specifically just prior to the fork.
#
# xf0.apply_to(trans_vs) is identical to last cage yielded?
cg = cage.CageGen(itertools.chain( cg = cage.CageGen(itertools.chain(
[cage0], [cage0],
recur(meshutil.Transform(), cage0, 8), recur(meshutil.Transform(), cage0, 8),
@ -186,6 +172,43 @@ def ram_horn_branch():
mesh = cg.to_mesh(count=32, close_first=True, close_last=True) mesh = cg.to_mesh(count=32, close_first=True, close_last=True)
return mesh return mesh
def dream_pendant():
center = meshutil.Transform().translate(-0.5, -0.5, 0)
cage0 = cage.Cage.from_arrays([
[0, 0, 0],
[1, 0, 0],
[1, 1, 0],
[0, 1, 0],
]).transform(center)
incr = meshutil.Transform() \
.scale(0.95, 1.0, 0.95) \
.rotate([0,1,0], 0.2) \
.translate(0,0,0.9)
def recur(xf, cage1, count):
for i in range(count):
if i > 0:
c = cage1.transform(xf)
yield c
xf0 = xf
xf = incr.compose(xf)
def xf_rot(a):
return meshutil.Transform().rotate([0,1,0], a)
subdiv, trans_vs, trans_es = cage1.subdivide_x_deprecated()
gens = [cage.CageGen(itertools.chain(
[cage_sub.transform(xf)],
recur(xf_rot(ang).compose(xf), cage_sub, 5)))
for cage_sub,ang in
zip(subdiv, [-0.2, 0.7])]
yield cage.CageFork(gens, xf.apply_to(trans_vs), trans_es)
cg = cage.CageGen(itertools.chain(
[cage0],
recur(meshutil.Transform(), cage0, 3),
))
# TODO: if this is just a list it seems silly to require itertools
mesh1 = cg.to_mesh(count=32, close_first=False, close_last=True)
mesh2 = mesh1.transform(meshutil.Transform().rotate([0,1,0], math.pi))
return meshutil.FaceVertexMesh.concat_many([mesh1, mesh2])
def branch_test(): def branch_test():
b0 = numpy.array([ b0 = numpy.array([
[0, 0, 0], [0, 0, 0],
@ -356,6 +379,7 @@ def main():
# TODO: Fix # TODO: Fix
#ram_horn3: "ramhorn3.stl", #ram_horn3: "ramhorn3.stl",
ram_horn_branch: "ramhorn_branch.stl", ram_horn_branch: "ramhorn_branch.stl",
dream_pendant: "dream_pendant.stl",
twist: "twist.stl", twist: "twist.stl",
twist_nonlinear: "twist_nonlinear.stl", twist_nonlinear: "twist_nonlinear.stl",
twist_from_gen: "twist_from_gen.stl", twist_from_gen: "twist_from_gen.stl",