RhinoCommon: How to know if a Texture uses WCS mapping?

Hi,

I’m trying to figure out how to determine if a Rhino.DocObjects.Texture instance is using WCS mapping in RhinoCommon. However, there doesn’t seem to be anything in the Texture object interface to indicate which type of mapping the texture is using.

I noticed that the Texture.MappingChannelId property seems to be -13 for WCS mapping and -14 for WCS/Box mapping but I couldn’t find any documentation confirming if that is intended or reliable behaviour. Although, this post seems to confirm the existence of hard-coded ChannelId values for certain types of mapping.

I’ve also tried to use the Rhino.Render.RenderTexture.GetProjectionMode(), but I’m having issues matching Texture instances to their RenderTexture counter-part. I’ve tried to use RenderContent.FromId() but it doesn’t seem to work with “generated” textures like “Tile Textures” or “Noise Textures”, passing the ID of those Texture instances fails to return a RenderContent object. I’ve tried matching generated texture manually by comparing some other property than the Id, but somehow the names of those RenderTextures are all “??? 005”, and comparing the file name hidden in the Xml property didn’t give me any match with the Texture.FileName either.

At that point, my only option seems to rely on the undocumented behaviour of Texture.MappingChannelId but I’m reluctant to do so since I could be wrong here. Could someone explain to me what is the proper way to determine the type of mapping used by a Texture object?

Thanks!

Just replying to let you know I’ve seen the question. About to head off to bed, but I’ll reply in more useful detail tomorrow.

1 Like

If at all possible you should stick to the RenderTexture type as much as possible. It is part of the RenderContent API that is provided by the Renderer Development Kit RDK, and essentially the moderner sibling of Texture.

Texture will always be a bitmap-based texture, RenderTexture can be a Rhino procedural texture.

Anyway, from a RenderTexture you can use RenderTexture.GetMappingChannel to get the mapping channel it is set to be used in.

To get to a Texture from the RenderTexture you can use SimulatedTexture:

RenderTexture rtex = GetRtFromSomewhere();
SimulatedTexture simtex = rtex.SimulatedTexture(RenderTexture.TextureGeneration.Allow);
Texture tex = simtex.Texture();

To create a RenderTexture from a Texture you will first have to construct a SimulatedTexture from it, then from that you can create the RenderTexture.

Texture tex = GetTexFromSomewhere();
SimulatedTexture simtex = new SimulatedTexture(doc, tex);
RenderTexture rtex = RenderTexture.NewBitmapTexture(simtex, doc);

The values you otherwise see for the channels are correct I think, but to be sure you should, assuming you start with the RenderTexture get the SimulatedTexture for it, then ask for its ProjectionMode, which will give you a value from the SimulatedTexture.ProjectionModes enum, which will be much easier to understand. This part of the SDK is a bit wieldy to use, unfortunately. But I hope this will give you all the info you need to get your code working.

2 Likes

Thanks a lot for the detailed answer it is very helpful.
Sorry reviving this post, I’ve only got one minor question in light of this information.

It appears we are using the somewhat deprecated “Texture” and “Material” classes rather than their “Render” counterpart. From what I see, we’ve got to use RenderMaterial too if we are to use the RenderTexture class (doesn’t see to be a way to get a “RenderTexture” from a “Material”, unless generating a new one using SimualtedTexture, which has some limitations).

I have only one question regarding the RenderMaterial: How do get the RenderMaterial for a specific RhinoObject? Do the RenderMaterials in RhinoDoc.RenderMaterials share the same “index” as their counterpart in RhinoDoc.Materials? Right now we’re using ObjectAttributes.MaterialIndex to find the material index but there is no ObjectAttribute.RenderMaterialIndex property.

As for the RDK, we can’t really use it, as from what I see this is a C++ Windows-only API, our plugin needs to run on Mac as well… Unless that is precisely what is exposed under the Rhino.Render namespace in RhinoCommon?

Thanks again

The RDK is indeed exposed via the Rhino.Render namespace. It is what I use to integrate the Cycles render engine into Rhino using C# - this way it runs on both Windows and MacOS.

You can get the RenderMaterial for a RhinoObject by using the RhinoObject.RenderMaterial Property. This is much more straightforward than trying to fiddle around with indices and tables.

I have a couple of literate Python scripts for Rhino here: https://jesterking.github.io/rhipy/ . They should show you how you can create, access and investigate render content using the RDK. Although these are written in Python they all use RhinoCommon as our Python scripting is built using IronPython for its .NET integration.

Let me know if you still have questions after looking at the literate scripts.

1 Like

Ah! I don’t know how I’ve missed that property! :upside_down_face:
Thanks a lot Nathan you’ve been very helpful, looks like we have all we need!

Good luck with the transformation to the RenderContent-based classes!

As always, do ask questions when you have them :slight_smile:

A post was split to a new topic: RhinoCommon: How to create an OCS texture mapping?