Featured post

new redirect for blender.org bpy docs.

http://www.blender.org/api/blender_python_api_current/ As of 10/11 november 2015 we can now link to the current api docs and not be worr...

May 06, 2013

developing a script from start to finish

I was asked by a member of the BlenderArtist community to write a script that can intersect all selected edges. So here i'll stick my development notes / code. More code less talk.

p4 The above code is hardly involved, but without it the next part isn't possible. The task is now to go through the remaining combinations -- stored as tuples -- and for every tuple that results in a valid intersection we store the tuple with the coordinate of the intersection. Something like (edge1, edge2, intersection_coordinate).

Then the theoretically easy, but practically more demanding, part is to add extra vertices to the edges that have an intersection. I think this is where I drew a blank last time I thought about this problem.

p5+6


if you are trying to follow along, the scene used to test this looks like this.
It appears that parallel lines can return the tuple (Vector((nan, nan, nan)), Vector((nan, nan, nan))) or None. At this stage of the development the script looks like this (fully commented) and i'm testing with this .blend to debug. It prints out the coordinates of all proper intersections found.

[(1, 2), (1, 10), (1, 11), (2, 10), (2, 11), (10, 11)]
---
(1, 2)  ->  (1, 0, 2, 1)
(1, 10)  ->  (1, 0, 6, 4)
(1, 11)  ->  (1, 0, 12, 10)
(2, 10)  ->  (2, 1, 6, 4)
(2, 11)  ->  (2, 1, 12, 10)
(10, 11)  ->  (6, 4, 12, 10)

> [(1, 10), (1, 11), (2, 10), (2, 11), (10, 11)]
[((1, 10), (Vector((3.1274282932281494, 3.220184564590454, -1.0)), 
            Vector((3.1274282932281494, 3.220184564590454, -1.0)))), 
((1, 11), (Vector((3.027259588241577, 3.220184564590454, -1.0)), 
           Vector((3.027259588241577, 3.220184564590454, -1.0)
)))]
number of intersections: 2
As it turns out, this .blend is not a reasonable representation of a real world example.
The coordinates of the expected intersections will be used to chop each edge. I think recursion would be an elegant solution, but it can be tricky to debug. Perhaps check each found intersection against every selected edge, and create list of tuples (edge_index, intersections_on_this_edge)

, from this list pick one point/vertex of the edge amd arrange the intersections_on_this_edge with respect to that point. Then create a new temporary edge geometry list, then delete all selected edges and build new edges from the temo list -- even if the edge didn't have any intersections ( algorithmically simpler). bam. then select all newly create geometry and remove doubles.

last part

I ended up with this

testing the algorithm

To the best of my knowledge these steps are the core of the algorithm. I have intentionally not implemented the bmesh way of adding geometry to the mesh yet. For now I can focus on trying to break the algorithm. Once I am confident about the accuracy I will refactor.

refactor

after some time, and some testing by several users i'm happy the core algorithm does as intended. Also wrapped some addon boilerplate code around it to turn it into an addon for convenience. Find the addon here ... found a small bug, must deselect edges that aren't intersected by any other edges (or duplicate it)

No comments:

Post a Comment

Please use Blender.StackExchange.com for python scripting questions unrelated to this post.