bool SaveIFS(std::string & fileName, const IndexedFaceSet<unsigned short> & ifs) { std::ofstream fout; fout.open(fileName.c_str()); if (!fout.fail()) { SaveIFSUnsignedShortArray(fout, "* CoordIndex", 0, (const unsigned short * const) ifs.GetCoordIndex(), ifs.GetNCoordIndex(), 3); SaveIFSIntArray(fout, "* MatID", 0, (const long * const) ifs.GetIndexBufferID(), ifs.GetNCoordIndex(), 1); SaveIFSFloatArray(fout, "* Coord", 0, ifs.GetCoord(), ifs.GetNCoord(), 3); SaveIFSFloatArray(fout, "* Normal", 0, ifs.GetNormal(), ifs.GetNNormal(), 3); for(unsigned long a = 0; a < ifs.GetNumFloatAttributes(); ++a) { SaveIFSFloatArray(fout, "* FloatAttribute", a, ifs.GetFloatAttribute(a), ifs.GetNFloatAttribute(a), ifs.GetFloatAttributeDim(a)); } for(unsigned long a = 0; a < ifs.GetNumIntAttributes(); ++a) { SaveIFSIntArray(fout, "* IntAttribute", a, ifs.GetIntAttribute(a), ifs.GetNIntAttribute(a), ifs.GetIntAttributeDim(a)); } fout.close(); } else { std::cout << "Not able to create file" << std::endl; return false; } return true; }
void ScenePrettyPrinter::visitIndexedFaceSet(IndexedFaceSet& ifs) { const real* vertices = ifs.vertices(); unsigned vsize = ifs.vsize(); _ofs << _space << "IndexedFaceSet" << endl; const real *p = vertices; for (unsigned i = 0; i < vsize / 3; i++) { _ofs << _space << " " << setw(3) << setfill('0') << i << ": " << (double) p[0] << ", " << (double) p[1] << ", " << (double) p[2] << endl; p += 3; } }
void WXEdgeBuilder::visitIndexedFaceSet(IndexedFaceSet& ifs) { if (_pRenderMonitor && _pRenderMonitor->testBreak()) return; WXShape *shape = new WXShape; if (!buildWShape(*shape, ifs)) { delete shape; return; } shape->setId(ifs.getId().getFirst()); shape->setName(ifs.getName()); //ifs.setId(shape->GetId()); }
bool WingedEdgeBuilder::buildWShape(WShape& shape, IndexedFaceSet& ifs) { unsigned int vsize = ifs.vsize(); unsigned int nsize = ifs.nsize(); //soc unused - unsigned tsize = ifs.tsize(); const real *vertices = ifs.vertices(); const real *normals = ifs.normals(); const real *texCoords = ifs.texCoords(); real *new_vertices; real *new_normals; new_vertices = new real[vsize]; new_normals = new real[nsize]; // transform coordinates from local to world system if (_current_matrix) { transformVertices(vertices, vsize, *_current_matrix, new_vertices); transformNormals(normals, nsize, *_current_matrix, new_normals); } else { memcpy(new_vertices, vertices, vsize * sizeof(*new_vertices)); memcpy(new_normals, normals, nsize * sizeof(*new_normals)); } const IndexedFaceSet::TRIANGLES_STYLE *faceStyle = ifs.trianglesStyle(); vector<FrsMaterial> frs_materials; if (ifs.msize()) { const FrsMaterial *const *mats = ifs.frs_materials(); for (unsigned i = 0; i < ifs.msize(); ++i) frs_materials.push_back(*(mats[i])); shape.setFrsMaterials(frs_materials); } #if 0 const FrsMaterial *mat = (ifs.frs_material()); if (mat) shape.setFrsMaterial(*mat); else if (_current_frs_material) shape.setFrsMaterial(*_current_frs_material); #endif const IndexedFaceSet::FaceEdgeMark *faceEdgeMarks = ifs.faceEdgeMarks(); // sets the current WShape to shape _current_wshape = &shape; // create a WVertex for each vertex buildWVertices(shape, new_vertices, vsize); const unsigned int *vindices = ifs.vindices(); const unsigned int *nindices = ifs.nindices(); const unsigned int *tindices = NULL; if (ifs.tsize()) { tindices = ifs.tindices(); } const unsigned int *mindices = NULL; if (ifs.msize()) mindices = ifs.mindices(); const unsigned int *numVertexPerFace = ifs.numVertexPerFaces(); const unsigned int numfaces = ifs.numFaces(); for (unsigned int index = 0; index < numfaces; index++) { switch (faceStyle[index]) { case IndexedFaceSet::TRIANGLE_STRIP: buildTriangleStrip(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; case IndexedFaceSet::TRIANGLE_FAN: buildTriangleFan(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; case IndexedFaceSet::TRIANGLES: buildTriangles(new_vertices, new_normals, frs_materials, texCoords, faceEdgeMarks, vindices, nindices, mindices, tindices, numVertexPerFace[index]); break; } vindices += numVertexPerFace[index]; nindices += numVertexPerFace[index]; if (mindices) mindices += numVertexPerFace[index]; if (tindices) tindices += numVertexPerFace[index]; faceEdgeMarks++; } delete[] new_vertices; delete[] new_normals; if (shape.GetFaceList().size() == 0) // this may happen due to degenerate triangles return false; // compute bbox shape.ComputeBBox(); // compute mean edge size: shape.ComputeMeanEdgeSize(); // Parse the built winged-edge shape to update post-flags set<Vec3r> normalsSet; vector<WVertex *>& wvertices = shape.getVertexList(); for (vector<WVertex *>::iterator wv = wvertices.begin(), wvend = wvertices.end(); wv != wvend; ++wv) { if ((*wv)->isBoundary()) continue; if ((*wv)->GetEdges().size() == 0) // This means that the WVertex has no incoming edges... (12-Sep-2011 T.K.) continue; normalsSet.clear(); WVertex::face_iterator fit = (*wv)->faces_begin(); WVertex::face_iterator fitend = (*wv)->faces_end(); for (; fit != fitend; ++fit) { WFace *face = *fit; normalsSet.insert(face->GetVertexNormal(*wv)); if (normalsSet.size() != 1) { break; } } if (normalsSet.size() != 1) { (*wv)->setSmooth(false); } } // Adds the new WShape to the WingedEdge structure _winged_edge->addWShape(&shape); return true; }
int testDecode(std::string & fileName) { std::string folder; long found = (long)fileName.find_last_of(PATH_SEP); if (found != -1) { folder = fileName.substr(0,found); } if (folder == "") { folder = "."; } std::string file(fileName.substr(found+1)); std::string outFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + "_dec.obj"; std::vector< Vec3<Real> > points; std::vector< Vec3<Real> > normals; std::vector< Vec2<Real> > colors; std::vector< Vec2<Real> > texCoords; std::vector< Vec3<Index> > triangles; std::vector< unsigned long > matIDs; std::vector< Material > materials; std::string materialLib; std::string matFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + ".mat"; bool ret = LoadMaterials(matFileName.c_str(), materials, materialLib); if (ret) { const size_t numMaterials = materials.size(); unsigned long n, shift = 0; for(size_t i = 0; i < numMaterials; ++i) { n = materials[i].m_numTriangles + shift; matIDs.resize(n, materials[i].m_id); shift = n; } } BinaryStream bstream; IndexedFaceSet<Index> ifs; FILE * fin = fopen(fileName.c_str(), "rb"); if (!fin) { return -1; } fseek(fin, 0, SEEK_END); unsigned long size = ftell(fin); bstream.Allocate(size); rewind(fin); unsigned long nread = (unsigned long)fread((void *) bstream.GetBuffer(), 1, size, fin); bstream.SetSize(size); if (nread != size) { return -1; } fclose(fin); std::cout << "Bitstream size (bytes) " << bstream.GetSize() << std::endl; SC3DMCDecoder<Index> decoder; // load header Timer timer; timer.Tic(); decoder.DecodeHeader(ifs, bstream); timer.Toc(); std::cout << "DecodeHeader time (ms) " << timer.GetElapsedTime() << std::endl; // allocate memory triangles.resize(ifs.GetNCoordIndex()); ifs.SetCoordIndex((Index * const ) &(triangles[0])); points.resize(ifs.GetNCoord()); ifs.SetCoord((Real * const ) &(points[0])); if (ifs.GetNNormal() > 0) { normals.resize(ifs.GetNNormal()); ifs.SetNormal((Real * const ) &(normals[0])); } if (ifs.GetNColor() > 0) { colors.resize(ifs.GetNColor()); ifs.SetColor((Real * const ) &(colors[0])); } if (ifs.GetNTexCoord() > 0) { texCoords.resize(ifs.GetNTexCoord()); ifs.SetTexCoord((Real * const ) &(texCoords[0])); } std::cout << "Mesh info "<< std::endl; std::cout << "\t# coords " << ifs.GetNCoord() << std::endl; std::cout << "\t# normals " << ifs.GetNNormal() << std::endl; std::cout << "\t# texcoords " << ifs.GetNTexCoord() << std::endl; std::cout << "\t# triangles " << ifs.GetNCoordIndex() << std::endl; // decode mesh timer.Tic(); decoder.DecodePlayload(ifs, bstream); timer.Toc(); std::cout << "DecodePlayload time (ms) " << timer.GetElapsedTime() << std::endl; std::cout << "Details" << std::endl; const SC3DMCStats & stats = decoder.GetStats(); std::cout << "\t CoordIndex " << stats.m_timeCoordIndex << " ms, " << stats.m_streamSizeCoordIndex <<" bytes (" << 8.0*stats.m_streamSizeCoordIndex / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Coord " << stats.m_timeCoord << " ms, " << stats.m_streamSizeCoord <<" bytes (" << 8.0*stats.m_streamSizeCoord / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Normal " << stats.m_timeNormal << " ms, " << stats.m_streamSizeNormal <<" bytes (" << 8.0*stats.m_streamSizeNormal / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t TexCoord " << stats.m_timeTexCoord << " ms, " << stats.m_streamSizeTexCoord <<" bytes (" << 8.0*stats.m_streamSizeTexCoord / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Color " << stats.m_timeColor << " ms, " << stats.m_streamSizeColor <<" bytes (" << 8.0*stats.m_streamSizeColor / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Float Attributes " << stats.m_timeFloatAttribute << " ms, " << stats.m_streamSizeFloatAttribute <<" bytes (" << 8.0*stats.m_streamSizeFloatAttribute / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Integer Attributes " << stats.m_timeFloatAttribute << " ms, " << stats.m_streamSizeFloatAttribute <<" bytes (" << 8.0*stats.m_streamSizeFloatAttribute / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Reorder " << stats.m_timeReorder << " ms, " << 0 <<" bytes (" << 0.0 <<" bpv)" <<std::endl; std::cout << "Saving " << outFileName << " ..." << std::endl; ret = SaveOBJ(outFileName.c_str(), points, texCoords, normals, triangles, materials, matIDs, materialLib); if (!ret) { std::cout << "Error: SaveOBJ()\n" << std::endl; return -1; } std::cout << "Done." << std::endl; return 0; }
int testEncode(const std::string & fileName, int qcoord, int qtexCoord, int qnormal, O3DGCSC3DMCStreamType streamType) { std::string folder; long found = (long) fileName.find_last_of(PATH_SEP); if (found != -1) { folder = fileName.substr(0,found); } if (folder == "") { folder = "."; } std::string file(fileName.substr(found+1)); std::string outFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + ".s3d"; std::vector< Vec3<Real> > points; std::vector< Vec3<Real> > normals; std::vector< Vec2<Real> > texCoords; std::vector< Vec3<Index> > triangles; std::vector< unsigned long > matIDs; std::vector< Material > materials; std::string materialLib; std::cout << "Loading " << fileName << " ..." << std::endl; bool ret = LoadOBJ(fileName, points, texCoords, normals, triangles, matIDs, materials, materialLib); if (!ret) { std::cout << "Error: LoadOBJ()\n" << std::endl; return -1; } if (points.size() == 0 || triangles.size() == 0) { std::cout << "Error: points.size() == 0 || triangles.size() == 0 \n" << std::endl; return -1; } std::cout << "Done." << std::endl; if (materials.size() > 0) { std::string matFileName = folder + PATH_SEP + file.substr(0, file.find_last_of(".")) + ".mat"; ret = SaveMaterials(matFileName.c_str(), materials, materialLib); } if (!ret) { std::cout << "Error: SaveMatrials()\n" << std::endl; return -1; } /* ret = SaveOBJ("debug.obj", points, texCoords, normals, triangles, materials, matIDs, materialLib); if (!ret) { std::cout << "Error: SaveOBJ()\n" << std::endl; return -1; } */ SC3DMCEncodeParams params; params.SetStreamType(streamType); IndexedFaceSet<Index> ifs; params.SetCoordQuantBits(qcoord); params.SetNormalQuantBits(qnormal); params.SetTexCoordQuantBits(qtexCoord); ifs.SetNCoord((unsigned long) points.size()); ifs.SetNNormal((unsigned long)normals.size()); ifs.SetNTexCoord((unsigned long)texCoords.size()); ifs.SetNCoordIndex((unsigned long)triangles.size()); std::cout << "Mesh info "<< std::endl; std::cout << "\t# coords " << ifs.GetNCoord() << std::endl; std::cout << "\t# normals " << ifs.GetNNormal() << std::endl; std::cout << "\t# texcoords " << ifs.GetNTexCoord() << std::endl; std::cout << "\t# triangles " << ifs.GetNCoordIndex() << std::endl; ifs.SetCoord((Real * const) & (points[0])); ifs.SetCoordIndex((Index * const ) &(triangles[0])); if (materials.size() > 1) { ifs.SetMatID((unsigned long * const ) &(matIDs[0])); } if (normals.size() > 0) { ifs.SetNormal((Real * const) & (normals[0])); } if (texCoords.size() > 0) { ifs.SetTexCoord((Real * const ) & (texCoords[0])); } // compute min/max ifs.ComputeMinMax(O3DGC_SC3DMC_MAX_ALL_DIMS); // O3DGC_SC3DMC_DIAG_BB BinaryStream bstream((unsigned long)points.size()*8); SC3DMCEncoder<Index> encoder; Timer timer; timer.Tic(); encoder.Encode(params, ifs, bstream); timer.Toc(); std::cout << "Encode time (ms) " << timer.GetElapsedTime() << std::endl; FILE * fout = fopen(outFileName.c_str(), "wb"); if (!fout) { return -1; } fwrite(bstream.GetBuffer(), 1, bstream.GetSize(), fout); fclose(fout); std::cout << "Bitstream size (bytes) " << bstream.GetSize() << std::endl; std::cout << "Details" << std::endl; const SC3DMCStats & stats = encoder.GetStats(); std::cout << "\t CoordIndex " << stats.m_timeCoordIndex << " ms, " << stats.m_streamSizeCoordIndex <<" bytes (" << 8.0 * stats.m_streamSizeCoordIndex / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Coord " << stats.m_timeCoord << " ms, " << stats.m_streamSizeCoord <<" bytes (" << 8.0 * stats.m_streamSizeCoord / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Normal " << stats.m_timeNormal << " ms, " << stats.m_streamSizeNormal <<" bytes (" << 8.0 * stats.m_streamSizeNormal / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t TexCoord " << stats.m_timeTexCoord << " ms, " << stats.m_streamSizeTexCoord <<" bytes (" << 8.0 * stats.m_streamSizeTexCoord / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Color " << stats.m_timeColor << " ms, " << stats.m_streamSizeColor <<" bytes (" << 8.0 * stats.m_streamSizeColor / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Float Attributes " << stats.m_timeFloatAttribute << " ms, " << stats.m_streamSizeFloatAttribute <<" bytes (" << 8.0 * stats.m_streamSizeFloatAttribute / ifs.GetNCoord() <<" bpv)" <<std::endl; std::cout << "\t Integer Attributes " << stats.m_timeFloatAttribute << " ms, " << stats.m_streamSizeFloatAttribute <<" bytes (" << 8.0 * stats.m_streamSizeFloatAttribute / ifs.GetNCoord() <<" bpv)" <<std::endl; return 0; }
IndexedFaceSet::IndexedFaceSet(const IndexedFaceSet& iBrother) : Rep(iBrother) { _VSize = iBrother.vsize(); _Vertices = new float[_VSize]; memcpy(_Vertices, iBrother.vertices(), _VSize * sizeof(float)); _NSize = iBrother.nsize(); _Normals = new float[_NSize]; memcpy(_Normals, iBrother.normals(), _NSize * sizeof(float)); _MSize = iBrother.msize(); if (_MSize) { _FrsMaterials = new FrsMaterial * [_MSize]; for (unsigned int i = 0; i < _MSize; ++i) { _FrsMaterials[i] = new FrsMaterial(*(iBrother._FrsMaterials[i])); } } else { _FrsMaterials = 0; } _TSize = iBrother.tsize(); _TexCoords = 0; if (_TSize) { _TexCoords = new float[_TSize]; memcpy(_TexCoords, iBrother.texCoords(), _TSize * sizeof(float)); } _NumFaces = iBrother.numFaces(); _NumVertexPerFace = new unsigned[_NumFaces]; memcpy(_NumVertexPerFace, iBrother.numVertexPerFaces(), _NumFaces * sizeof(unsigned)); _FaceStyle = new TRIANGLES_STYLE[_NumFaces]; memcpy(_FaceStyle, iBrother.trianglesStyle(), _NumFaces * sizeof(TRIANGLES_STYLE)); _FaceEdgeMarks = new FaceEdgeMark[_NumFaces]; memcpy(_FaceEdgeMarks, iBrother.faceEdgeMarks(), _NumFaces * sizeof(FaceEdgeMark)); _VISize = iBrother.visize(); _VIndices = new unsigned[_VISize]; memcpy(_VIndices, iBrother.vindices(), _VISize * sizeof(unsigned)); _NISize = iBrother.nisize(); _NIndices = new unsigned[_NISize]; memcpy(_NIndices, iBrother.nindices(), _NISize * sizeof(unsigned)); _MISize = iBrother.misize(); if (_MISize) { _MIndices = new unsigned[_MISize]; memcpy(_MIndices, iBrother.mindices(), _MISize * sizeof(unsigned)); } else { _MIndices = 0; } _TISize = iBrother.tisize(); _TIndices = 0; if (_TISize) { _TIndices = new unsigned[_TISize]; memcpy(_TIndices, iBrother.tindices(), _TISize * sizeof(unsigned)); } _displayList = 0; }
NodeGroup* PLYFileLoader::Load() { printf("Loading PLY file %s\n", _FileName); FILE * fp = fopen(_FileName, "rt"); if (fp == NULL) { printf("ERROR: CANNOT OPEN INPUT FILE %s\n", _FileName); exit(1); } // ---------- Read the headers --------- char buffer[200]; unsigned numVertices = 0, numFaces = 0; fscanf(fp, "ply\nformat ascii 1.0\n"); fgets(buffer, 200, fp); bool meshSilhouettes = (strcmp(buffer, "comment mesh silhouettes\n") == 0); if (!meshSilhouettes && (strcmp(buffer, "comment smooth silhouettes\n") != 0)) { printf("missing comment indicating smooth vs. mesh silhouettes. line: %s\n", buffer); exit(1); } fscanf(fp,"element vertex %d\n", &numVertices); fscanf(fp, "property float x\nproperty float y\nproperty float z\n"); fscanf(fp, "property float nx\n"); fscanf(fp, "property float ny\n"); fscanf(fp, "property float nz\n"); fscanf(fp, "property float red\n"); fscanf(fp, "property float green\n"); fscanf(fp, "property float blue\n"); fscanf(fp, "property float ndotv\n"); fscanf(fp,"element face %d\n", &numFaces); if (numVertices <= 0 || numFaces <= 0) { printf("ERROR: READING PLY (nv = %d, nf = %d)\n", numVertices, numFaces); exit(1); } fscanf(fp, "property list uchar int vertex_index\n"); fscanf(fp, "property uchar int\n"); // vbf fscanf(fp, "end_header\n"); // ------ Initialize data structures ------ // create of the scene root node _Scene = new NodeGroup; NodeShape * shape = new NodeShape; _Scene->AddChild(shape); // allocate elements for the indexed face set real * vertices = new real[3*numVertices]; unsigned * nvertPerFace = new unsigned[numFaces]; IndexedFaceSet::TRIANGLES_STYLE * faceStyles = new IndexedFaceSet::TRIANGLES_STYLE[numFaces]; unsigned * faces = new unsigned[3*numFaces]; _numFacesRead = numFaces; unsigned numNormals = numVertices; real * normals = new real[numNormals * 3]; unsigned * nindices = new unsigned[numFaces * 3]; int * faceUserData = new int[numFaces]; float * vertexUserData = new float[numVertices]; real minBBox[3] = { 0,0,0}; real maxBBox[3] = { 0,0,0}; // real minBBox[3] = { DBL_MAX, DBL_MAX, DBL_MAX }; // real maxBBox[3] = { DBL_MIN, DBL_MIN, DBL_MIN }; printf("Num Vertices = %d, Num Faces = %d\n", numVertices, numFaces); // ------- Read the vertices and faces ----- for(unsigned i=0;i<numVertices;i++) { if (feof(fp) != 0) { printf("UNEXPECTED EOF IN PLY\n"); exit(1); } // note: should be using strtod char buffer[200]; fgets(buffer, 200, fp); real x,y,z, ndotv; char * nextptr; setlocale(LC_NUMERIC,"C"); x = strtod(buffer, &nextptr); y = strtod(nextptr, &nextptr); z = strtod(nextptr, &nextptr); vertices[3*i] = x; vertices[3*i+1] = y; vertices[3*i+2] = z; for(int j=0;j<3;j++) { if (vertices[3*i+j] < minBBox[j] || i == 0) minBBox[j] = vertices[3*i+j]; if (vertices[3*i+j] > maxBBox[j] || i == 0) maxBBox[j] = vertices[3*i+j]; } // per-vertex normals real nx, ny, nz; nx = strtod(nextptr, &nextptr); ny = strtod(nextptr, &nextptr); nz = strtod(nextptr, &nextptr); Vec3r normal(nx,ny,nz); normal.normalize(); for(int j=0;j<3;j++) normals[3*i+j]=normal[j]; // per-vertex color real red, green, blue; red = strtod(nextptr, &nextptr); green = strtod(nextptr, &nextptr); blue = strtod(nextptr, &nextptr); ndotv = strtod(nextptr, &nextptr); vertexUserData[i] = ndotv; //if (i < 3 || i+4 > numVertices ) //printf("Vertex %d: %f %f %f (%g %g %g)\n", i, vertices[3*i], vertices[3*i+1], vertices[3*i+2],x,y,z); } for(unsigned i=0;i<numFaces;i++) { if (feof(fp) != 0) { printf("UNEXPECTED EOF IN PLY\n"); exit(1); } // char buffer[200]; // fgets(buffer, 200, fp); int N, v[3], vfint; int r = fscanf(fp, "%d %d %d %d %d\n", &N, &v[0], &v[1], &v[2], &vfint); faces[3*i] = 3*v[0]; // why multiply by 3? no idea (there's a mysterious division by 3 is in WingedEdgeBuilder::buildTriangles) faces[3*i+1] = 3*v[1]; faces[3*i+2] = 3*v[2]; // fscanf(fp, "%d %d %d %d\n", &N, &faces[3*i], &faces[3*i+1], &faces[3*i+2]); // if (i <5 || i +3 > numFaces -1) // printf("Face %d: %d verts: %d %d %d (r = %d)\n", i, N, v[0], v[1], v[2], r); if (N != 3) { printf("UNEXPECTED NON-TRIANGULAR FACE IN PLY %d: %d vertices)\n", i, N); exit(1); } nvertPerFace[i] = N; faceStyles[i] = IndexedFaceSet::TRIANGLES; faceUserData[i] = vfint; // vbf goes here Vec3r vert[3]; for(int j=0;j<3;j++) for(int k=0;k<3;k++) vert[j][k] = vertices[3*v[j] + k]; for(int j=0; j<3; j++) { real norm = sqrt((vert[j] - vert[(j+1)%3])*(vert[j] - vert[(j+1)%3])); if(_minEdgeSize > norm) _minEdgeSize = norm; } // if (meshSilhouettes) // per-face normals // { // Vec3r normal = (vert[2] - vert[0]) ^ (vert[1] - vert[0]); // normal.normalize(); // for(int j=0;j<3;j++) // 3 entries of the normal vector // normals[3*i+j] = normal[j]; // for(int j=0;j<3;j++) // normal for each vertex // nindices[3*i+j] = 3*i; // mysterious factor of 3 (see WingedEdgeBuilder::buildTriangles) // } // else for(int j=0;j<3;j++) // per-vertex normals nindices[3*i+j] = 3*v[j]; } // -------- create the indexed face set and finish up IndexedFaceSet * rep = new IndexedFaceSet(vertices, 3*numVertices, normals, 3*numNormals, NULL, 0, 0, 0, numFaces, nvertPerFace, faceStyles, faces, 3*numFaces, nindices, 3*numFaces, NULL, 0, NULL, 0, faceUserData, vertexUserData, 0, meshSilhouettes); // set to zero means it will be deallocated elsewhere rep->SetId(Id(0,0)); const BBox<Vec3r> bbox(Vec3r(minBBox[0], minBBox[1], minBBox[2]), Vec3r(maxBBox[0], maxBBox[1], maxBBox[2])); rep->SetBBox(bbox); shape->AddRep(rep); // printf("dbl_min = %f, dbl_max = %f\n", DBL_MIN, DBL_MAX); // printf("bbox: %f, %f, %f ; %f %f %f\n", minBBox[0], minBBox[1], minBBox[2], // maxBBox[0], maxBBox[1], maxBBox[2]); // printf("bbox: %f, %f, %f ; %f %f %f\n", bbox.getMin()[0], bbox.getMin()[1], bbox.getMin()[2], // bbox.getMax()[0], bbox.getMax()[1], bbox.getMax()[2]); //Returns the built scene. return _Scene; }
void testDecode(shared_ptr <GLTFMesh> mesh, BinaryStream &bstream) { SC3DMCDecoder <unsigned short> decoder; IndexedFaceSet <unsigned short> ifs; unsigned char* outputData; decoder.DecodeHeader(ifs, bstream); unsigned int vertexSize = ifs.GetNCoord() * 3 * sizeof(float); unsigned int normalSize = ifs.GetNNormal() * 3 * sizeof(float); unsigned int texcoordSize = ifs.GetNFloatAttribute(0) * 2 * sizeof(float); unsigned int indicesSize = ifs.GetNCoordIndex() * 3 * sizeof(unsigned short); outputData = (unsigned char*)malloc(vertexSize + normalSize + texcoordSize + indicesSize); size_t vertexOffset = indicesSize; float* uncompressedVertices = (Real * const )(outputData + vertexOffset); ifs.SetCoordIndex((unsigned short * const ) outputData ); ifs.SetCoord((Real * const )uncompressedVertices); if (ifs.GetNNormal() > 0) { ifs.SetNormal((Real * const )(outputData + indicesSize + vertexSize)); } if (ifs.GetNFloatAttribute(0)) { ifs.SetFloatAttribute(0, (Real * const )(outputData + indicesSize + vertexSize + normalSize)); } decoder.DecodePlayload(ifs, bstream); //--- shared_ptr <GLTFMeshAttribute> meshAttribute = mesh->getMeshAttribute(POSITION, 0); meshAttribute->computeMinMax(); const double* min = meshAttribute->getMin(); const double* max = meshAttribute->getMax(); float* vertices = (float*)meshAttribute->getBufferView()->getBufferDataByApplyingOffset(); printf("coord nb:%d\n",(int)meshAttribute->getCount()); printf("min: %f %f %f\n", min[0], min[1], min[2]); printf("max: %f %f %f\n", max[0], max[1], max[2]); float maxQuantError[3]; maxQuantError[0] = (float)(max[0] - min[0]) / (2^12 - 1); maxQuantError[1] = (float)(max[1] - min[1]) / (2^12 - 1); maxQuantError[2] = (float)(max[2] - min[2]) / (2^12 - 1); if (meshAttribute->getCount() == ifs.GetNCoord()) { for (size_t i = 0 ; i < (meshAttribute->getCount() * 3) ; i++ ) { float error = vertices[i] - uncompressedVertices[i]; if (error > maxQuantError[i%3]) { printf("%d:input:%f compressed:%f\n",(int) i%3, vertices[i], uncompressedVertices[i]); printf("delta is: %f\n", error); } else { //printf("ok\n"); } } } else { printf("Fatal error: vertex count do not match\n"); } free(outputData); }