//data loading bool ModelData::LoadIn(QString filepath) { bool loaderReady; bool abort; STLTri* pLoadedTri = NULL; Triangle3D newtri; this->filepath = filepath; if(filepath.isEmpty()) return false; //extract filename from path! filename = QFileInfo(filepath).fileName(); B9ModelLoader mLoader(filepath,loaderReady,NULL); if(loaderReady == false)//error opening model data { //display Loader Error QMessageBox msgBox; msgBox.setText(mLoader.GetError()); msgBox.exec(); return false; } //make a progress bar and connect it to LoadingBar loadbar(0,100); loadbar.useCancelButton(false); loadbar.setDescription("Importing: " + filename); QObject::connect(&mLoader,SIGNAL(PercentCompletedUpdate(qint64,qint64)), &loadbar,SLOT(setProgress(qint64,qint64))); //now we are ready to walk the loader through reading each triangle //and copying it into the this model data. while(mLoader.LoadNextTri(pLoadedTri,abort)) { if(abort) { //display Loader abort error QMessageBox msgBox; msgBox.setText(mLoader.GetError()); msgBox.exec(); return false; } else { //newtri.normal.setX(pLoadedTri->nx); //newtri.normal.setY(pLoadedTri->ny); //newtri.normal.setZ(pLoadedTri->nz); newtri.vertex[0].setX(pLoadedTri->x0); newtri.vertex[0].setY(pLoadedTri->y0); newtri.vertex[0].setZ(pLoadedTri->z0); newtri.vertex[1].setX(pLoadedTri->x1); newtri.vertex[1].setY(pLoadedTri->y1); newtri.vertex[1].setZ(pLoadedTri->z1); newtri.vertex[2].setX(pLoadedTri->x2); newtri.vertex[2].setY(pLoadedTri->y2); newtri.vertex[2].setZ(pLoadedTri->z2); //use right hand rule for importing normals - ignore file normals.. newtri.UpdateNormalFromGeom(); delete pLoadedTri; newtri.UpdateBounds(); triList.push_back(newtri); } } qDebug() << "Loaded triangles: " << triList.size(); //now center it! CenterModel(); //generate a normal display lists. int displaySuccess = FormNormalDisplayLists(); if(displaySuccess) return true; else return false; }
//Baking //using all rotations scales positions etc, generates the list of triangles that //is represented by the rendered shapes. //similar to instance baking. //remember that this function needed to always reflect what render() does but inverted. void B9SupportStructure::BakeToInstanceGeometry() { unsigned int t; unsigned short int v; Triangle3D* pNewTri; QVector3D topScale; QVector3D topPos; QVector3D midScale; QVector3D midPos; QVector3D bottomScale; QVector3D bottomPos; //first bake the top topScale = QVector3D(topRadius*2.0,topRadius*2.0,topLength + topPenetration); topPos = QVector3D((topPenetrationPoint.x() + topPivot.x())*0.5 ,(topPenetrationPoint.y() + topPivot.y())*0.5 ,(topPenetrationPoint.z() + topPivot.z())*0.5); if(topAttachShape != NULL) for(t = 0; t < topAttachShape->GetTriangles()->size(); t++) { pNewTri = new Triangle3D(topAttachShape->GetTriangles()->at(t)); for(v=0;v<3;v++) { //scale triangle vertices 1st pNewTri->vertex[v] *= topScale; //Rotate 2nd //dont deal with y - not needed in rendering or baking RotateVector(pNewTri->vertex[v], topThetaX, QVector3D(1,0,0));//x RotateVector(pNewTri->vertex[v], topThetaZ, QVector3D(0,0,1));//z //Translate 3rd into global space pNewTri->vertex[v] += topPos; pNewTri->vertex[v] += instanceParent->GetPos(); } //Update the triangle bounds and normal pNewTri->UpdateBounds(); pNewTri->UpdateNormalFromGeom(); //Add To List instanceParent->triList.push_back(pNewTri); } //second bake the middle midScale = QVector3D(midRadius*2.0,midRadius*2.0,midLength); midPos = QVector3D((topMidExtensionPoint.x() + bottomMidExtensionPoint.x())*0.5 ,(topMidExtensionPoint.y() + bottomMidExtensionPoint.y())*0.5 ,(topMidExtensionPoint.z() + bottomMidExtensionPoint.z())*0.5); if(midAttachShape != NULL) for(t = 0; t < midAttachShape->GetTriangles()->size(); t++) { pNewTri = new Triangle3D(midAttachShape->GetTriangles()->at(t)); for(v=0;v<3;v++) { //scale triangle vertices 1st pNewTri->vertex[v] *= midScale; //Rotate 2nd //dont deal with y - not needed in rendering or baking RotateVector(pNewTri->vertex[v], midThetaX, QVector3D(1,0,0));//x RotateVector(pNewTri->vertex[v], midThetaZ, QVector3D(0,0,1));//z //Translate 3rd into global space pNewTri->vertex[v] += midPos; pNewTri->vertex[v] += instanceParent->GetPos(); } //Update the triangle bounds and normal pNewTri->UpdateBounds(); pNewTri->UpdateNormalFromGeom(); //Add To List instanceParent->triList.push_back(pNewTri); } //third bake the bottom bottomScale = QVector3D(bottomRadius*2.0,bottomRadius*2.0,bottomLength + bottomPenetration); bottomPos = QVector3D((bottomPenetrationPoint.x() + bottomPivot.x())*0.5 ,(bottomPenetrationPoint.y() + bottomPivot.y())*0.5 ,(bottomPenetrationPoint.z() + bottomPivot.z())*0.5); if(bottomAttachShape != NULL) for(t = 0; t < bottomAttachShape->GetTriangles()->size(); t++) { pNewTri = new Triangle3D(bottomAttachShape->GetTriangles()->at(t)); for(v=0;v<3;v++) { //scale triangle vertices 1st pNewTri->vertex[v] *= bottomScale; //Rotate 2nd //dont deal with y - not needed in rendering or baking RotateVector(pNewTri->vertex[v], bottomThetaX+180, QVector3D(1,0,0));//x RotateVector(pNewTri->vertex[v], bottomThetaZ, QVector3D(0,0,1));//z //Translate 3rd into global space pNewTri->vertex[v] += bottomPos; pNewTri->vertex[v] += instanceParent->GetPos(); } //Update the triangle bounds and normal pNewTri->UpdateBounds(); pNewTri->UpdateNormalFromGeom(); //Add To List instanceParent->triList.push_back(pNewTri); } }
//Imports void B9SupportStructure::ImportAttachmentDataFromStls() { int i; bool s; bool triangleError; STLTri* pLoadedTri = NULL; Triangle3D newtri; QDir appdir(CROSS_OS_GetDirectoryFromLocationTag("APPLICATION_DIR")); QStringList filters; B9SupportAttachmentData importedData; qDebug() << "B9SupportStructure: Importing Stl Attachments..."; //Import All Stl in the application directory begining with "SUPPORT" filters << "SUPPORT_*"; appdir.setNameFilters(filters); QFileInfoList stlFiles = appdir.entryInfoList(); for(i = 0; i < stlFiles.size(); i++) { B9ModelLoader stlLoader(stlFiles[i].filePath(),s); if(s) { while(stlLoader.LoadNextTri(pLoadedTri,triangleError)) { if(triangleError) { qDebug() << "B9SupportStructure: ErrorLoading triangle"; return; } newtri.normal.setX(pLoadedTri->nx); newtri.normal.setY(pLoadedTri->ny); newtri.normal.setZ(pLoadedTri->nz); newtri.vertex[0].setX(pLoadedTri->x0); newtri.vertex[0].setY(pLoadedTri->y0); newtri.vertex[0].setZ(pLoadedTri->z0); newtri.vertex[1].setX(pLoadedTri->x1); newtri.vertex[1].setY(pLoadedTri->y1); newtri.vertex[1].setZ(pLoadedTri->z1); newtri.vertex[2].setX(pLoadedTri->x2); newtri.vertex[2].setY(pLoadedTri->y2); newtri.vertex[2].setZ(pLoadedTri->z2); delete pLoadedTri; newtri.UpdateBounds(); importedData.GetTriangles()->push_back(newtri); } //save the data into the Static List. importedData.SetName(stlFiles[i].baseName().remove("SUPPORT_")); importedData.CenterGeometry();//center the triangles around 0,0,0 B9SupportStructure::AttachmentDataList.push_back(importedData); //clear out importedData importedData = B9SupportAttachmentData(); } else { qDebug() << "B9SupportStructure: Error Loading: " << stlFiles[i].fileName(); } } qDebug() << "B9SupportStructure: Succesfully Loaded " << B9SupportStructure::AttachmentDataList.size() << " Attachment Types"; }
//data loading bool ModelData::LoadIn(QString filepath) { unsigned int m; unsigned int t; unsigned int i; Triangle3D newtri; const struct aiFace* face; this->filepath = filepath; if(filepath.isEmpty()) return false; //extract filename from path! filename = QFileInfo(filepath).baseName(); //AI_CONFIG_PP_FD_REMOVE = aiPrimitiveType_POINTS | aiPrimitiveType_LINES; pScene = aiImportFile(filepath.toAscii(), aiProcess_Triangulate);// | aiProcess_JoinIdenticalVertices); //trian if(pScene == NULL)//assimp cant handle the file - lets try our own reader. { //display Assimp Error QMessageBox msgBox; msgBox.setText("Assimp Error: " + QString().fromAscii(aiGetErrorString())); msgBox.exec(); aiReleaseImport(pScene); return false; } qDebug() << "Model imported with " << pScene->mMeshes[0]->mNumFaces << " faces."; for (m = 0; m < pScene->mNumMeshes; m++) { const aiMesh* mesh = pScene->mMeshes[m]; for (t = 0; t < mesh->mNumFaces; t++) { face = &mesh->mFaces[t]; if(face->mNumIndices == 3) { for(i = 0; i < face->mNumIndices; i++) { int index = face->mIndices[i]; newtri.normal.setX(mesh->mNormals[index].x); newtri.normal.setY(mesh->mNormals[index].y); newtri.normal.setZ(mesh->mNormals[index].z); newtri.vertex[i].setX(mesh->mVertices[index].x); newtri.vertex[i].setY(mesh->mVertices[index].y); newtri.vertex[i].setZ(mesh->mVertices[index].z); } newtri.UpdateBounds(); triList.push_back(newtri); } } } aiReleaseImport(pScene); qDebug() << "Loaded triangles: " << triList.size(); //now center it! CenterModel(); //generate a displaylist int displayerror = FormDisplayList(); //check for errors in display list creation (if its a large model the card may run out of memory. if(displayerror){ while(displayerror)//loop and see if there are additional errors as well. { //display Assimp Error qDebug() << "Display List Error: " << displayerror; //write to log as well. QMessageBox msgBox; switch(displayerror) { case GL_OUT_OF_MEMORY: msgBox.setText("OpenGL Error: GL_OUT_OF_MEMORY\nModel is too large to render on your graphics card."); break; case GL_INVALID_ENUM: msgBox.setText("OpenGL Error: GL_INVALID_ENUM"); break; case GL_INVALID_VALUE: msgBox.setText("OpenGL Error: GL_INVALID_VALUE"); break; case GL_INVALID_FRAMEBUFFER_OPERATION: msgBox.setText("OpenGL Error: GL_INVALID_FRAMEBUFFER_OPERATION"); break; case GL_STACK_UNDERFLOW: msgBox.setText("OpenGL Error: GL_STACK_UNDERFLOW"); break; case GL_STACK_OVERFLOW: msgBox.setText("OpenGL Error: GL_STACK_OVERFLOW"); break; default: break; } msgBox.exec(); displayerror = glGetError(); } return false; } return true; }