Merge pull request #1935 from assimp/issue_842
Issue 842: Solving for ascii stl point cloud exportpull/1931/head^2
commit
66f77e93ba
|
@ -62,6 +62,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
|||
#include "JoinVerticesProcess.h"
|
||||
#include "MakeVerboseFormat.h"
|
||||
#include "ConvertToLHProcess.h"
|
||||
#include "PretransformVertices.h"
|
||||
#include <assimp/Exceptional.h>
|
||||
#include "ScenePrivate.h"
|
||||
#include <memory>
|
||||
|
@ -397,6 +398,11 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
|||
}
|
||||
}
|
||||
|
||||
bool exportPointCloud(false);
|
||||
if (nullptr != pProperties) {
|
||||
exportPointCloud = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
||||
}
|
||||
|
||||
// dispatch other processes
|
||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||
BaseProcess* const p = pimpl->mPostProcessingSteps[a];
|
||||
|
@ -405,7 +411,9 @@ aiReturn Exporter::Export( const aiScene* pScene, const char* pFormatId, const c
|
|||
&& !dynamic_cast<FlipUVsProcess*>(p)
|
||||
&& !dynamic_cast<FlipWindingOrderProcess*>(p)
|
||||
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
||||
|
||||
if (dynamic_cast<PretransformVertices*>(p) && exportPointCloud) {
|
||||
continue;
|
||||
}
|
||||
p->Execute(scenecopy.get());
|
||||
}
|
||||
}
|
||||
|
@ -441,7 +449,6 @@ const char* Exporter::GetErrorString() const {
|
|||
return pimpl->mError.c_str();
|
||||
}
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Exporter::FreeBlob() {
|
||||
delete pimpl->blob;
|
||||
|
@ -470,7 +477,7 @@ size_t Exporter::GetExportFormatCount() const {
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
const aiExportFormatDesc* Exporter::GetExportFormatDescription( size_t index ) const {
|
||||
if (index >= GetExportFormatCount()) {
|
||||
return NULL;
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Return from static storage if the requested index is built-in.
|
||||
|
@ -495,7 +502,8 @@ aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void Exporter::UnregisterExporter(const char* id) {
|
||||
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin(); it != pimpl->mExporters.end(); ++it) {
|
||||
for(std::vector<ExportFormatEntry>::iterator it = pimpl->mExporters.begin();
|
||||
it != pimpl->mExporters.end(); ++it) {
|
||||
if (!strcmp((*it).mDescription.id,id)) {
|
||||
pimpl->mExporters.erase(it);
|
||||
break;
|
||||
|
@ -531,8 +539,7 @@ bool ExportProperties::SetPropertyFloat(const char* szName, ai_real iValue) {
|
|||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Set a configuration property
|
||||
bool ExportProperties :: SetPropertyString(const char* szName, const std::string& value)
|
||||
{
|
||||
bool ExportProperties::SetPropertyString(const char* szName, const std::string& value) {
|
||||
return SetGenericProperty<std::string>(mStringProperties, szName,value);
|
||||
}
|
||||
|
||||
|
|
|
@ -60,14 +60,17 @@ using namespace Assimp;
|
|||
// ------------------------------------------------------------------------------------------------
|
||||
// Constructor to be privately used by Importer
|
||||
PretransformVertices::PretransformVertices()
|
||||
: configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation()
|
||||
{
|
||||
: configKeepHierarchy (false)
|
||||
, configNormalize(false)
|
||||
, configTransform(false)
|
||||
, configTransformation()
|
||||
, mConfigPointCloud( false ) {
|
||||
// empty
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Destructor, private as well
|
||||
PretransformVertices::~PretransformVertices()
|
||||
{
|
||||
PretransformVertices::~PretransformVertices() {
|
||||
// nothing to do here
|
||||
}
|
||||
|
||||
|
@ -89,6 +92,8 @@ void PretransformVertices::SetupProperties(const Importer* pImp)
|
|||
configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0));
|
||||
|
||||
configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
|
||||
|
||||
mConfigPointCloud = pImp->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
|
@ -502,9 +507,7 @@ void PretransformVertices::Execute( aiScene* pScene)
|
|||
pScene->mMeshes[i]->mBones = NULL;
|
||||
pScene->mMeshes[i]->mNumBones = 0;
|
||||
}
|
||||
}
|
||||
else {
|
||||
|
||||
} else {
|
||||
apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
|
||||
std::list<unsigned int> aiVFormats;
|
||||
|
||||
|
@ -557,6 +560,7 @@ void PretransformVertices::Execute( aiScene* pScene)
|
|||
|
||||
// If no meshes are referenced in the node graph it is possible that we get no output meshes.
|
||||
if (apcOutMeshes.empty()) {
|
||||
|
||||
throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
|
||||
}
|
||||
else
|
||||
|
|
|
@ -61,15 +61,11 @@ namespace Assimp {
|
|||
* and removes the whole graph. The output is a list of meshes, one for
|
||||
* each material.
|
||||
*/
|
||||
class ASSIMP_API PretransformVertices : public BaseProcess
|
||||
{
|
||||
class ASSIMP_API PretransformVertices : public BaseProcess {
|
||||
public:
|
||||
|
||||
PretransformVertices ();
|
||||
~PretransformVertices ();
|
||||
|
||||
public:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Check whether step is active
|
||||
bool IsActive( unsigned int pFlags) const;
|
||||
|
@ -82,7 +78,6 @@ public:
|
|||
// Setup import settings
|
||||
void SetupProperties(const Importer* pImp);
|
||||
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** @brief Toggle the 'keep hierarchy' option
|
||||
* @param d hm ... difficult to guess what this means, hu!?
|
||||
|
@ -100,7 +95,6 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
// Count the number of nodes
|
||||
unsigned int CountNodes( aiNode* pcNode );
|
||||
|
@ -161,6 +155,7 @@ private:
|
|||
bool configNormalize;
|
||||
bool configTransform;
|
||||
aiMatrix4x4 configTransformation;
|
||||
bool mConfigPointCloud;
|
||||
};
|
||||
|
||||
} // end of namespace Assimp
|
||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/mesh.h>
|
||||
|
||||
class RemoveRedundantMatsTest;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
|
|
|
@ -54,14 +54,17 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/ByteSwapper.h>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
// Worker function for exporting a scene to Stereolithograpy. Prototyped and registered in Exporter.cpp
|
||||
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties )
|
||||
{
|
||||
bool exportPointClouds = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
||||
|
||||
// invoke the exporter
|
||||
STLExporter exporter(pFile, pScene);
|
||||
STLExporter exporter(pFile, pScene, exportPointClouds );
|
||||
|
||||
if (exporter.mOutput.fail()) {
|
||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
||||
|
@ -75,10 +78,12 @@ void ExportSceneSTL(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene
|
|||
|
||||
outfile->Write( exporter.mOutput.str().c_str(), static_cast<size_t>(exporter.mOutput.tellp()),1);
|
||||
}
|
||||
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* /*pProperties*/)
|
||||
void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene* pScene, const ExportProperties* pProperties )
|
||||
{
|
||||
bool exportPointClouds = pProperties->GetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS);
|
||||
|
||||
// invoke the exporter
|
||||
STLExporter exporter(pFile, pScene, true);
|
||||
STLExporter exporter(pFile, pScene, exportPointClouds, true);
|
||||
|
||||
if (exporter.mOutput.fail()) {
|
||||
throw DeadlyExportError("output data creation failed. Most likely the file became too large: " + std::string(pFile));
|
||||
|
@ -95,9 +100,11 @@ void ExportSceneSTLBinary(const char* pFile,IOSystem* pIOSystem, const aiScene*
|
|||
|
||||
} // end of namespace Assimp
|
||||
|
||||
static const char *SolidToken = "solid";
|
||||
static const char *EndSolidToken = "endsolid";
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool binary)
|
||||
STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool exportPointClouds, bool binary)
|
||||
: filename(_filename)
|
||||
, endl("\n")
|
||||
{
|
||||
|
@ -118,20 +125,53 @@ STLExporter :: STLExporter(const char* _filename, const aiScene* pScene, bool bi
|
|||
}
|
||||
AI_SWAP4(meshnum);
|
||||
mOutput.write((char *)&meshnum, 4);
|
||||
|
||||
if (exportPointClouds) {
|
||||
|
||||
}
|
||||
|
||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
WriteMeshBinary(pScene->mMeshes[i]);
|
||||
}
|
||||
} else {
|
||||
const std::string& name = "AssimpScene";
|
||||
|
||||
mOutput << "solid " << name << endl;
|
||||
// Exporting only point clouds
|
||||
if (exportPointClouds) {
|
||||
WritePointCloud("Assimp_Pointcloud", pScene );
|
||||
return;
|
||||
}
|
||||
|
||||
// Export the assimp mesh
|
||||
const std::string name = "AssimpScene";
|
||||
mOutput << SolidToken << " " << name << endl;
|
||||
for(unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
WriteMesh(pScene->mMeshes[ i ]);
|
||||
}
|
||||
mOutput << "endsolid " << name << endl;
|
||||
mOutput << EndSolidToken << name << endl;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void STLExporter::WritePointCloud(const std::string &name, const aiScene* pScene) {
|
||||
mOutput << " " << SolidToken << " " << name << endl;
|
||||
aiVector3D nor;
|
||||
mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
|
||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||
aiMesh *mesh = pScene->mMeshes[i];
|
||||
if (nullptr == mesh) {
|
||||
continue;
|
||||
}
|
||||
|
||||
for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
||||
const aiVector3D& v = mesh->mVertices[a];
|
||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
||||
}
|
||||
}
|
||||
mOutput << EndSolidToken << " " << name << endl;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
void STLExporter::WriteMesh(const aiMesh* m)
|
||||
{
|
||||
|
@ -145,7 +185,7 @@ void STLExporter :: WriteMesh(const aiMesh* m)
|
|||
for(unsigned int a = 0; a < f.mNumIndices; ++a) {
|
||||
nor += m->mNormals[f.mIndices[a]];
|
||||
}
|
||||
nor.Normalize();
|
||||
nor.NormalizeSafe();
|
||||
}
|
||||
mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
|
||||
mOutput << " outer loop" << endl;
|
||||
|
|
|
@ -52,8 +52,7 @@ struct aiScene;
|
|||
struct aiNode;
|
||||
struct aiMesh;
|
||||
|
||||
namespace Assimp
|
||||
{
|
||||
namespace Assimp {
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
/** Helper class to export a given scene to a STL file. */
|
||||
|
@ -62,15 +61,13 @@ class STLExporter
|
|||
{
|
||||
public:
|
||||
/// Constructor for a specific scene to export
|
||||
STLExporter(const char* filename, const aiScene* pScene, bool binary = false);
|
||||
|
||||
public:
|
||||
STLExporter(const char* filename, const aiScene* pScene, bool exportPOintClouds, bool binary = false);
|
||||
|
||||
/// public stringstreams to write all output into
|
||||
std::ostringstream mOutput;
|
||||
|
||||
private:
|
||||
|
||||
void WritePointCloud(const std::string &name, const aiScene* pScene);
|
||||
void WriteMesh(const aiMesh* m);
|
||||
void WriteMeshBinary(const aiMesh* m);
|
||||
|
||||
|
|
|
@ -75,4 +75,5 @@ bool CPUSupportsSSE2() {
|
|||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // Namespace Assimp
|
||||
|
|
|
@ -115,12 +115,16 @@ public:
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
/**
|
||||
* @brief The class constructor.
|
||||
*/
|
||||
Exporter();
|
||||
|
||||
/**
|
||||
* @brief The class destructor.
|
||||
*/
|
||||
~Exporter();
|
||||
|
||||
public:
|
||||
// -------------------------------------------------------------------
|
||||
/** Supplies a custom IO handler to the exporter to use to open and
|
||||
* access files.
|
||||
|
@ -172,8 +176,10 @@ public:
|
|||
* Any IO handlers set via #SetIOHandler are ignored here.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene. */
|
||||
const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* = NULL);
|
||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||
const aiExportDataBlob* ExportToBlob(const aiScene* pScene, const char* pFormatId,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* = nullptr);
|
||||
const aiExportDataBlob* ExportToBlob( const aiScene* pScene, const std::string& pFormatId,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Convenience function to export directly to a file. Use
|
||||
|
@ -208,8 +214,10 @@ public:
|
|||
* @return AI_SUCCESS if everything was fine.
|
||||
* @note Use aiCopyScene() to get a modifiable copy of a previously
|
||||
* imported scene.*/
|
||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||
aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath, unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = NULL);
|
||||
aiReturn Export( const aiScene* pScene, const char* pFormatId, const char* pPath,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
aiReturn Export( const aiScene* pScene, const std::string& pFormatId, const std::string& pPath,
|
||||
unsigned int pPreprocessing = 0u, const ExportProperties* pProperties = nullptr);
|
||||
|
||||
// -------------------------------------------------------------------
|
||||
/** Returns an error description of an error that occurred in #Export
|
||||
|
|
|
@ -46,15 +46,15 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/ai_assert.h>
|
||||
#include "Hash.h"
|
||||
#include <map>
|
||||
|
||||
#include <map>
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool SetGenericProperty(std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& value)
|
||||
{
|
||||
ai_assert(NULL != szName);
|
||||
inline
|
||||
bool SetGenericProperty(std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& value) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::iterator it = list.find(hash);
|
||||
|
@ -63,20 +63,22 @@ inline bool SetGenericProperty(std::map< unsigned int, T >& list,
|
|||
return false;
|
||||
}
|
||||
(*it).second = value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& errorReturn)
|
||||
{
|
||||
ai_assert(NULL != szName);
|
||||
inline
|
||||
const T& GetGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName, const T& errorReturn) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
|
||||
if (it == list.end())
|
||||
if (it == list.end()) {
|
||||
return errorReturn;
|
||||
}
|
||||
|
||||
return (*it).second;
|
||||
}
|
||||
|
@ -85,16 +87,17 @@ inline const T& GetGenericProperty(const std::map< unsigned int, T >& list,
|
|||
// Special version for pointer types - they will be deleted when replaced with another value
|
||||
// passing NULL removes the whole property
|
||||
template <class T>
|
||||
inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
||||
const char* szName, T* value, bool* bWasExisting = NULL)
|
||||
{
|
||||
ai_assert(NULL != szName);
|
||||
inline
|
||||
void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
||||
const char* szName, T* value, bool* bWasExisting = nullptr ) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T*>::iterator it = list.find(hash);
|
||||
if (it == list.end()) {
|
||||
if (bWasExisting)
|
||||
if (bWasExisting) {
|
||||
*bWasExisting = false;
|
||||
}
|
||||
|
||||
list.insert(std::pair<unsigned int,T*>( hash, value ));
|
||||
return;
|
||||
|
@ -106,20 +109,23 @@ inline void SetGenericPropertyPtr(std::map< unsigned int, T* >& list,
|
|||
if (!value) {
|
||||
list.erase(it);
|
||||
}
|
||||
if (bWasExisting)
|
||||
if (bWasExisting) {
|
||||
*bWasExisting = true;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------------------------------
|
||||
template <class T>
|
||||
inline bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName)
|
||||
{
|
||||
ai_assert(NULL != szName);
|
||||
inline
|
||||
bool HasGenericProperty(const std::map< unsigned int, T >& list,
|
||||
const char* szName) {
|
||||
ai_assert(nullptr != szName);
|
||||
const uint32_t hash = SuperFastHash(szName);
|
||||
|
||||
typename std::map<unsigned int, T>::const_iterator it = list.find(hash);
|
||||
if (it == list.end()) return false;
|
||||
if (it == list.end()) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -85,7 +85,6 @@ struct aiExportFormatDesc
|
|||
*/
|
||||
ASSIMP_API size_t aiGetExportFormatCount(void);
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
/** Returns a description of the nth export file format. Use #aiGetExportFormatCount()
|
||||
* to learn how many export formats are supported. The description must be released by
|
||||
|
@ -186,7 +185,6 @@ ASSIMP_API aiReturn aiExportSceneEx( const C_STRUCT aiScene* pScene,
|
|||
C_STRUCT aiFileIO* pIO,
|
||||
unsigned int pPreprocessing );
|
||||
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
/** Describes a blob of exported scene data. Use #aiExportSceneToBlob() to create a blob containing an
|
||||
* exported scene. The memory referred by this structure is owned by Assimp.
|
||||
|
@ -245,8 +243,8 @@ private:
|
|||
* @param pPreprocessing Please see the documentation for #aiExportScene
|
||||
* @return the exported data or NULL in case of error
|
||||
*/
|
||||
ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId, unsigned int pPreprocessing );
|
||||
|
||||
ASSIMP_API const C_STRUCT aiExportDataBlob* aiExportSceneToBlob( const C_STRUCT aiScene* pScene, const char* pFormatId,
|
||||
unsigned int pPreprocessing );
|
||||
|
||||
// --------------------------------------------------------------------------------
|
||||
/** Releases the memory associated with the given exported data. Use this function to free a data blob
|
||||
|
|
|
@ -953,6 +953,11 @@ enum aiComponent
|
|||
|
||||
#define AI_CONFIG_EXPORT_XFILE_64BIT "EXPORT_XFILE_64BIT"
|
||||
|
||||
/**
|
||||
*
|
||||
*/
|
||||
#define AI_CONFIG_EXPORT_POINT_CLOUDS "EXPORT_POINT_CLOUDS"
|
||||
|
||||
/**
|
||||
* @brief Specifies a gobal key factor for scale, float value
|
||||
*/
|
||||
|
|
|
@ -141,6 +141,7 @@ TEST_F( utPLYImportExport, vertexColorTest ) {
|
|||
// Test issue #623, PLY importer should not automatically create faces
|
||||
TEST_F(utPLYImportExport, pointcloudTest) {
|
||||
Assimp::Importer importer;
|
||||
|
||||
//Could not use aiProcess_ValidateDataStructure since it's missing faces.
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/issue623.ply", 0);
|
||||
EXPECT_NE(nullptr, scene);
|
||||
|
|
|
@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
|||
|
||||
#include <assimp/Importer.hpp>
|
||||
#include <assimp/postprocess.h>
|
||||
#include <assimp/Exporter.hpp>
|
||||
#include <assimp/scene.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
using namespace Assimp;
|
||||
|
||||
|
@ -68,3 +72,73 @@ TEST_F( utSTLImporterExporter, test_with_two_solids ) {
|
|||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure );
|
||||
EXPECT_NE( nullptr, scene );
|
||||
}
|
||||
|
||||
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||
|
||||
TEST_F(utSTLImporterExporter, exporterTest) {
|
||||
Assimp::Importer importer;
|
||||
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/STL/Spider_ascii.stl", aiProcess_ValidateDataStructure);
|
||||
|
||||
Assimp::Exporter mAiExporter;
|
||||
mAiExporter.Export( scene, "stl", "spiderExport.stl" );
|
||||
|
||||
const aiScene *scene2 = importer.ReadFile("spiderExport.stl", aiProcess_ValidateDataStructure);
|
||||
EXPECT_NE(nullptr, scene2);
|
||||
}
|
||||
|
||||
TEST_F(utSTLImporterExporter, test_export_pointclouds) {
|
||||
struct XYZ {
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
std::vector<XYZ> points;
|
||||
|
||||
for (size_t i = 0; i < 10; ++i) {
|
||||
XYZ current;
|
||||
current.x = static_cast<float>(i);
|
||||
current.y = static_cast<float>(i);
|
||||
current.z = static_cast<float>(i);
|
||||
points.push_back(current);
|
||||
}
|
||||
aiScene scene;
|
||||
scene.mRootNode = new aiNode();
|
||||
|
||||
scene.mMeshes = new aiMesh*[1];
|
||||
scene.mMeshes[0] = nullptr;
|
||||
scene.mNumMeshes = 1;
|
||||
|
||||
scene.mMaterials = new aiMaterial*[1];
|
||||
scene.mMaterials[0] = nullptr;
|
||||
scene.mNumMaterials = 1;
|
||||
|
||||
scene.mMaterials[0] = new aiMaterial();
|
||||
|
||||
scene.mMeshes[0] = new aiMesh();
|
||||
scene.mMeshes[0]->mMaterialIndex = 0;
|
||||
|
||||
scene.mRootNode->mMeshes = new unsigned int[1];
|
||||
scene.mRootNode->mMeshes[0] = 0;
|
||||
scene.mRootNode->mNumMeshes = 1;
|
||||
|
||||
auto pMesh = scene.mMeshes[0];
|
||||
|
||||
long numValidPoints = points.size();
|
||||
|
||||
pMesh->mVertices = new aiVector3D[numValidPoints];
|
||||
pMesh->mNumVertices = numValidPoints;
|
||||
|
||||
int i = 0;
|
||||
for (XYZ &p : points) {
|
||||
pMesh->mVertices[i] = aiVector3D(p.x, p.y, p.z);
|
||||
++i;
|
||||
}
|
||||
|
||||
Assimp::Exporter mAiExporter;
|
||||
ExportProperties *properties = new ExportProperties;
|
||||
properties->SetPropertyBool(AI_CONFIG_EXPORT_POINT_CLOUDS, true);
|
||||
mAiExporter.Export(&scene, "stl", "testExport.stl", 0, properties );
|
||||
|
||||
delete properties;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
Loading…
Reference in New Issue