Convert a mesh into a plane

Hi!

I would like to convert a mesh into a plane. These will be roads from a city.
This:



Not this:

Thanks in advance!
Ana.

Is this a scripting question or are you just wanting to make that?

Yes, is a scripting question.

Yes, is a scripting question. Well, I need to know how to do it too.

There are some ways to do that without python but I don’t like any of them. In my opinion the easiest would be to use a curve and extrude the curve. However, this does not maintain a uniform width so I don’t like it. If you give me a couple days I can write up some code for you

Of course! Any help would be welcome. :slight_smile:

This should be enough to get you started. Essentially the script finds the intersections of lines parallel to the one you traced out and then adds vertices. Use this script with the .blend I attached. In object mode run the script and you will see vertices added where you would need them in edit mode. Currently it only adds them on one side and its not always the same side so you will need to extend it to add on both sides. Ask me any clarifying questions and I can help out.

import bpyfrom mathutils import Vector,geometry


#set road width here
width = 0.2


ob = bpy.data.objects['Plane']
#matrix to convert local vertex coordinates to world coordinates
mat = ob.matrix_world
inv_mat = mat.inverted()


#define list to store vectors from one vert to another (AKA edges)
edge_vectors = []
#add an entry for each vert. Each entry will contain either one or two
#vectors depending on how many edges the vert is connected to
for verts in ob.data.vertices:
    edge_vectors.append([]) 


for edge in ob.data.edges:
    #convert local vertex coordinates to world coordinates
    v0_co = mat * ob.data.vertices[edge.vertices[0]].co
    v1_co = mat * ob.data.vertices[edge.vertices[1]].co    
    v1_v0 = (v1_co-v0_co)
    v0_v1 = (v0_co-v1_co)    
    #append vector and vert index to which vector is pointing
    edge_vectors[edge.vertices[0]].append([v1_v0,edge.vertices[1]])
    edge_vectors[edge.vertices[1]].append([v0_v1,edge.vertices[0]])    


print("--------------------------------------------")
for vert in edge_vectors:
    print(vert)
#print("edge_vectors = ",edge_vectors)
print(edge_vectors[0][0])


vert_idx = 0
for vert in edge_vectors:
    #for verts connected to only one edge    
    #NEEDS TO BE EXPANDED TO INCLUDE ALL VERTICES#
    if len(vert)==1:
        print("vert_idx = ",vert_idx)
        #find vector perpendicular to edge        
        vec_perp1 = Vector((-vert[0][0][1],vert[0][0][0],vert[0][0][2]))
        #find point along this vector that is t distance away
        #where t is the road width 
        vec_perp1_norm = vec_perp1.normalized()
        vec_perp1_len = vec_perp1_norm * width
        print("vec_perp1_len = ",vec_perp1_len)
        #get two points on the line originating from this point and 
        #parallel to the edge
        road_edge_pt1 = (mat * ob.data.vertices[vert_idx].co) + vec_perp1_len
        print("road_edge_pt1 = ",road_edge_pt1)
        ob.data.vertices.add(1)
        #must use inv_mat to convert from global back to local coords
        ob.data.vertices[-1].co = inv_mat*road_edge_pt1
        road_edge_pt2 = road_edge_pt1 + vert[0][0]
        
        #find the two vectors(edges) of the connected vertex
        connected_vert_idx = vert[0][1]
        connected_vert_edge1 = edge_vectors[connected_vert_idx][0][0].normalized()
        connected_vert_edge2 = edge_vectors[connected_vert_idx][1][0].normalized()         
        connected_vert_vec = (connected_vert_edge1 + connected_vert_edge2).normalized() 
        connected_vert_pos = (mat * ob.data.vertices[connected_vert_idx].co)
        #prob with adding here
        connected_vert_pt2 = connected_vert_pos + connected_vert_vec
        
        print("road_edge_pt1 = ",road_edge_pt1)
        print("road_edge_pt2 = ",road_edge_pt2)
        print("connected_vert_pos = ",connected_vert_pos)
        print("connected_vert_pt2 = ",connected_vert_pt2) 
        intersection = geometry.intersect_line_line(road_edge_pt1, road_edge_pt2, connected_vert_pos, connected_vert_pt2)
        ob.data.vertices.add(1)
        
        ob.data.vertices[-1].co = inv_mat*intersection[0]
        print("+++++++++")
        print("intersection = ", intersection)
        print("+++++++++")  
    vert_idx+=1           
    bpy.context.scene.update()
'''        
    else:
        vec_perp1 = Vector((-vert[0][1],vert[0][0],vert[0][2]))
        vec_perp2 = -vec_perp1
'''


    
     



Attachments

Road_Script.blend (466 KB)

Wow, thank you very much! This is what I was looking for.
I’ll show you the final results. :slight_smile:

Use 2d curve with bevel object (like straight line) and it will maintain uniform width.

Good point, JuhaW. That does indeed maintain a uniform width. Is there a way to make this flat? I can’t find a setting that will do this

Yes, bevel object horizontal straight line, X axis.

Attachments


Nice! I didn’t know about that feature. Is it possible to make a four way intersection by this method? When I tried to extrude in the middle of a curve it didn’t work.

No, curves do not have that feature. You can have many curves in one curve object but still one curve point can connect to only two points.

Gotcha thats a bummer. But still helpful to know