How can I merge overlapping faces?

I’ve looked all over the internets now, even looked at Union 2D, but it sadly does not do a good enough job with it in my experience.

What I need is to be able to merge a lot of overlapping roads I imported through osm to Blender into one continous surface. Going in and do all the junctions and so on manually would take way too much time.

I’ce tried all the stuff inside Blender already and I can’t seem to get anything to work. My most elaborate attempt involved booleans and unions with other objects but it still didn’t work. I am starting to think this could be something for a Python script, or I might just modify the existing Union 2D-one.

Please help me, I’d really like to get something like this done efficiently.

What does the mesh look like? Depending on how close the road edges are to eachother, you might be able to merge them with “remove doubles” if you increase the area.

I’ll get some screenshots ready.

A blend file with a sample would be a better choice.

I’ll get both ready. It’s been a rather busy week, lol.

Ok, so I have posted it in the relevant thread for Union 2D as well:

Here is what I want:


Here is what it looks like in edit-mode:


And here is how Union 2D does it with extra overlapping faces that have no automated way of getting removed (why isn’t there a clean-up script that can remove/merge double faces, or did I miss something?):


Here is the .blend-file:

http://quakeulf.suxos.org/3d/uniteme.blend

I happen to be working on a modification to the boolean intersect tool that would solve this problem. But unfortunately it is a long way from ready. (The current boolean intersect tool deliberately doesn’t handle cases of coplanar overlaps). It does feel that your best short term bet is to find a 2d vector editor tools that does unions well. I don’t know which 2d vector tools have that capability.

Ok,that’sgenius. I can just use Illustrator, then. I didn’t even think of it. However, in the long-term your tool is exactly what I need.

I made a PME macro a while back that takes any mesh shape, separates it, applies knife project, rejoins and removes doubles, but you’d need Pie Menu Editor addon to import it and use as a hotkey.

Uploading in case you wanted to have a look at the commands I used for the macro.

knife.zip (546 Bytes)

Interesting, but I still have to select parts manually?

Yes. The macro only performs a set of commands and doesn’t really check for anything. Depending on the complexity of your imported osm it may not be feasible.

Sometimes I wish I knew enough Python to script something like this myself.

Well, I know enough Python but not enough about Blender, lol.

I suspect it will go something like this:

  1. Traverse all vector3 coordinates to find fills.
  2. Check along lines from vector to vector to find overlaps.
  3. Insert new vector3-points at the intersections.
  4. Check which fills are inside other fills.
  5. Remove fills inside fills.
  6. Merge shapes.
  7. Done.

So after looking at the source code for the Union 2D-script it seems it is actually doing something similar to what you have done there.

Observe:

for i in range(len(new_obs)):
            for j in range(len(new_obs)):
                if i!=j:
                    bpy.ops.object.select_all(action='DESELECT')
                    new_obs[j].select=True
                    bpy.context.scene.objects.active=new_obs[i]
                    bpy.ops.object.mode_set(mode = 'EDIT')
<b>                    bpy.ops.mesh.knife_project(cut_through=True)</b>
                    bpy.ops.object.mode_set(mode = 'OBJECT')
        bpy.ops.object.select_all(action='DESELECT')
        for obj in new_obs:
            obj.select=True
        bpy.context.scene.objects.active=ob
        bpy.ops.object.join()

It does a knife-project on the faces, but somehow does not remove internal faces. Below in the code is this:

bmesh.ops.remove_doubles(bm, verts=bm.verts, dist=0.0003)
        if self.flag:
            bmesh.ops.dissolve_limit(bm, angle_limit=0.087, use_dissolve_boundaries=0, verts=bm.verts, edges=bm.edges)

I am thinking that the use_dissolve_boundaries is somehow the clue to get this working, but I need to test a little first. I am no expert on Blender.

Not sure why it uses limited dissolve at all. After using Knife Project operator, the default behavior is to select the cut geometry. At that point, the faces should be outright deleted.

I added an entry to delete after Knife Project and commented out limited dissolve, since it seems to be useless.

Can you try this?

Attachments

boolean_2d_union_no_dissolve_delete_faces.zip (1.83 KB)

Wow, this seems to work, but the performance is still terrible when selecting many places that overlaps. I think it’s the looping that does it. Some operations might be expensive the way they are performed.

I did a little test and got satisfactory results:



I noticed the bad performance, too. I’ll leave the debugging to you :stuck_out_tongue:

So I found that the inner loop is using global instead of local variables, but when I try to make the knife-project into a local variable it crashes the loop. The others seem fine, somehow.

I managed to get slightly better performance by using local variables where I could.

It’s far from perfect, but at least it’s a little bit better than it was, and doesn’t crash Blender as often for me.

Attachments

bewlenyan_2d_yoonyan.zip (1.89 KB)

As a general algorithm something like

  1. Find all overlapping faces
  2. Combine each overlap cluster into one ngon by iterating the outer rim in one direction with always choosing the next edge based on smallest angle

might work