From 2487861fbc2f13c012d2da4fcac82fbcbd4ceaeb Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Tue, 29 Jan 2002 12:52:04 +0000 Subject: [PATCH] Have add new osg::CopyOp which replaces last nights osg::Cloner, the new class now combines Cloner and DeepCopy into one class. Cloner and DeepCopy will be removed in next commit. Also have added osgcopy app to Demos which shows how the CopyOp have be subclassed to create users own specific handling of copying. Have fixed copy constructor problems in GeoSet which fix the deep copy problem experienced yesterday. --- Make/makedefs.linux | 8 +- VisualStudio/Demos/osgcopy/osgcopy.dsp | 191 +++++++++++++++++ VisualStudio/VisualStudio.dsw | 24 +++ VisualStudio/osg/osg.dsp | 12 +- include/osg/CopyOp | 60 ++++++ include/osg/Object | 7 +- src/Demos/Makefile | 2 +- src/Demos/osgcopy/Makedepend | 0 src/Demos/osgcopy/Makefile | 22 ++ src/Demos/osgcopy/osgcopy.cpp | 274 +++++++++++++++++++++++++ src/osg/CopyOp.cpp | 74 +++++++ src/osg/GeoSet.cpp | 12 +- src/osg/Geode.cpp | 2 +- src/osg/Group.cpp | 2 +- src/osg/Makefile | 4 +- src/osg/Node.cpp | 4 +- src/osg/StateSet.cpp | 14 +- 17 files changed, 683 insertions(+), 29 deletions(-) create mode 100755 VisualStudio/Demos/osgcopy/osgcopy.dsp create mode 100644 include/osg/CopyOp create mode 100644 src/Demos/osgcopy/Makedepend create mode 100644 src/Demos/osgcopy/Makefile create mode 100644 src/Demos/osgcopy/osgcopy.cpp create mode 100644 src/osg/CopyOp.cpp diff --git a/Make/makedefs.linux b/Make/makedefs.linux index 523ada4d0..221ab8610 100644 --- a/Make/makedefs.linux +++ b/Make/makedefs.linux @@ -10,16 +10,16 @@ C++ = g++ YFLAGS = -d LCINCS += -I/usr/X11R6/include LC++INCS += ${LCINCS} -CFLAGS = -O2 -W -Wall $(LCINCS) -#CFLAGS = -g -W -Wall $(LCINCS) +#CFLAGS = -O2 -W -Wall $(LCINCS) +CFLAGS = -g -W -Wall $(LCINCS) C++FLAGS = ${CFLAGS} CPPFLAGS = ${CFLAGS} SO_EXT = so DL_EXT = so -LDFLAGS = -O2 -W -Wall -L/usr/X11R6/lib -#LDFLAGS = -g -W -Wall -L/usr/X11R6/lib +#LDFLAGS = -O2 -W -Wall -L/usr/X11R6/lib +LDFLAGS = -g -W -Wall -L/usr/X11R6/lib LINKERARGS = -Xlinker DYNAMICLIBRARYLIB = -ldl diff --git a/VisualStudio/Demos/osgcopy/osgcopy.dsp b/VisualStudio/Demos/osgcopy/osgcopy.dsp new file mode 100755 index 000000000..81ccf9d50 --- /dev/null +++ b/VisualStudio/Demos/osgcopy/osgcopy.dsp @@ -0,0 +1,191 @@ +# Microsoft Developer Studio Project File - Name="osgcopy" - Package Owner=<4> + +# Microsoft Developer Studio Generated Build File, Format Version 6.00 + +# ** DO NOT EDIT ** + + + +# TARGTYPE "Win32 (x86) Console Application" 0x0103 + + + +CFG=osgcopy - Win32 Debug + +!MESSAGE This is not a valid makefile. To build this project using NMAKE, + +!MESSAGE use the Export Makefile command and run + +!MESSAGE + +!MESSAGE NMAKE /f "osgcopy.mak". + +!MESSAGE + +!MESSAGE You can specify a configuration when running NMAKE + +!MESSAGE by defining the macro CFG on the command line. For example: + +!MESSAGE + +!MESSAGE NMAKE /f "osgcopy.mak" CFG="osgcopy - Win32 Debug" + +!MESSAGE + +!MESSAGE Possible choices for configuration are: + +!MESSAGE + +!MESSAGE "osgcopy - Win32 Release" (based on "Win32 (x86) Console Application") + +!MESSAGE "osgcopy - Win32 Debug" (based on "Win32 (x86) Console Application") + +!MESSAGE + + + +# Begin Project + +# PROP AllowPerConfigDependencies 0 + +# PROP Scc_ProjName "" + +# PROP Scc_LocalPath "" + +CPP=cl.exe + +RSC=rc.exe + + + +!IF "$(CFG)" == "osgcopy - Win32 Release" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 0 + +# PROP BASE Output_Dir "Release" + +# PROP BASE Intermediate_Dir "Release" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 0 + +# PROP Output_Dir "Release" + +# PROP Intermediate_Dir "Release" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MD /W3 /GR /GX /O2 /I "../../../include" /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "NDEBUG" + +# ADD RSC /l 0x809 /d "NDEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /machine:I386 + +# ADD LINK32 /nologo /subsystem:console /pdb:none /machine:I386 /out:"../../../bin/osgcopy.exe" /libpath:"../../../lib" + + + +!ELSEIF "$(CFG)" == "osgcopy - Win32 Debug" + + + +# PROP BASE Use_MFC 0 + +# PROP BASE Use_Debug_Libraries 1 + +# PROP BASE Output_Dir "Debug" + +# PROP BASE Intermediate_Dir "Debug" + +# PROP BASE Target_Dir "" + +# PROP Use_MFC 0 + +# PROP Use_Debug_Libraries 1 + +# PROP Output_Dir "Debug" + +# PROP Intermediate_Dir "Debug" + +# PROP Ignore_Export_Lib 0 + +# PROP Target_Dir "" + +# ADD BASE CPP /nologo /W3 /Gm /GX /Zi /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c + +# ADD CPP /nologo /MDd /W3 /Gm /vd0 /GR /GX /Zi /Od /I "../../../include" /D "_CONSOLE" /D "_MBCS" /D "WIN32" /D "_DEBUG" /D "FL_DLL" /FR /YX /FD /c + +# ADD BASE RSC /l 0x809 /d "_DEBUG" + +# ADD RSC /l 0x809 /d "_DEBUG" + +BSC32=bscmake.exe + +# ADD BASE BSC32 /nologo + +# ADD BSC32 /nologo + +LINK32=link.exe + +# ADD BASE LINK32 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib /nologo /subsystem:console /debug /machine:I386 /pdbtype:sept + +# ADD LINK32 glut32.lib glu32.lib opengl32.lib /nologo /subsystem:console /debug /machine:I386 /nodefaultlib:"libcmt" /out:"../../../bin/osgcopyd.exe" /pdbtype:sept /libpath:"../../../lib" + +# SUBTRACT LINK32 /incremental:no + + + +!ENDIF + + + +# Begin Target + + + +# Name "osgcopy - Win32 Release" + +# Name "osgcopy - Win32 Debug" + +# Begin Source File + + + +SOURCE=..\..\..\src\Demos\osgcopy\osgcopy.cpp + +# End Source File + +# End Target + +# Begin Group "Resource Files" + + + +# PROP Default_Filter "ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe" + +# End Group + +# End Project + + \ No newline at end of file diff --git a/VisualStudio/VisualStudio.dsw b/VisualStudio/VisualStudio.dsw index 771c337e2..b48f05d6f 100644 --- a/VisualStudio/VisualStudio.dsw +++ b/VisualStudio/VisualStudio.dsw @@ -540,6 +540,30 @@ Package=<4> ############################################################################### +Project: "osgcopy"=".\Demos\osgcopy\osgcopy.dsp" - Package Owner=<4> + +Package=<5> +{{{ +}}} + +Package=<4> +{{{ + Begin Project Dependency + Project_Dep_Name osg + End Project Dependency + Begin Project Dependency + Project_Dep_Name osgUtil + End Project Dependency + Begin Project Dependency + Project_Dep_Name osgDB + End Project Dependency + Begin Project Dependency + Project_Dep_Name osgGLUT + End Project Dependency +}}} + +############################################################################### + Project: "tga"=".\osgPlugins\tga\tga.dsp" - Package Owner=<4> Package=<5> diff --git a/VisualStudio/osg/osg.dsp b/VisualStudio/osg/osg.dsp index 9538af1e6..5290d9d4e 100755 --- a/VisualStudio/osg/osg.dsp +++ b/VisualStudio/osg/osg.dsp @@ -125,6 +125,10 @@ SOURCE=..\..\src\osg\ColorMatrix.cpp # End Source File # Begin Source File +SOURCE=..\..\src\osg\CopyOp.cpp +# End Source File +# Begin Source File + SOURCE=..\..\src\osg\CullFace.cpp # End Source File # Begin Source File @@ -357,11 +361,11 @@ SOURCE=..\..\Include\Osg\ColorMatrix # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\CullFace +SOURCE=..\..\Include\Osg\CopyOp # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\DeepCopy +SOURCE=..\..\Include\Osg\CullFace # End Source File # Begin Source File @@ -525,10 +529,6 @@ SOURCE=..\..\Include\Osg\ShadeModel # End Source File # Begin Source File -SOURCE=..\..\Include\Osg\ShallowCopy -# End Source File -# Begin Source File - SOURCE=..\..\Include\Osg\State # End Source File # Begin Source File diff --git a/include/osg/CopyOp b/include/osg/CopyOp new file mode 100644 index 000000000..7c1d8c59a --- /dev/null +++ b/include/osg/CopyOp @@ -0,0 +1,60 @@ +//C++ header - Open Scene Graph - Copyright (C) 1998-2001 Robert Osfield +//Distributed under the terms of the GNU Library General Public License (LGPL) +//as published by the Free Software Foundation. + +#ifndef OSG_COPYOP +#define OSG_COPYOP 1 + +namespace osg { + +class Referenced; +class Object; +class Image; +class Texture; +class StateSet; +class StateAttribute; +class Node; +class Drawable; + +/** Copy Op(erator) used to control the whether shallow or deep copy is used + * during copy construction and clone operation.*/ +class CopyOp +{ + + public: + + enum Options + { + SHALLOW_COPY = 0, + DEEP_COPY_OBJECTS = 1, + DEEP_COPY_NODES = 2, + DEEP_COPY_DRAWABLES = 4, + DEEP_COPY_STATESETS = 8, + DEEP_COPY_STATEATTRIBUTES = 16, + DEEP_COPY_TEXTURES = 32, + DEEP_COPY_IMAGES = 64, + DEEP_COPY_ALL = 0xffffffff + }; + + typedef unsigned int CopyFlags; + + inline CopyOp(CopyFlags flags=SHALLOW_COPY):_flags(flags) {} + virtual ~CopyOp() {} + + virtual Referenced* operator() (const Referenced* ref) const; + virtual Object* operator() (const Object* obj) const; + virtual Node* operator() (const Node* node) const; + virtual Drawable* operator() (const Drawable* drawable) const; + virtual StateSet* operator() (const StateSet* stateset) const; + virtual StateAttribute* operator() (const StateAttribute* attr) const; + virtual Texture* operator() (const Texture* text) const; + virtual Image* operator() (const Image* image) const; + + protected: + + CopyFlags _flags; +}; + +}; + +#endif diff --git a/include/osg/Object b/include/osg/Object index bfb141a88..a1191f969 100644 --- a/include/osg/Object +++ b/include/osg/Object @@ -6,10 +6,13 @@ #define OSG_OBJECT 1 #include -#include +#include namespace osg { +typedef CopyOp Cloner; +typedef CopyOp ShallowCopy; + /** META_Object macro define the standard clone, isSameKindAs and className methods. * Use when subclassing from Object to make it more convinient to define * the standard pure virtual clone, isSameKindAs and className methods @@ -38,7 +41,7 @@ class SG_EXPORT Object : public Referenced /** Copy constructor, optional Cloner object can be used to control * shallow vs deep copying of dynamic data.*/ - Object(const Object&,const Cloner& cloner=ShallowCopy()); + Object(const Object&,const Cloner& cloner=CopyOp::SHALLOW_COPY); /** Clone the type of an object, with Object* return type. Must be defined by derived classes.*/ diff --git a/src/Demos/Makefile b/src/Demos/Makefile index 857263d9b..720219953 100644 --- a/src/Demos/Makefile +++ b/src/Demos/Makefile @@ -1,7 +1,7 @@ #!smake SHELL=/bin/sh -DIRS = sgv osgconv osgcube osgscribe osgreflect osgtexture osgimpostor osgviews hangglide +DIRS = sgv osgconv osgcube osgscribe osgreflect osgtexture osgimpostor osgviews osgcopy hangglide # comment out if you don't have the freetype and GLU1.3 library installed. DIRS += osgtext diff --git a/src/Demos/osgcopy/Makedepend b/src/Demos/osgcopy/Makedepend new file mode 100644 index 000000000..e69de29bb diff --git a/src/Demos/osgcopy/Makefile b/src/Demos/osgcopy/Makefile new file mode 100644 index 000000000..f30c733a0 --- /dev/null +++ b/src/Demos/osgcopy/Makefile @@ -0,0 +1,22 @@ +#!smake +include $(OSGHOME)/Make/makedefs + +C++FILES = \ + osgcopy.cpp + +TARGET = $(OSGHOME)/bin/osgcopy + +TARGET_BIN_FILES = osgcopy + +#note, standard library list. +LIBS = -losgGLUT -losgUtil -losgDB -losg $(GLUTLIB) $(GL_LIBS) $(X_LIBS) + +#under Darwin we have to use the framework stuff to get GLUT OpenGL etc. +MACOSXLIBS = -losgGLUT -losgUtil -losgDB -losg -lm -ldl -lstdc++ -lobjc + + +C++FLAGS += -I$(OSGHOME)/include +LDFLAGS += -L$(OSGHOME)/lib + +include $(OSGHOME)/Make/makerules + diff --git a/src/Demos/osgcopy/osgcopy.cpp b/src/Demos/osgcopy/osgcopy.cpp new file mode 100644 index 000000000..7bf569ba4 --- /dev/null +++ b/src/Demos/osgcopy/osgcopy.cpp @@ -0,0 +1,274 @@ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#include +#include +#include + +#include +#include + +#include + +void write_usage(std::ostream& out,const std::string& name) +{ + out << std::endl; + out <<"usage:"<< std::endl; + out <<" "<className(); + std::cout<className()<<" '"<getName()<<"'"; + std::cout<className(); + std::cout<className(); + std::cout<className(); + std::cout<className(); + std::cout<className(); + std::cout< commandLine; + for(int i=1;i(rootnode->clone(osg::CopyOp::DEEP_COPY_ALL)); + std::cout << "Doing a deep copy of scene graph"<(rootnode->clone(MyCopyOp(osg::CopyOp::DEEP_COPY_ALL))); + + std::cout << "----------------------------------------------------------------"<(rootnode->clone(MyCopyOp(osg::CopyOp::SHALLOW_COPY))); + + + std::cout << std::endl << "Writing out the original scene graph as 'original.osg'"<(rootnode->clone(osg::CopyOp::DEEP_COPY_NODES | DEEP_COPY_DRAWABLES)); + // Which shares state but creates copies of all nodes and drawables (which contain the geometry). + // + // You may also want to subclass from CopyOp to provide finer grained control of what gets shared (shallow copy) vs + // cloned (deep copy). + + + +// ------------- End of copy specific code ------------------------------------------------------- + + // add a viewport to the viewer and attach the scene graph. + viewer.addViewport( rootnode ); + + // register trackball, flight and drive. + viewer.registerCameraManipulator(new osgUtil::TrackballManipulator); + viewer.registerCameraManipulator(new osgUtil::FlightManipulator); + viewer.registerCameraManipulator(new osgUtil::DriveManipulator); + + // open the viewer window. + viewer.open(); + + // fire up the event loop. + viewer.run(); + + return 0; +} diff --git a/src/osg/CopyOp.cpp b/src/osg/CopyOp.cpp new file mode 100644 index 000000000..9cd03df94 --- /dev/null +++ b/src/osg/CopyOp.cpp @@ -0,0 +1,74 @@ +#include +#include +#include +#include +#include + +using namespace osg; + +Referenced* CopyOp::operator() (const Referenced* ref) const +{ + return const_cast(ref); +} + +Object* CopyOp::operator() (const Object* obj) const +{ + if (obj && _flags&DEEP_COPY_OBJECTS) + return obj->clone(*this); + else return const_cast(obj); +} + +Node* CopyOp::operator() (const Node* node) const +{ + if (node && _flags&DEEP_COPY_NODES) + return dynamic_cast(node->clone(*this)); + else + return const_cast(node); +} + +Drawable* CopyOp::operator() (const Drawable* drawable) const +{ + if (drawable && _flags&DEEP_COPY_DRAWABLES) + return dynamic_cast(drawable->clone(*this)); + else + return const_cast(drawable); +} + +StateSet* CopyOp::operator() (const StateSet* stateset) const +{ + if (stateset && _flags&DEEP_COPY_STATESETS) + return dynamic_cast(stateset->clone(*this)); + else + return const_cast(stateset); +} + +StateAttribute* CopyOp::operator() (const StateAttribute* attr) const +{ + if (attr && _flags&DEEP_COPY_STATEATTRIBUTES) + { + const Texture* text = dynamic_cast(attr); + if (text) + { + return operator()(text); + } + else + return dynamic_cast(attr->clone(*this)); + } + else + return const_cast(attr); +} + +Texture* CopyOp::operator() (const Texture* text) const +{ + if (text && _flags&DEEP_COPY_TEXTURES) + return dynamic_cast(text->clone(*this)); + else + return const_cast(text); +} + +Image* CopyOp::operator() (const Image* image) const +{ + if (image && _flags&DEEP_COPY_IMAGES) + return dynamic_cast(image->clone(*this)); + else return const_cast(image); +} diff --git a/src/osg/GeoSet.cpp b/src/osg/GeoSet.cpp index 9940a96eb..43ec5a0e9 100644 --- a/src/osg/GeoSet.cpp +++ b/src/osg/GeoSet.cpp @@ -66,8 +66,8 @@ GeoSet::GeoSet(const GeoSet& geoset,const Cloner& cloner): _flat_shaded_skip = geoset._flat_shaded_skip; if (geoset._primLengths) { - _primLengths = new int [_primlength]; - memcpy(_primLengths,geoset._primLengths,_primlength); + _primLengths = new int [_numprims]; + memcpy(_primLengths,geoset._primLengths,_numprims*sizeof(int)); } else { @@ -79,7 +79,7 @@ GeoSet::GeoSet(const GeoSet& geoset,const Cloner& cloner): if (geoset._coords) { _coords = new Vec3 [_numcoords]; - memcpy(_coords,geoset._coords,_numcoords); + memcpy(_coords,geoset._coords,_numcoords*sizeof(Vec3)); } else { @@ -92,7 +92,7 @@ GeoSet::GeoSet(const GeoSet& geoset,const Cloner& cloner): if (geoset._normals) { _normals = new Vec3 [_numnormals]; - memcpy(_normals,geoset._normals,_numnormals); + memcpy(_normals,geoset._normals,_numnormals*sizeof(Vec3)); } else { @@ -105,7 +105,7 @@ GeoSet::GeoSet(const GeoSet& geoset,const Cloner& cloner): if (geoset._colors) { _colors = new Vec4 [_numcolors]; - memcpy(_colors,geoset._colors,_numcolors); + memcpy(_colors,geoset._colors,_numcolors*sizeof(Vec4)); } else { @@ -118,7 +118,7 @@ GeoSet::GeoSet(const GeoSet& geoset,const Cloner& cloner): if (geoset._tcoords) { _tcoords = new Vec2 [_numtcoords]; - memcpy(_tcoords,geoset._tcoords,_numtcoords); + memcpy(_tcoords,geoset._tcoords,_numtcoords*sizeof(Vec2)); } else { diff --git a/src/osg/Geode.cpp b/src/osg/Geode.cpp index bc9eb7e77..2ad0252f8 100644 --- a/src/osg/Geode.cpp +++ b/src/osg/Geode.cpp @@ -18,7 +18,7 @@ Geode::Geode(const Geode& geode,const Cloner& cloner): ++itr) { Drawable* drawable = cloner(itr->get()); - if (drawable) _drawables.push_back(drawable); + if (drawable) addDrawable(drawable); } } diff --git a/src/osg/Group.cpp b/src/osg/Group.cpp index 66f93b5a9..096819c1b 100644 --- a/src/osg/Group.cpp +++ b/src/osg/Group.cpp @@ -21,7 +21,7 @@ Group::Group(const Group& group,const Cloner& cloner): ++itr) { Node* child = cloner(itr->get()); - if (child) _children.push_back(child); + if (child) addChild(child); } } diff --git a/src/osg/Makefile b/src/osg/Makefile index 683094a1e..d5c8fb43e 100644 --- a/src/osg/Makefile +++ b/src/osg/Makefile @@ -10,6 +10,7 @@ C++FILES = \ ClipPlane.cpp \ ColorMask.cpp \ ColorMatrix.cpp \ + CopyOp.cpp \ CullFace.cpp\ Depth.cpp \ DisplaySettings.cpp\ @@ -75,9 +76,9 @@ TARGET_INCLUDE_FILES = \ osg/ClippingVolume\ osg/ColorMask\ osg/ColorMatrix\ + osg/CopyOp\ osg/CullFace\ osg/Depth\ - osg/DeepCopy\ osg/DisplaySettings\ osg/Drawable\ osg/EarthSky\ @@ -114,7 +115,6 @@ TARGET_INCLUDE_FILES = \ osg/Plane\ osg/Quat\ osg/Referenced\ - osg/ShallowCopy\ osg/State\ osg/StateAttribute\ osg/StateSet\ diff --git a/src/osg/Node.cpp b/src/osg/Node.cpp index 7977c3659..332e84c91 100644 --- a/src/osg/Node.cpp +++ b/src/osg/Node.cpp @@ -27,9 +27,9 @@ Node::Node(const Node& node,const Cloner& cloner): _name(node._name), _parents(), // leave empty as parentList is managed by Group. _appCallback(node._appCallback), - _numChildrenRequiringAppTraversal(node._numChildrenRequiringAppTraversal), + _numChildrenRequiringAppTraversal(0), // assume no children yet. _cullingActive(node._cullingActive), - _numChildrenWithCullingDisabled(node._numChildrenWithCullingDisabled), + _numChildrenWithCullingDisabled(0), // assume no children yet. _userData(cloner(node._userData.get())), _nodeMask(node._nodeMask), _descriptions(node._descriptions), diff --git a/src/osg/StateSet.cpp b/src/osg/StateSet.cpp index 0846a2f3c..a03814a0f 100644 --- a/src/osg/StateSet.cpp +++ b/src/osg/StateSet.cpp @@ -23,11 +23,17 @@ StateSet::StateSet() StateSet::StateSet(const StateSet& rhs,const Cloner& cloner):Object(rhs,cloner) { - // shallow copy right now, we should go through each attribute and - // use the cloner instead of attribute list copy.. on the TODO list. Robert. Jan 2002. - _modeList = rhs._modeList; - _attributeList = rhs._attributeList; + + for(AttributeList::const_iterator itr=rhs._attributeList.begin(); + itr!=rhs._attributeList.end(); + ++itr) + { + StateAttribute::Type type = itr->first; + const RefAttributePair& rap = itr->second; + StateAttribute* attr = cloner(rap.first.get()); + if (attr) _attributeList[type]=RefAttributePair(attr,rap.second); + } _renderingHint = rhs._renderingHint;