Isotropix Forums

Dump scene objects,its attrs & values in json to get overrid

Clarisse Scripting related topics

Dump scene objects,its attrs & values in json to get overrid

Unread postby vishumish » Thu Jun 11, 2020 8:45 am

Hi,

I need urgent help on this. I am using clarisse 3.6 sp11 x64. I want to find out in-scene-edits/overrides of a clarisse scene. I saw there is an ofAttr method "is_overriden" but this only works in case of remote (referenced) objects. So i was planning to take two snapshots (in json format as objects, attributes and their value) of the scene. First, while loading it and second when the user demands to see the overrides. And then I could compare them to find out what all had been changed.

Is there an inbuild way of traversing through the scene graph in clarisse? Also when I am using following code, its crashing while fetching values of attributes (see following)

Please help!

python code

def get_attrs(item):
attrs = {}
for i in xrange(item.get_attribute_count()):
attribute = item.get_attribute(i)
attr_value = str(attribute.get_value_count())
#for j in xrange(attribute.get_value_count()): ######## when i am running this loop to get the values ofthe attr its crashing ######
# attr_value = attr_value + " " + str(attribute[j])

attrs.update({attribute.get_name(): attr_value})
return attrs

def run():
print "*" * 1000
project_item_list = ix.api.OfObjectArray()
ix.application.get_factory().get_all_objects(project_item_list)

data = {}
for index in xrange(project_item_list.get_count()):
item = project_item_list[index]
data.update({item.get_full_name(): get_attrs(item)})
print data

run()


EDIT:
Its crashing when I am running following loop in get_attrs method :

python code

for j in xrange(attribute.get_value_count()): ######## when i am running this loop to get the values ofthe attr its crashing ######
attr_value = attr_value + " " + str(attribute[j])


Let me know if there is some other way to do this as this won't store the changes in viewport settings etc.
Thanks
=VM
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby dcourtois » Tue Jun 23, 2020 10:23 am

Hi,

As you already found out, the concept of "overrides" is only applicable to references. When you change an attribute in your main scene, the value is simply updated, so if you want to be able to get the "diff", you can only compare the values before and after.

As for the crash, use `range` instead of `xrange`, that'll fix it. And no, there is no builtin traversal in Clarisse since by default there is no hierarchy and everything's flat. You could work on only the select contexts if you need though.
User avatar
dcourtois
 
Posts: 94
Joined: Tue Jul 25, 2017 3:15 pm

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby vishumish » Tue Jun 23, 2020 1:35 pm

Hi dcourtois,

Thanks for the reply. The crash issue is fixed by now. But I still have few questions to move further. Writing them down here :

# Is there a way to dump and load objects, attrs and their value in the same format as clarisse stores in the project file? Do we have access to it?
# When I change certain attribute of any object (for example translate and rotate of a sphere) clarisse stores value of those two objects only (and not attrs of sphere object) in the .project file along with some additional attrs like created, modified date etc. Similarly is there a way to get about only those attributes so that i can dump only those attributes and not all for that object. This would help me to avoid storing redundant data while taking a dump of all the objects (right now i am storing info about all the objects most of them are having their default value also the json size is appear to be huge this way)
# One confirmation I need i.e., if I set overridden parameter of an object to "False" using object.set_overriden(False) method am I correct to assume that all the attributes of that object will automatically have overridden value as False afterwards regardless of their independent overridden state?
# Is there a way to get information about viewport parameters (lut, gamma, exposure etc. and layers parameters in the same way)
# Can you confirm that mine is the quickest possible way to traverse through all the SceneObjects, their attrs and their values. if not then can you suggest something?

a quick answer would be very helpful

Thanks!
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby dcourtois » Tue Jun 23, 2020 2:47 pm

Hi again,

1. You can read and write objects using the serialize and deserialize methods of OfObject. Sorry the documentation is missing in https://clarissewiki.com/4.0/sdk/class_of_object.html for those methods, but it's quite easy to do:

python code

# serialize
object = ix.item_exists("project://scene/light")
parser_entry = object.serialize()
serial = ix.api.CoreString()
parser_entry.get_text(serial, True)
print(serial)

# deserializing
parser_group = ix.api.ParserGroup("")
parser_group.set_text(serial.get_data())
parser_entry = parser_group.get_entry(0)
context = ix.item_exists("project://scene")
object = context.add_object("copy", parser_entry.get_name())
object.deserialize(parser_entry)

Edit: I added an example to deserialize an object.

2. Here is an example. Basically there is a function that extracts the content of an attribute, another one that compare

python code

# small helper used to get the content of an attribute
def get_attr_content(attr):
content = ""
if attr != None:
for i in range(attr.get_value_count()):
content = content + attr.get_serialized_string(i)
return content

# get a test object
object = ix.item_exists("project://scene/light")

# get the class for the object
object_class = object.get_class()

# compare the attributes and print the ones that differ
for i in range(object.get_attribute_count()):
# get the attribute, and get the corresponding attribute in the class
# note that the attribute might be a custom one and might not exist in the class, so get it by name
attribute = object.get_attribute(i)
class_attribute = object_class.get_attribute(attribute.get_name())

# and compare using our utility function
if get_attr_content(attribute) != get_attr_content(class_attribute):
print(attribute)

3. You should not use OfObject.set_overridden (nore OfAttr.set_overridden) Those are mostly private methods, and modifying this flag might break some stuff.

4. I'm not sure if we can access those in Python, I'll have to take a look and get back to you.

