This is my first attempt at a relatively complicated Python script. Terrachild was so kind as to help me with a measuring script which I got working. So far so good.
Im getting the correct distance so that works out well.
Instead of the code:
bpy.data.objects['Cube'].location
I would like to substitute ‘Cube’ with something more generic. I dont want to type an enormous list of al the LOD objects in the scene, there has to be a better way.
I intend to use this script to render a forest economicly with the objects near the camera with high detail and the ones far away with less detail. I’m going to create multiple variations of a set of trees, a high rez, medium rez and low rez one.
These objects wil be hidden based on their distance to the camera.
Object.hide
Object.hide_render
If I duplicate the trees to build the forest I would get filenames like “tree_HR.011”, “tree_LR.309”, etc. If I create a forest like that I’ll go crazy typing al the names in the script.
If anyone knows a good way of doing this I would much apriciate it.
for ob in bpy.data.objects:
d = get_distance(cam, ob.location)
if d > 16:
bpy.data.objects[ob.name].hide_render = True
#Or
bpy.data.objects[ob.name].hide = True
Here’s another option that may prove useful.
If the name of all of you tree objects starts with “tree”, like, “tree.001, tree.002” etc. then the added line below:
if ob.name.find("tree") == 0:
will check to see each object’s name starts with “tree”
If it does, then it will do the distance checking, and hiding.
This will let you name your objects, and independently hide or show them by type.
for ob in bpy.data.objects:
if ob.name.find("tree") == 0:
d = get_distance(cam, ob.location)
if d > 16:
bpy.data.objects[ob.name].hide_render = True
#Or
bpy.data.objects[ob.name].hide = True
“myhousetree” will fail this test because the position of the sub-string “tree” will return “7” with “.find”
If the test string is not found then “.find” returns “-1”
If the sub-string is found then “.find” returns the index position counting from “0” from the start of the searched string.
As a result, the code above will only be true for objects whose name begins with “tree”
In addition to the string ‘tree’ or maybe instead, I also plan to evaluate on the string ‘_HR’,‘_MR’ and ‘_LR’ representing; High Resolution, Medium Resolution and Low Resolution. This wil make it easier to add other types of objects other then trees to the LOD system.
HR, LR and MR will need to be evaluated for different distances, for example: HR distance from camera 0 to 50 BU/ or meters MR distance from camera 51 to 100 BU/ or meters LR distance from camera 101 to 500 BU/ or meters OFF distance from camera 501 and greater BU/ or meters
So you would have something like the following: tree_01_HR.001 --> High Resolution tree_01_MR.001 --> Medium Resolution tree_01_LR.001 --> Low Resolution
And you would be able to do the same thing for a ‘shrubbery’ without changing the script: shrubbery_01_HR.012 --> High Resolution shrubbery_01_MR.012 --> Medium Resolution shrubbery_01_LR.012 --> Low Resolution
There’s probably a neater way of writing this but it does what it’s supposed to.
For some reason I couldnt change the following code:
if ob_HR.name.find("HR_")==0
to
if ob_HR.name.find("HR")
Removing ==0 gave an error, I just wanted to search for the string “HR” regardless of its position. I probably was oversimplefying it a bit.
I got it working by changing the names of the LOD object to start with HR_something, MR_something, LR_something, etc.
import bpy
def get_distance(point1, point2):
v = point1-point2
return v.length
cam=bpy.data.objects['Camera'].location
for ob_HR in bpy.data.objects:
if ob_HR.name.find("HR_")==0:
d = get_distance(cam, ob_HR.location)
if d < 15: # _HR Objects 15 BU away and less are visible
bpy.data.objects[ob_HR.name].hide_render = False
bpy.data.objects[ob_HR.name].hide = False
if d > 15: # _HR Objects further then 15 BU away are are hidden
bpy.data.objects[ob_HR.name].hide_render = True
bpy.data.objects[ob_HR.name].hide = True
for ob_MR in bpy.data.objects:
if ob_MR.name.find("MR_")==0:
d = get_distance(cam, ob_MR.location)
if d < 30: # _MR Objects 30 BU away and less are visible
bpy.data.objects[ob_MR.name].hide_render = False
bpy.data.objects[ob_MR.name].hide = False
if d < 15: # _MR Objects 15 BU away and less are hidden
bpy.data.objects[ob_MR.name].hide_render = True
bpy.data.objects[ob_MR.name].hide = True
if d > 30: # _MR Objects further then 30 BU away are are hidden
bpy.data.objects[ob_MR.name].hide_render = True
bpy.data.objects[ob_MR.name].hide = True
for ob_LR in bpy.data.objects:
if ob_LR.name.find("LR_")==0:
d = get_distance(cam, ob_LR.location)
if d < 50: # _LR Objects 50 BU away and less are visible
bpy.data.objects[ob_LR.name].hide_render = False
bpy.data.objects[ob_LR.name].hide = False
if d < 30: # _LR Objects 30 BU away and less are hidden
bpy.data.objects[ob_LR.name].hide_render = True
bpy.data.objects[ob_LR.name].hide = True
if d > 50: # _LR Objects further then 50 BU away are are hidden
bpy.data.objects[ob_LR.name].hide_render = True
bpy.data.objects[ob_LR.name].hide = True
I basicly need this script to work when rendering an animation. It would also be benefitial to have it running in realtime in the 3d workspace and on framechange.
I couldnt find anything on this, so help would be apriciated. I’ve added the Blend file with the script.