diff --git a/src/osgPlugins/3ds/ReaderWriter3DS.cpp b/src/osgPlugins/3ds/ReaderWriter3DS.cpp index 7227d39f2..3193e3eb7 100644 --- a/src/osgPlugins/3ds/ReaderWriter3DS.cpp +++ b/src/osgPlugins/3ds/ReaderWriter3DS.cpp @@ -36,6 +36,50 @@ using namespace std; using namespace osg; +/// Implementation borrowed from boost and slightly modified +template class scoped_array // noncopyable +{ +private: + T * px; + scoped_array(scoped_array const &); + scoped_array & operator=(scoped_array const &); + typedef scoped_array this_type; + + void operator==( scoped_array const& ) const; + void operator!=( scoped_array const& ) const; + +public: + typedef T element_type; + explicit scoped_array( T * p = 0 ) : px( p ) {} + + ~scoped_array() { delete[] px; } + + void reset(T * p = 0) { + assert( p == 0 || p != px ); // catch self-reset errors + this_type(p).swap(*this); + } + + T & operator[](std::ptrdiff_t i) const // never throws + { + assert( px != 0 ); + assert( i >= 0 ); + return px[i]; + } + + T * get() const // never throws + { + return px; + } + + void swap(scoped_array & b) // never throws + { + T * tmp = b.px; + b.px = px; + px = tmp; + } +}; + + void copyLib3dsMatrixToOsgMatrix(osg::Matrix& osg_matrix, const Lib3dsMatrix lib3ds_matrix) { @@ -315,22 +359,22 @@ void ReaderWriter3DS::ReaderObject::addDrawableFromFace(osg::Geode * geode, Face // don't get shared. FaceList& smoothFaceMap = sitr->second; osg::ref_ptr drawable = createDrawable(mesh,smoothFaceMap,matrix); - if (drawable) + if (drawable.valid()) { if (stateSet) drawable->setStateSet(stateSet); - geode->addDrawable(drawable); + geode->addDrawable(drawable.get()); } } } else // ignore smoothing groups. { osg::ref_ptr drawable = createDrawable(mesh,faceList,matrix); - if (drawable) + if (drawable.valid()) { if (stateSet) drawable->setStateSet(stateSet); - geode->addDrawable(drawable); + geode->addDrawable(drawable.get()); } } } @@ -700,8 +744,7 @@ use matrix to pretransform geometry, or NULL to do nothing */ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceList& faceList, const osg::Matrix * matrix) { - - osg::Geometry* geom = new osg::Geometry; + osg::Geometry * geom = new osg::Geometry; unsigned int i; std::vector orig2NewMapping; @@ -730,8 +773,8 @@ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceL // create vertices. - osg::Vec3Array* osg_coords = new osg::Vec3Array(noVertex); - geom->setVertexArray(osg_coords); + osg::ref_ptr osg_coords = new osg::Vec3Array(noVertex); + geom->setVertexArray(osg_coords.get()); for (i=0; invertices; ++i) { @@ -752,8 +795,8 @@ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceL // create texture coords if needed. if (m->texcos) { - osg::Vec2Array* osg_tcoords = new osg::Vec2Array(noVertex); - geom->setTexCoordArray(0,osg_tcoords); + osg::ref_ptr osg_tcoords = new osg::Vec2Array(noVertex); + geom->setTexCoordArray(0, osg_tcoords.get()); for (i=0; invertices; ++i) { if (orig2NewMapping[i]>=0) (*osg_tcoords)[orig2NewMapping[i]].set(m->texcos[i][0],m->texcos[i][1]); @@ -767,9 +810,9 @@ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceL { //Lib3dsVector * normals = new Lib3dsVector[m->nfaces*3]; //lib3ds_mesh_calculate_vertex_normals(m, normals); - Lib3dsVector * normals = new Lib3dsVector[m->nfaces]; - lib3ds_mesh_calculate_face_normals(m, normals); - osg::Vec3Array* osg_normals = new osg::Vec3Array(noVertex); + scoped_array normals( new Lib3dsVector[m->nfaces] ); // Temporary array + lib3ds_mesh_calculate_face_normals(m, normals.get()); + osg::ref_ptr osg_normals = new osg::Vec3Array(noVertex); // initialize normal list to zero's. for (i=0; isetNormalArray(osg_normals); + geom->setNormalArray(osg_normals.get()); geom->setNormalBinding(osg::Geometry::BIND_PER_VERTEX); - } else { - Lib3dsVector * normals = new Lib3dsVector[m->nfaces]; + scoped_array normals ( new Lib3dsVector[m->nfaces] ); lib3ds_mesh_calculate_face_normals(m, normals); - osg::Vec3Array* osg_normals = new osg::Vec3Array(faceList.size()); + osg::ref_ptr osg_normals = new osg::Vec3Array(faceList.size()); osg::Vec3Array::iterator normal_itr = osg_normals->begin(); for (fitr=faceList.begin(); fitr!=faceList.end(); @@ -809,19 +851,18 @@ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceL osgNormal.normalize(); *(normal_itr++) = osgNormal; } - geom->setNormalArray(osg_normals); + geom->setNormalArray(osg_normals.get()); geom->setNormalBinding(osg::Geometry::BIND_PER_PRIMITIVE); } - osg::Vec4ubArray* osg_colors = new osg::Vec4ubArray(1); + osg::ref_ptr osg_colors = new osg::Vec4ubArray(1); (*osg_colors)[0].set(255,255,255,255); - geom->setColorArray(osg_colors); + geom->setColorArray(osg_colors.get()); geom->setColorBinding(osg::Geometry::BIND_OVERALL); - // create primitives int numIndices = faceList.size()*3; - DrawElementsUShort* elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES,numIndices); + osg::ref_ptr elements = new osg::DrawElementsUShort(osg::PrimitiveSet::TRIANGLES,numIndices); DrawElementsUShort::iterator index_itr = elements->begin(); for (fitr=faceList.begin(); @@ -829,13 +870,12 @@ osg::Drawable* ReaderWriter3DS::ReaderObject::createDrawable(Lib3dsMesh *m,FaceL ++fitr) { Lib3dsFace& face = m->faces[*fitr]; - *(index_itr++) = orig2NewMapping[face.index[0]]; *(index_itr++) = orig2NewMapping[face.index[1]]; *(index_itr++) = orig2NewMapping[face.index[2]]; } - geom->addPrimitiveSet(elements); + geom->addPrimitiveSet(elements.get()); #if 0 osgUtil::TriStripVisitor tsv; @@ -1034,7 +1074,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& nod osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->getDatabasePathList().push_front(osgDB::getFilePath(fileName)); - if (!createFileObject(node, file3ds, fileName, local_opt)) ok = false; + if (!createFileObject(node, file3ds, fileName, local_opt.get())) ok = false; if (ok && !lib3ds_file_save(file3ds, fileName.c_str())) ok = false; } catch (...) { lib3ds_file_free(file3ds); @@ -1069,7 +1109,7 @@ osgDB::ReaderWriter::WriteResult ReaderWriter3DS::writeNode(const osg::Node& nod osg::ref_ptr local_opt = options ? static_cast(options->clone(osg::CopyOp::SHALLOW_COPY)) : new Options; local_opt->getDatabasePathList().push_front(osgDB::getFilePath(optFileName)); - if (!createFileObject(node, file3ds, optFileName, local_opt)) ok = false; + if (!createFileObject(node, file3ds, optFileName, local_opt.get())) ok = false; if (ok && !lib3ds_file_write(file3ds, &io)) ok = false; } catch (...) {