GhPython/RhinoCommon Decal Placement

Is it possible to use the Decal Methods in the RhinoCommon library to update decal application based on a variable point position? I am struggling to find documentation and the Decal constructors aren’t working for me at the moment.

I see only a way to create decals, not how to manipulate existing ones. So currently it is not possible to set decal location/size etc programmatically.

I have logged a bug report: RH-64608 Make it possible to set decal properties.

2 Likes

Thanks!

Hi @nathanletwory, can you show an example ? The link to the bug report is dead.

thanks,
c.

It was not dead, just not set to publicly readable - but that I changed now.

Let me see if I can whip up something.

It is going to involve: https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Render_DecalCreateParams.htm, https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Render_Decal_Create.htm, https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Render_Decals.htm and https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Render_Decal.htm in some combination.

Hi @nathanletwory,

yes, i am trying to apply a decal using a python script. So far i created a simulated texture:

sim = Rhino.Render.SimulatedTexture()
sim.Filename = r"D:\Temp\MyImage.png"
sim.MappingChannel = 1

Next i created a RenderTexture from this using:

rt = Rhino.Render.RenderTexture.NewBitmapTexture(sim, scriptcontext.doc)

To get it in the texture panel, i needed to use this which, according to the documentation is obsolete:

Rhino.Render.RenderContent.AddPersistentRenderContent(rt)

The documentation says to use RhinoDoc.RenderMaterials.Attach, which does not exist (V6,V7).

Next i tried to build my decal using this:

params = Rhino.Render.DecalCreateParams()
params.TextureInstanceId = rt.Id
params.DecalMapping = Rhino.Render.DecalMapping.Planar
params.DecalProjection = Rhino.Render.DecalProjection.Forward
params.Origin = Rhino.Geometry.Point3d(-10,-10,0)
params.VectorUp = Rhino.Geometry.Vector3d(0,20,0)
params.VectorAcross = Rhino.Geometry.Vector3d(20,0,0)
decal = Rhino.Render.Decal.Create(params)

And to apply it to an object, i use this:

rh_obj.Attributes.Decals.Add(decal)
rh_obj.CommitChanges()

But the result in the decal panel is:

Planar map: (cannot find texture)

I’ve found out, that the rt.Id before using AddPersistentRenderContent is different than after using it. So it somehow changes by using that method. If i use the “old” one in this line when i set it to the decal:

params.TextureInstanceId = old_id

I do get a decal assignment. However, if i delete the decal from the Rhino Decals Panel and delete the texture from the Textures panel and re-run the script, no decal is created. If i delete the object (brep) and try a new brep, it works. But only one time.

I would appreciate a working example.

thanks,
c.

Your code is very close to how I would write it:

https://jesterking.github.io/rhipy/create_decal.html

I do notice buggy behavior with adding decals once you’ve already added one to an object. I have logged RH-67878 Attempts to add more decals after first fail to track that.

Hi @nathanletwory, thanks for confirming the bug. Your report might include that even when the Decals table is cleared before adding, you cannot add a decal once one was ever added before. There is clearly something wrong.

Your example code does not use an image file, i wonder how you would assign it ?

Edit: your code gives this error:

Message: Create() takes at least 3 arguments (2 given)

The Textures panel and the list of Decals for the selected object remains empty ?!

thanks,
c.

I used https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Render_RenderContent_Create.htm, which is available from Rhino 7.9 onward. If you need older Rhino then https://developer.rhino3d.com/api/RhinoCommon/html/M_Rhino_Render_RenderContent_Create_5.htm probably works. I think you should pass None of https://developer.rhino3d.com/api/RhinoCommon/html/T_Rhino_Render_RenderContent_ShowContentChooserFlags.htm as the second parameter.

Did you read the explanation on https://jesterking.github.io/rhipy/create_decal.html of how this works to create the texture?

Yes, it is basically a copy of the code i posted but it does neither use an image file (from disk), nor does it create any entries in the Decals or Textures panel. So i wonder how someone would use this example code to apply a decal programmatically ? (I do not want to pop up a dialog to choose a file). What i am trying is to add and probably later edit existing decals of on object. This includes swapping decal images and probably changing their placement too.

I personally try to write code which is downward compatible. If something was added in V7.9 it is OK, then i limit it to this version. But for now i must conclude, it it not save to add decals programmatically because of the bug RH-67878. Editing is probably not possible because of the bug RH-64608 (which i cannot see).

_
c.

Hi @nathanletwory, two follow up questions (Rhino 7):

can i programmatically show the decal widget ? I’ve tried to script the _Properties _Decals command but there is only an option to _Add.

If you create one decal with your script in Rhino 7, does the Textures panel remain empty on your side too?

_
c.

I changed the visibility some 17 hours ago: RH-64608 Make it possible to set decal properties. You should be able to see it.

It certainly does

You can create the bitmap texture like I do in https://jesterking.github.io/rhipy/create_pbr_material_with_textures.html

lines 9-10 in the final script

No need to simulate the texture nor material, just attach it to the document like you do in your script.

Note that in my script version you need to have an object selected for the decal to be even added, and over the world origin for the decal to show once added.

Manipulating decals using RhinoCommon is indeed currently tricky and buggy.

I don’t know. @maxsoder do you happen to know if there is access to this somewhere?

No, see my screenshot.

Thank you @nathanletwory, i’ll try now with the new example code.

Ok, i noticed that and see it working in Rhino 7 for adding one decal. Adding a different one again on the same object seems to fail, even if i use Decals.Clear() but i’ll try if i can circumvent that if i create a duplicate from the object. In the end, i have to assign two decals in total and hope that RH-67878 gets resolved during the V7 life cycle.

This is great. Thank you!

Ok, seems to be a difference compared to V6. I see the texture listed in the Decals list but expected to see it in the Textures panel like in V6. As long as i can see it in the viewport it is good enough.

thanks,
c.

Hi @clement! Do you have a working snippet of code for the Decals you can share here? Much appreciate

Hi @sadovshikov, note that the bugs reported above are still there in the current Rhino 7 SR20. I’ve tested below in Rhino 6 and 7 and it works for one decal. To test it, add a surface in world xy plane from -10,-10,0 to 10,10,0 then start the script, it will prompt for the decal image (i’ve used a square one)…

DecalTest.py (1.9 KB)

_
c.

1 Like

HI @clement! Seems like the Decals.Add() method adds only one decal, that is all? Strange behavior, indeed, rugging the code multiple times I get nothing than first one decal. Do you have the same result?

Hi @sadovshikov

yes, with the example posted above this is the case since it creates new object attributes the old attributes seem to be discarded. Decals are added to the attributes and i’ve found that once you assign one decal, the attributes somehow get bogous and any subsequent additions fail. This is what has been mentioned in the bug report RH-67878.

_
c.

1 Like

Thank you @clement for reply! Just a few hours ago, somehow I was success to add different decals many times changing their extensions and origin positions but can’t repeat it again

The issue RH-67878 is still open and being worked on.

Hi @nathanletwory, that’s good to hear since in Rhino 8 WIP (Windows) it is not possible yet to assign even a single decal using code. In Rhino 7 at least one could be assigned when using a fresh instance of Rhino.DocObjects.ObjectAttributes.

Speaking of Rhino 7 (Windows), assigning a decal to the existing attributes of an object works exactly one time, but then the object attributes somehow get kinda bogus. If the decal is removed using the GUI and you try to assign one again via code, it never shows up. I’m not ranting here, just trying to post my findings which hopefully lead to the source of the problem after reading the response from @johnc.

thanks,
c.