The Persistence of Vision Raytracer (POV-Ray).
This is the legacy Bug Tracking System for the POV-Ray project. Bugs listed here are being migrated to our github issue tracker. Please refer to that for new reports or updates to existing ones on this system.
Opened by Juha Nieminen - 2010-03-22
Last edited by William F Pokorny - 2017-04-10
FS#87 - Add new feature: Reference object
When you instantiate an object several times, eg:
object { MyObj translate -x*10 } object { MyObj translate x*10 }
POV-Ray will copy that object in memory, at least for most types of objects. Not for all of them, though. Most famously if MyObj is a mesh, it won’t be copied, but only a reference to the original will be used, thus saving memory. (There are a few other primitives which also don’t cause a copy, such as bicubic_patch and blob, but those are naturally not so popular as mesh, so it’s a less known fact.)
AFAIK the reason why referencing (rather than copying) is not used for all types of objects is rather complicated, and mostly related to how transformations are applied to these objects. For example if the object being instantiated is a union, the translates above will be (AFAIK) applied to the individual members of the union rather than to the union object itself.
Copying, however, can be quite detrimental in some situations. For example if you have a huge union, and you want to instantiate it many times, the memory usage will be that many times larger (compared to just one instance). This is sometimes something which the user would not want, even if it made the rendering slightly slower as a consequence. (In other words, better to be able to render the scene in the first place, rather than running out of memory.)
Redesigning POV-Ray so that all objects would be referenced rather than copied would probably be a huge job, and in some cases a questionable one. There probably are situations where the current method really produces faster rendering times, so redesigning POV-Ray so that it would always reference instead of copy, could make some scenes render slower.
So this got me thinking about an alternative approach: How hard would it be to create a special object which sole purpose is to act as a reference to another object, without copying it? This special reference object would act as any regular object, would have its own transformation matrix and all that data related to objects, but its sole purpose is to simply be a “wrapper” which references an existing object. It could be, for example, like this:
object_ref { MyObj translate -x*10 } object_ref { MyObj translate x*10 }
The end result would be exactly identical as earlier, but the difference is that now MyObj behaves in the same way as a mesh (in the sense that it’s not instantiated twice, but only once, even though it appears twice in the scene), regardless of what MyObj is.
In some cases this might render slightly slower than the first version (because POV-Ray has to apply the transformations of the object_ref first, after which it applies whatever transformations are inside MyObj), but that’s not the point here. The point is to save memory if MyObj is large.
An object_ref would behave like any other object, so you could do things like:
#declare MyObjRef = object_ref { MyObj }; object { MyObjRef translate -x*10 } object { MyObjRef translate x*10 }
(The only thing being instantiated (and copied) here is the “MyObjRef” object, not the object it’s referring to, so that actual object is still stored in memory only once.)
In some situations it might even be so that referenced objects actually render faster than if the objects were copied because references increase data locality, lessening cache misses.
I believe this could be a rather useful feature and should be seriously considered, unless there are some major obstacles in implementing it.
To be exact, POV-Ray will create a new geometric object for all primitive types; however, for primitive types based on bulk data (most notably mesh/mesh2 and blobs), this very bulk data is shared between copies wherever possible. Another common feature of such "bulk objects" is that they have internal bounding mechanisms in place.
Allowing for arbitrary objects to be referenced by "reference objects" in a similar manner would seem to open up quite a can of worms: For instance, lifetime management of geometric primitives would need a major overhaul to make sure that objects are not deleted prematurely (e.g. right after parsing when they are not used directly in the scene) nor create memory leaks; care must be taken when to add an object's bounding box to the global bounding data structure, while properly adding it to some local bounding data structure of any reference objects that refer to them; and problems may arise regarding the desired effect of manipulations of a reference object other than transformations.
This certainly is a worthwhile feature, but requires changes only planned for the long term. The basic issue that is holding up implementation is as simple as the corresponding code having a strong C history and adding the feature requires cleaning up the use of C pointers first, by replacing them with container classes.
Now tracked on github as issue #274.