fix memory leak during export
parent
6f8d96b57e
commit
ccd13436da
|
@ -189,42 +189,42 @@ M3D_INDEX addMaterial(const Assimp::M3DWrapper &m3d, const aiMaterial *mat) {
|
||||||
continue;
|
continue;
|
||||||
if (aiProps[k].pKey) {
|
if (aiProps[k].pKey) {
|
||||||
switch (m3d_propertytypes[k].format) {
|
switch (m3d_propertytypes[k].format) {
|
||||||
case m3dpf_color:
|
case m3dpf_color:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, c) == AI_SUCCESS)
|
aiProps[k].index, c) == AI_SUCCESS)
|
||||||
addProp(&m3d->material[mi],
|
addProp(&m3d->material[mi],
|
||||||
m3d_propertytypes[k].id, mkColor(&c));
|
m3d_propertytypes[k].id, mkColor(&c));
|
||||||
break;
|
break;
|
||||||
case m3dpf_float:
|
case m3dpf_float:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, f) == AI_SUCCESS)
|
aiProps[k].index, f) == AI_SUCCESS)
|
||||||
addProp(&m3d->material[mi],
|
addProp(&m3d->material[mi],
|
||||||
m3d_propertytypes[k].id,
|
m3d_propertytypes[k].id,
|
||||||
/* not (uint32_t)f, because we don't want to convert
|
/* not (uint32_t)f, because we don't want to convert
|
||||||
* it, we want to see it as 32 bits of memory */
|
* it, we want to see it as 32 bits of memory */
|
||||||
*((uint32_t *)&f));
|
*((uint32_t *)&f));
|
||||||
break;
|
break;
|
||||||
case m3dpf_uint8:
|
case m3dpf_uint8:
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
aiProps[k].index, j) == AI_SUCCESS) {
|
aiProps[k].index, j) == AI_SUCCESS) {
|
||||||
// special conversion for illumination model property
|
// special conversion for illumination model property
|
||||||
if (m3d_propertytypes[k].id == m3dp_il) {
|
if (m3d_propertytypes[k].id == m3dp_il) {
|
||||||
switch (j) {
|
switch (j) {
|
||||||
case aiShadingMode_NoShading: j = 0; break;
|
case aiShadingMode_NoShading: j = 0; break;
|
||||||
case aiShadingMode_Phong: j = 2; break;
|
case aiShadingMode_Phong: j = 2; break;
|
||||||
default: j = 1; break;
|
default: j = 1; break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
addProp(&m3d->material[mi],
|
|
||||||
m3d_propertytypes[k].id, j);
|
|
||||||
}
|
}
|
||||||
break;
|
addProp(&m3d->material[mi],
|
||||||
default:
|
m3d_propertytypes[k].id, j);
|
||||||
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
}
|
||||||
aiProps[k].index, j) == AI_SUCCESS)
|
break;
|
||||||
addProp(&m3d->material[mi],
|
default:
|
||||||
m3d_propertytypes[k].id, j);
|
if (mat->Get(aiProps[k].pKey, aiProps[k].type,
|
||||||
break;
|
aiProps[k].index, j) == AI_SUCCESS)
|
||||||
|
addProp(&m3d->material[mi],
|
||||||
|
m3d_propertytypes[k].id, j);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (aiTxProps[k].pKey &&
|
if (aiTxProps[k].pKey &&
|
||||||
|
@ -292,8 +292,8 @@ void ExportSceneM3D(
|
||||||
// Prototyped and registered in Exporter.cpp
|
// Prototyped and registered in Exporter.cpp
|
||||||
void ExportSceneM3DA(
|
void ExportSceneM3DA(
|
||||||
const char *,
|
const char *,
|
||||||
IOSystem*,
|
IOSystem *,
|
||||||
const aiScene*,
|
const aiScene *,
|
||||||
const ExportProperties *
|
const ExportProperties *
|
||||||
|
|
||||||
) {
|
) {
|
||||||
|
@ -312,7 +312,9 @@ void ExportSceneM3DA(
|
||||||
M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
|
M3DExporter::M3DExporter(const aiScene *pScene, const ExportProperties *pProperties) :
|
||||||
mScene(pScene),
|
mScene(pScene),
|
||||||
mProperties(pProperties),
|
mProperties(pProperties),
|
||||||
outfile() {}
|
outfile() {
|
||||||
|
// empty
|
||||||
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void M3DExporter::doExport(
|
void M3DExporter::doExport(
|
||||||
|
@ -352,6 +354,9 @@ void M3DExporter::doExport(
|
||||||
// explicitly release file pointer,
|
// explicitly release file pointer,
|
||||||
// so we don't have to rely on class destruction.
|
// so we don't have to rely on class destruction.
|
||||||
outfile.reset();
|
outfile.reset();
|
||||||
|
|
||||||
|
M3D_FREE(m3d->name);
|
||||||
|
m3d->name = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
|
|
|
@ -50,15 +50,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||||
|
|
||||||
# if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
#if (__cplusplus >= 201103L) || !defined(_MSC_VER) || (_MSC_VER >= 1900) // C++11 and MSVC 2015 onwards
|
||||||
# define threadlocal thread_local
|
#define threadlocal thread_local
|
||||||
# else
|
#else
|
||||||
# if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
#if defined(_MSC_VER) && (_MSC_VER >= 1800) // there's an alternative for MSVC 2013
|
||||||
# define threadlocal __declspec(thread)
|
#define threadlocal __declspec(thread)
|
||||||
# else
|
#else
|
||||||
# define threadlocal
|
#define threadlocal
|
||||||
# endif
|
#endif
|
||||||
# endif
|
#endif
|
||||||
|
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
|
||||||
|
@ -66,37 +66,37 @@ extern "C" {
|
||||||
threadlocal void *m3dimporter_pIOHandler;
|
threadlocal void *m3dimporter_pIOHandler;
|
||||||
|
|
||||||
unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
unsigned char *m3dimporter_readfile(char *fn, unsigned int *size) {
|
||||||
ai_assert(nullptr != fn);
|
ai_assert(nullptr != fn);
|
||||||
ai_assert(nullptr != size);
|
ai_assert(nullptr != size);
|
||||||
std::string file(fn);
|
std::string file(fn);
|
||||||
std::unique_ptr<Assimp::IOStream> pStream(
|
std::unique_ptr<Assimp::IOStream> pStream(
|
||||||
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
|
(reinterpret_cast<Assimp::IOSystem *>(m3dimporter_pIOHandler))->Open(file, "rb"));
|
||||||
size_t fileSize = 0;
|
size_t fileSize = 0;
|
||||||
unsigned char *data = NULL;
|
unsigned char *data = NULL;
|
||||||
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
|
// sometimes pStream is nullptr in a single-threaded scenario too for some reason
|
||||||
// (should be an empty object returning nothing I guess)
|
// (should be an empty object returning nothing I guess)
|
||||||
if (pStream) {
|
if (pStream) {
|
||||||
fileSize = pStream->FileSize();
|
fileSize = pStream->FileSize();
|
||||||
// should be allocated with malloc(), because the library will call free() to deallocate
|
// should be allocated with malloc(), because the library will call free() to deallocate
|
||||||
data = (unsigned char *)malloc(fileSize);
|
data = (unsigned char *)malloc(fileSize);
|
||||||
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
|
if (!data || !pStream.get() || !fileSize || fileSize != pStream->Read(data, 1, fileSize)) {
|
||||||
pStream.reset();
|
pStream.reset();
|
||||||
*size = 0;
|
*size = 0;
|
||||||
// don't throw a deadly exception, it's not fatal if we can't read an external asset
|
// don't throw a deadly exception, it's not fatal if we can't read an external asset
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
pStream.reset();
|
pStream.reset();
|
||||||
}
|
}
|
||||||
*size = (int)fileSize;
|
*size = (int)fileSize;
|
||||||
return data;
|
return data;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
M3DWrapper::M3DWrapper() {
|
M3DWrapper::M3DWrapper() {
|
||||||
// use malloc() here because m3d_free() will call free()
|
// use malloc() here because m3d_free() will call free()
|
||||||
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
|
m3d_ = (m3d_t *)calloc(1, sizeof(m3d_t));
|
||||||
}
|
}
|
||||||
|
|
||||||
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
|
M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &buffer) {
|
||||||
|
@ -105,41 +105,42 @@ M3DWrapper::M3DWrapper(IOSystem *pIOHandler, const std::vector<unsigned char> &b
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef ASSIMP_USE_M3D_READFILECB
|
#ifdef ASSIMP_USE_M3D_READFILECB
|
||||||
// pass this IOHandler to the C callback in a thread-local pointer
|
// pass this IOHandler to the C callback in a thread-local pointer
|
||||||
m3dimporter_pIOHandler = pIOHandler;
|
m3dimporter_pIOHandler = pIOHandler;
|
||||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
|
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), m3dimporter_readfile, free, nullptr);
|
||||||
// Clear the C callback
|
// Clear the C callback
|
||||||
m3dimporter_pIOHandler = nullptr;
|
m3dimporter_pIOHandler = nullptr;
|
||||||
#else
|
#else
|
||||||
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
|
m3d_ = m3d_load(const_cast<unsigned char *>(buffer.data()), nullptr, nullptr, nullptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
M3DWrapper::~M3DWrapper() {
|
M3DWrapper::~M3DWrapper() {
|
||||||
reset();
|
reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void M3DWrapper::reset() {
|
void M3DWrapper::reset() {
|
||||||
ClearSave();
|
ClearSave();
|
||||||
if (m3d_)
|
if (m3d_) {
|
||||||
m3d_free(m3d_);
|
m3d_free(m3d_);
|
||||||
m3d_ = nullptr;
|
}
|
||||||
|
m3d_ = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
|
unsigned char *M3DWrapper::Save(int quality, int flags, unsigned int &size) {
|
||||||
#if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
|
#if (!(ASSIMP_BUILD_NO_EXPORT || ASSIMP_BUILD_NO_M3D_EXPORTER))
|
||||||
ClearSave();
|
ClearSave();
|
||||||
saved_output_ = m3d_save(m3d_, quality, flags, &size);
|
saved_output_ = m3d_save(m3d_, quality, flags, &size);
|
||||||
return saved_output_;
|
return saved_output_;
|
||||||
#else
|
#else
|
||||||
return nullptr;
|
return nullptr;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void M3DWrapper::ClearSave() {
|
void M3DWrapper::ClearSave() {
|
||||||
if (saved_output_)
|
if (saved_output_)
|
||||||
M3D_FREE(saved_output_);
|
M3D_FREE(saved_output_);
|
||||||
saved_output_ = nullptr;
|
saved_output_ = nullptr;
|
||||||
}
|
}
|
||||||
} // namespace Assimp
|
} // namespace Assimp
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue