예제 #1
0
파일: BinFilter.cpp 프로젝트: imight/trunk
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;
}
예제 #2
0
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;
}