SketchUp / api-issue-tracker

Public issue tracker for the SketchUp and LayOut's APIs
https://developer.sketchup.com/
39 stars 10 forks source link

Get/Set Texture and transparency of a Tag / Layer #766

Open Fredosixx opened 2 years ago

Fredosixx commented 2 years ago

I did not find a way to get or set the texture and alpha for a Tag. In the API, it seems you can only access the color (and not even its alpha value).

Do I miss something?

Otherwise, it would be a request to have a get / set for

DanRathbun commented 2 years ago

Do I miss something?

We have issues open already ... (Please add comments in these) ...

Issue 7 : Layer.material instead of Layer.color OCT 2017 by @prachtan

Issue 180 : Access hidden materials like hidden definitions NOV 2018 by @Aerilius

Issue 715 : Sketchup::Layer alpha channel access Formerly logged here SEP 2021 (although requested for years) by @DanRathbun

Also see the discussion for Layer (Tag) material access for both APIs in ... Issue 418 : C API : Get and Set Material Color for a SULayerRef JAN 2020 by @DanRathbun Renamed (2022-02-08) was: "SULayerGetColor() and SULayerSetColor()"

Fredosixx commented 2 years ago

Thanks. So, an old issue, not addressed yet, whereas the comments in Issue 418 tend to show that it would not be very complex to do.

DanRathbun commented 2 years ago

Yes the mechanisms appear to be there in the core, but just not yet fully exposed in the APIs.

thomthom commented 2 years ago

There are some internal complications related to ownership of layer materials/textures that makes it non-trivial.

DanRathbun commented 2 years ago

Okay, @thomthom, but do we really need another open issue with the other 4 we already have ?

Fredosixx commented 2 years ago

At least, we could have the GET methods quickly...?

thomthom commented 2 years ago

Ain't that easy I'm afraid. Because that means you have a material that is owned by a layer, you don't want that applied to anything else. We've had issues with image materials applied to faces etc.

Fredosixx commented 2 years ago

At least a GET for the texture file, the size and the opacity, all 3 parameters which are used in the Sketchup regular UI.

This would allow to display properly the visual in any list of layers.

DanRathbun commented 2 years ago

Just as image objects got a #image_rep getter method at v2019.2, ... a valid request could be for the Layer class to also get an #image_rep method.

DanRathbun commented 2 years ago

@Fredosixx : At least a GET for the texture file, the size and the opacity, all 3 parameters which are used in the Sketchup regular UI. This would allow to display properly the visual in any list of layers.

Hmmm... (thinking) ... getting the average color, size and scaling, etc. for a material is difficult from only the bitmap data. (Ie, from an ImageRep object if Layer#image_rep were to be implemented.)

@thomthom : Ain't that easy I'm afraid. Because that means you have a material that is owned by a layer, you don't want that applied to anything else. We've had issues with image materials applied to faces etc.

So ... musing, ... the main challenge is to provide a safe Sketchup::Material object that is manager owned.

Similar to a clone method ... the Ruby API could have a Sketchup::Materials collection factory method that clones a layer owned material to a new manager owned material.

# Get a handle to the current model:
model = Sketchup.active_model
# Get a handle to the model's materials collection:
materials = model.materials
# Get a handle to the model's layers collection:
layers = model.layers
# Create a new material from the "Insulation" layer:
new_matl = materials.create_from_layer( layers["Insulation"], "Insulation - Attic" )

The new material should have all the same properties as the layer owned material it was cloned from.

If an optional 2nd name argument is not given, the new material's name would be based upon the layer's #display_name, but run through Materials#unique_name regardless to be sure it's distinct.


As the C API only has arrays for resource collections, the function would likely be something like:

SUResult SUMaterialCreateFromLayer(SUMaterialRef *material, SULayerRef layer)

The question would be, is the new material's owner type the same (layer) or by default should it be a manager owned material ? But the SUModelAddMaterials function's doc says that materials being added must "not be owned", so I wonder if the function automatically sets the owner type ?

DanRathbun commented 2 years ago

I think that some of the discussed features above are already possible using the "live" C API.

A copy of the layer material's SUImageRepRef (from it's texture) can be passed back to Ruby using SUImageRepToRuby and then on the Ruby side, a new manager owned material can use it in it's #texture= setter.

sketchupbot commented 2 years ago

Logged as: SKEXT-3340

Eneroth3 commented 2 years ago

I'd be quite reluctant to expose direct getters and setters for material properties on the layer object itself. It's a bit similar to how Groups once didn't have a definition getter but had direct access to the entities, trying to hide the actual implementation.

There are cases where the actual implementation is only an internal concern and can be hidden in favor of a more streamlined and easily understandable mental model, but also cases where honesty and transparency makes it easier to understand.

In any case, it isn't as easy as just exposing a method or two. We need to discuss what approach is the best before committing to anything.

DanRathbun commented 2 years ago

@Eneroth3 In any case, it isn't as easy as just exposing a method or two. We need to discuss what approach is the best before committing to anything.

The C API has already exposed everything, except ...

@Eneroth3 I'd be quite reluctant to expose direct getters and setters for material properties on the layer object itself.

... that a SULayerRef material is automatically generated (either when it is created or when it's added to a model with SUModelAddLayers.) So there already is the SULayerGetMaterial getter but no setter that replaces a material like the Ruby API's setters do.

Instead (non-live) C code must change whatever properties need changing. And it appears that everything is exposed for a layer owned material just as with materials for geometry and images.

~