openframeworks / openFrameworks

openFrameworks is a community-developed cross platform toolkit for creative coding in C++.
http://openframeworks.cc
Other
9.92k stars 2.55k forks source link

ofxAssimpModelLoader: segv on loading scene files exported from SynthEyes #3281

Closed ghost closed 9 years ago

ghost commented 9 years ago

I have a collada file that was exported from SynthEyes, it supposed to be a pointcloud of 3D trackers. When I'm trying to import it into a model it crashes with segv. I started to manually search for lines which cause it and I found it was this one (ofxAssimpModelLoader.cpp#L64-L66):

    // only ever give us triangles.
    aiSetImportPropertyInteger(AI_CONFIG_PP_SBP_REMOVE, aiPrimitiveType_LINE | aiPrimitiveType_POINT );
    aiSetImportPropertyInteger(AI_CONFIG_PP_PTV_NORMALIZE, true);

Not sure why it throws segv here, but since these lines just define a flag I commented them. Next segv happened here (ofxAssimpUtils.h#L80-L87):

    for (int i=0; i <(int) aim->mNumFaces;i++){
        if(aim->mFaces[i].mNumIndices>3){
            ofLogWarning("ofxAssimpUtils") << "aiMeshToOfMesh(): non triangular face found: model face " << i;
        }
        for (int j=0; j<(int)aim->mFaces[i].mNumIndices; j++){
            ofm.addIndex(aim->mFaces[i].mIndices[j]);
        }
    }

For the file that I've got aim->mNumFaces returns number 6, but aim->mFaces[0] throws segv so I guess it doesn't exist.

Here's how this collada file looks when imported to Blender:

When I select a polygon of one of them they all select their faces, as if they're instances of one shape:

Used .dae file: https://mega.co.nz/#!y0pjQYSL!GxwhHxVmp7jIPI84y6_Txc9usUFc0K0OKZTNBX-DGr4

ghost commented 9 years ago

Lightwave scene exported from the same SynthEyes scene file: https://mega.co.nz/#!S1wm0JIY!2s8UeAyXO4yXPy84uZz9zL-9Up3nyhuKUhHWKzWwQ44

App throws segv on loading .lws too... Maybe it's just my setup, curious to see if someone have the same segmentation fault error. Code to test:

#include <ofMain.h>
#include <ofxAssimpModelLoader.h>

int main()
{
    ofSetupOpenGL(1280, 720, OF_WINDOW);
    ofRunApp(new ofApp());
}

class ofApp : public ofBaseApp
{
  public:
    void setup();
    void draw();

    ofEasyCam cam;
    ofxAssimpModelLoader mesh;
};

void ofApp::setup()
{
  ofSetLogLevel(OF_LOG_VERBOSE);
  mesh.loadModel("track.lws");
}

void ofApp::draw()
{
  cam.begin();

  mesh.drawVertices();

  cam.end();
}
[verbose] ofxAssimpModelLoader: loadModel(): loading "track.lws" from "/media/constantine/Space/Dev/SynthEyesImport/build/data/"
Segmentation fault
bilderbuchi commented 9 years ago

pinging @openframeworks/2d-3d

ghost commented 9 years ago

Clang's asan reports the same:

    #3 0x871b03 in ofxAssimpModelLoader::initImportProperties(bool) /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpModelLoader.cpp:65
    #4 0x8713fd in ofxAssimpModelLoader::loadModel(std::string, bool) /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpModelLoader.cpp:34
    #5 0x805eaf in ofApp::setup() /media/constantine/Space/Dev/SynthEyesImport/debug/../ofApp.cpp:16

After commenting assimp flags:

==10179==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000882fcb sp 0x7fff3b878120 bp 0x7fff3b878cb0 T0)
    #0 0x882fca in aiMeshToOfMesh(aiMesh const*, ofMesh&, ofxAssimpMeshHelper*) /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpUtils.h:81
    #1 0x87a49e in ofxAssimpModelLoader::loadGLResources() /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpModelLoader.cpp:283
    #2 0x87203f in ofxAssimpModelLoader::processScene() /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpModelLoader.cpp:83
    #3 0x871503 in ofxAssimpModelLoader::loadModel(std::string, bool) /media/constantine/Space/Dev/SynthEyesImport/debug/../ofxAssimpModelLoader/src/ofxAssimpModelLoader.cpp:39
    #4 0x805e4f in ofApp::setup() /media/constantine/Space/Dev/SynthEyesImport/debug/../ofApp.cpp:16
