Re: [osg-users] Copy Constructor Advice
Hi Jeremy, In your case where you have data being shared between a subclass and its base class I feel that this duplication of ref_ptr to the shared data is inappropriate. Rather what you should use in your own code is dynamic_castVec3Array* where you need access to the array, or to provide a convenience method to getVec3Array() { return dynamic_castVec3Array*(getVertexArray()); } Would this solve this problem? Robert. On Feb 18, 2008 7:31 PM, Jeremy Moles [EMAIL PROTECTED] wrote: Thanks for the response, Robert. On Mon, 2008-02-18 at 17:54 +, Robert Osfield wrote: Hi Jeremy, Most OSG objects implement the clone operator with CopyOp parameter so you can just pass this along. For objects like std::vector etc you would typically just implement a deep copy, i.e. copy all the contents, unless of course its a vector of ref_ptr's in which case copying the contents of the vector shares the pointers so you have to do a element by element deep copy op on the objects if that's what is required. To see examples of various ways of implementing the copy operator have a look at the implementations - they are all over the OSG. Hmm, I think I probably wasn't as clear as I could have been--or perhaps I'm still misunderstanding. Let me provide another very simple, contrived example here: // --- struct MyGeometry: public Geometry { ref_ptrVec3Array _verts; MyGeometry() { _verts = allocateSomeGeometry(); setVertexArray(_verts.get()); } MyGeometry(const MyGeometry myG, const CopyOp co): Geometry(myG, co) { } } MyGeometry* mg1 = new MyGeometry(); MyGeometry* mg2 = mg1-clone(CopyOp::DEEP_COPY_ALL); // --- With the above code, the _verts ref_ptr in mg2 won't point to anything, since I haven't intialized it, although mg2 WILL have the proper geometry, since there was a deep copy of all the existing data (in fact, osgWidget introduces it's own cloneAs method which always does a DEEP_COPY, since this is almost always desired). What I'm wanting to do--and haven't been able to find an example of in OSG yet--is an easy way to set _verts in the copy. Simply adjusting the copy constructor to look like the following: // --- MyGeometry(const MyGeometry myG, const CopyOp co): Geometry (myG, co), _verts (myG._verts) { } // --- ...gives me a ref_ptr that references data in the old object, naturally. Currently, I'm able to work around and get the desired behavior, but I want to make sure everything is proper before implementing a lot of stuff wrong and having the submission rejected because of little weird things like this. :) You can see a real world example in action here: http://code.google.com/p/osgwidget/source/browse/tags/0.1.5/src/Widget.cpp#70 Robert. On Feb 18, 2008 5:10 PM, Jeremy Moles [EMAIL PROTECTED] wrote: I have a quick question that I may be over-thinking, of which I have yet to find a simple answer. Imagine that I have a class Derived from osg::MatrixTransform--let's call this osgWidget::Window. In my derived Window class, I have a number of osg::ref_ptr objects referencing various things that get added to the Window object itself, and which I keep around for ease of use elsewhere in the API. I want to provide suitable copy constructors (and am required to do so by using the META_Object macro, thankfully), but I'm beginning to see a definite problem when setting the pointers in the new copies ref_ptr object. Usually I can come up with clever tricks to do so, but generally it's not very straightforward--which leads me to my main question: is it generally bad design to keep ref_ptr's around like this when designing classes that will directly derive from OSG objects? Using osg::CopyOp::DEEP_COPY_ALL ensures that I will get a full copy of the subgraph, which is certainly the desired behavior, but I'm not entirely sure I know the best way to easily set any internal ref_ptr's to the new subgraph after copy other than--like I mentioned earlier--clever tricks. :) Below is an example of one such abomination: // Here we're in the copy ctor() Window::Window(const Window w, const CopyOp co): MatrixTransform(w, co) { ColorArray* c = dynamic_castColorArray*(getColorArray()); if(c) _c = c; } ...where _c is my osg::ref_ptrColorArray object, and where getColorArray() works because we're using DEEP_COPY_ALL and we assume all of the geometry was deeply copied into the new object. I really feel like I'm missing an easier way to do this... ___ osg-users
Re: [osg-users] Copy Constructor Advice
On Tue, 2008-02-19 at 09:44 +, Robert Osfield wrote: Hi Jeremy, In your case where you have data being shared between a subclass and its base class I feel that this duplication of ref_ptr to the shared data is inappropriate. Rather what you should use in your own code is dynamic_castVec3Array* where you need access to the array, or to provide a convenience method to getVec3Array() { return dynamic_castVec3Array*(getVertexArray()); } Yeah, you're right about this; the duplication probably is inappropriate, and is exemplified by issues here with it. :) Would this solve this problem? Yes indeed! I will make it so... Robert. On Feb 18, 2008 7:31 PM, Jeremy Moles [EMAIL PROTECTED] wrote: Thanks for the response, Robert. On Mon, 2008-02-18 at 17:54 +, Robert Osfield wrote: Hi Jeremy, Most OSG objects implement the clone operator with CopyOp parameter so you can just pass this along. For objects like std::vector etc you would typically just implement a deep copy, i.e. copy all the contents, unless of course its a vector of ref_ptr's in which case copying the contents of the vector shares the pointers so you have to do a element by element deep copy op on the objects if that's what is required. To see examples of various ways of implementing the copy operator have a look at the implementations - they are all over the OSG. Hmm, I think I probably wasn't as clear as I could have been--or perhaps I'm still misunderstanding. Let me provide another very simple, contrived example here: // --- struct MyGeometry: public Geometry { ref_ptrVec3Array _verts; MyGeometry() { _verts = allocateSomeGeometry(); setVertexArray(_verts.get()); } MyGeometry(const MyGeometry myG, const CopyOp co): Geometry(myG, co) { } } MyGeometry* mg1 = new MyGeometry(); MyGeometry* mg2 = mg1-clone(CopyOp::DEEP_COPY_ALL); // --- With the above code, the _verts ref_ptr in mg2 won't point to anything, since I haven't intialized it, although mg2 WILL have the proper geometry, since there was a deep copy of all the existing data (in fact, osgWidget introduces it's own cloneAs method which always does a DEEP_COPY, since this is almost always desired). What I'm wanting to do--and haven't been able to find an example of in OSG yet--is an easy way to set _verts in the copy. Simply adjusting the copy constructor to look like the following: // --- MyGeometry(const MyGeometry myG, const CopyOp co): Geometry (myG, co), _verts (myG._verts) { } // --- ...gives me a ref_ptr that references data in the old object, naturally. Currently, I'm able to work around and get the desired behavior, but I want to make sure everything is proper before implementing a lot of stuff wrong and having the submission rejected because of little weird things like this. :) You can see a real world example in action here: http://code.google.com/p/osgwidget/source/browse/tags/0.1.5/src/Widget.cpp#70 Robert. On Feb 18, 2008 5:10 PM, Jeremy Moles [EMAIL PROTECTED] wrote: I have a quick question that I may be over-thinking, of which I have yet to find a simple answer. Imagine that I have a class Derived from osg::MatrixTransform--let's call this osgWidget::Window. In my derived Window class, I have a number of osg::ref_ptr objects referencing various things that get added to the Window object itself, and which I keep around for ease of use elsewhere in the API. I want to provide suitable copy constructors (and am required to do so by using the META_Object macro, thankfully), but I'm beginning to see a definite problem when setting the pointers in the new copies ref_ptr object. Usually I can come up with clever tricks to do so, but generally it's not very straightforward--which leads me to my main question: is it generally bad design to keep ref_ptr's around like this when designing classes that will directly derive from OSG objects? Using osg::CopyOp::DEEP_COPY_ALL ensures that I will get a full copy of the subgraph, which is certainly the desired behavior, but I'm not entirely sure I know the best way to easily set any internal ref_ptr's to the new subgraph after copy other than--like I mentioned earlier--clever tricks. :) Below is an example of one such abomination: // Here we're in the copy ctor() Window::Window(const Window w, const CopyOp co): MatrixTransform(w, co) { ColorArray* c = dynamic_castColorArray*(getColorArray()); if(c) _c = c; }
Re: [osg-users] Copy Constructor Advice
Hi Jeremy, Most OSG objects implement the clone operator with CopyOp parameter so you can just pass this along. For objects like std::vector etc you would typically just implement a deep copy, i.e. copy all the contents, unless of course its a vector of ref_ptr's in which case copying the contents of the vector shares the pointers so you have to do a element by element deep copy op on the objects if that's what is required. To see examples of various ways of implementing the copy operator have a look at the implementations - they are all over the OSG. Robert. On Feb 18, 2008 5:10 PM, Jeremy Moles [EMAIL PROTECTED] wrote: I have a quick question that I may be over-thinking, of which I have yet to find a simple answer. Imagine that I have a class Derived from osg::MatrixTransform--let's call this osgWidget::Window. In my derived Window class, I have a number of osg::ref_ptr objects referencing various things that get added to the Window object itself, and which I keep around for ease of use elsewhere in the API. I want to provide suitable copy constructors (and am required to do so by using the META_Object macro, thankfully), but I'm beginning to see a definite problem when setting the pointers in the new copies ref_ptr object. Usually I can come up with clever tricks to do so, but generally it's not very straightforward--which leads me to my main question: is it generally bad design to keep ref_ptr's around like this when designing classes that will directly derive from OSG objects? Using osg::CopyOp::DEEP_COPY_ALL ensures that I will get a full copy of the subgraph, which is certainly the desired behavior, but I'm not entirely sure I know the best way to easily set any internal ref_ptr's to the new subgraph after copy other than--like I mentioned earlier--clever tricks. :) Below is an example of one such abomination: // Here we're in the copy ctor() Window::Window(const Window w, const CopyOp co): MatrixTransform(w, co) { ColorArray* c = dynamic_castColorArray*(getColorArray()); if(c) _c = c; } ...where _c is my osg::ref_ptrColorArray object, and where getColorArray() works because we're using DEEP_COPY_ALL and we assume all of the geometry was deeply copied into the new object. I really feel like I'm missing an easier way to do this... ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org ___ osg-users mailing list osg-users@lists.openscenegraph.org http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org