// swaps two index entries static void Swap(IndexVec& v, IndexVec& n, IndexVec& t, IndexVec& c, size_t sI, size_t tI) { std::swap(v[sI],v[tI]); if (v.size() == n.size()) std::swap(n[sI],n[tI]); if (v.size() == t.size()) std::swap(t[sI],t[tI]); if (v.size() == c.size()) std::swap(c[sI],c[tI]); }
void AbstrGeoConverter::SortByGradient(const VertVec& vertices, IndexVec& v, IndexVec& n, IndexVec& t, IndexVec& c) { if(v.size() < 2) return; // find AA projection direction that is not coplanar to the polygon size_t iPlaneX = 2; size_t iPlaneY = 1; FLOATVECTOR3 tan = (vertices[v[0]]-vertices[v[1]]).normalized(); FLOATVECTOR3 bin = (vertices[v[0]]-vertices[v[2]]).normalized(); FLOATVECTOR3 norm = tan%bin; if (norm.y != 0) { iPlaneX = 0; iPlaneY = 2; } else if (norm.z != 0) { iPlaneX = 0; iPlaneY = 1; } // else use default which is the x-plane // move bottom element to front of array for (size_t i = 1; i<v.size(); i++) { if (vertices[v[0]][iPlaneY] > vertices[v[i]][iPlaneY]) { Swap(v,n,t,c,0,i); } } // *** sort points according to gradient SortPoints(vertices,v,n,t,c,iPlaneX,iPlaneY); }
CassError set(StringRef name, const T value) { IndexVec indices; if (get_indices(name, &indices) == 0) { return CASS_ERROR_LIB_NAME_DOES_NOT_EXIST; } for (IndexVec::const_iterator it = indices.begin(), end = indices.end(); it != end; ++it) { size_t index = *it; CassError rc = set(index, value); if (rc != CASS_OK) return rc; } return CASS_OK; }
static void SortPoints(const VertVec& vertices, IndexVec& v, IndexVec& n, IndexVec& t, IndexVec& c, size_t iPlaneX, size_t iPlaneY) { // for small arrays, this bubble sort actually beats qsort. for (size_t i= 1; i<v.size(); ++i) { bool bDidSwap = false; for (size_t j = 1; j<v.size()-i; ++j) if (!CheckOrdering(vertices[v[j]],vertices[v[j+1]],vertices[v[0]],iPlaneX,iPlaneY)) { Swap(v,n,t,c,j,j+1); bDidSwap = true; } if (!bDidSwap) return; } }
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); }
int Tree::choiceBestSplitEdge( IndexVec const& idxEdges ) { int minVal = INT_MAX; int result = -1; //return result; for( IndexVec::const_iterator iter ( idxEdges.begin() ) , itEnd( idxEdges.end() ) ; iter != itEnd ; ++iter ) { int numFront = 0; int numBack = 0; int numSplit = 0; int numOnPlane = 0; Edge& edge = mEdges[ *iter ]; Plane& plane = edge.plane; for( IndexVec::const_iterator iter2 ( idxEdges.begin() ) ; iter2 != itEnd ; ++iter2 ) { Edge& edgeTest = mEdges[ *iter2 ]; switch( plane.testSegment( edgeTest.v ) ) { case SIDE_FRONT: ++numFront; break; case SIDE_BACK: ++numBack; break; case SIDE_SPLIT: ++numSplit; break; case SIDE_IN: ++numOnPlane; break; } } if ( ( numSplit == 0 ) && ( numBack == 0 || numFront == 0) ) continue; int val = abs( numFront - numBack ) + 8 * numSplit; if ( val < minVal ) { result = *iter; minVal = val; } } return result; }
//-***************************************************************************** void AbcReader::f( const IndexVec &vIndices, const IndexVec &vtIndices, const IndexVec &vnIndices ) { int count = vIndices.size(); if ( count > 2 ) { m_counts.push_back( count ); for ( int i = 0; i < count; ++i ) { m_indices.push_back( ( int )( vIndices[i]-1 ) ); } } }
void Maze::updateWall(const IndexVec &cur, const Direction& newState, bool forceSetDone) { //二重書き込みを防ぐ if (!forceSetDone && wall[cur.y][cur.x].isDoneAll()) return; dirty = true; if (forceSetDone) wall[cur.y][cur.x] |= newState | (uint8_t)0xf0; else wall[cur.y][cur.x] |= newState; //今のEASTをx+1のWESTに反映 //今のNORTHをy+1のSOUTHに反映 //今のWESTをx-1のEASTに反映 //今のSOUTHをy-1のNORTHに反映 for (int i=0;i<4;i++) { if (cur.canSum(IndexVec::vecDir[i])) { IndexVec neighbor(cur + IndexVec::vecDir[i]); //今のi番目の壁情報ビットとDoneビットを(i+2)%4番目(180度回転方向)に反映 if (forceSetDone) wall[neighbor.y][neighbor.x] |= (0x10 | newState[i]) << (i+2)%4; else wall[neighbor.y][neighbor.x] |= ((newState[i+4]<<4) | newState[i]) << (i+2)%4; } } }
std::shared_ptr<Mesh> OBJGeoConverter::ConvertToMesh(const std::string& strFilename) { bool bFlipVertices = false; 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()) { // hack, we really want some kind of 'file not found' exception. throw tuvok::io::DSOpenFailed(strFilename.c_str(), __FILE__, __LINE__); } float x,y,z,w; size_t iVerticesPerPoly = 0; fs.seekg(0,std::ios::end); std::streamoff iFileLength = fs.tellg(); fs.seekg(0,std::ios::beg); size_t iBytesRead = 0; size_t iLine = 0; while (!fs.fail()) { getline(fs, line); iBytesRead += line.size() + 1; iLine++; if (fs.fail()) break; // no more lines to read line = SysTools::ToLowerCase(SysTools::TrimStr(line)); // 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 // find the linetype size_t off = line.find_first_of(" \r\n\t"); if (off == std::string::npos) continue; std::string linetype = SysTools::TrimStrRight(line.substr(0,off)); line = SysTools::TrimStr(line.substr(linetype.length())); if (linetype == "o") { WARNING("Skipping Object Tag in OBJ file"); } else if (linetype == "mtllib") { WARNING("Skipping Material Library Tag in OBJ file"); } else if (linetype == "v") { // vertex attrib found std::vector< std::string > pos = SysTools::Tokenize(line, SysTools::PM_NONE); if (pos.size() < 3) { WARNING("Found broken v tag (to few coordinates, " "filling with zeroes"); x = (pos.size() > 0) ? SysTools::FromString<float>(pos[0]) : 0.0f; y = (pos.size() > 1) ? SysTools::FromString<float>(pos[1]) : 0.0f; z = 0.0f; } else { x = SysTools::FromString<float>(pos[0]); y = SysTools::FromString<float>(pos[1]); z = SysTools::FromString<float>(pos[2]); if (pos.size() >= 6) { // this is a "meshlab extended" obj file that includes vertex colors float r = SysTools::FromString<float>(pos[3]); float g = SysTools::FromString<float>(pos[4]); float b = SysTools::FromString<float>(pos[5]); float a = (pos.size() > 6) ? SysTools::FromString<float>(pos[6]):1.0f; colors.push_back(FLOATVECTOR4(r,g,b,a)); } else if (pos.size() > 3) { // file specifies homogeneous coordinate float w = SysTools::FromString<float>(pos[3]); if (w != 0) { x /= w; y /= w; z /= w; } } } vertices.push_back(FLOATVECTOR3(x,y,(bFlipVertices) ? -z : z)); } else if (linetype == "vt") { // vertex texcoord found x = float(atof(GetToken(line).c_str())); y = float(atof(GetToken(line).c_str())); texcoords.push_back(FLOATVECTOR2(x,y)); } else if (linetype == "vc") { // vertex color found x = float(atof(GetToken(line).c_str())); y = float(atof(GetToken(line).c_str())); z = float(atof(GetToken(line).c_str())); w = float(atof(GetToken(line).c_str())); colors.push_back(FLOATVECTOR4(x,y,z,w)); } else if (linetype == "vn") { // vertex normal found x = float(atof(GetToken(line).c_str())); y = float(atof(GetToken(line).c_str())); z = float(atof(GetToken(line).c_str())); FLOATVECTOR3 n(x,y,z); n.normalize(); normals.push_back(n); } else if (linetype == "f" || linetype == "l") { // face or line found size_t off = line.find_first_of(" \r\n\t"); if (off == std::string::npos) continue; std::string analysis = SysTools::TrimStrRight(line.substr(0,off)); int count = CountOccurences(analysis,"/"); IndexVec v, n, t, c; while (line.length() > 0) { switch (count) { case 0 : { int vI = atoi(GetToken(line).c_str())-1; v.push_back(vI); break; } case 1 : { int vI = atoi(GetToken(line,"/",true).c_str())-1; v.push_back(vI); int vT = atoi(GetToken(line).c_str())-1; t.push_back(vT); line = TrimToken(line); break; } case 2 : { int vI = atoi(GetToken(line,"/",true).c_str())-1; v.push_back(vI); if (line[0] != '/') { int vT = atoi(GetToken(line,"/",true).c_str())-1; t.push_back(vT); }else line = TrimToken(line,"/",true); int vN = atoi(GetToken(line).c_str())-1; n.push_back(vN); break; } case 3 : { int vI = atoi(GetToken(line,"/",true).c_str())-1; v.push_back(vI); if (line[0] != '/') { int vT = atoi(GetToken(line,"/",true).c_str())-1; t.push_back(vT); }else line = TrimToken(line,"/",true); if (line[0] != '/') { int vN = atoi(GetToken(line,"/",true).c_str())-1; n.push_back(vN); } else line = TrimToken(line,"/",true); int vC = atoi(GetToken(line).c_str())-1; c.push_back(vC); break; } } SysTools::TrimStrLeft(line); } if (v.size() == 1) { WARNING("Skipping points in OBJ file"); continue; } if (iVerticesPerPoly == 0) iVerticesPerPoly = v.size(); if (v.size() == 2) { if ( iVerticesPerPoly != 2 ) { WARNING("Skipping a line in a file that also contains polygons"); continue; } AddToMesh(vertices,v,n,t,c,VertIndices,NormalIndices,TCIndices,COLIndices); } else { if ( iVerticesPerPoly == 2 ) { WARNING("Skipping polygon in file that also contains lines"); continue; } AddToMesh(vertices,v,n,t,c,VertIndices,NormalIndices,TCIndices,COLIndices); } } else { WARNING("Skipping unknown tag %s in OBJ file", linetype.c_str()); } if (iLine % 5000 == 0) { MESSAGE("Reading line %u (%u / %u kb)", unsigned(iLine), unsigned(iBytesRead/1024),unsigned(iFileLength/1024)); } } fs.close(); std::string desc = m_vConverterDesc + " data converted from " + SysTools::GetFilename(strFilename); // generate color indies for "meshlab extended" format if (COLIndices.size() == 0 && vertices.size() == colors.size()) COLIndices = VertIndices; std::shared_ptr<Mesh> m( new Mesh(vertices,normals,texcoords,colors, VertIndices,NormalIndices,TCIndices,COLIndices, false, false, desc, ((iVerticesPerPoly == 2) ? Mesh::MT_LINES : Mesh::MT_TRIANGLES)) ); return m; }
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]); } } }
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; }
MojErr MojDbKind::configureIndexes(const MojObject& obj, const MojString& locale, MojDbReq& req) { MojLogTrace(s_log); // make sure indexes changes count against our usage MojErr err = req.curKind(this); MojErrCheck(err); // add default id index to set MojObject idIndex; err = idIndex.fromJson(IdIndexJson); MojErrCheck(err); ObjectSet newIndexObjects; err = newIndexObjects.put(idIndex); MojErrCheck(err); // change back to a set and use contains MojSet<MojString> indexNames; MojString defaultIdxName; err = defaultIdxName.assign(IdIndexName); MojErrCheck(err); err = indexNames.put(defaultIdxName); MojErrCheck(err); // add indexes to set to uniquify and order them MojObject indexArray; if (obj.get(IndexesKey, indexArray)) { MojObject::ConstArrayIterator end = indexArray.arrayEnd(); for (MojObject::ConstArrayIterator i = indexArray.arrayBegin(); i != end; ++i) { MojString indexName; err = i->getRequired(MojDbIndex::NameKey, indexName); MojErrCheck(err); err = indexName.toLower(); MojErrCheck(err); if (!indexNames.contains(indexName)) { MojObject idx = *i; // make sure we keep the lower-cased index name err = idx.putString(MojDbIndex::NameKey, indexName); MojErrCheck(err); err = newIndexObjects.put(idx); MojErrCheck(err); err = indexNames.put(indexName); MojErrCheck(err); } else { MojErrThrowMsg(MojErrDbInvalidIndexName, _T("db: cannot repeat index name: '%s'"), indexName.data()); } } } // figure out what to add and what to delete ObjectSet toDrop; err = m_indexObjects.diff(newIndexObjects, toDrop); MojErrCheck(err); ObjectSet toAdd; err = newIndexObjects.diff(m_indexObjects, toAdd); MojErrCheck(err); // drop deleted indexes IndexVec newIndexes; for (IndexVec::ConstIterator i = m_indexes.begin(); i != m_indexes.end(); ++i) { if (toDrop.contains((*i)->object())) { err = dropIndex(i->get(), req); MojErrCheck(err); } else { err = newIndexes.push(*i); MojErrCheck(err); } } // add new indexes for (ObjectSet::ConstIterator i = toAdd.begin(); i != toAdd.end(); ++i) { // create index MojRefCountedPtr<MojDbIndex> index(new MojDbIndex(this, m_kindEngine)); MojAllocCheck(index.get()); err = index->fromObject(*i, locale); MojErrCheck(err); // open index err = openIndex(index.get(), req); MojErrCheck(err); err = newIndexes.push(index); MojErrCheck(err); } // sort indexes by the prop vec so that for indexes that share prop prefixes, the shortest one comes first err = newIndexes.sort(); MojErrCheck(err); // update members m_indexObjects = newIndexObjects; m_indexes = newIndexes; return MojErrNone; }
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) ); }