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; }
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; }
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); }