Wish list: Set bitmap texture from memory stream

Apologies for duplication, as this request has been made before, here and here. In each case the thread drifted off topic, so I’m hoping to recenter the discussion.

It would be very useful to construct a RhinoCommon Texture object from a memory stream rather than a file path. (FileName and FileReference are the only options at present.) I’m raising the issue because our plugin uses texture mapping to paint falsecolor data onto render meshes. This often involves thousands of maps, which need to be updated progressively every second or so. Having to create thousands of disk files makes this process prohibitively slow. So my questions are as follows:

  1. How feasible is adding a stream constructor to RhinoCommon?
  2. Are there any workarounds?
  3. Ultimately I need to render the textures in a display conduit. As I understand it, this requires a DisplayMaterial. Is there any way to create my own texture evaluator in this case, to bypass the limitations of the Texture class? (Similar question here.)
  4. If one has to use disk files, is there a trick to ensuring that DisplayMaterials and Textures refresh properly when a file is overwritten? At present, the display pipleline occasionally gets “stuck” on a cached bitmap, even though I’ve created a new Texture and DisplayMaterial from scratch (and confirmed that the bitmap file was correctly overwritten prior to calling these constructors). Changing the file path seems the only guarantee of success, but this incurs big System.IO penalties.

Thanks,

Jon

1 Like

Did you try using my in-memory texture sample from the thread you linked to?

It should serve as a good example of how you can approach this. Instead of the Bitmap object you’d use your stream. The evaluator you’d adapt to work with it.

Don’t forget to change any GUID

Thanks @nathanletwory, I did see your post. But per question (3) above, I’m looking for a way to draw directly in a display conduit (the meshes in question are not doc objects). As I understand it, RenderMaterials cannot be applied to DisplayPipeline meshes, or am I missing something?

Ok, I didn’t realize you want to use only display conduit. For that I hope @stevebaer can help more, as I am not familiar with DisplayMaterials

To make this more concrete, I’ve created a lightweight C# PlugIn that illustrates what I’m trying to do – and highlights the issues raised in question (4). As a placeholder for the progressive falsecolor pipeline, the project includes a “BitmapTexture” command that repeatedly re-textures a bunch of spheres:

The objective is to update the display as quickly as possible. Disk file writing is not optimal for this, but as the example project makes clear, it’s not the only issue I’m having. When I try to reset textures by overwriting existing bitmap files (i.e reusing the same paths), the textures tend to remain “stuck” for some unpredictable number of iterations before they start refreshing properly. On the other hand, if I use new bitmap paths each iteration, the display materials update reliably but suffer from a rather horrific runaway slowdown:

Command: BitmapTexture
Reuse bitmap paths? <Y> ( Y  N ): n
Replacing paths:
  pass 0 complete (2952 ms) - redraw in 1535 ms
  pass 1 complete (2968 ms) - redraw in 1791 ms
  pass 2 complete (2927 ms) - redraw in 2093 ms
  pass 3 complete (3618 ms) - redraw in 2372 ms
  pass 4 complete (4502 ms) - redraw in 2728 ms
  pass 5 complete (5347 ms) - redraw in 3039 ms
  pass 6 complete (6183 ms) - redraw in 3511 ms
  pass 7 complete (7469 ms) - redraw in 3832 ms
  pass 8 complete (11566 ms) - redraw in 4269 ms
  pass 9 complete (17508 ms) - redraw in 4653 ms

Perhaps I’m failing to dispose of cached objects properly, or suffering from some other ill conception? If @stevebaer or anyone else on the McNeel team can have a look and set me straight, it would be much appreciated.

We don’t really have a good mechanism for setting bitmap textures with anything other than file paths. It sounds like the first thing we need to figure out is if there is a bug in the texture cache as that seems to be what is happening if reusing paths is unpredictably updating.

@DavidEranen can you take a look at this? Also, is there a way to force clearing of the texture cache from one frame to the next?

@sarg Thanks for reporting and for the example project. So far I’ve created two YouTrack items based on my testing:

https://mcneel.myjetbrains.com/youtrack/issue/RH-59415 (Deleting a texture file from disk will cause a slowdown in the resource manager)
https://mcneel.myjetbrains.com/youtrack/issue/RH-59416 (Filewatcher causing texture update issues due to depending on timer)

I don’t have a good workaround for now.

-David

1 Like

Thanks @DavidEranen. I’ll stay tuned. In the meantime I suppose I can play with map-compositing to reduce the number of files, since I don’t need the textures to wrap.

@stevebaer and @DavidEranen,

would it be possible to add a property for the DisplayMaterial (for use in conduits only) which accepts a System.Drawing.Bitmap which only exists in memory but not physically ? I think this is the initial request of this and the two threads linked above.

_
c.

Hi Clement,
We don’t have a good system for this yet. I request makes sense and I can understand the need, but the texture caching mechanism at the moment doesn’t allow for this. We could let you set a System.Drawing.Bitmap on a material, but before we have a new architecture in place we would need to just write the bitmap to a temp location and set a path to the temp file in the background. This would be just as slow or slower than what is being done in the initial request.

Let’s see what David comes up with for fixing some bugs in the texture cache as listed above. Once that is complete, we can examine alternate ways to define bitmaps that are used as textures.

2 Likes

RH-59416 is fixed in the latest WIP