CAD Addon: Edge Tools (blender 2.6x)

Broken link so deleted post.

Bao2, looks like you’ve done a good job! I do request that you use a different name (mesh_parametric_drawing_tool.py or something) for your script and add your name as a co-author. We might think about making a shared library that both our scripts can be clients of so as to reduce duplicate code? what are your thoughts on that?

I would prefer to go that way for at least one reason: I have no need for an extra panel in N to get VTX functionality, and i can imagine plenty of other users would at least like to have that choice too.

It is your script, the GNU thing oblies me to make public any change on it but I am not going to post it in any other place / repository of scripts, so there will no be another version on the web than the one you will be giving us. Don’t put the version on the name of the script because we would end having a lot of scripts doing almost the same instead overwriting the old with the new one.

There was a bug on my modification not working when the object was not in the origin of the world. It seems it is now solved. I changed the link in post 61 but same name.

does your script works only as per view like front side or top ?
or in 3D ?

Thanks

If it don’t works in all type of view then is a bug to report me. But working in perspective instead of orthogonal will give you perspective distorted results. Numpad5 to change to orthogonal view.

In the next version of this script i will be correcting some of the things you mentioned like:

  • id_name using spaces (these are not variables nor functions but strings)
  • author version duplicate (i’m still new to this stuff!)
  • added “(W)” in the location text, seems good.

I have not received many bug reports or feedback about my implementation, but if someone were to ask me about the code you wrote I would not have a fast answer. My suggestion still stands about using my functions by importing them. Maybe we can share a directory inside addons, like a CAD library. So you get to keep your code clean by merely referencing my functions and i get to maintain only the code that i wrote and deal only with potential bugs from that code. Does that sound reasonable? The benefit for users is that they can choose the type of interface changes themselves.

Do the changes you want. No problem for me.
One idea that I think it would be useful: Imagine there is a edge on the mesh with length 2.98 and the user wants it to be length 3.0. Just now there is no a direct way of doing that. It would be great add that option. When the edge grows/shrinks to the desired size it could do in three ways: from center, from the vertex on one side or from the vertex to the other side (this vertex would be the selected one and it would be “pinned” so don’t moves when growing/shrinking the edge). If after some weeks I don’t see that in any script I will code it because I think is necessary.

another option may be for angle

most of time we work with degrees but sometimes you need radians too!

happy 2.5

in themes, 3dview look for Edge Length Text :slight_smile: i didn’t know this until just a few minutes ago

Awesome script zeffii :slight_smile:
I downloaded it a while ago but forgot to comment :wink:

thanks metalliandy! and may you find it useful some day :slight_smile:
ps. if you look at the last 1/4 of the code you’ll see I have a major incentive to refactor.

nice script zeffii, but IMHO it does the operation too inefficient, the biggest concern being that the user has to chose which operation is needed (X,V,T) which python could do for you.

here is my version of your script:


import bpy
from mathutils import Vector
from mathutils.geometry import LineIntersect

