LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Programming (https://www.linuxquestions.org/questions/programming-9/)
-   -   Simple Assimp import and export problem (https://www.linuxquestions.org/questions/programming-9/simple-assimp-import-and-export-problem-4175734652/)

mostlyharmless 03-07-2024 01:25 PM

Simple Assimp import and export problem
 
I'm just trying to understand some simple things about assimp. As a test program, I've got a simple program, below,(originally from https://stackoverflow.com/questions/...rows-exception) which imports a file then exports the data. For some reason, none of the exported files are readable by, e.g. meshlab. What I am missing?

Code:

#include <assimp/cimport.h>
#include <stdlib.h>
#include <stdio.h>
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

int main(int argc, char** argv)
{
    std::string filename = "float-color.ply";

 //  auto stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
 //  aiAttachLogStream(&stream);

    Assimp::Importer Importer;
    //Importer.
    std::cout << "\tReading file using ASSIMP" << std::endl;
    const aiScene *aiscene = Importer.ReadFile(filename.c_str(), aiProcess_ValidateDataStructure | aiProcessPreset_TargetRealtime_MaxQuality);

    std::string str = Importer.GetErrorString();


    if (!aiscene) {
        printf("Error parsing '%s': '%s'\n", filename.c_str(), Importer.GetErrorString());
        return 1;
    }


    Assimp::Exporter Exporter;
    const aiExportFormatDesc* format = Exporter.GetExportFormatDescription(0);
    int lIndex = filename.find_last_of('/');
    //const string path = Filename.substr(0,lIndex+1);
    std::string path = "float-color.off";
    std::cout << "\tExport path: " << path << std::endl;
    aiReturn ret = Exporter.Export(aiscene, format->id, path);
    std::cout << Exporter.GetErrorString() << std::endl;


    return 0;
}

The test file comes from the unit tests in assimp, below:
Code:

ply
format ascii 1.0
comment VCGLIB generated
element vertex 3
property float x
property float y
property float z
property float red
property float green
property float blue
property float alpha
element face 1
property list uchar int vertex_indices
end_header
0.0 0.0 0.0 0 0 1 1
100.0 0.0 0.0 0 0 1 1
200.0 200.0 0.0 0 0 1 1
3 0 1 2

The code compiles cleanly, runs without error, generates an "off" file, but the file is unreadable by meshlab. Same with multiple other exported file formats...

NevemTeve 03-07-2024 11:44 PM

> the file is unreadable by meshlab

Is there an error message from `meshlab`? Please quote it.

mostlyharmless 03-08-2024 08:25 AM

Thanks for responding!

Depends on the file type, "off" produces "Invalid file", "obj" says "No vertex found", "ply says "header not found".

I realized that all the output files were actually the same identical file regardless of suffix, and the output is an "xml" file.

So.. clearly there is something wrong with my Exporter.Export(aiscene, format->id, path) call, but I haven't figured out how to make it generate actual off, ply, obj, blah blah files. I changed the last few lines to
Code:

    aiReturn ret = Exporter.Export(aiscene, format->id, path, 0);

    if (!(aiReturn_SUCCESS == 0)) {
        printf("Error exporting '%s': '%s'\n", filename.c_str(), Exporter.GetErrorString());
        return 1;
    }

but get no reported error. meshlab produces no error if I feed it the xml file with the suffix xml, but it also produces no graphics.
(Added)
I tried to change it to aiReturn ret = Exporter.Export(aiscene, "stl" , path, 0); which also produces no error and no output file at all.

ntubski 03-08-2024 08:31 AM

Quote:

Originally Posted by mostlyharmless (Post 6488229)
Code:

    const aiExportFormatDesc* format = Exporter.GetExportFormatDescription(0);

What format does 0 correspond to? Maybe it's the wrong one?

mostlyharmless 03-08-2024 09:09 AM

Hmm, good idea. I tried 1,2,3,4 and got different file types. I suppose I need to dig through assimp and see which types are which, or figure out a better way to specify file types. Just putting in the extension didn't produce any output.

I found this https://github.com/assimp/assimp/issues/2481 which lists these types
0: dae 1: x 2: stp 3: obj 4: obj 5: stl 6: stl 7: ply 8: ply 9: 3ds 10: gltf 11: glb 12: gltf2 13: assbin 14: assxml 15: x3d 16: 3mf
but it seems hit or miss. ASCII ply works, obj works, stl produces nothing..

and.. aiReturn ret = Exporter.Export(aiscene, "obj", path); actually works to make a file, just not stl or off. In addition, I tried a different .ply file and found the obj file created is only grey scale. I suspect the latter is because the ply file has color set for each vertex, and assimp is assuming some sort of texture or uv channel?

mostlyharmless 03-13-2024 09:11 AM

Update: solved, kind of.. It's quite flaky, and I've only tested a ply file with vertex colors and normals, but I've got dae/collada, ascii ply and stl,3ds,x,fbx and x3d successfully made. I'm posting my code here for anyone with a similar problem.
Code:

#include <assimp/cimport.h>
#include <stdio.h>
#include <iostream>
#include <assimp/Importer.hpp>
#include <assimp/Exporter.hpp>
#include <assimp/scene.h>
#include <assimp/postprocess.h>

int main(int argc, char** argv)
{
    const char* filenameout = NULL;
    const char* filename = NULL;
    filename = argv[1];
    filenameout = argv[2];

    auto stream = aiGetPredefinedLogStream(aiDefaultLogStream_STDOUT,NULL);
    aiAttachLogStream(&stream);
    Assimp::Importer Importer;
    Assimp::Exporter Exporter;
    const aiImporterDesc *iformat = nullptr;

    // Check and validate the specified model file extension.
    // https://github.com/assimp/assimp/issues/3827  binary ply is broken, use rply instead
    // has to be on both the import and export list.
    // only obj,dae,ascii ply,ascii stl,3ds,x and fbx verified to work from ply. Colors are not always preserved
    const char* extension = strrchr(filenameout, '.');
    if (!extension) {
        std::cout <<"Please provide a file with a valid extension.\n";
        return 1;
    }
    if (AI_FALSE == aiIsExtensionSupported(extension)) {
        std::cout <<"The specified model file extension is currently unsupported in Assimp\n ";
        return 1;
    }

    std::cout << "\tReading file using ASSIMP" << std::endl;
    const aiScene *aiscene = Importer.ReadFile(filename, aiProcess_ValidateDataStructure | aiProcessPreset_TargetRealtime_MaxQuality);
    if (!aiscene) {
        printf("Error parsing '%s': '%s'\n", filename, Importer.GetErrorString());
        return 1;}

    uint countin = Importer.GetImporterCount();
;
    uint ID = Importer.GetImporterIndex(extension);  //unfortunately these are not Exporter formatIDs
    int i = 0 ;
    do {
        iformat = Importer.GetImporterInfo(i);
        std::cout << "id: "<< i << " " << iformat->mFileExtensions << "\n";
        i++;
    } while (i < countin);


    //std::cout << "ID: "<< ID << "\n";
    iformat = Importer.GetImporterInfo(ID);
    uint count = Exporter.GetExportFormatCount();
    // std::cout << "count: "<< count << "\n";
    const aiExportFormatDesc *format;
    i = 0 ;
    do {
        format = Exporter.GetExportFormatDescription(i);
        std::cout << "id: "<< i << " " << format->id << "\n";
        if (iformat->mFileExtensions == format->id){
    //        std::cout << "ID is " << i << "\n";
            Exporter.Export(aiscene, format->id , filenameout, 0);
            std::cout << "Wrote " << filenameout << "\n";
        }
        i++;
    } while (i < count);

    // special cases

    if (ID == 26) {  // dae or collada
        format = Exporter.GetExportFormatDescription(0);
        Exporter.Export(aiscene, format->id , filenameout, 0);
        std::cout << "Wrote " << filenameout << "\n";
    }

    if (ID == 45) {  //x3d
        format = Exporter.GetExportFormatDescription(16);
        Exporter.Export(aiscene, format->id , filenameout, 0);
        std::cout << "Wrote " << filenameout << "\n";
    }

    if (ID == 3) { //3ds
        format = Exporter.GetExportFormatDescription(9);
        Exporter.Export(aiscene, format->id , filenameout, 0);
        std::cout << "Wrote " << filenameout << "\n";
    }

    if (!(aiReturn_SUCCESS == 0)) {
        std::cout << "Error exporting" << filenameout << Exporter.GetErrorString() << "\n" ;
    }

    aiDetachAllLogStreams();

    return 0;
}



All times are GMT -5. The time now is 08:02 PM.