Building A Weave Along A Surface

Why Am I Here: First and foremost, I’m here because I’ve noticed that when I write down my problems, I tend to solve them. Maybe it grants my mind the chance to step away from the problem far enough that I can finally see the forest through the trees? I don’t know, but I do know this code smells horrid - and I know I might be able to learn a lot by posting it. A lot of people will likely look at it and just ask “Why?” And that, I think, might be a good thing as the issues that I imagine to be wrong with this code, should also be readily solvable with some basic debugging, but as I’m limited to print statements nested in if statements about now, my productivity as a developer has come to a crawl (which is bad because I feel like I should be able to code things so much bigger than this). I might also be wasting lines with code that could be written in only a few at places. Python is rather flexible, so I might be ignoring many of it’s wonderful traits only making my own life more difficult.

So outside of posting this to clarify my goals for me… What’s the community accepted standard for doing debugging of this kinda stuff in Blender?

What I Am Trying to Do: Create a weave structure that bends around any arbitrary shape by feeding in that arbitrary shape and the basic structure of the weave to be repeated over and over again. The purpose of this is to provide high quality imitations of various weaves used in fabrics and meshes so that I can then bake them into lower polygonal models as textures.

What I’ve Gotten So Far: I succeeded in creating the basic weave in 2 dimensions. In fact, I probably could have achieved this result with an array modifier, but I did succeed in keeping all of my ‘threads’ as singular Bezier Curves and more importantly I have the source and understand what I did, so I can modify to fit my needs better (useful later on).

[ATTACH=CONFIG]466966[/ATTACH]
EXAMPLE 1: A nice weave done in two dimensions.

Getting results like the one in example 1, I tried to use the shrink-wrap modifier to bend my plane-based object around other topologies, but shrink-wrap would have none of it, and the lattice deformation modifier stretched my mesh out too unevenly and was too choppy CPU-wise for this many vertices (quad core 4.0 ghz). So I decided, “Why not just code in the deformation while we build our mesh?”

To do this, I worked out the following strategy…

Basic Strategy

  • Presuming that I have a triangular mesh active object and the rest of my selection is a set of base bezier curves that I am repeating…
  • As I repeatedly duplicate the original set of vertices from the first bezier curve offset further down the line, I should find the closest point on the active object mesh using the following strategy…
  • Create an orthogonal line between the plane created by each triangular face and the origin for the new chunk of bezier element.
  • Using this, determine if the line crosses the plane inside of the triange or outside the triangle. If it falls outside, rotate the plane into the x-y plane and find the distance between each of the edges of the triangle face and the intersection point, adding this to the total distance. Otherwise, just use the distance to the plane.
  • Find the lowest of the values accumulated above and we should have a good measure of the closest face on the mesh to the chunk of bezier curves being created.
  • The 2-D rotation matrix that rotated that mesh into the x-y axis, has an inverse that will rotate our 2-D plane bezier curve into the plane of that triangle. Do this for the closest plane to all of our points in the bezier curve.
  • Use the rotated ending point of each chunk as the origin to start creating the new chunk except for new lines (which have no preceding chunk) which use the top-left point of the segment below it and the first one, which we presume to have itself as a starting point.

Retrofitting the original code was non-trivial, and the unfortunately the algorithm only seems to work for the first ‘chunk’ on the first ‘row’. Like this…

[ATTACH=CONFIG]466967[/ATTACH]
EXAMPLE 2: Trying this out on my dev-topology. Well, it worked the first time…

What I Think Is Going Wrong: After looking around for a while, what I think I have are two seperate contributing issues.

The first is that my code is getting a bad ‘closest plane’ value. This causes each ‘chunk’ after the first plane to rotate to the original chunks orientation, the code presumes that this plane IS the closest planet every time, so it never ‘bends’ around the edges.

Second, I think my offsets are off for new lines, somehow I’m not getting the ‘upper right hand corner’ value for each section of thread and they’re instead just lining up one after another behind the original, slowly moving to the side. As this is all handled on that ‘first chunk’ that’s where things are going awry.

The Code

I should also post the code - if only to have a place to see my sins unfolded before me.

I’ve posted it as a gist to avoid character limitations of forum posts: Python Code Gist