0
$\begingroup$

I'm to test a programming idea I have in Blender. I need to combine multiple cubes. I want to create lots of duplicate cubes, and then delete all faces that are doubled.

I know there is the remove double faces, but that doesn't do what I want. It leaves a single face where two faces were.

Blender two cubes In this example, I want to join the two cubes, but where they join, I want both faces deleted since they can't be seen.

$\endgroup$
  • $\begingroup$ I marked the answer on this question as complete, since it solves my initial question and provides some information at a basic level. Since it didn't solve my problem yet, I reposted a new question which adds additional info about this question. $\endgroup$ – Lazetti May 21 at 17:57
1
$\begingroup$
  • 'Remove Doubles' (that refers to vertices, actually, not faces) as you already have..
  • In the header Select menu: Select All by Trait > Interior Faces
  • X > Delete Faces
$\endgroup$
  • $\begingroup$ .. but maybe expand on your programming idea.. there may be other approaches.. $\endgroup$ – Robin Betts May 15 at 23:52
  • $\begingroup$ That works pretty close for what I wanted, and it answers the question I posed. I'm going to open a new question linking back to this for the full question. I'm trying to create a voxel map like what is done with Minecraft. In a voxel-map like that, faces are only drawn if they are exposed to a non-solid block. I'm trying to make a model based on blocks and then delete the duplicate faces because that's the same procedure. The answer works, but when I try to scale it up, it doesn't. $\endgroup$ – Lazetti May 21 at 17:32
1
$\begingroup$

BMesh script.

enter image description here

Wrote the script for another robloxic type question, buggered if I can find it maybe didn't post an answer. Also note script is for blender 2.8, whereas your question image is clearly 2.79. If you are just starting out scripting in blender, my advice is to start using 2.8

Any way, here is a script to run in object mode with all the cubes you want to join selected.

Loads all selected objects into a global bmesh. Make sure only cubes are selected, haven't tested for it as script expects selected objects to only be 8 vertex cubes. Also added commented out code to select cubes based on their name starting with "Cube"

Tests if two faces have same center using a bvh tree loaded with the bmesh. The find_nearest_range method finds each face twice, hence 4 matches being a pair, and 2 matches being no match

A further more robust test would be checking opposite facing normals, and to be sure to be sure the vert coordinates of the face themselves.

If remove_originals is set to True then the original cube objects are removed.

If remove_doubles is set to True it will remove doubles.

import bpy
import bmesh
from mathutils import Vector
from mathutils.bvhtree import BVHTree

remove_originals = True
remove_doubles = True

context = bpy.context
scene = context.scene
# by selection
cubes = context.selected_objects
# by name
#cubes = [o for o in scene.objects if o.name.startswith("Cube")]

bm = bmesh.new()
for o in cubes:
    bm.from_mesh(o.data)
    bmesh.ops.transform(bm,
            verts=bm.verts[-8:],
            matrix=o.matrix_world
            )
if remove_originals:
    bpy.ops.object.delete()

bvhtree = BVHTree().FromBMesh(bm, epsilon=1e-7)
faces = bm.faces[:]

remove = list()
while faces:        
    f = faces.pop()        
    pair = bvhtree.find_nearest_range(f.calc_center_median(), 1e-4)
    if len(pair) > 2:
        # mark face for removal
        remove.extend(p[2] for p in pair)

bm.faces.ensure_lookup_table()
bmesh.ops.delete(bm,
        geom=[bm.faces[i] for i in set(remove)],
        context='FACES_KEEP_BOUNDARY',
        )
if remove_doubles:
    bmesh.ops.remove_doubles(bm,
            verts=bm.verts,
            dist=1e-7)

me = bpy.data.meshes.new("CubeBoundaryFaces")
bm.to_mesh(me)
ob = bpy.data.objects.new("CubeBoundaryFaces", me)

scene.collection.objects.link(ob)
context.view_layer.objects.active = ob
ob.select_set(True)

Note, would be for quicker, as pointed out by subd guru @RobinBetts, to simply join, remove doubles then remove interior faces, done via a script using the appropriate operators and object mode for them.

Another take would be to use the set of face indices to remove the faces from the original cubes without joining them. Since the compound bmesh faces will be in same order as the originals.

for i in set(remove):
    ob = cubes[i // 6] # 6 faces per cube
    f = ob.data.polygons[i % 6]
$\endgroup$
  • $\begingroup$ I think this answers my question, so +1, but I would like to be able to do it without scripting. $\endgroup$ – Lazetti May 21 at 17:36
0
$\begingroup$

To do that, turn on all vertex visibility,

Select all the Vertex at the point of contact, then look for "Loop Tool" under the editing panel in the "Tool Shelf"

Use either "Bridge" or "Loft" in the "Loop Tool" option.

It will join them together

$\endgroup$

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.