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: DecalCreateParams Class, Decal.Create Method, Decals Class and Decal Class 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 RenderContent.Create Method (RhinoDoc, Guid), which is available from Rhino 7.9 onward. If you need older Rhino then RenderContent.Create Method (Guid, RenderContent.ShowContentChooserFlags, RhinoDoc) probably works. I think you should pass None of RenderContent.ShowContentChooserFlags Enumeration 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.

(post deleted by author)

Hi @nathanletwory, could you reveal the full script on the image, cause it partly obscured? Apparently the obstructed snippet is just a Guid of the RenderContent.Create Method. I wonder how do you get the Guid to the texture in Rhino and also is it possible to reference to the grasshopper bitmap component with texture in it. When I run the code in GhPython component I get “Error: Runtime error (ArgumentTypeException): expected RhinoDoc, got GrasshopperDocumen” for the string N4, apparently sc.doc gives GrasshopperDocumen instead of RhinoDoc, should I use something instead of sc.doc for GhPython?

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.