0
$\begingroup$

i created this script because i have a blender file that has alot of cubes with unnecessary faces. Most of them have 10 faces so i made this script to replace the cubes with normal cubes from the add mesh menu that only has 6 faces by getting the old cube locations and dimensions and rotation then saving them to text files then deleting the old cube then setting the old cube data to the new one

The script is working fine when i replace the normal cube with another from add mesh menu but when i test this with cubes that have 10 faces i get a bigger cube and little different rotation and location but i have the right data in the transform menu

my code

import bpy
import re
file_data = [] # create an empty list
animation_data = {} # create an empty dictionary
thexdimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/thexdimensionsline","w")
theydimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/theydimensionsline","w")
thezdimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/thezdimensionsline","w")
thexlocationline = open("/home/my new blender addon/convert to lowpoly cubes/thexlocationlinefil","w")
theylocationline = open("/home/my new blender addon/convert to lowpoly cubes/theylocationlinefile","w")
thezlocationline = open("/home/my new blender addon/convert to lowpoly cubes/thezlocationfile","w")
#readdddddddd
thexrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/thexrotaionlinefil","w")
theyrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/theyrotationlinefile","w")
thezrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/thezrotationfile","w")
class DissolvePanel(bpy.types.Panel):
    bl_label = "lowpoly cube changer"
    bl_idname = "OBJECT_PT_hello"
    bl_space_type = 'VIEW_3D'
    bl_region_type = 'TOOLS'
    bpy.ops.object.origin_set(type='ORIGIN_GEOMETRY') 
    thexdimensionsline.write(str(bpy.context.object.dimensions[0])) 
    thexdimensionsline.close()
    theydimensionsline.write(str(bpy.context.object.dimensions[1])) 
    theydimensionsline.close()
    thezdimensionsline.write(str(bpy.context.object.dimensions[2])) 
    thezdimensionsline.close()

    thexlocationline.write(str(bpy.context.object.location[0])) 
    thexlocationline.close()
    theylocationline.write(str(bpy.context.object.location[1])) 
    theylocationline.close()
    thezlocationline.write(str(bpy.context.object.location[2])) 
    thezlocationline.close()    

    thexrotaionline.write(str(bpy.context.object.rotation_euler[0])) 
    thexrotaionline.close()
    theyrotaionline.write(str(bpy.context.object.rotation_euler[1])) 
    theyrotaionline.close()
    thezrotaionline.write(str(bpy.context.object.rotation_euler[2])) 
    thezrotaionline.close() 


    bpy.ops.object.delete(use_global=False)
    bpy.ops.mesh.primitive_cube_add(location=(2,0,0))
    thexdimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/thexdimensionsline","r")
    theydimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/theydimensionsline","r")
    thezdimensionsline = open("/home/my new blender addon/convert to lowpoly cubes/thezdimensionsline","r")
    thexlocationline = open("/home/my new blender addon/convert to lowpoly cubes/thexlocationlinefil","r")
    theylocationline = open("/home/my new blender addon/convert to lowpoly cubes/theylocationlinefile","r")
    thezlocationline = open("/home/my new blender addon/convert to lowpoly cubes/thezlocationfile","r")

    thexrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/thexrotaionlinefil","r")
    theyrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/theyrotationlinefile","r")
    thezrotaionline = open("/home/my new blender addon/convert to lowpoly cubes/thezrotationfile","r")

    actor_name = bpy.context.scene.objects.active.name
    thexdim = thexdimensionsline.readline()
    theydim = theydimensionsline.readline()
    thezdim = thezdimensionsline.readline()

    print(thexdim,theydim,thezdim)

    bpy.data.objects[actor_name].dimensions = (float(thexdim),float(theydim),float(thezdim))
    thexloco = thexlocationline.readline()
    theyloco = theylocationline.readline()
    thezloco= thezlocationline.readline()

    print(thexloco,theyloco,thezloco)

    bpy.data.objects[actor_name].location = (float(thexloco),float(theyloco),float(thezloco))


    thexroteto = thexrotaionline.readline()
    theyroteto = theyrotaionline.readline()
    thezroteto = thezrotaionline.readline()

    print(thexdim,theydim,thezdim)

    bpy.data.objects[actor_name].rotation_euler = (float(thexroteto),float(theyroteto),float(thezroteto))


    #print("afterbla",thexdim,theydim,thezdim)
    def draw(self, context):


        layout = self.layout
        col = layout.column(align=True)
        row = col.row(align=True)

        row.operator("mesh.subdivide", text = "Dissolve Verts")
        bpy.context.scene.update() 
        # invoke custom operator
        # row.operator("object.simple_operator" , text = "All")

def register():
    bpy.utils.register_class(DissolvePanel)

def unregister():
    bpy.utils.unregister_class(DissolvePanel)

if __name__ == "__main__":
    register()

There are two big cubes in my blend file, the blue cube, the cube with ten faces and the red cube, just a normal cube i added from mesh menu and created the small cubes around them. They are just to make you notice the dimensions for the cube that are created after running the script with the cube that has 10 faces but if you execute the script with the red cube the cube replacement will work just fine and the new cube will take the right dimensions successfully

$\endgroup$

1 Answer 1

1
$\begingroup$

Bmesh approach.

Using bmesh,

  1. Make a new bmesh using the vert coords of context object's mesh
  2. Make a convex hull from vert coordinates
  3. Find any diagonals (edge face angle is zero) and dissolve.
  4. Replace original with the new mesh.

The transformations will be dealt with because we are using the local vertex coordiantes of the original, and keeping the object's transformations. Similarly for materials.

Test script. Converts all selected mesh objects.

import bpy
import bmesh

context = bpy.context

# create a new bmesh
bm = bmesh.new()
for ob in context.selected_objects:
    if ob.type != 'MESH':
        continue
    me = ob.data # old mesh
    # add the verts of original
    for v in me.vertices:
        bm.verts.new(v.co)
    # convex hull
    bmesh.ops.convex_hull(bm, input=bm.verts)
    # update normals (for edge angle calc... may not need)
    bm.normal_update()
    # find diagonals
    diags = [e for e in bm.edges
            if e.calc_face_angle() < 0.0001] # zero face angle
    # dissolve diagonals
    bmesh.ops.dissolve_edges(bm, edges=diags)
    bm.to_mesh(me)
    bm.clear() # clear the mesh if looping on obs.
    me.update()
bm.free()

Edit mode result of running script on blue cube enter image description here

Possibly the major issue you were having was that the blue box has had rotation applied. The object dimensions are the dimensions of its bounding box. Image below shows the bounding box of your blue box, and how it "skews" its box dimensions.

enter image description here

$\endgroup$
1
  • 1
    $\begingroup$ @shar edited code in answer to loop thru selected objects. $\endgroup$
    – batFINGER
    Feb 19, 2018 at 12:31

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .