I’m looking to set the material on a layer using a material that’s already in the container. Forgive me (and let me know) if that’s in the latest SDK. I’m using one version older than current as far as I know.
Without that function it’s not possible for material refs to be shared between layers or between layers and drawing elements. Maybe there’s a work around that I’m not familiar with, please enlighten me if that’s the case.
Right now, in my Rhino exporter, I call SULayerGetMaterial to create a new material ref for the layer and then set all of the contents the same as a material that already exists. It would be so nice just to use the same ref.
Robert McNeel & Associates
That said, for the longest time, the color getter and setter methods were not exposed in the Ruby API, and finally were implemented for the 2014 release.
Perhaps the C API never received the same love ?
These layer colors are only used in a special “Color by Layer” display mode, which is display only, and does not propagate the colors to actual entity materials.
I think I do recall FRs to implement “Material by Layer” display features. This feature (it is hoped,) would allow textures to be assigned to layers as well, and have the texture render onto drawing elements when in this display mode.
Layer materials cannot be shared in SketchUp. The layer itself owns the material. This is different from the materials applied to entities (which is owned by the Materials collection (In Ruby this is exposed as model.materials where as in the C API you ask the ModelRef directly (I wish there had been a MaterialsRef collection in the C API as well, alas.))
So you don’t want to mix layer materials and materials from DrawingElements - their ownership works differently.
In the C API there is no SULayerSetMaterial, but SULayerGetMaterial gets you a reference to the MaterialRef for that layer and let you modify that.
Incidentally, I am also curious to know which material has precedence in SketchUp should there be a material associated with the layer reference of a drawing entity and the same drawing entity has a material reference as well.
OK. I’m following you. I think. But let me blather on to make sure. In Rhino, several layers and objects can all reference the same material. In SketchUp, drawing entities can share a material reference between drawing entities but not with layers. Nor can layers share material references with other layers. So, I’ll need do duplicate materials in my exporter should there be an object and a layer, or multiple layers, that reference the same material in Rhino. Does that sound right?
To clarify a bit, in SketchUp layers aren’t really supposed to be able to have materials, just colors. However, under the hood the material class seems to be re-used to handle layer color as well. To the user (and Ruby developers) this is completely hidden and layers appear to only have a color.
Yes, DrawingElements, what you see in the viewport, will references materials from the model’s materials collection. SUModelGetMaterials.
From the UI in SketchUp you can only change layer colors. Hence in the Ruby API you can only get/set the layer color.
Internally layers own their own materials (unrelated to the model’s material collection.) Now, for some reason the C API exposed the material. (Why is not known to me - it was before me. My guess is that the original implementer wasn’t aware of this detail and simply exposed the material instead of just the colors.) So that’s some internal implementation details that unfortunately got exposed to the API. Some extensions have actually made use of that, so we are kind of stuck with it.
As for how SU determine what material to apply to a drawing element:
Depending on the current style’s setting there are various decision trees. (Use SURenderingOptionsRef) (In Ruby API the key is "FaceColorMode" - I think it’s the same for the C API"
If it’s applied directly to the entity that will take precedence.
If the entity have no material itself it will inherit from it’s first parent instance (group or component).
Same rules as above, except that textures are not used.
Then there is another option to make layer color override entity materials. "DisplayColorByLayer"
In this case the rules appear to be.
If the drawing element have a layer other than the special Layer0 the layer color is used. If the entity is on the default Layer0 then SU will find the nearest parent with non-Layer0 layer and use that.
There is another mode as well: "RenderMode" 5
Faces are all drawn using the default front/back color of the current style. This overrides the ColorByLayer mode.
Note that RenderMode also affect other things, such as mode 1
This will not use entity or layer material, but fill the faces with the style’s background color without any shading.
The addition of the exposure of these to the Ruby API predated the C API (but they always existed in the SketchUp C++ core.) So they’ve just not yet been added via the “C API <-> Ruby API parity project”.
It doesn’t matter. SketchUp is mostly implemented in C++. The Ruby interpreter is implemented in C (later versions with C++.) The Ruby API object interfaces C-side as wrappers around the SketchUp core C++ objects.
So what is exposed in the Ruby API is a good indicator of the underlying core functionality of SketchUp and it’s SKP document object model. Consulting the SketchUp Ruby API documentation can often give you insight that you might not get from the terse C API documentation.
If you look at the Ruby API page for the Sketchup::Layer class, you’ll notice that it is only a property collection class for display behaviors only. This class has no entity collection of any kind. In SketchUp therefore, layers are not geometric collections like they are historically in most other design software. They are currently simply shared behaviors for display purposes that entities can be assigned to use.
This presents challenges when an import / export coder like you must translate between SketchUp’s “display layers” and other software’s “geometric layers.”
I’ve never myself tried Rhino so I don’t know what kind of “layering” you’ve implemented.