From 21f5faf364e672d27722edb864a7bb8121ffe32f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jan=20M=C3=B6bius?= Date: Wed, 26 Nov 2008 09:10:45 +0000 Subject: [PATCH] Created copy constructors and copy funtions for objects provided by core ( Meshobject,GroupObject, Baseobject and baseobjectdata) git-svn-id: http://www.openflipper.org/svnrepo/OpenFlipper/branches/Free@3800 383ad7c9-94d9-4d36-a494-682f7c89f535 --- BasePlugin/PluginFunctions.cc | 80 +++++++++++++++++++++++------------ BasePlugin/PluginFunctions.hh | 10 +++++ common/BaseObject.cc | 20 +++++++++ common/BaseObject.hh | 9 ++++ common/BaseObjectData.cc | 12 ++++++ common/BaseObjectData.hh | 9 +++- common/GroupObject.cc | 16 ++++++- common/GroupObject.hh | 36 ++++++++++------ common/MeshObjectT.cc | 31 +++++++++++++- common/MeshObjectT.hh | 16 ++++++- 10 files changed, 194 insertions(+), 45 deletions(-) diff --git a/BasePlugin/PluginFunctions.cc b/BasePlugin/PluginFunctions.cc index 97c19292..10a64790 100644 --- a/BasePlugin/PluginFunctions.cc +++ b/BasePlugin/PluginFunctions.cc @@ -12,12 +12,12 @@ // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. -// +// // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // @@ -168,39 +168,39 @@ bool get_target_identifiers( std::vector& _identifiers ) { // =============================================================================== bool get_object( int _identifier , BaseObject*& _object ) { - + if ( _identifier == -1 ) return false; - + _object = objectRoot_->childExists( _identifier ); return ( _object != 0 ); } bool get_object( int _identifier , BaseObjectData*& _object ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); _object = dynamic_cast< BaseObjectData* >(object); return ( _object != 0 ); } bool get_object( int _identifier , TriMeshObject*& _object ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); _object = dynamic_cast< TriMeshObject* >(object); return ( _object != 0 ); } bool get_object( int _identifier , PolyMeshObject*& _object ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); _object = dynamic_cast< PolyMeshObject* >(object); return ( _object != 0 ); @@ -211,10 +211,10 @@ bool get_object( int _identifier , PolyMeshObject*& _object ) { bool get_mesh( int _identifier , TriMesh*& _mesh ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); // Unable to find object @@ -232,10 +232,10 @@ bool get_mesh( int _identifier , TriMesh*& _mesh ) { } bool get_mesh( int _identifier , PolyMesh*& _mesh ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); // Unable to find object @@ -253,7 +253,7 @@ bool get_mesh( int _identifier , PolyMesh*& _mesh ) { } bool deleteObject( int _id ) { - + if ( _id == -1 ) return false; @@ -281,12 +281,40 @@ void deleteAll( ) { objectRoot()->deleteSubtree(); } +int copyObject( int _id ) { + if ( _id == -1 ) + return -1; + + // get the node + BaseObject* object = objectRoot_->childExists(_id); + + if ( !object ) { + std::cerr << "Error while copying object ... not found" << std::endl; + return -1; + } + + // remove the whole subtree below this item + BaseObject* copy = object->copy(); + + if ( copy == 0 ) { + std::cerr << "Unable to create a copy of the object." << std::endl; + } + + // Integrate into object tree + copy->setParent( object->parent() ); + if ( object->parent() ) + object->parent()->appendChild(copy); + else + std::cerr << "Unable to add copy to object list" << std::endl; + + return copy->id(); +} bool object_exists( int _identifier ) { - + if ( _identifier == -1 ) return false; - + BaseObject* object = objectRoot_->childExists( _identifier ); return ( object != 0 ); } @@ -421,8 +449,8 @@ void translate( const ACG::Vec3d &_vector ) { examiner_widget_->translate(_vector); } -void rotate(const ACG::Vec3d& _axis, - double _angle, +void rotate(const ACG::Vec3d& _axis, + double _angle, const ACG::Vec3d& _center) { examiner_widget_->rotate(_axis,_angle,_center); @@ -437,11 +465,11 @@ void viewAll() { } ACG::Vec3d viewingDirection() { - return examiner_widget_->glState().viewing_direction(); + return examiner_widget_->glState().viewing_direction(); } ACG::Vec3d eyePos() { - return examiner_widget_->glState().eye(); + return examiner_widget_->glState().eye(); } ACG::Vec3d upVector() { @@ -694,14 +722,14 @@ ObjectIterator objects_end() { BaseObjectData* baseObjectData( BaseObject* _object ){ if ( _object == 0 ) return 0; - + return dynamic_cast< BaseObjectData* >(_object); } TriMesh* triMesh( BaseObjectData* _object ) { if ( _object == 0 ) return 0; - + if ( _object->dataType(DATA_TRIANGLE_MESH) ) { TriMeshObject* object = dynamic_cast< TriMeshObject* >(_object); return object->mesh(); @@ -712,7 +740,7 @@ TriMesh* triMesh( BaseObjectData* _object ) { PolyMesh* polyMesh( BaseObjectData* _object ) { if ( _object == 0 ) return 0; - + if ( _object->dataType(DATA_POLY_MESH) ) { PolyMeshObject* object = dynamic_cast< PolyMeshObject* >(_object); return object->mesh(); @@ -723,7 +751,7 @@ PolyMesh* polyMesh( BaseObjectData* _object ) { TriMeshObject* triMeshObject( BaseObjectData* _object ) { if ( _object == 0 ) return 0; - + if ( ! _object->dataType(DATA_TRIANGLE_MESH) ) return NULL; return dynamic_cast< TriMeshObject* >( _object ); @@ -732,7 +760,7 @@ TriMeshObject* triMeshObject( BaseObjectData* _object ) { PolyMeshObject* polyMeshObject( BaseObjectData* _object ) { if ( _object == 0 ) return 0; - + if ( ! _object->dataType(DATA_POLY_MESH) ) return NULL; return dynamic_cast< PolyMeshObject* >( _object ); diff --git a/BasePlugin/PluginFunctions.hh b/BasePlugin/PluginFunctions.hh index 8d245a9e..851aa603 100644 --- a/BasePlugin/PluginFunctions.hh +++ b/BasePlugin/PluginFunctions.hh @@ -123,6 +123,16 @@ bool deleteObject( int _id ); DLLEXPORT void deleteAll( ); +/** \brief Create a copy of the object with the given id + * + * Creates a copy of an object. All scenegraph nodes will be created. The object will + * not be part of the object tree. This has to be done by setParent of the object. + * @return Pointer to new object or 0 if failed; + * */ +DLLEXPORT +int copyObject( int _id ); + + /** @} */ diff --git a/common/BaseObject.cc b/common/BaseObject.cc index 7de39b62..a0d39b8e 100644 --- a/common/BaseObject.cc +++ b/common/BaseObject.cc @@ -54,6 +54,21 @@ */ static int idGenerator = 1; +BaseObject::BaseObject(const BaseObject& _object) { + id_ = idGenerator; + ++idGenerator; + persistentId_ = _object.persistentId_; + objectType_ = _object.objectType_; + target_ = _object.target_; + source_ = _object.source_; + visible_ = _object.visible_; + parentItem_ = 0; + childItems_.clear(); + name_ = "Copy of " + _object.name_; + + ///@todo Maybe copy per Object Data + dataMap_.clear(); +} BaseObject::BaseObject(BaseObject* _parent) : id_(-1), @@ -533,6 +548,11 @@ void BaseObject::dumpTree() { } +BaseObject* BaseObject::copy() { + std::cerr << "Copy not supported by this Object" << std::endl; + return 0; +} + // =============================================================================== // per Object data functions diff --git a/common/BaseObject.hh b/common/BaseObject.hh index 89c1a0bd..202f3e8d 100644 --- a/common/BaseObject.hh +++ b/common/BaseObject.hh @@ -78,6 +78,12 @@ class DLLEXPORT BaseObject { friend class BaseObjectData; public : + + /** Creates a copy of this Object. Currently it will not have any per Object data attached. + * Its also not attached to the object tree. This has to be done by using setParent. + */ + BaseObject(const BaseObject& _object); + BaseObject( BaseObject *_parent = 0); virtual ~BaseObject(); @@ -239,6 +245,9 @@ class DLLEXPORT BaseObject { /// Debugging function, writing the subtree to output void dumpTree(); + /// Returns a full copy of the object + virtual BaseObject* copy(); + /** @} */ diff --git a/common/BaseObjectData.cc b/common/BaseObjectData.cc index ac0253b9..f1cbf872 100644 --- a/common/BaseObjectData.cc +++ b/common/BaseObjectData.cc @@ -48,6 +48,18 @@ //== CLASS DEFINITION ========================================================= +BaseObjectData::BaseObjectData(const BaseObjectData& _object) + : BaseObject(_object), + path_("."), + rootNode_(_object.rootNode_), + separatorNode_(0), + manipulatorNode_(0), + materialNode_(0) +{ + // We have to create our own visualization nodes as we are a new object + init(); +} + BaseObjectData::BaseObjectData( SeparatorNode* _rootNode ) : BaseObject(), path_("."), diff --git a/common/BaseObjectData.hh b/common/BaseObjectData.hh index c0ba84f9..36a4a31f 100644 --- a/common/BaseObjectData.hh +++ b/common/BaseObjectData.hh @@ -55,7 +55,7 @@ #else #define DLLEXPORT #endif -#endif +#endif //== INCLUDES ================================================================= @@ -87,6 +87,13 @@ typedef ACG::SceneGraph::BaseNode BaseNode; class DLLEXPORT BaseObjectData : public BaseObject { public: + + /** \brief copy constructor + * + * Create new basic scenegraph nodes for this object + */ + BaseObjectData(const BaseObjectData& _object); + /// constructor BaseObjectData(SeparatorNode* _rootNode); diff --git a/common/GroupObject.cc b/common/GroupObject.cc index c2a7ab21..b3e5a269 100644 --- a/common/GroupObject.cc +++ b/common/GroupObject.cc @@ -12,12 +12,12 @@ // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. -// +// // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // @@ -49,6 +49,13 @@ //== CLASS DEFINITION ========================================================= +GroupObject::GroupObject(const GroupObject& _object ): + BaseObject(_object) +{ + setDataType(DATA_GROUP); + setName(name()); +} + GroupObject::GroupObject( QString _groupName , GroupObject *_parent) : BaseObject(_parent) { @@ -60,5 +67,10 @@ GroupObject::~GroupObject() { } +BaseObject* GroupObject::copy() { + GroupObject* copy = new GroupObject(*this); + return dynamic_cast< BaseObject* > (copy); +} + //============================================================================= diff --git a/common/GroupObject.hh b/common/GroupObject.hh index 6fdbfd96..fd10a484 100644 --- a/common/GroupObject.hh +++ b/common/GroupObject.hh @@ -12,12 +12,12 @@ // it under the terms of the GNU Lesser General Public License as published by // the Free Software Foundation, either version 3 of the License, or // (at your option) any later version. -// +// // OpenFlipper is distributed in the hope that it will be useful, // but WITHOUT ANY WARRANTY; without even the implied warranty of // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the // GNU Lesser General Public License for more details. -// +// // You should have received a copy of the GNU Lesser General Public License // along with OpenFlipper. If not, see . // @@ -39,7 +39,7 @@ //============================================================================= /** - * \file Types.hh + * \file Types.hh * This File contains the basic available datatypes in the Framework. */ @@ -47,21 +47,21 @@ #ifndef GROUPOBJECT_HH #define GROUPOBJECT_HH - + #ifndef DLLEXPORT #ifdef WIN32 #define DLLEXPORT __declspec(dllexport) #else #define DLLEXPORT #endif -#endif +#endif //== INCLUDES ================================================================= #include //== TYPEDEFS ================================================================= - + //== CLASS DEFINITION ========================================================= @@ -70,20 +70,32 @@ */ class DLLEXPORT GroupObject : public BaseObject { public: + + /** copy constructor + * + */ + GroupObject(const GroupObject& _object ); + + /** constructor - * + * * @param _groupName Name of the new Group object */ GroupObject(QString _groupName = "Group" , GroupObject *parent = 0 ); - + /// destructor virtual ~GroupObject(); - - - /** @} */ + + /** return a full copy of this object. The object will not be a part of the object tree. + * This has to be done with the setParent() function. + */ + BaseObject* copy(); + + + /** @} */ }; - + //============================================================================= #endif // GROUPOBJECT_HH defined //============================================================================= diff --git a/common/MeshObjectT.cc b/common/MeshObjectT.cc index dc0ff966..cce63faa 100644 --- a/common/MeshObjectT.cc +++ b/common/MeshObjectT.cc @@ -52,6 +52,22 @@ //== CLASS DEFINITION ========================================================= + template < class MeshT , DataType objectDataType > + MeshObject< MeshT , objectDataType >::MeshObject(const MeshObject& _object) : + BaseObjectData(_object), + statusNode_(0), + areaNode_(0), + handleNode_(0), + meshNode_(0), + textureNode_(0), + shaderNode_(0), + triangle_bsp_(0) + { + init(_object.mesh_); + + setName( name() ); + } + /** Constructor for Mesh Objects. This object class gets a Separator Node giving * the root node to which it should be connected. The mesh is generated internally * and all nodes for visualization will be added below the scenegraph node.\n @@ -144,8 +160,12 @@ * the mesh and requests all required properties for the mesh. */ template < class MeshT , DataType objectDataType > - void MeshObject< MeshT , objectDataType >::init() { - mesh_ = new MeshT(); + void MeshObject< MeshT , objectDataType >::init(MeshT* _mesh) { + + if ( _mesh == 0 ) + mesh_ = new MeshT(); + else + mesh_ = new MeshT(*_mesh); mesh_->request_vertex_normals(); mesh_->request_face_normals(); @@ -307,6 +327,13 @@ handleNode_->update_cache(); } + + template < class MeshT , DataType objectDataType > + BaseObject* MeshObject< MeshT , objectDataType >::copy() { + MeshObject< MeshT , objectDataType >* object = new MeshObject< MeshT , objectDataType >(*this); + return dynamic_cast< BaseObject* >(object); + } + // =============================================================================== // Visualization // =============================================================================== diff --git a/common/MeshObjectT.hh b/common/MeshObjectT.hh index c83dbca8..87821d9c 100644 --- a/common/MeshObjectT.hh +++ b/common/MeshObjectT.hh @@ -54,7 +54,7 @@ #else #define DLLEXPORT #endif -#endif +#endif //== INCLUDES ================================================================= @@ -99,6 +99,13 @@ typedef ACG::SceneGraph::TextureNode TextureNode; template < class MeshT, DataType objectDataType > class DLLEXPORT MeshObject : public BaseObjectData { public: + + /** \brief copy constructor + * + * Create a copy of this object + */ + MeshObject(const MeshObject& _object); + /// constructor MeshObject(SeparatorNode* _rootNode); @@ -111,7 +118,7 @@ class DLLEXPORT MeshObject : public BaseObjectData { protected: /// Initialise current object, including all related nodes. - virtual void init(); + virtual void init( MeshT* _mesh = 0); //=========================================================================== /** @name Name and Path handling @@ -147,6 +154,11 @@ class DLLEXPORT MeshObject : public BaseObjectData { /// Update Topology of all data structures void updateTopology(); + /** return a full copy of this object ( All scenegraph nodes will be created ) + * but the object will not be a part of the object tree. + */ + BaseObject* copy(); + private: MeshT* mesh_; -- GitLab