1
$\begingroup$

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

$\endgroup$
4
  • 2
    $\begingroup$ 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 $\endgroup$ – Gorgious Oct 9 '20 at 7:57
  • $\begingroup$ 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. $\endgroup$ – Christoph Werner Oct 9 '20 at 8:03
  • $\begingroup$ 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 $\endgroup$ – Gorgious Oct 9 '20 at 8:09
  • $\begingroup$ 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. $\endgroup$ – Christoph Werner Oct 10 '20 at 15:17
4
$\begingroup$

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

$\endgroup$
2
  • 1
    $\begingroup$ 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! $\endgroup$ – Christoph Werner Oct 10 '20 at 15:27
  • 2
    $\begingroup$ Glad it was useful anyway :) And thank you for your tuts ;) $\endgroup$ – Gorgious Oct 10 '20 at 16:28
2
$\begingroup$
  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

$\endgroup$
1
  • 2
    $\begingroup$ 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 $\endgroup$ – Gorgious Oct 10 '20 at 16:35

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.