void AbstrGeoConverter::AddToMesh(const VertVec& vertices, IndexVec& v, IndexVec& n, IndexVec& t, IndexVec& c, IndexVec& VertIndices, IndexVec& NormalIndices, IndexVec& TCIndices, IndexVec& COLIndices) { if (v.size() > 3) { // per OBJ definition any poly with more than 3 verices has // to be planar and convex, so we can safely triangulate it SortByGradient(vertices,v,n,t,c); for (size_t i = 0; i<v.size()-2; i++) { IndexVec mv, mn, mt, mc; mv.push_back(v[0]); mv.push_back(v[i+1]); mv.push_back(v[i+2]); if (n.size() == v.size()) { mn.push_back(n[i]); mn.push_back(n[i+1]); mn.push_back(n[i+2]); } if (t.size() == v.size()) { mt.push_back(t[i]); mt.push_back(t[i+1]); mt.push_back(t[i+2]); } if (c.size() == v.size()) { mc.push_back(c[i]); mc.push_back(c[i+1]); mc.push_back(c[i+2]); } AddToMesh(vertices, mv,mn,mt,mc, VertIndices, NormalIndices, TCIndices, COLIndices); } } else { for (size_t i = 0; i<v.size(); i++) { VertIndices.push_back(v[i]); if (n.size() == v.size()) NormalIndices.push_back(n[i]); if (t.size() == v.size()) TCIndices.push_back(t[i]); if (c.size() == v.size()) COLIndices.push_back(c[i]); } } }
void RenderMeshGL::PrepareTransBuffers(GLuint IndexVBO, const SortIndexPVec& list) { if (list.empty()) return; IndexVec VertIndices; VertIndices.reserve(list.size()); for(SortIndexPVec::const_iterator index = list.begin(); index != list.end(); ++index) { size_t iIndex = (*index)->m_index; for(size_t i = 0;i<m_VerticesPerPoly;i++) { VertIndices.push_back(m_Data.m_VertIndices[iIndex+i]); } } glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBO); glBufferData(GL_ELEMENT_ARRAY_BUFFER, VertIndices.size()*sizeof(uint32_t), &VertIndices[0], GL_STREAM_DRAW); }
std::shared_ptr<Mesh> MedAlyVisFiberTractGeoConverter::ConvertToMesh(const std::string& strFilename) { VertVec vertices; ColorVec colors; IndexVec VertIndices; IndexVec COLIndices; std::ifstream fs; std::string line; fs.open(strFilename.c_str()); if (fs.fail()) { throw tuvok::io::DSOpenFailed(strFilename.c_str(), __FILE__, __LINE__); } int iReaderState = SEARCHING_DIM; UINTVECTOR3 iDim; FLOATVECTOR3 fScale; FLOATVECTOR3 fTranslation; INTVECTOR4 iMetadata; size_t iElementCounter=0; size_t iElementReadCounter=0; int iLineCounter=-1; // get filesize. fs.seekg(0, std::ios_base::end); std::streampos sz = fs.tellg(); fs.seekg(0, std::ios_base::beg); double prev_progress = 0.0; while (!fs.fail() || iLineCounter == iMetadata[2]) { getline(fs, line); if (fs.fail()) break; // no more lines to read // remove comments size_t cPos = line.find_first_of('#'); if (cPos != std::string::npos) line = line.substr(0,cPos); line = SysTools::TrimStr(line); if (line.length() == 0) continue; // skips empty and comment lines double progress = static_cast<double>(fs.tellg()) / static_cast<double>(sz); if(progress - prev_progress > 0.01 || progress > 0.98) { prev_progress = progress; MESSAGE("Reading mesh... %g%%", progress*100.0); } switch (iReaderState) { case SEARCHING_DIM : { iDim[0] = atoi(line.c_str()); line = TrimToken(line); iDim[1] = atoi(line.c_str()); line = TrimToken(line); iDim[2] = atoi(line.c_str()); iReaderState++; } break; case SEARCHING_SCALE : { fScale[0] = float(atof(line.c_str())); line = TrimToken(line); fScale[1] = float(atof(line.c_str())); line = TrimToken(line); fScale[2] = float(atof(line.c_str())); iReaderState++; } break; case SEARCHING_TRANSLATION : { fTranslation[0] = float(atof(line.c_str())); line = TrimToken(line); fTranslation[1] = float(atof(line.c_str())); line = TrimToken(line); fTranslation[2] = float(atof(line.c_str())); iReaderState++; } break; case SEARCHING_METADATA : { iMetadata[0] = atoi(line.c_str()); line = TrimToken(line); iMetadata[1] = atoi(line.c_str()); line = TrimToken(line); iMetadata[2] = atoi(line.c_str()); line = TrimToken(line); iMetadata[3] = atoi(line.c_str()); iLineCounter = 0; iReaderState++; } break; case PARSING_COUNTER : { iElementCounter = atoi(line.c_str()); iElementReadCounter = 0; iReaderState++; } break; case PARSING_DATA : { FLOATVECTOR3 vec; vec[0] = float(atof(line.c_str())); line = TrimToken(line); vec[1] = float(atof(line.c_str())); line = TrimToken(line); vec[2] = float(atof(line.c_str())); vec = (vec + 0.5f*FLOATVECTOR3(iDim)*fScale) / (FLOATVECTOR3(iDim)*fScale) - 0.5f; vertices.push_back(vec); iElementReadCounter++; if (iElementCounter == iElementReadCounter) { size_t iStartIndex = vertices.size() - iElementCounter; for (size_t i = 0;i<iElementCounter-1;i++) { VertIndices.push_back(uint32_t(iStartIndex)); VertIndices.push_back(uint32_t(iStartIndex+1)); COLIndices.push_back(uint32_t(iStartIndex)); COLIndices.push_back(uint32_t(iStartIndex+1)); if (i == 0) { FLOATVECTOR3 direction = (vertices[iStartIndex+1]-vertices[iStartIndex]).normalized(); colors.push_back((direction).abs()); } else if (i == iElementCounter-2) { FLOATVECTOR3 directionB = (vertices[iStartIndex]-vertices[iStartIndex-1]).normalized(); FLOATVECTOR3 directionF = (vertices[iStartIndex+1]-vertices[iStartIndex]).normalized(); colors.push_back(((directionB+directionF)/2.0f).abs()); colors.push_back((directionF).abs()); } else { FLOATVECTOR3 directionB = (vertices[iStartIndex]-vertices[iStartIndex-1]).normalized(); FLOATVECTOR3 directionF = (vertices[iStartIndex+1]-vertices[iStartIndex]).normalized(); colors.push_back(((directionB+directionF)/2.0f).abs()); } iStartIndex++; } iLineCounter++; iReaderState = PARSING_COUNTER; } } break; default : throw std::runtime_error("unknown parser state"); } } std::string desc = m_vConverterDesc + " data converted from " + SysTools::GetFilename(strFilename); std::shared_ptr<Mesh> m( new Mesh(vertices,NormVec(),TexCoordVec(),colors, VertIndices,IndexVec(),IndexVec(),COLIndices, false,false,desc,Mesh::MT_LINES) ); return m; }
Tree::Node* Tree::contructTree_R( IndexVec& idxEdges ) { if ( idxEdges.empty() ) return nullptr; int idx = choiceBestSplitEdge( idxEdges ); Node* node = new Node; node->idxEdge = idx; if ( idx < 0 ) // leaf { node->tag = ~uint32( mLeaves.size() ); node->front = nullptr; node->back = nullptr; mLeaves.push_back( Leaf() ); Leaf& data = mLeaves.back(); data.node = node; data.edges.swap( idxEdges ); return node; } else { node->tag = uint32( mNodes.size() ); mNodes.push_back( node ); } //triList.erase( cIter ); IndexVec idxFronts; IndexVec idxBacks; Plane& plane = mEdges[ idx ].plane; for( IndexVec::iterator iter( idxEdges.begin() ) , itEnd( idxEdges.end() ) ; iter != itEnd ; ++iter ) { int idxTest = *iter; Edge& edgeTest = mEdges[ idxTest ]; Vec2f vSplit[2]; switch ( plane.splice( edgeTest.v , vSplit ) ) { case SIDE_FRONT: case SIDE_IN: idxFronts.push_back( idxTest ); break; case SIDE_BACK: idxBacks.push_back( idxTest ); break; case SIDE_SPLIT: { idxFronts.push_back( idxTest ); idxBacks.push_back( (int)mEdges.size() ); mEdges.push_back( Edge() ); Edge& edge = mEdges.back(); edge.v[0] = vSplit[0]; edge.v[1] = vSplit[1]; edge.plane = edgeTest.plane; edge.idx = edgeTest.idx; } break; } } node->front = contructTree_R( idxFronts ); if ( node->front ) node->front->parent = node; node->back = contructTree_R( idxBacks ); if ( node->back ) node->back->parent = node; node->tag = 0; return node; }
std::shared_ptr<Mesh> MobileGeoConverter::ConvertToMesh(const std::string& strFilename) { VertVec vertices; NormVec normals; TexCoordVec texcoords; ColorVec colors; IndexVec VertIndices; IndexVec NormalIndices; IndexVec TCIndices; IndexVec COLIndices; G3D::GeometrySoA geometry; G3D::read(strFilename, &geometry); if (geometry.info.indexSize == sizeof(uint16_t)) { for (uint32_t i=0; i<geometry.info.numberIndices; ++i) VertIndices.push_back((uint32_t)((uint16_t*)geometry.indices)[i]); } else VertIndices = IndexVec(geometry.indices, (uint32_t*)geometry.indices + geometry.info.numberIndices); uint32_t i = 0; for (std::vector<uint32_t>::iterator it=geometry.info.attributeSemantics.begin(); it<geometry.info.attributeSemantics.end(); ++it) { if (*it == G3D::Position) vertices = VertVec((FLOATVECTOR3*)geometry.vertexAttributes.at(i), (FLOATVECTOR3*)geometry.vertexAttributes.at(i) + geometry.info.numberVertices); else if (*it == G3D::Normal) normals = NormVec((FLOATVECTOR3*)geometry.vertexAttributes.at(i), (FLOATVECTOR3*)geometry.vertexAttributes.at(i) + geometry.info.numberVertices); else if (*it == G3D::Color) colors = ColorVec((FLOATVECTOR4*)geometry.vertexAttributes.at(i), (FLOATVECTOR4*)geometry.vertexAttributes.at(i) + geometry.info.numberVertices); else if (*it == G3D::Tex) texcoords = TexCoordVec((FLOATVECTOR2*)geometry.vertexAttributes.at(i), (FLOATVECTOR2*)geometry.vertexAttributes.at(i) + geometry.info.numberVertices); ++i; } if (vertices.size() == normals.size()) NormalIndices = VertIndices; if (vertices.size() == colors.size()) COLIndices = VertIndices; if (vertices.size() == texcoords.size()) TCIndices = VertIndices; bool success = false; Mesh::EMeshType mtype = Mesh::MT_TRIANGLES; switch (geometry.info.primitiveType) { case G3D::Point: T_ERROR("Unsupported primitive type."); break; case G3D::Line: mtype = Mesh::MT_LINES; success = true; break; case G3D::Triangle: mtype = Mesh::MT_TRIANGLES; success = true; break; default: T_ERROR("Unknown primitive type."); break; } G3D::clean(&geometry); if (!success) return nullptr; std::string desc = m_vConverterDesc + " data converted from " + SysTools::GetFilename(strFilename); return std::shared_ptr<Mesh>( new Mesh(vertices,normals,texcoords,colors, VertIndices,NormalIndices,TCIndices,COLIndices, false, false, desc, mtype) ); }
std::shared_ptr<Mesh> PLYGeoConverter::ConvertToMesh(const std::string& strFilename) { VertVec vertices; NormVec normals; TexCoordVec texcoords; ColorVec colors; IndexVec VertIndices; IndexVec NormalIndices; IndexVec TCIndices; IndexVec COLIndices; std::ifstream fs; std::string line; fs.open(strFilename.c_str()); if (fs.fail()) { throw tuvok::io::DSOpenFailed(strFilename.c_str(), __FILE__, __LINE__); } int iFormat = FORMAT_ASCII; int iReaderState = SEARCHING_MAGIC; size_t iVertexCount=0; size_t iFaceCount=0; size_t iLineCount=0; bool bNormalsFound = false; bool bTexCoordsFound = false; bool bColorsFound = false; MESSAGE("Reading Header"); fs.seekg(0,std::ios::end); streamoff iFileLength = fs.tellg(); fs.seekg(0,std::ios::beg); size_t iBytesRead = 0; size_t iLine = 0; while (!fs.fail() && iReaderState < PARSING_VERTEX_DATA) { getline(fs, line); if (fs.fail()) break; // no more lines to read iBytesRead += line.size() + 1; iLine++; if (iLine % 5000 == 0) { MESSAGE("Reading Header (Line %u %u/%u kb)", unsigned(iLine), unsigned(iBytesRead/1024),unsigned(iFileLength/1024)); } // remove comments line = SysTools::TrimStr(line); if (line.length() == 0) continue; // skip empty lines // find the linetype string linetype = GetToken(line); if (linetype == "comment") continue; // skip comment lines switch (iReaderState) { case SEARCHING_MAGIC : { if (linetype == "ply") iReaderState = PARSING_GENERAL_HEADER; else continue; } break; case PARSING_FACE_HEADER : case PARSING_VERTEX_HEADER : case PARSING_EDGE_HEADER : case PARSING_GENERAL_HEADER : { if (linetype == "format") { string format = GetToken(line); if (format == "ascii") iFormat = FORMAT_ASCII; else if (format == "binary_little_endian") iFormat = FORMAT_BIN_LITTLE; else if (format == "binary_big_endian") iFormat = FORMAT_BIN_BIG; else { stringstream s; s << "unknown format " << format.c_str(); throw tuvok::io::DSParseFailed(strFilename.c_str(), s.str().c_str(),__FILE__, __LINE__); } string version = GetToken(line); if (version != "1.0") { stringstream s; s << "unknown version " << version.c_str(); throw tuvok::io::DSParseFailed(strFilename.c_str(), s.str().c_str(),__FILE__, __LINE__); } } else if (linetype == "element") { string elemType = GetToken(line); if (elemType == "vertex") { iReaderState = PARSING_VERTEX_HEADER; string strCount = GetToken(line); iVertexCount = atoi(strCount.c_str()); } else if (elemType == "face") { iReaderState = PARSING_FACE_HEADER; string strCount = GetToken(line); iFaceCount = atoi(strCount.c_str()); } else if (elemType == "edge") { iReaderState = PARSING_EDGE_HEADER; string strCount = GetToken(line); iLineCount = atoi(strCount.c_str()); } } else if (linetype == "property") { if (iReaderState == PARSING_VERTEX_HEADER){ propType t = StringToType(GetToken(line)); vertexProp p = StringToVProp(GetToken(line)); vertexProps.push_back(make_pair(t,p)); } else if (iReaderState == PARSING_FACE_HEADER) { faceProp p = StringToFProp(GetToken(line)); propType t1 = StringToType(GetToken(line)); propType t2 = StringToType(GetToken(line)); faceProps.push_back(make_tuple(t1,t2,p)); } else if (iReaderState == PARSING_EDGE_HEADER) { propType t = StringToType(GetToken(line)); edgeProp p = StringToEProp(GetToken(line)); edgeProps.push_back(make_pair(t,p)); } else { WARNING("property outside vertex or face data found"); } } else if (linetype == "end_header") { iReaderState = PARSING_VERTEX_DATA; } } break; default : throw tuvok::io::DSParseFailed(strFilename.c_str(), "unknown parser state header",__FILE__, __LINE__); } } if (iFormat != FORMAT_ASCII) { throw tuvok::io::DSParseFailed(strFilename.c_str(), "Binary PLY files not supported yet.",__FILE__, __LINE__); } if (iFaceCount > 0 && iLineCount > 0) { WARNING("found both, polygons and lines, in the file, ignoring lines"); } MESSAGE("Reading Vertices"); size_t iFacesFound = 0; vertices.reserve(iVertexCount); // parse data body of PLY file while (!fs.fail() && iReaderState != PARSING_DONE) { getline(fs, line); if (fs.fail()) break; // no more lines to read iBytesRead += line.size() + 1; iLine++; if (iLine % 5000 == 0) { if (PARSING_VERTEX_DATA) MESSAGE("Reading Vertices (Line %u %u/%u kb)", unsigned(iLine), unsigned(iBytesRead/1024),unsigned(iFileLength/1024)); else MESSAGE("Reading Indices (Line %u %u/%u kb)", unsigned(iLine), unsigned(iBytesRead/1024),unsigned(iFileLength/1024)); } line = SysTools::TrimStr(line); if (iReaderState == PARSING_VERTEX_DATA) { FLOATVECTOR3 pos; FLOATVECTOR3 normal(0,0,0); FLOATVECTOR4 color(0,0,0,1); for (size_t i = 0;i<vertexProps.size();i++) { string strValue = GetToken(line); double fValue=0.0; int iValue=0; if (vertexProps[i].first <= PROPT_DOUBLE) { fValue = atof(strValue.c_str()); iValue = int(fValue); } else { iValue = atoi(strValue.c_str()); fValue = double(iValue); } switch (vertexProps[i].second) { case VPROP_X : pos.x = float(fValue); break; case VPROP_Y : pos.y = float(fValue); break; case VPROP_Z : pos.z = float(fValue); break; case VPROP_NX : bNormalsFound = true; normal.x = float(fValue); break; case VPROP_NY : bNormalsFound = true; normal.y = float(fValue); break; case VPROP_NZ : bNormalsFound = true; normal.z = float(fValue); break; case VPROP_RED : bColorsFound = true; color.x = (vertexProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case VPROP_GREEN : bColorsFound = true; color.y = (vertexProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case VPROP_BLUE : bColorsFound = true; color.z = (vertexProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case VPROP_OPACITY : bColorsFound = true; color.w = (vertexProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case VPROP_INTENSITY : bColorsFound = true; color = (vertexProps[i].first <= PROPT_DOUBLE) ? FLOATVECTOR4(float(fValue),float(fValue),float(fValue),1.0f) : FLOATVECTOR4(iValue/255.0f,iValue/255.0f,iValue/255.0f,1.0f); break; default: break; } } vertices.push_back(pos); if (bColorsFound) colors.push_back(color); if (bNormalsFound) normals.push_back(normal); if (vertices.size() == iVertexCount) { iReaderState = (iFaceCount > 0) ? PARSING_FACE_DATA : PARSING_EDGE_DATA; MESSAGE("Reading Faces"); } } else if (iReaderState == PARSING_FACE_DATA) { IndexVec v, n, t, c; for (size_t i = 0;i<faceProps.size();i++) { string strValue = GetToken(line); double fValue=0.0; int iValue=0; if (std::get<1>(faceProps[i]) <= PROPT_DOUBLE) { fValue = atof(strValue.c_str()); iValue = static_cast<int>(fValue); } else { iValue = atoi(strValue.c_str()); fValue = static_cast<double>(iValue); } switch (std::get<2>(faceProps[i])) { case FPROP_LIST : { for (int j = 0;j<iValue;j++) { // hack: read everything as int, regardless of the // type stored in std::get<1>(faceProps[i]) strValue = GetToken(line); int elem = atoi(strValue.c_str()); v.push_back(elem); if (bNormalsFound) n.push_back(elem); if (bTexCoordsFound) t.push_back(elem); if (bColorsFound) c.push_back(elem); } } break; default: break; } } AddToMesh(vertices,v,n,t,c,VertIndices,NormalIndices,TCIndices,COLIndices); iFacesFound++; if (iFacesFound == iFaceCount) iReaderState = PARSING_DONE; } else if (iReaderState == PARSING_EDGE_DATA) { FLOATVECTOR4 color(0,0,0,1); bool bEdgeColorsFound=false; for (size_t i = 0;i<edgeProps.size();i++) { string strValue = GetToken(line); double fValue=0.0; int iValue=0; if (edgeProps[i].first <= PROPT_DOUBLE) { fValue = atof(strValue.c_str()); iValue = int(fValue); } else { iValue = atoi(strValue.c_str()); fValue = double(iValue); } switch (edgeProps[i].second) { case EPROP_VERTEX1 : VertIndices.push_back(iValue); break; case EPROP_VERTEX2 : VertIndices.push_back(iValue); break; case EPROP_RED : bEdgeColorsFound = true; color.x = (edgeProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case EPROP_GREEN : bEdgeColorsFound = true; color.y = (edgeProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case EPROP_BLUE : bEdgeColorsFound = true; color.z = (edgeProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case EPROP_OPACITY : bEdgeColorsFound = true; color.w = (edgeProps[i].first <= PROPT_DOUBLE) ? float(fValue) : iValue/255.0f; break; case EPROP_INTENSITY : bEdgeColorsFound = true; color = (edgeProps[i].first <= PROPT_DOUBLE) ? FLOATVECTOR4(float(fValue),float(fValue),float(fValue),1.0f) : FLOATVECTOR4(iValue/255.0f,iValue/255.0f,iValue/255.0f,1.0f); break; default: break; } } if (bEdgeColorsFound) { COLIndices.push_back(uint32_t(colors.size())); COLIndices.push_back(uint32_t(colors.size())); colors.push_back(color); } if (VertIndices.size() == iLineCount*2) iReaderState = PARSING_DONE; } else throw tuvok::io::DSParseFailed(strFilename.c_str(), "unknown parser state data",__FILE__, __LINE__); } MESSAGE("Creating Mesh Object"); std::string desc = m_vConverterDesc + " data converted from " + SysTools::GetFilename(strFilename); return std::shared_ptr<Mesh>( new Mesh(vertices,normals,texcoords,colors, VertIndices,NormalIndices,TCIndices,COLIndices, false,false,desc, (iFaceCount > 0) ? Mesh::MT_TRIANGLES : Mesh::MT_LINES) ); }