4

Is there a way to get the data path of object dimensions for using in drivers?

How to get the variable for a specific object y-dimensions for example?

Thank you Chris

Christoph Werner
  • 1,965
  • 1
  • 14
  • 31
  • 2
    Does this answer your question? Can I get the object dimensions in Cycles? TLDR : Use dimensions[0] for x, dimensions[1] for y and dimensions[2] for z – Gorgious Oct 09 '20 at 07:57
  • Thank you. Yes, this could be one way. But you are always forced to place a value node into the object material. As soon as you change the material, the connection interrupts.

    But I would like to read the data directly, without using material nodes.

    – Christoph Werner Oct 09 '20 at 08:03
  • Okay then, could you elaborate on what you want to achieve with this data ? I assume it's for shading given the topics of your tutorials :) I can think of a hacky way to get it in any material using the viewport color output of the object info node. Let met know if that would suit your need – Gorgious Oct 09 '20 at 08:09
  • Thank you. But it's not used for materials. :) I need it for arranging objects dynamically by using drivers and calculate a position dependent of an object size. And because the object size can change dyamically, I need the current resulting x-y-z values. – Christoph Werner Oct 10 '20 at 15:17

2 Answers2

5
  1. To use the current dimensions of an object for a driver, you have to use the dimensions array.

The values for the object width are stored in the array as following:

object size of x-axis (width) =  dimensions[0]
object size of y-axis (depth) =  dimensions[1]
object size of z-axis (height) =  dimensions[2]

The complete list of the object data IDs can be found here: https://docs.blender.org/api/current/bpy.types.Object.html

  1. If the driver doesn't update in the viewport or output an error, try to press "Update Dependencies" in the drivers editor sidebar. My driver were set right, but didn't work and I didn't know why nothing happened. This was the main reason for this post here. Updating the dependencies solved my issue.

Here's an example how it could look like in the Drivers editor:

enter image description here

Christoph Werner
  • 1,965
  • 1
  • 14
  • 31
  • 2
    Sometimes the drivers need to be "reset" for instance when at one time you introduce an error in the expression like a division by 0. Then you have to update the dependencies for it to work again. Maybe that happened – Gorgious Oct 10 '20 at 16:35
4

You can use the object viewport color to transfer information to the material. Here it's convenient because the dimensions are always positive and the RGB channels can only hold positive values so we can just use the raw value.

You can either add a driver to each of the R, G, B channel of the viewport color property by hand or by using a script.

Use dimensions[0] for the $X$ dimension, dimensions[1] for $Y$ and dimensions[2] for $Z$.

Alternatively (and perhaps more intuitively) you can use dimensions.x, dimensions.y, dimensions.z.

enter image description here

Here is a script to automate it :

import bpy

def main(): ao = bpy.context.active_object if not ao or ao.type not in ('MESH', 'CURVE', 'SURFACE', 'META', 'FONT', 'VOLUME', 'GPENCIL'): print("Select a mesh, curve, surface, metaball, text, volume or grease pencil object") return for i in range(0, 3): add_driver_to(ao, "color", "dimensions", "dim", i)

def add_driver_to(obj, prop_to, prop_from, var_name, dim): """ Add a driver to obj's prop_to property Using obj's prop_from property

Both properties must be at least of dimension dim
"""
if not obj:
    return
if not hasattr(obj, prop_to):
    print(f"Object '{obj.name}' doesn't have a property named '{prop_to}'")
    return
driver = obj.driver_add(prop_to, dim).driver
# Make sure we don't add variables indefinitely :
var = driver.variables.get(var_name)
if not var:
    var = driver.variables.new()
var.name = "dim"
var.type = 'SINGLE_PROP'

target = var.targets[0]
target.id_type = 'OBJECT'
target.id = obj
target.data_path = f"{prop_from}[{dim}]"

driver.expression = var_name


if name == "main": main()

To visualize what we just did, set the viewport object color to "Object".

enter image description here

Execute the script and scale the object.

enter image description here

To access it in a shader access the "Color" output of the "Object Info" node and separate each channel.

enter image description here

Scale along X for example (Values > 1 are pure white):

enter image description here

Gorgious
  • 30,723
  • 2
  • 44
  • 101
  • 1
    As I commented in my 1st post above, it doesn't solve my needs. But it's very interesting, how you control the object color in this way and I've learned a lot. Especially the python code is very informative for me.

    Thank you for this proposal!

    – Christoph Werner Oct 10 '20 at 15:27
  • 2
    Glad it was useful anyway :) And thank you for your tuts ;) – Gorgious Oct 10 '20 at 16:28