Edit: Here is the way to access the layers of an image (they are objects like all others, so you can get their attributes and values)

python code

image = ix.item_exists("project://scene/image")
layers = image.attribute_exists("layers")
for i in range(layers.get_value_count()):
print(layers.get_object(i))


5. Usually what you want is get the objects or a given context to avoid getting too many things. See OfContext.get_objects. This can retrieve objects in a given context, recursively or not, and you can filter the objects by type too, to avoid getting things that you don't need.
User avatar
dcourtois
 
Posts: 94
Joined: Tue Jul 25, 2017 3:15 pm

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby vishumish » Tue Jun 23, 2020 3:41 pm

Thanks a lot dcourtois for quick response. It will help me a lot. Though few suggestions raised some new questions so writing them down here :

Edit : I got answers for few questions so updating them with the most recent ones.
1. From following code snippet :

python code

import ix
serial = ix.api.CoreString()
serial.set_data('CameraFisheye { name "fisheye" #version 0.9 #created 1592993786 #modified 1592993799 translate 0.0 0.0 10 }')
parser_group = ix.api.ParserGroup("")
parser_group.set_text(serial.get_data())
parser_entry = parser_group.get_entry(0)
serial = ix.api.CoreString()
parser_entry.get_text(serial, False)
print(serial)


1.1 I want to remove "#created" & "#modified" keys and values from parser entry. Method "remove_value()" removes the whole struct so is there any other way to remove these two keys?
1.2 I want to get the name of the object i.e., "fisheye" but couldn't find any relevant method in parser_entry object.
1.3 Also would be very helpful if you can share some clarisse native example of dumping this data to a text file and reading from it since its not a standrd json format. Though I went through with ParserFile class but didn't find any significant.

2. If I won't use "set_overriden" method of OfObject and OfAttr then I won't be able to differentiate the overrides made in a particular clarisse scene session. is_overridden will always return True even if the overrides have been made in any previous clarisse session and even if the user has not changed anything after loading the scene.

Thanks again!
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby dcourtois » Wed Jun 24, 2020 3:00 pm

Here is an example for how to achieve 1.1 and 1.2:

python code

import ix

# test parser group
serial = ix.api.CoreString()
serial.set_data('CameraFisheye { name "fisheye" #version 0.9 #created 1592993786 #modified 1592993799 translate 0.0 0.0 10 }')
parser_group = ix.api.ParserGroup("")
parser_group.set_text(serial.get_data())
parser_entry = parser_group.get_entry(0)

# remove #created and #modified
def parse_group(entry):
# ignore non-group entries
if not entry.is_group():
return
# remove the unwnated entries
group = entry.get_group()
group.remove_entry("#created")
group.remove_entry("#modified")

# get the name of an object
def get_name(entry):
# ignore non-group entries
if not entry.is_group():
return
# get the group
group = entry.get_group()
# get the "name" entry
name = group.get_entry("name")
# check that the entry is valid and has a single string value
if name and name.get_value_count() == 1 and name.is_value_string(0):
# return the value
return name.get_string(0)
# something was wrong, return an empty string

return ""

# print the name
print(get_name(parser_entry))

# filter out the #created/modified and print the result
parse_group(parser_entry)
serial = ix.api.CoreString()
parser_group.get_entry(0).get_text(serial, False)
print(serial)


As for 1.3, you don't really need to use the ParserFile class, you can just use the usual Python functions to write the ParserGroup's text data, or read from the file, and recreate the ParserGroup from its content, like you do in the previous example.
User avatar
dcourtois
 
Posts: 94
Joined: Tue Jul 25, 2017 3:15 pm

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby vishumish » Fri Jun 26, 2020 1:09 pm

Thanks again dcourtois for the solution. It helped me move further though I just realized that it will be near to impossible for me to convert the serialized data into "object.attribute : value" (please let me know if thats possible) format. So to get and set overrides on existing objects i will try to use other methods (getter & setter probably) and for newly created objects I will try to serialize and deserialize them.

Still if I will stuck somewhere will post a message again.
Thanks again :)
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby vishumish » Wed Jul 01, 2020 8:50 am

Hi dcortois, I have a quick question about the snippet you suggested for fetching layers from the scene. How can I merge\append the result of "image.attribute_exist("layers") with an object of ix.api.OfObjectArray().

python code

image = ix.item_exists("project://renderPasses/default_BEAUTY/lighting_default_L010_BEAUTY")
layers = image.attribute_exists("layers")
print dir(layers)


I don't want to run two loop for objects and layers to fetch the information of all their attributes. I have all the objects in an OfObjectArray(), is it possible to append all layers in the same? I want to do something like this :

python code

project_item_list = ix.api.OfObjectArray()
ix.application.get_factory().get_all_objects(project_item_list)
project_item_list.append(layers) # layers is result of previous snippet
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby dcourtois » Wed Jul 01, 2020 2:43 pm

Hi,

`layers` is an `OfAttr` object. Check https://clarissewiki.com/4.0/sdk/class_of_attr.html it has everything you need to get the layer objects from it.
User avatar
dcourtois
 
Posts: 94
Joined: Tue Jul 25, 2017 3:15 pm

Re: Dump scene objects,its attrs & values in json to get ove

Unread postby vishumish » Thu Jul 02, 2020 7:34 am

Got it. Thanks!
vishumish
 
Posts: 17
Joined: Mon Jan 27, 2020 11:38 am


Return to Scripting