def intersect():
    error_margin = 1e-3

    obj = bpy.context.active_object
    if obj.data.total_edge_sel != 2:
        print("more than 2 edges selected")
        return # more than 2 edges selected
    oldMode = obj.mode
    bpy.ops.object.mode_set(mode='OBJECT')
    verts = []
    vertIDs = []
    edges = []
    edgeIDs = []
    i = -1
    # get selected verts
    for e in obj.data.edges:
        i += 1
        if e.select:
            edges.append(e)
            edgeIDs.append(i)
            verts.append(obj.data.vertices[e.vertices[0]].co)
            verts.append(obj.data.vertices[e.vertices[1]].co)
            vertIDs.append(e.vertices[0])
            vertIDs.append(e.vertices[1])
    
    # see if coplanar
    intersections = LineIntersect(verts[0],verts[1],verts[2],verts[3])
    # LineIntersect returns 2 vertices, namely the begin and end of the shortest line between the two edges
    # so if the 4 verts are not coplanar, if you want, you could work with that
    
    if (intersections[1]-intersections[0]).length > error_margin:
        print("edges not coplanar")
        return # not coplanar
    
    intersection = intersections[0]
    vertIDs.append(len(obj.data.vertices))
    
    obj.data.vertices.add(1)
    obj.data.vertices[-1].co = intersection
    obj.data.edges.add(2)
    
    normal = (verts[1]-verts[0]).cross(verts[2]-verts[0])
    perp1 = normal.cross(verts[1]-verts[0]) # line through vert[0] perpendicular to edge 1
    perp2 = normal.cross(verts[3]-verts[2]) # line through vert[2] perpendicular to edge 2
    
    # now we check which situation (X, V T) applies
    # if both of the others verts are on one side of the edge, V intersection
    # this is if the dot product between the perpendicular line and the vertices have the same sign ( +/- )
    
    if (perp1.dot(verts[2]-verts[0]) < 0) == (perp1.dot(verts[3]-verts[0]) < 0):
        # now for the second edge
        if (perp2.dot(verts[0]-verts[2]) < 0) == (perp2.dot(verts[1]-verts[2]) < 0):
            # make V pattern, connect the closest verts to the intersection
            if (verts[0]-intersection).length < (verts[1]-intersection).length:
                obj.data.edges[-2].vertices = [vertIDs[0],vertIDs[4]]
            else:
                obj.data.edges[-2].vertices = [vertIDs[1],vertIDs[4]]
            
            if (verts[2]-intersection).length < (verts[3]-intersection).length:
                obj.data.edges[-1].vertices = [vertIDs[2],vertIDs[4]]
            else:
                obj.data.edges[-1].vertices = [vertIDs[3],vertIDs[4]]
                
        else: # this means T intersection with edge 1 splitting
            # make T pattern, connect the verts of the first edge and the closest vert of the 2nd to the intersection
            obj.data.edges[edgeIDs[0]].vertices = [vertIDs[0],vertIDs[4]]
            obj.data.edges[-2].vertices = [vertIDs[1],vertIDs[4]]
            
            if (verts[2]-intersection).length < (verts[3]-intersection).length:
                obj.data.edges[-1].vertices = [vertIDs[2],vertIDs[4]]
            else:
                obj.data.edges[-1].vertices = [vertIDs[3],vertIDs[4]]
                
    else: # edge 1 goes between the two verts of edge 2
        if (perp2.dot(verts[0]-verts[2]) < 0) == (perp2.dot(verts[1]-verts[2]) < 0):
            # this means T intersection with edge 2 splitting
            # make T pattern connect the verts of the 2nd edge and the closest of the first to the intersection
            if (verts[0]-intersection).length < (verts[1]-intersection).length:
                obj.data.edges[-2].vertices = [vertIDs[0],vertIDs[4]]
            else:
                obj.data.edges[-2].vertices = [vertIDs[1],vertIDs[4]]
            obj.data.edges[edgeIDs[1]].vertices = [vertIDs[2],vertIDs[4]]
            obj.data.edges[-1].vertices = [vertIDs[3],vertIDs[4]]
        else: # this means X intersection 
            # make X pattern , connect the four verts to the intersection  
            obj.data.edges[edgeIDs[0]].vertices = [vertIDs[0],vertIDs[4]]
            obj.data.edges[edgeIDs[1]].vertices = [vertIDs[1],vertIDs[4]]
            obj.data.edges[-2].vertices = [vertIDs[2],vertIDs[4]]
            obj.data.edges[-1].vertices = [vertIDs[3],vertIDs[4]]
            
    obj.data.update()
    bpy.ops.object.mode_set(mode=oldMode)
    
    
if __name__ == "__main__":
    intersect()

past this in the blender text editor and run(Alt-P) it when you’ve selected 2 edges
please dont take this as negative critisism, but rather as a different approach
i always say that blender should do as much for you as possible

keep on scripting

Thanks for the feedback, previous iterations of the script decided what to do with 2 selected edges, the same way your script operates. My code might be a bit verbose… your approach looks quite slick, i’ll have to study my assumptions!

i agree python should do the more time consuming work for us. The current state of the script reflects the level of annoyance i can withstand as a modeler. Already i am satisfied with Edge Tools, but i aim to expand the functionality to be more like AutoCAD _extend _trim. Currently the script is structured to facilitate such extension (and major refactor, optimizations)… if i ever get around to it.

@dreampainter
Yes, very nice your (different) approach … works in 2.56 :wink:

i notice a few bugs now in my code…woah… will have to jump up and down on them in the new year :slight_smile:

Broken link so deleted post.

dreampainters code is an inspiration :slight_smile: (i dont understand most of it, yet) I finally replaced LineLineIntersect with LineIntersect from mathutils.geometry, works better now. maybe next week i will do a full refactor and implement new code.

anyone still using my version should update. (go to the first page)

There have been recent renamings to mathutils functions so expect an update with refactor lateron today. I think perhaps while refactoring i might have obfuscated parts of the code…

looking around for geometry.TriangleNormal now… found it.
http://lists.blender.org/pipermail/bf-blender-cvs/2011-January/033190.html

check first post for update, not a full refactor…yet.

changes what are they for Mathutil ?

when are they going to stop changing this Module
each time it creates major problems with older scripts!

Thanks