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.
-
$\begingroup$ What file format is your original data in? Is it possible you could bring it into Inkscape, set the stroke width you want, convert strokes to paths, then import the .svg into Blender? (Just thinking of possible things to try.) $\endgroup$– MentalistMar 14, 2018 at 18:45
-
$\begingroup$ @Mentalist I'm sure I can remember an answer using svg to convert osm roads like in sample file above. Danged if I can find it. $\endgroup$– batFINGERMar 14, 2018 at 19:30
-
$\begingroup$ @Mentalist, as batFINGER noticed right, the source data is in osm file. I use "Import OpenStreetMap (.osm)" add-on by Vladimir Elistratov to import it. Yes, I can hack the importer to export it to any vector format. Or I can export already imported to Blender mesh to Inscape. I have thought about it too. But it's strange to have no such ability in the modelling tool like Blender. $\endgroup$– MechanicMar 14, 2018 at 19:51
-
$\begingroup$ I agree that a tool for adding thickness to edges should be included as a standard feature. As for your case, I think batFINGER just nailed it. :-) $\endgroup$– MentalistMar 14, 2018 at 20:18
-
1$\begingroup$ @Mentalist nicer version here $\endgroup$– batFINGERMar 21, 2018 at 13:33
3 Answers
BMesh Approach
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.
-
$\begingroup$ Nice!!! I like how you happened to have the perfect script just lying around waiting for this question to be asked. That's next-level. lol $\endgroup$ Mar 14, 2018 at 20:11
-
1
-
$\begingroup$ This is the kind of thing that reminds me to keep on learning Python. $\endgroup$ Mar 14, 2018 at 20:22
-
1$\begingroup$ @batFINGER, Excellent! Thank you! That's the best result so far. Marking the answer as the answer. :-) And also, thanks to all participants! $\endgroup$– MechanicMar 14, 2018 at 20:36
-
1$\begingroup$ OSM import into Blender? That's a great idea. Is it on Github or so? $\endgroup$ Mar 14, 2018 at 23:14
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
-
$\begingroup$ Thanks! It looks like a solution. Sadly, I use Blender 2.76 (win XP) and I still cannot find " Edit Tools 2" as a separate add-on. But if it really does the trick, the problem is solved. Can you show, how it handles tree-like edges (where the edge splits)? It looks nice, but just to be sure, before possibly trying to adapt the add-on. $\endgroup$– MechanicMar 14, 2018 at 16:58
-
$\begingroup$ Your answer got me curious and I tried this out. Unfortunately it seems the add-on can't handle a fork in the road. It gives an error: "Overlap detected. Select non-overlapping edge loops" ...too bad, since OP wants to create roads. $\endgroup$ Mar 14, 2018 at 18:07
-
$\begingroup$ Sad to hear that. @Mentalist, thank you for your test. It saves time not to fiddle with the add-on source (i've found it on github (sobotka/blender-addons/tree/master/mesh_extra_tools)). Now there are still two possible ways: external software (Inscape), or my own script for blender. $\endgroup$– MechanicMar 14, 2018 at 19:58
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.
NOTE:
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).
-
$\begingroup$ It sounds good, but it's not the case. I already have a wire geometry (vertices and edges). And even if I use the Knife Project tool, it doesn't do well. $\endgroup$– MechanicMar 14, 2018 at 14:33
-
1$\begingroup$ Could you develop ? Where is the problem ? $\endgroup$ Mar 14, 2018 at 15:00
-
2$\begingroup$ You can still use this method if you use knife project from your original input onto a plane. This is a pretty good answer IMHO. $\endgroup$ Mar 14, 2018 at 15:59
-
3
-
1$\begingroup$ Update: If you Apply the Skin Modifier first, then Scale flat on Z and Remove Doubles again, you can select one of the rungs and use Select Similar > Length to get the others. From there, Dissolve Edges. It's not perfect (some intersections end up too wide or too narrow), but it's the most usable solution I've been able to come up with so far. $\endgroup$ Mar 14, 2018 at 19:55