Introduce export with test for point clouds.
parent
9f835ea843
commit
2c47717ca6
|
@ -62,6 +62,7 @@ Here we implement only the C++ interface (Assimp::Exporter).
|
||||||
#include "JoinVerticesProcess.h"
|
#include "JoinVerticesProcess.h"
|
||||||
#include "MakeVerboseFormat.h"
|
#include "MakeVerboseFormat.h"
|
||||||
#include "ConvertToLHProcess.h"
|
#include "ConvertToLHProcess.h"
|
||||||
|
#include "PretransformVertices.h"
|
||||||
#include <assimp/Exceptional.h>
|
#include <assimp/Exceptional.h>
|
||||||
#include "ScenePrivate.h"
|
#include "ScenePrivate.h"
|
||||||
#include <memory>
|
#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
|
// dispatch other processes
|
||||||
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
for( unsigned int a = 0; a < pimpl->mPostProcessingSteps.size(); a++) {
|
||||||
BaseProcess* const p = pimpl->mPostProcessingSteps[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<FlipUVsProcess*>(p)
|
||||||
&& !dynamic_cast<FlipWindingOrderProcess*>(p)
|
&& !dynamic_cast<FlipWindingOrderProcess*>(p)
|
||||||
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
&& !dynamic_cast<MakeLeftHandedProcess*>(p)) {
|
||||||
|
if (dynamic_cast<PretransformVertices*>(p) && exportPointCloud) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
p->Execute(scenecopy.get());
|
p->Execute(scenecopy.get());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -441,7 +449,6 @@ const char* Exporter::GetErrorString() const {
|
||||||
return pimpl->mError.c_str();
|
return pimpl->mError.c_str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter::FreeBlob() {
|
void Exporter::FreeBlob() {
|
||||||
delete pimpl->blob;
|
delete pimpl->blob;
|
||||||
|
@ -495,7 +502,8 @@ aiReturn Exporter::RegisterExporter(const ExportFormatEntry& desc) {
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void Exporter::UnregisterExporter(const char* id) {
|
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)) {
|
if (!strcmp((*it).mDescription.id,id)) {
|
||||||
pimpl->mExporters.erase(it);
|
pimpl->mExporters.erase(it);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -60,14 +60,17 @@ using namespace Assimp;
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Constructor to be privately used by Importer
|
// Constructor to be privately used by Importer
|
||||||
PretransformVertices::PretransformVertices()
|
PretransformVertices::PretransformVertices()
|
||||||
: configKeepHierarchy (false), configNormalize(false), configTransform(false), configTransformation()
|
: configKeepHierarchy (false)
|
||||||
{
|
, configNormalize(false)
|
||||||
|
, configTransform(false)
|
||||||
|
, configTransformation()
|
||||||
|
, mConfigPointCloud( false ) {
|
||||||
|
// empty
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
// Destructor, private as well
|
// Destructor, private as well
|
||||||
PretransformVertices::~PretransformVertices()
|
PretransformVertices::~PretransformVertices() {
|
||||||
{
|
|
||||||
// nothing to do here
|
// 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));
|
configTransform = (0 != pImp->GetPropertyInteger(AI_CONFIG_PP_PTV_ADD_ROOT_TRANSFORMATION,0));
|
||||||
|
|
||||||
configTransformation = pImp->GetPropertyMatrix(AI_CONFIG_PP_PTV_ROOT_TRANSFORMATION, aiMatrix4x4());
|
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]->mBones = NULL;
|
||||||
pScene->mMeshes[i]->mNumBones = 0;
|
pScene->mMeshes[i]->mNumBones = 0;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
|
|
||||||
apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
|
apcOutMeshes.reserve(pScene->mNumMaterials<<1u);
|
||||||
std::list<unsigned int> aiVFormats;
|
std::list<unsigned int> aiVFormats;
|
||||||
|
|
||||||
|
@ -556,7 +559,8 @@ void PretransformVertices::Execute( aiScene* pScene)
|
||||||
}
|
}
|
||||||
|
|
||||||
// If no meshes are referenced in the node graph it is possible that we get no output meshes.
|
// If no meshes are referenced in the node graph it is possible that we get no output meshes.
|
||||||
if (apcOutMeshes.empty()) {
|
if (apcOutMeshes.empty()) {
|
||||||
|
|
||||||
throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
|
throw DeadlyImportError("No output meshes: all meshes are orphaned and are not referenced by any nodes");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -61,15 +61,11 @@ namespace Assimp {
|
||||||
* and removes the whole graph. The output is a list of meshes, one for
|
* and removes the whole graph. The output is a list of meshes, one for
|
||||||
* each material.
|
* each material.
|
||||||
*/
|
*/
|
||||||
class ASSIMP_API PretransformVertices : public BaseProcess
|
class ASSIMP_API PretransformVertices : public BaseProcess {
|
||||||
{
|
|
||||||
public:
|
public:
|
||||||
|
|
||||||
PretransformVertices ();
|
PretransformVertices ();
|
||||||
~PretransformVertices ();
|
~PretransformVertices ();
|
||||||
|
|
||||||
public:
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Check whether step is active
|
// Check whether step is active
|
||||||
bool IsActive( unsigned int pFlags) const;
|
bool IsActive( unsigned int pFlags) const;
|
||||||
|
@ -82,7 +78,6 @@ public:
|
||||||
// Setup import settings
|
// Setup import settings
|
||||||
void SetupProperties(const Importer* pImp);
|
void SetupProperties(const Importer* pImp);
|
||||||
|
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
/** @brief Toggle the 'keep hierarchy' option
|
/** @brief Toggle the 'keep hierarchy' option
|
||||||
* @param d hm ... difficult to guess what this means, hu!?
|
* @param d hm ... difficult to guess what this means, hu!?
|
||||||
|
@ -100,7 +95,6 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
// -------------------------------------------------------------------
|
// -------------------------------------------------------------------
|
||||||
// Count the number of nodes
|
// Count the number of nodes
|
||||||
unsigned int CountNodes( aiNode* pcNode );
|
unsigned int CountNodes( aiNode* pcNode );
|
||||||
|
@ -161,6 +155,7 @@ private:
|
||||||
bool configNormalize;
|
bool configNormalize;
|
||||||
bool configTransform;
|
bool configTransform;
|
||||||
aiMatrix4x4 configTransformation;
|
aiMatrix4x4 configTransformation;
|
||||||
|
bool mConfigPointCloud;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // end of namespace Assimp
|
} // end of namespace Assimp
|
||||||
|
|
|
@ -50,6 +50,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include <assimp/mesh.h>
|
#include <assimp/mesh.h>
|
||||||
|
|
||||||
class RemoveRedundantMatsTest;
|
class RemoveRedundantMatsTest;
|
||||||
|
|
||||||
namespace Assimp {
|
namespace Assimp {
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
|
|
|
@ -141,13 +141,15 @@ STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool expo
|
||||||
mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
|
mOutput << " facet normal " << nor.x << " " << nor.y << " " << nor.z << endl;
|
||||||
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
for (unsigned int i = 0; i < pScene->mNumMeshes; ++i) {
|
||||||
aiMesh *mesh = pScene->mMeshes[i];
|
aiMesh *mesh = pScene->mMeshes[i];
|
||||||
if (mesh->mNormals) {
|
if (nullptr == mesh) {
|
||||||
for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
continue;
|
||||||
const aiVector3D& v = mesh->mVertices[a];
|
}
|
||||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
|
||||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
for (unsigned int a = 0; a < mesh->mNumVertices; ++a) {
|
||||||
mOutput << " vertex " << v.x << " " << v.y << " " << v.z << endl;
|
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 << "endsolid " << name << endl;
|
mOutput << "endsolid " << name << endl;
|
||||||
|
@ -163,7 +165,7 @@ STLExporter::STLExporter(const char* _filename, const aiScene* pScene, bool expo
|
||||||
}
|
}
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
void STLExporter :: WriteMesh(const aiMesh* m)
|
void STLExporter::WriteMesh(const aiMesh* m)
|
||||||
{
|
{
|
||||||
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
|
for (unsigned int i = 0; i < m->mNumFaces; ++i) {
|
||||||
const aiFace& f = m->mFaces[i];
|
const aiFace& f = m->mFaces[i];
|
||||||
|
|
|
@ -52,8 +52,7 @@ struct aiScene;
|
||||||
struct aiNode;
|
struct aiNode;
|
||||||
struct aiMesh;
|
struct aiMesh;
|
||||||
|
|
||||||
namespace Assimp
|
namespace Assimp {
|
||||||
{
|
|
||||||
|
|
||||||
// ------------------------------------------------------------------------------------------------
|
// ------------------------------------------------------------------------------------------------
|
||||||
/** Helper class to export a given scene to a STL file. */
|
/** Helper class to export a given scene to a STL file. */
|
||||||
|
|
|
@ -138,18 +138,19 @@ TEST_F( utPLYImportExport, vertexColorTest ) {
|
||||||
EXPECT_EQ(2u, first_face.mIndices[2]);
|
EXPECT_EQ(2u, first_face.mIndices[2]);
|
||||||
}
|
}
|
||||||
|
|
||||||
//Test issue #623, PLY importer should not automatically create faces
|
// Test issue #623, PLY importer should not automatically create faces
|
||||||
TEST_F(utPLYImportExport, pointcloudTest) {
|
TEST_F(utPLYImportExport, pointcloudTest) {
|
||||||
Assimp::Importer importer;
|
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);
|
|
||||||
|
|
||||||
EXPECT_EQ(1u, scene->mNumMeshes);
|
//Could not use aiProcess_ValidateDataStructure since it's missing faces.
|
||||||
EXPECT_NE(nullptr, scene->mMeshes[0]);
|
const aiScene *scene = importer.ReadFile(ASSIMP_TEST_MODELS_DIR "/PLY/issue623.ply", 0);
|
||||||
EXPECT_EQ(24u, scene->mMeshes[0]->mNumVertices);
|
EXPECT_NE(nullptr, scene);
|
||||||
EXPECT_EQ(aiPrimitiveType::aiPrimitiveType_POINT, scene->mMeshes[0]->mPrimitiveTypes);
|
|
||||||
EXPECT_EQ(0u, scene->mMeshes[0]->mNumFaces);
|
EXPECT_EQ(1u, scene->mNumMeshes);
|
||||||
|
EXPECT_NE(nullptr, scene->mMeshes[0]);
|
||||||
|
EXPECT_EQ(24u, scene->mMeshes[0]->mNumVertices);
|
||||||
|
EXPECT_EQ(aiPrimitiveType::aiPrimitiveType_POINT, scene->mMeshes[0]->mPrimitiveTypes);
|
||||||
|
EXPECT_EQ(0u, scene->mMeshes[0]->mNumFaces);
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *test_file =
|
static const char *test_file =
|
||||||
|
|
|
@ -47,6 +47,10 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
#include <assimp/Importer.hpp>
|
#include <assimp/Importer.hpp>
|
||||||
#include <assimp/postprocess.h>
|
#include <assimp/postprocess.h>
|
||||||
|
#include <assimp/Exporter.hpp>
|
||||||
|
#include <assimp/scene.h>
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
|
||||||
using namespace Assimp;
|
using namespace Assimp;
|
||||||
|
|
||||||
|
@ -68,3 +72,60 @@ TEST_F( utSTLImporterExporter, test_with_two_solids ) {
|
||||||
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure );
|
const aiScene *scene = importer.ReadFile( ASSIMP_TEST_MODELS_DIR "/STL/triangle_with_two_solids.stl", aiProcess_ValidateDataStructure );
|
||||||
EXPECT_NE( nullptr, scene );
|
EXPECT_NE( nullptr, scene );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef ASSIMP_BUILD_NO_EXPORT
|
||||||
|
|
||||||
|
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 );
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
Loading…
Reference in New Issue