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:
How feasible is adding a stream constructor to RhinoCommon?
Are there any workarounds?
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.)
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.
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.
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?
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?
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.
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.
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.