CC_FILE_ERROR BinFilter::LoadFileV1(QFile& in, ccHObject& container, unsigned nbScansTotal, bool alwaysDisplayLoadDialog) { ccLog::Print("[BIN] Version 1.0"); if (nbScansTotal > 99) { if (QMessageBox::question(0, QString("Oups"), QString("Hum, do you really expect %1 point clouds?").arg(nbScansTotal), QMessageBox::Yes, QMessageBox::No) == QMessageBox::No) return CC_FERR_WRONG_FILE_TYPE; } else if (nbScansTotal == 0) { return CC_FERR_NO_LOAD; } ccProgressDialog pdlg(true); pdlg.setMethodTitle("Open Bin file (old style)"); for (unsigned k=0; k<nbScansTotal; k++) { HeaderFlags header; unsigned nbOfPoints=0; if (ReadEntityHeader(in,nbOfPoints,header) < 0) return CC_FERR_READING; //Console::print("[BinFilter::loadModelFromBinaryFile] Entity %i : %i points, color=%i, norms=%i, dists=%i\n",k,nbOfPoints,color,norms,distances); if (nbOfPoints == 0) { //Console::print("[BinFilter::loadModelFromBinaryFile] rien a faire !\n"); continue; } //progress for this cloud CCLib::NormalizedProgress* nprogress = 0; if (alwaysDisplayLoadDialog) { nprogress = new CCLib::NormalizedProgress(&pdlg,nbOfPoints); pdlg.reset(); char buffer[256]; sprintf(buffer,"cloud %u/%u (%u points)",k+1,nbScansTotal,nbOfPoints); pdlg.setInfo(buffer); pdlg.start(); QApplication::processEvents(); } //Cloud name char cloudName[256] = "unnamed"; if (header.name) { for (int i=0; i<256; ++i) { if (in.read(cloudName+i,1)<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the cloud name!\n"); return CC_FERR_READING; } if (cloudName[i] == 0) break; } //we force the end of the name in case it is too long! cloudName[255] = 0; } else { sprintf(cloudName,"unnamed - Cloud #%u",k); } //Cloud name char sfName[1024] = "unnamed"; if (header.sfName) { for (int i=0; i<1024; ++i) { if (in.read(sfName+i,1)<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the cloud name!\n"); return CC_FERR_READING; } if (sfName[i] == 0) break; } //we force the end of the name in case it is too long! sfName[1023] = 0; } else { strcpy(sfName,"Loaded scalar field"); } //Creation ccPointCloud* loadedCloud = new ccPointCloud(cloudName); if (!loadedCloud) return CC_FERR_NOT_ENOUGH_MEMORY; unsigned fileChunkPos = 0; unsigned fileChunkSize = std::min(nbOfPoints,CC_MAX_NUMBER_OF_POINTS_PER_CLOUD); loadedCloud->reserveThePointsTable(fileChunkSize); if (header.colors) { loadedCloud->reserveTheRGBTable(); loadedCloud->showColors(true); } if (header.normals) { loadedCloud->reserveTheNormsTable(); loadedCloud->showNormals(true); } if (header.scalarField) loadedCloud->enableScalarField(); unsigned lineRead = 0; int parts = 0; const ScalarType FORMER_HIDDEN_POINTS = (ScalarType)-1.0; //lecture du fichier for (unsigned i=0; i<nbOfPoints; ++i) { if (lineRead == fileChunkPos+fileChunkSize) { if (header.scalarField) loadedCloud->getCurrentInScalarField()->computeMinAndMax(); container.addChild(loadedCloud); fileChunkPos = lineRead; fileChunkSize = std::min(nbOfPoints-lineRead,CC_MAX_NUMBER_OF_POINTS_PER_CLOUD); char partName[64]; ++parts; sprintf(partName,"%s.part_%i",cloudName,parts); loadedCloud = new ccPointCloud(partName); loadedCloud->reserveThePointsTable(fileChunkSize); if (header.colors) { loadedCloud->reserveTheRGBTable(); loadedCloud->showColors(true); } if (header.normals) { loadedCloud->reserveTheNormsTable(); loadedCloud->showNormals(true); } if (header.scalarField) loadedCloud->enableScalarField(); } float Pf[3]; if (in.read((char*)Pf,sizeof(float)*3)<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity point !\n",k); return CC_FERR_READING; } loadedCloud->addPoint(CCVector3::fromArray(Pf)); if (header.colors) { unsigned char C[3]; if (in.read((char*)C,sizeof(colorType)*3)<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity colors !\n",k); return CC_FERR_READING; } loadedCloud->addRGBColor(C); } if (header.normals) { CCVector3 N; if (in.read((char*)N.u,sizeof(float)*3)<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity norms !\n",k); return CC_FERR_READING; } loadedCloud->addNorm(N.u); } if (header.scalarField) { double D; if (in.read((char*)&D,sizeof(double))<0) { //Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity distance!\n",k); return CC_FERR_READING; } ScalarType d = static_cast<ScalarType>(D); loadedCloud->setPointScalarValue(i,d); } lineRead++; if (nprogress && !nprogress->oneStep()) { loadedCloud->resize(i+1-fileChunkPos); k=nbScansTotal; i=nbOfPoints; } } if (nprogress) { pdlg.stop(); QApplication::processEvents(); delete nprogress; nprogress = 0; } if (header.scalarField) { CCLib::ScalarField* sf = loadedCloud->getCurrentInScalarField(); assert(sf); sf->setName(sfName); //replace HIDDEN_VALUES by NAN_VALUES for (unsigned i=0; i<sf->currentSize(); ++i) { if (sf->getValue(i) == FORMER_HIDDEN_POINTS) sf->setValue(i,NAN_VALUE); } sf->computeMinAndMax(); loadedCloud->setCurrentDisplayedScalarField(loadedCloud->getCurrentInScalarFieldIndex()); loadedCloud->showSF(true); } container.addChild(loadedCloud); } return CC_FERR_NO_ERROR; }
bool ccGenericMesh::laplacianSmooth(unsigned nbIteration, float factor, CCLib::GenericProgressCallback* progressCb/*=0*/) { if (!m_associatedCloud) return false; //vertices unsigned vertCount = m_associatedCloud->size(); //triangles unsigned faceCount = size(); if (!vertCount || !faceCount) return false; GenericChunkedArray<3,PointCoordinateType>* verticesDisplacement = new GenericChunkedArray<3,PointCoordinateType>; if (!verticesDisplacement->resize(vertCount)) { //not enough memory verticesDisplacement->release(); return false; } //compute the number of edges to which belong each vertex unsigned* edgesCount = new unsigned[vertCount]; if (!edgesCount) { //not enough memory verticesDisplacement->release(); return false; } memset(edgesCount, 0, sizeof(unsigned)*vertCount); placeIteratorAtBegining(); for(unsigned j=0; j<faceCount; j++) { const CCLib::TriangleSummitsIndexes* tri = getNextTriangleIndexes(); edgesCount[tri->i1]+=2; edgesCount[tri->i2]+=2; edgesCount[tri->i3]+=2; } //progress dialog CCLib::NormalizedProgress* nProgress = 0; if (progressCb) { unsigned totalSteps = nbIteration; nProgress = new CCLib::NormalizedProgress(progressCb,totalSteps); progressCb->setMethodTitle("Laplacian smooth"); progressCb->setInfo(qPrintable(QString("Iterations: %1\nVertices: %2\nFaces: %3").arg(nbIteration).arg(vertCount).arg(faceCount))); progressCb->start(); } //repeat Laplacian smoothing iterations for(unsigned iter = 0; iter < nbIteration; iter++) { verticesDisplacement->fill(0); //for each triangle placeIteratorAtBegining(); for(unsigned j=0; j<faceCount; j++) { const CCLib::TriangleSummitsIndexes* tri = getNextTriangleIndexes(); const CCVector3* A = m_associatedCloud->getPoint(tri->i1); const CCVector3* B = m_associatedCloud->getPoint(tri->i2); const CCVector3* C = m_associatedCloud->getPoint(tri->i3); CCVector3 dAB = (*B-*A); CCVector3 dAC = (*C-*A); CCVector3 dBC = (*C-*B); CCVector3* dA = (CCVector3*)verticesDisplacement->getValue(tri->i1); (*dA) += dAB+dAC; CCVector3* dB = (CCVector3*)verticesDisplacement->getValue(tri->i2); (*dB) += dBC-dAB; CCVector3* dC = (CCVector3*)verticesDisplacement->getValue(tri->i3); (*dC) -= dAC+dBC; } if (nProgress && !nProgress->oneStep()) { //cancelled by user break; } //apply displacement verticesDisplacement->placeIteratorAtBegining(); for (unsigned i=0; i<vertCount; i++) { //this is a "persistent" pointer and we know what type of cloud is behind ;) CCVector3* P = const_cast<CCVector3*>(m_associatedCloud->getPointPersistentPtr(i)); const CCVector3* d = (const CCVector3*)verticesDisplacement->getValue(i); (*P) += (*d)*(factor/(PointCoordinateType)edgesCount[i]); } } m_associatedCloud->updateModificationTime(); if (hasNormals()) computeNormals(); if (verticesDisplacement) verticesDisplacement->release(); verticesDisplacement=0; if (edgesCount) delete[] edgesCount; edgesCount=0; if (nProgress) delete nProgress; nProgress=0; return true; }