Is there a way to make some "2D solidify" from edges to faces. (It's about creating roads from GIS data). I've tried Skin modifier, converting to curves with depth and back to mesh, but all the methods resulted in a dirty mesh with lots of intersections and bad geometry. The problem seems to be that simple and straightforward that it simply must have a simple way to solve. But I don't see it. Please, point it out.
Seems many moons ago now, I was dabbling with writing an OSM importer and came up with this script for roads. Basically it looks for intersections and creates an ngon intersection, then either fills from the intersection to terminus, or half way to next intersection. Designed to run on a mesh that is on the XY plane.
It builds the mesh in object mode over the old mesh. The old mesh is selected in edit mode (the middle of the road) , and hence can be removed easily.
To run on your test file I selected all the road meshes, joined and removed doubles before running script. It took a while to grind out, but came out with a reasonable result.
To run select the road mesh in object mode, and run script. Edit the road width value to suit.
import bpy import bmesh from mathutils import Vector road_width = 0.2 up = Vector((0, 0, 1)) # z axis north = Vector((0, 1, 0)) # y axis context = bpy.context me = context.object.data bm = bmesh.new() bm.from_mesh(me) #bm = bmesh.from_edit_mesh(me) for v in bm.verts: v.select = True # find all intersections intersections = [v for v in bm.verts if len(v.link_edges) > 1] for iv in intersections: iv.select = True iverts =  for r in iv.link_edges: ov = r.other_vert(iv) dir = (ov.co - iv.co).normalized() v = iv.co + road_width * dir xdir = up.cross(dir) v1 = bm.verts.new(v + road_width / 2 * xdir) v2 = bm.verts.new(v - road_width / 2 * xdir) iverts.extend([v1, v2]) e = bm.edges.new([v1, v2]) ret = bmesh.ops.extrude_edge_only( bm, edges=[e]) verts = [e for e in ret["geom"] if isinstance(e, bmesh.types.BMVert)] if len(ov.link_edges) == 1: # terminus dist = ov.co - v else: dist = (iv.co + ov.co) / 2 - v # fill roads bmesh.ops.translate(bm, verts=verts, vec=dist) # make intersection face bm.faces.new(sorted(iverts, key=lambda v: north.xy.angle_signed(v.co.xy - iv.co.xy))) bm.to_mesh(me) me.update()
As previously mentioned the old verts are not removed and are selected and can be removed in edit mode with delete vertices. And then also need to remove doubles.
NOTE: Here is an object mode version. In particular handling of elbows. Select roads to stroke, edit width desired on last line and run script.
The easy way, which requires a bit (just a bit) of manual work:
- Install "Edit Tools 2" and "Loop Tools" addons. They're both available in basic blender 2.79/2.79a, so just find them in addons and enable
- Select your edge, hit W > Edit Tools > Offset Edges (make sure you're in edge editing mode)
- Offset twice, for both positive and negative direction
- Select both of edges you've just created. Hit W > Loop Tools > Bridge
I tried it and this is the method I found :
- Create a plane (or whatever geometry that will contain your model)
- Cut it in the shape you want with the knife tool K (the path you create should intersect with the plane edges, if this is not the case, modify the plane or your path) : you have nice n-gons
- select the shape's vertices and use the bevel tool Ctrl + B
- Delete the unwanted faces
Here's the Knife Project Process On the Attached Blend
It did add a few more cuts, but not enough to be able to quickly Deselect before running the bevel operation.
After the knife project is made: Tab + Tab to persist your vision to what does/doesn't belong and in edit mode deselect (This is a very quick process).