0
$\begingroup$

This question has been asked already, but no solutions were proposed.

I have a huge set of imported tree objects, each as a separate data block, each with scale applied. I want to link them all into a single data block, so I can later quickly swap all geometries with my own model. But I also want to keep their original dimensions that are different for each object. Obviously, all linked objects will inherit dimensions of the active so I'll lose the original sizes.

I have an idea of how that could work, but I can't python, and it's probably the only way to get there:

  1. duplicate all objects without linking,
  2. link all copies to my reference object,
  3. for each object with ".001" suffix in name, find its "sibling" with the same name but no suffix, and copy its dimensions to the "object.001" dimensions or scale (the result should be the same either way, and maybe overriding scale is easier than overriding dimensions, I don't know).

Also, maybe instead of comparing object names, the script could find each copied object's "sibling" that has the same coordinates, since I won't be moving the copies and no trees share the same coordinates. I don't know which approach seems easier.

Muchas gracias if someone could figure this out.

Example Blend:

https://drive.google.com/file/d/1TPgcHIMWkhO8Jz3joZBFFyyWmOPeXM25/view?usp=sharing

$\endgroup$

1 Answer 1

2
$\begingroup$

1. Generate a scene based on your description

import bpy

trees = []

bpy.ops.mesh.primitive_cone_add(radius1=1, radius2=0, depth=2)
trees.append(bpy.context.object)
bpy.ops.mesh.primitive_cone_add(radius1=2, radius2=0, depth=4)
trees.append(bpy.context.object)
bpy.ops.mesh.primitive_cone_add(radius1=3, radius2=0, depth=6)
trees.append(bpy.context.object)

trees[0].location = 1, 1, 1
trees[1].location = 4, 4, 4
trees[2].location = -6, -2, -2
trees[2].rotation_euler[1] += 0.5

enter image description here

2. Select them and make one active

enter image description here

3. Run script, the meshes will be assigned to the active object mesh

import bpy

def calc_max_distance(obj): # object scale must 1, 1, 1
    return max(v.co.length for v in obj.data.vertices)

objects = bpy.context.selected_objects

ref = bpy.context.object
mesh = ref.data
ref_dis = calc_max_distance(ref)
if ref_dis == 0.0: zero_not_working


for ob in objects:
    fac = calc_max_distance(ob) / ref_dis

    ob.data = mesh
    ob.scale = fac, fac, fac
    
# clear unused data-block
meshes = bpy.data.meshes
for mesh in meshes:
    if mesh.users == 0: meshes.remove(mesh)
$\endgroup$
7
  • $\begingroup$ Thanks for the script. I see you approached it differently, but it doesn't work for me. After running your script, trees' dimensions change. I added a Blend to my question, with a small part of the model. $\endgroup$
    – michalpe
    Mar 26 at 13:43
  • $\begingroup$ Am I doing something wrong? Your suggested workflow skips the duplication of objects, right? $\endgroup$
    – michalpe
    Mar 26 at 13:44
  • $\begingroup$ @michalpe The old one doesn't work because the origin point of objects in your file. The new one should work when object's origin point are relatively similar. $\endgroup$
    – X Y
    Mar 26 at 15:46
  • $\begingroup$ There is no need to copy the objects because one object stores a mesh and we can then change all objects' meshes to the same mesh. $\endgroup$
    – X Y
    Mar 26 at 15:50
  • $\begingroup$ Fantastic! It works now. A thousand thanks to you. Out of curiosity, do you think my approach would also be doable, easier or harder to code than yours? Mine seems rather straightforward, maybe even primitive, but maybe you wanted to make it better and avoid the need to perform extra manual steps. Cause yours works out of the box. $\endgroup$
    – michalpe
    Mar 26 at 16:11

You must log in to answer this question.

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