-
SummaryReferenced BSDF parameters seem to be accessed as nested parameters held by the first shape (in alphabetical order) that references them. System configuration
DescriptionConsider the following script: import mitsuba as mi
mi_scene = mi.load_dict(
{
"type": "scene",
"some_bsdf": {"type": "diffuse"},
"rectangle": {
"type": "rectangle",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
"disk": {
"type": "disk",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
}
)
print(mi.traverse(mi_scene)) I get the following output (I'm using a monochrome variant):
The BSDF's reflectance value is accessed by Things become even more confusing when the referencing shape is nested in an instanced import mitsuba as mi
mi_scene = mi.load_dict(
{
"type": "scene",
"some_bsdf": {"type": "diffuse"},
"disk": {
"type": "disk",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
"a_group": {
"type": "shapegroup",
"rectangle": {
"type": "rectangle",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
"sphere": {
"type": "sphere",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
},
"an_instance": {
"type": "instance",
"the_group": {"type": "ref", "id": "a_group"},
},
}
)
print(mi.traverse(mi_scene)) which produces the output
Would it be possible to reference top-level BSDF parameters by their ID? For instance, in this case: |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 2 replies
-
This is an interesting problem. We've had a few similar questions already, I'll give a longer explanation here. There is one main problem currently: the referencing with the Fundamentally, this boils down to how we want to structure any exposed parameters:
Now, as you mentioned in your thread there are workarounds. I think the more robust way of programmatically "mapping" parameters to the description is to import mitsuba as mi
mi.set_variant('scalar_rgb')
scene = mi.load_dict(
{
"type": "scene",
"some_bsdf": {"type": "diffuse"},
"rectangle": {
"type": "rectangle",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
"disk": {
"type": "disk",
"bsdf": {
"type": "ref",
"id": "some_bsdf",
},
},
}
)
print(mi.traverse(scene)) # Rectangle does not have `bsdf`
key = ['rectangle', 'some_bsdf'] # The keys in the scene description
index = 0
for shape in scene.shapes():
if shape.id() == key[index]: # The id() matches the object's key in the description
index += 1
bsdf = shape.bsdf()
if bsdf.id() == key[index]: # Not necessary (only 1 BSDF per shape) but can serve as an assert
print(mi.traverse(bsdf)) # Will only show `relfectance.value`
index -= 1 This is not super generic, it still requires you to know that the scene structure is scene->shape->bsdf. But it's fairly programmatic and robust w.r.t. to the ordering in your scene description. I've used variations of this successfully a few times. |
Beta Was this translation helpful? Give feedback.
-
Thanks @njroussel for this explanation. I think I can work out a lookup protocol to recover parameter IDs thanks to your suggestion. By the way, I'm now realising that this thread should rather have been a discussion than an issue, sorry for posting it on the wrong channel. |
Beta Was this translation helpful? Give feedback.
-
I have another question now: I'd like my lookup to be able to go through shape groups as well, is that possible? |
Beta Was this translation helpful? Give feedback.
This is an interesting problem. We've had a few similar questions already, I'll give a longer explanation here.
There is one main problem currently: the referencing with the
ref
type is only used during the parsing phase of the object construction. Once the object is constructed the "top-level"-nature of the object is lost. For example, in yourshapegroup
example, thesome_bsdf
object is obviously not a child of the scene once the scene is built. Thetraverse
mechanism only woks on instantiated objects, so the whole referencing mechanism/information is lost at that point.In short, references are only used in the object description and are almost completely lost once the object is built w…