first draft nexus exporter

This commit is contained in:
alemuntoni 2021-06-18 12:45:17 +02:00
parent 4f0da2fb37
commit c520f4d9de
2 changed files with 135 additions and 1 deletions

2
src/external/nexus vendored

@ -1 +1 @@
Subproject commit 8f507ed591c9edaeb0e31a9b8950ed64cfade507
Subproject commit f15c1a0b24e402a61622395cf46da44e5291278c

View File

@ -24,6 +24,12 @@
#include <common/ml_document/mesh_model.h>
#include "io_nxs.h"
#include <QTextStream>
#include <nxsbuild/nexusbuilder.h>
#include <nxsbuild/meshstream.h>
#include <nxsbuild/vcgloader.h>
#include <nxsbuild/kdtree.h>
QString IONXSPlugin::pluginName() const
{
return "IONXS";
@ -79,7 +85,135 @@ void IONXSPlugin::save(
vcg::CallBackPos*)
{
if (fileFormat.toUpper() == "NXS"){
int node_size = 1<<15;
int top_node_size = 4096;
float vertex_quantization = 0.0f; //optionally quantize vertices position.
int tex_quality(92); //default jpg texture quality
//QString decimation("quadric"); //simplification method
int ram_buffer(2000); //Mb of ram to use
int n_threads = 4;
float scaling(0.5); //simplification ratio
int skiplevels = 0;
vcg::Point3d origin(0, 0, 0);
bool center = false;
bool point_cloud = false;
bool normals = false;
bool no_normals = false;
bool colors = false;
bool no_colors = false;
bool no_texcoords = false;
bool useOrigTex = false;
bool create_pow_two_tex = false;
bool deepzoom = false;
QVariant adaptive(0.333f);
Stream* stream = nullptr;
VcgLoader<CMeshO>* loader = nullptr;
KDTree* tree = nullptr;
try {
quint64 max_memory = (1<<20)*(uint64_t)ram_buffer/4; //hack 4 is actually an estimate...
std::string input = "mesh";
if (point_cloud) {
input = "pointcloud";
stream = new StreamCloud("cache_stream");
}
else
stream = new StreamSoup("cache_stream");
stream->setVertexQuantization(vertex_quantization);
stream->setMaxMemory(max_memory);
if(center) {
stream->origin = m.cm.bbox.Center();
} else
stream->origin = origin;
vcg::Point3d &o = stream->origin;
if(o[0] != 0.0 || o[1] != 0.0 || o[2] != 0.0) {
int lastPoint = fileName.lastIndexOf(".");
QString ref = fileName.left(lastPoint) + ".js";
QFile file(ref);
if(!file.open(QFile::ReadWrite)) {
throw MLException("Could not save reference file: " + ref);
}
QTextStream stream(&file);
stream.setRealNumberPrecision(12);
stream << "{ \"origin\": [" << o[0] << ", " << o[1] << ", " << o[2] << "] }\n";
}
loader = new VcgLoader<CMeshO>;
//todo
bool has_colors = false, has_normals = false, has_textures = false;
loader->load(&m.cm, has_colors, has_normals, has_textures);
stream->load(loader);
quint32 components = 0;
if(!point_cloud) components |= NexusBuilder::FACES;
if((!no_normals && (!point_cloud || has_normals)) || normals) {
components |= NexusBuilder::NORMALS;
cout << "Normals enabled\n";
}
if((has_colors && !no_colors ) || colors ) {
components |= NexusBuilder::COLORS;
cout << "Colors enabled\n";
}
if(has_textures && !no_texcoords) {
components |= NexusBuilder::TEXTURES;
cout << "Textures enabled\n";
}
//WORKAROUND to save loading textures not needed
if(!(components & NexusBuilder::TEXTURES)) {
stream->textures.clear();
}
NexusBuilder builder(components);
builder.skipSimplifyLevels = skiplevels;
builder.setMaxMemory(max_memory);
builder.n_threads = n_threads;
builder.setScaling(scaling);
builder.useNodeTex = !useOrigTex;
builder.createPowTwoTex = create_pow_two_tex;
if(deepzoom)
builder.header.signature.flags |= nx::Signature::Flags::DEEPZOOM;
builder.tex_quality = tex_quality;
bool success = builder.initAtlas(stream->textures);
if(!success) {
throw MLException("Fail");
}
if(point_cloud)
tree = new KDTreeCloud("cache_tree", adaptive.toFloat());
else
tree = new KDTreeSoup("cache_tree", adaptive.toFloat());
tree->setMaxMemory((1<<20)*(uint64_t)ram_buffer/2);
KDTreeSoup *treesoup = dynamic_cast<KDTreeSoup *>(tree);
if(treesoup)
treesoup->setTrianglesPerBlock(node_size);
KDTreeCloud *treecloud = dynamic_cast<KDTreeCloud *>(tree);
if(treecloud)
treecloud->setTrianglesPerBlock(node_size);
builder.create(tree, stream, top_node_size);
builder.save(fileName);
delete tree;
delete loader;
delete stream;
}
catch(QString error) {
delete tree;
delete loader;
delete stream;
throw MLException("Fatal error: " + error);
} catch(const char *error) {
delete tree;
delete loader;
delete stream;
throw MLException("Fatal error: " + QString(error));
}
}
else {
wrongSaveFormat(fileFormat);