ghost commented 9 years ago

Can't see the points, but at least it's loading now without a crash. I commented polygon-related lines:

--- a/ofxAssimpUtils.h
+++ b/ofxAssimpUtils.h
@@ -42,7 +42,7 @@
 static void aiMeshToOfMesh(const aiMesh* aim, ofMesh& ofm, ofxAssimpMeshHelper * helper = NULL){

    // default to triangle mode
-  ofm.setMode(OF_PRIMITIVE_TRIANGLES);
+  ofm.setMode(OF_PRIMITIVE_POINTS);

   // copy vertices
    for (int i=0; i < (int)aim->mNumVertices;i++){
@@ -77,6 +77,7 @@
        }
    }

+  /*
   for (int i=0; i <(int) aim->mNumFaces;i++){
     if(aim->mFaces[i].mNumIndices>3){
            ofLogWarning("ofxAssimpUtils") << "aiMeshToOfMesh(): non triangular face found: model face " << i;
@@ -85,6 +86,7 @@
            ofm.addIndex(aim->mFaces[i].mIndices[j]);
        }
   }
+  */
 }

 //--------------------------------------------------------------
--- a/ofxAssimpModelLoader.cpp
+++ b/ofxAssimpModelLoader.cpp
@@ -318,6 +318,7 @@
            meshHelper.vbo.setTexCoordData(meshHelper.cachedMesh.getTexCoordsPointer()[0].getPtr(),mesh->mNumVertices,GL_STATIC_DRAW,sizeof(ofVec2f));
         }

+        /*
         meshHelper.indices.resize(mesh->mNumFaces * 3);
         int j=0;
         for (unsigned int x = 0; x < mesh->mNumFaces; ++x){
@@ -327,6 +328,7 @@
        }

         meshHelper.vbo.setIndexData(&meshHelper.indices[0],meshHelper.indices.size(),GL_STATIC_DRAW);
+        */

         //modelMeshes.push_back(meshHelper);
     }
[verbose] ofxAssimpModelLoader: loadModel(): loading "track.lws" from "/media/constantine/Space/Dev/SynthEyesImport/debug/data/"
[verbose] ofxAssimpModelLoader: calculateDimensions(): inited scene with 2 meshes & 1 animations
[verbose] ofxAssimpModelLoader: loadGLResources(): starting
[verbose] ofxAssimpModelLoader: loadGLResources(): loading mesh 0
[verbose] ofxAssimpModelLoader: loadGLResources(): loading mesh 1
[verbose] ofxAssimpModelLoader: loadGLResource(): finished
[verbose] ofxAssimpModelLoader: loadModel(): scene has 1animations

I guess ofxAssimpModelLoader was written with meshes in mind, since it works well for meshes, but in this case it's a pointcloud without polygon faces...

ghost commented 9 years ago

Ok, got it draw stuff:

mesh.getMesh(1).drawVertices();

Incredibly hacky :)

arturoc commented 9 years ago

we should just add a check to see if the mesh->nFaces is 0 and then not try to add the indices at all. when drawing the vboMesh should do the right thing

ghost commented 9 years ago

@arturoc from my first post:

For the file that I've got aim->mNumFaces returns number 6, but aim->mFaces[0] throws segv so I guess it doesn't exist.

I guess that scene mixes pointcloud with polygonal meshes, that grid in blender viewport for example.

arturoc commented 9 years ago

then it's a bug in assimp or your model is somehow corrupt and there's little we can do to fix it apart from upgrading to assimp 3

ghost commented 9 years ago

Yeah, I think it's more of a SynthEyes's fault... Half of its export formats don't even export animation, what a piece of garbage.

arturoc commented 9 years ago

:)