From 4a4f5a0e508ae536780d2dbf56d6d9a329b71f4e Mon Sep 17 00:00:00 2001 From: Chris Hodapp Date: Sat, 14 Dec 2019 05:48:33 +0100 Subject: [PATCH] Finally made some 'transition cage' nonsense --- README.md | 17 +++++++++++++++-- cage.py | 20 ++++++++++++++++++++ 2 files changed, 35 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 476a03b..aa44568 100644 --- a/README.md +++ b/README.md @@ -9,11 +9,12 @@ not sufficient that the subdivided edges both lie incident on some other edge and cover it completely. You must subdivide that larger edge, and thus the triangle it lies on.) - - See line 97 of cage.py, and then 169. + - See cage.py and CageGen.to_mesh - CageFork may need to supply some 'opening' cage that I use as a basis for how I subdivide a 'closing' cage. If I subdivide the closing cage, then I must triangulate *after*, not before. - - classify_overlap tells what's needed, but I need to *use* it + - classify_overlap might be unnecessary, but its classification may + have the right idea. - https://en.wikipedia.org/wiki/Polygon_triangulation - do this to fix my wave example! - http://www.polygontriangulation.com/2018/07/triangulation-algorithm.html @@ -71,3 +72,15 @@ ## ???? - Embed this in Blender? +## Future thoughts + +- What if I had a function that could generate a Cage as if + from a parametric formula and smoothly vary its orientation? + My existing tools could easily turn this to a mesh. If I could vary + the detail of the Cage itself (if needed), then I could also + generate a mesh at an arbitrary level of detail simply by sampling at + finer and finer points on the parameter space. (This might also tie + into the Parallel Transport work.) +- What are the limitations of using Cages? +- Current system is very "generative". Could I do basically L-system + if I have rules for how a much is *refined*? What about IFS? diff --git a/cage.py b/cage.py index c692e5c..5b273c2 100644 --- a/cage.py +++ b/cage.py @@ -172,6 +172,24 @@ class CageFork(object): self.edges = edges def is_fork(self): return True + def transition_from(self, cage): + """Generate a transitional mesh to adapt the given starting Cage""" + vs = numpy.concatenate([cage.verts, self.verts]) + # Indices 0...offset-1 are from cage, rest are from self.verts + offset = cage.verts.shape[0] + # We have one face for total sub-elements in self.edges: + count = sum([len(e) for e in self.edges]) + fs = numpy.zeros((count, 3), dtype=int) + face_idx = 0 + for j, adjs in enumerate(self.edges): + for k, adj in enumerate(adjs[:-1]): + adj_next = adjs[(k + 1) % len(adjs)] + # Proceed in direction of cage.verts: + fs[face_idx] = [j, offset + adj_next, offset + adj] + face_idx += 1 + fs[face_idx] = [j, (j + 1) % len(cage.verts), offset + adjs[-1]] + face_idx += 1 + return meshutil.FaceVertexMesh(vs, fs) class CageGen(object): """A generator, finite or infinite, that produces objects of type Cage. @@ -209,6 +227,8 @@ class CageGen(object): # If it's a fork, then recursively generate all the geometry # from them, depth-first: if cage_cur.is_fork(): + # First, transition the cage properly: + # TODO: Clean up these recursive calls; parameters are ugly. # Some of them also make no sense in certain combinations # (e.g. loop with fork)