12
$\begingroup$

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. how to go from this to this

$\endgroup$
  • $\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$ – Mentalist Mar 14 '18 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$ – batFINGER Mar 14 '18 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$ – Mechanic Mar 14 '18 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$ – Mentalist Mar 14 '18 at 20:18
  • 1
    $\begingroup$ @Mentalist nicer version here $\endgroup$ – batFINGER Mar 21 '18 at 13:33
10
$\begingroup$

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.

enter image description here

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.

enter image description here

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.

$\endgroup$
  • $\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$ – Mentalist Mar 14 '18 at 20:11
  • 1
    $\begingroup$ @Mentalist Have an OSM importer 50% finished got stuck on roofs. Using PyOsmium $\endgroup$ – batFINGER Mar 14 '18 at 20:17
  • $\begingroup$ This is the kind of thing that reminds me to keep on learning Python. $\endgroup$ – Mentalist Mar 14 '18 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$ – Mechanic Mar 14 '18 at 20:36
  • 1
    $\begingroup$ OSM import into Blender? That's a great idea. Is it on Github or so? $\endgroup$ – Thomas Weller Mar 14 '18 at 23:14
17
$\begingroup$

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) My randomly selected edges. Notice, that edge editing mode is selected
  • Offset twice, for both positive and negative direction Offsetted twice, with width 0.2 and -0.2
  • Select both of edges you've just created. Hit W > Loop Tools > Bridge Here comes the bridge!
$\endgroup$
  • $\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$ – Mechanic Mar 14 '18 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$ – Mentalist Mar 14 '18 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$ – Mechanic Mar 14 '18 at 19:58
10
$\begingroup$

I tried it and this is the method I found :

  1. Create a plane (or whatever geometry that will contain your model)
  2. 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
  3. select the shape's vertices and use the bevel tool Ctrl + B
  4. Delete the unwanted faces

Method


Here's the Knife Project Process On the Attached Blend

enter image description here

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).


$\endgroup$
  • $\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$ – Mechanic Mar 14 '18 at 14:33
  • 1
    $\begingroup$ Could you develop ? Where is the problem ? $\endgroup$ – Papounetman Mar 14 '18 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$ – Rick Riggs Mar 14 '18 at 15:59
  • 3
    $\begingroup$ How to use knife project $\endgroup$ – Rick Riggs Mar 14 '18 at 16:06
  • 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$ – Mentalist Mar 14 '18 at 19:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.