CC_VISIBILITY_TYPE ccGenericPointCloud::testVisibility(const CCVector3& P)
{
    unsigned i=0,childNum=getChildrenNumber();

    CC_VISIBILITY_TYPE nvt, vt = ALL;

    while (i<childNum && vt==VIEWED)
    {
        if (m_children[i]->isKindOf(CC_SENSOR))
        {
            nvt = static_cast<ccSensor*>(m_children[i])->checkVisibility(P);
            vt = ccMin(vt,nvt);
        }
        ++i;
    }

	return (vt==ALL ? VIEWED : vt);
}
示例#2
0
文件: PVFilter.cpp 项目: eimix/trunk
CC_FILE_ERROR PVFilter::loadFile(const char* filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, double* coordinatesShift/*=0*/)
{
	//ccConsole::Print("[PVFilter::loadFile] Opening binary file '%s'...\n",filename);

	//opening file
	FILE *fp = fopen(filename, "rb");
    if (!fp)
        return CC_FERR_NO_ERROR;

	CCLib::CCMiscTools::fseek64(fp,0,2);		                //we reach the end of the file
	__int64 fileSize = CCLib::CCMiscTools::ftell64(fp);		//file size query
	CCLib::CCMiscTools::fseek64(fp,0,0);						//back to the begining

    //we read the points number
	unsigned nbOfPoints = (unsigned) (fileSize  / (__int64)(4*sizeof(float)));

	//ccConsole::Print("[PVFilter::loadFile] Points: %i\n",nbOfPoints);

    //if the file is too big, it will be chuncked in multiple parts
	unsigned fileChunkPos = 0;
	unsigned fileChunkSize = ccMin(nbOfPoints,CC_MAX_NUMBER_OF_POINTS_PER_CLOUD);

	//new cloud
    char name[64],k=0;
	sprintf(name,"unnamed - Cloud #%i",k);
	ccPointCloud* loadedCloud = new ccPointCloud(name);
    loadedCloud->reserveThePointsTable(fileChunkSize);
	loadedCloud->enableScalarField();

    float rBuff[3];

	//progress dialog
	ccProgressDialog pdlg(true); //cancel available
	CCLib::NormalizedProgress nprogress(&pdlg,nbOfPoints);
	pdlg.setMethodTitle("Open PV file");
	char buffer[256];
	sprintf(buffer,"Points: %u",nbOfPoints);
	pdlg.setInfo(buffer);
	pdlg.start();

    //number of points read from the begining of the current cloud part
    //WARNING: different from lineCounter
	unsigned pointsRead=0;

	for (unsigned i=0;i<nbOfPoints;i++)
	{
        //if we reach the max. cloud size limit, we cerate a new chunk
		if (pointsRead == fileChunkPos+fileChunkSize)
		{
			loadedCloud->getCurrentInScalarField()->computeMinAndMax();
			int sfIdx = loadedCloud->getCurrentInScalarFieldIndex();
			loadedCloud->setCurrentDisplayedScalarField(sfIdx);
			loadedCloud->showSF(sfIdx>=0);
            container.addChild(loadedCloud);
			fileChunkPos = pointsRead;
			fileChunkSize = ccMin(nbOfPoints-pointsRead,CC_MAX_NUMBER_OF_POINTS_PER_CLOUD);
            sprintf(name,"unnamed - Cloud #%i",++k);
			loadedCloud = new ccPointCloud(name);
            loadedCloud->reserveThePointsTable(fileChunkSize);
			loadedCloud->enableScalarField();
		}

        //we read the 3 coordinates of the point
		if (fread(rBuff,4,3,fp)>=0)
		{
		    //conversion to CCVector3
		    CCVector3 P = CCVector3(PointCoordinateType(rBuff[0]),
                                    PointCoordinateType(rBuff[1]),
                                    PointCoordinateType(rBuff[2]));
			loadedCloud->addPoint(P);
		}
		else
		{
            fclose(fp);
			return CC_FERR_NO_ERROR;
		}

        //then the scalar value
		if (fread(rBuff,4,1,fp)>=0)
		{
		    //conversion to DistanceType
		    DistanceType d = DistanceType(rBuff[0]);
		    loadedCloud->setPointScalarValue(pointsRead,d);
		}
		else
		{
            fclose(fp);
			return CC_FERR_NO_ERROR;
		}

		++pointsRead;

		if (!nprogress.oneStep())
		{
			loadedCloud->resize(i+1-fileChunkPos);
			break;
		}
    }

    loadedCloud->getCurrentInScalarField()->computeMinAndMax();
	int sfIdx = loadedCloud->getCurrentInScalarFieldIndex();
	loadedCloud->setCurrentDisplayedScalarField(sfIdx);
	loadedCloud->showSF(sfIdx>=0);

    container.addChild(loadedCloud);

    fclose(fp);

	return CC_FERR_NO_ERROR;
}
示例#3
0
文件: LASFilter.cpp 项目: eimix/trunk
CC_FILE_ERROR LASFilter::loadFile(const char* filename, ccHObject& container, bool alwaysDisplayLoadDialog/*=true*/, bool* coordinatesShiftEnabled/*=0*/, double* coordinatesShift/*=0*/)
{
	//opening file
	std::ifstream ifs;
	ifs.open(filename, std::ios::in | std::ios::binary);

	if (ifs.fail())
		return CC_FERR_READING;

	liblas::Reader* reader = 0;
	unsigned nbOfPoints = 0;
	std::vector<std::string> dimensions;

	try
	{
		reader = new liblas::Reader(liblas::ReaderFactory().CreateWithStream(ifs));	//using factory for automatic and transparent
																					//handling of compressed/uncompressed files
		liblas::Header const& header = reader->GetHeader();

#ifdef _DEBUG
		//ccConsole::Print("[LAS FILE] %s - signature: %s",filename,header.GetFileSignature().c_str());
#endif

		//get fields present in file
		dimensions = header.GetSchema().GetDimensionNames();

		//and of course the number of points
		nbOfPoints = header.GetPointRecordsCount();
	}
	catch (...)
	{
		delete reader;
		ifs.close();
		return CC_FERR_READING;
	}

	if (nbOfPoints==0)
	{
		//strange file ;)
		delete reader;
		ifs.close();
		return CC_FERR_NO_LOAD;
	}

	liblas::Color rgbColorMask; //(0,0,0) on construction
	bool hasClassif = false;
	bool hasIntensity = false;
	bool hasTime = false;
	bool hasReturnNumber = false;
	for (unsigned k=0;k<dimensions.size();++k)
	{
		QString dim = QString(dimensions[k].c_str()).toUpper();
		bool handled=true;
		if (dim == "RED")
			rgbColorMask.SetRed(~0);
		else if (dim == "BLUE")
			rgbColorMask.SetBlue(~0);
		else if (dim == "GREEN")
			rgbColorMask.SetGreen(~0);
		else if (dim == "CLASSIFICATION")
			hasClassif=true;
		else if (dim == "TIME")
			hasTime=true;
		else if (dim == "INTENSITY")
			hasIntensity=true;
		else if (dim == "RETURN NUMBER")
			hasReturnNumber=true;
		else if (dim != "X" && dim != "Y" && dim != "Z")
			handled=false;

		ccConsole::Print(QString("[LAS FILE] Found dimension '%1' (%2)").arg(dimensions[k].c_str()).arg(handled ? "handled" : "not handled"));
	}
	bool hasColor = (rgbColorMask[0] || rgbColorMask[1] || rgbColorMask[2]);

	//progress dialog
	ccProgressDialog pdlg(true); //cancel available
	CCLib::NormalizedProgress nprogress(&pdlg,nbOfPoints);
	pdlg.setMethodTitle("Open LAS file");
	pdlg.setInfo(qPrintable(QString("Points: %1").arg(nbOfPoints)));
	pdlg.start();

	//number of points read from the begining of the current cloud part
	unsigned pointsRead=0;
	double Pshift[3]={0.0,0.0,0.0};

	//by default we read color as 8 bits integers and we will change this to 16 bits if it's not (16 bits is the standard!)
	unsigned char colorCompBitDec = 0;
	colorType rgb[3]={0,0,0};

	ccPointCloud* loadedCloud=0;
	
	ccScalarField* classifSF=0;
	uint8_t firstClassifValue=0;
	
	ccScalarField* timeSF=0;
	double firstTime=0.0;

	ccScalarField* intensitySF=0;
	uint16_t firstIntensity=0;
	
	ccScalarField* returnNumberSF=0;
	uint16_t firstReturnNumber=0;

	//if the file is too big, we will chunck it in multiple parts
	unsigned int fileChunkPos = 0;
	unsigned int fileChunkSize = 0;

	while (true)
	{
		//if we reach the end of the file, or the max. cloud size limit (in which case we cerate a new chunk)
		bool newPointAvailable = (nprogress.oneStep() && reader->ReadNextPoint());

		if (!newPointAvailable || pointsRead == fileChunkPos+fileChunkSize)
		{
			if (loadedCloud)
			{
				if (loadedCloud->size())
				{
					bool thisChunkHasColors = loadedCloud->hasColors();
					loadedCloud->showColors(thisChunkHasColors);
					if (hasColor && !thisChunkHasColors)
						ccLog::Warning("[LAS FILE] Color field was all black! We ignored it...");

					if (hasClassif)
					{
						if (classifSF)
						{
							classifSF->computeMinAndMax();
							int cMin = (int)classifSF->getMin();
							int cMax = (int)classifSF->getMax();
							classifSF->setColorRampSteps(cMax-cMin);
							//classifSF->setMinSaturation(cMin);
							int sfIndex = loadedCloud->addScalarField(classifSF);
							if (!loadedCloud->hasDisplayedScalarField())
							{
								loadedCloud->setCurrentDisplayedScalarField(sfIndex);
								loadedCloud->showSF(!thisChunkHasColors);
							}
						}
						else
							ccLog::Warning(QString("[LAS FILE] All classification values were the same (%1)! We ignored them...").arg(firstClassifValue));
					}

					if (hasIntensity)
					{
						if (intensitySF)
						{
							intensitySF->computeMinAndMax();
							intensitySF->setColorRamp(GREY);
							int sfIndex = loadedCloud->addScalarField(intensitySF);
							if (!loadedCloud->hasDisplayedScalarField())
							{
								loadedCloud->setCurrentDisplayedScalarField(sfIndex);
								loadedCloud->showSF(!thisChunkHasColors);
							}
						}
						else
							ccLog::Warning(QString("[LAS FILE] All intensities were the same (%1)! We ignored them...").arg(firstIntensity));
					}

					if (hasTime)
					{
						if (timeSF)
						{
							timeSF->computeMinAndMax();
							int sfIndex = loadedCloud->addScalarField(timeSF);
							if (!loadedCloud->hasDisplayedScalarField())
							{
								loadedCloud->setCurrentDisplayedScalarField(sfIndex);
								loadedCloud->showSF(!thisChunkHasColors);
							}
						}
						else
							ccLog::Warning(QString("[LAS FILE] All timestamps were the same (%1)! We ignored them...").arg(firstTime));
					}

					if (hasReturnNumber)
					{
						if (returnNumberSF)
						{
							returnNumberSF->computeMinAndMax();
							int rMin = (int)returnNumberSF->getMin();
							int rMax = (int)returnNumberSF->getMax();
							returnNumberSF->setColorRampSteps(rMax-rMin);
							int sfIndex = loadedCloud->addScalarField(returnNumberSF);
							if (!loadedCloud->hasDisplayedScalarField())
							{
								loadedCloud->setCurrentDisplayedScalarField(sfIndex);
								loadedCloud->showSF(!thisChunkHasColors);
							}
						}
						else
							ccLog::Warning(QString("[LAS FILE] All return numbers were the same (%1)! We ignored them...").arg(firstReturnNumber));
					}

					//if we have reserved too much memory
					if (loadedCloud->size() < loadedCloud->capacity())
						loadedCloud->resize(loadedCloud->size());

					QString chunkName("unnamed - Cloud");
					unsigned n = container.getChildrenNumber();
					if (n!=0) //if we have more than one cloud, we append an index
					{
						if (n==1)  //we must also update the first one!
							container.getChild(0)->setName(chunkName+QString(" #1"));
						chunkName += QString(" #%1").arg(n+1);
					}
					loadedCloud->setName(chunkName);

					container.addChild(loadedCloud);
					loadedCloud=0;
				}
				else
				{
					//empty cloud?!
					delete loadedCloud;
					loadedCloud=0;
				}

				if (classifSF)
					classifSF->release();
				classifSF=0;
				if (intensitySF)
					intensitySF->release();
				intensitySF=0;
				if (returnNumberSF)
					returnNumberSF->release();
				returnNumberSF=0;
				if (timeSF)
					timeSF->release();
				timeSF=0;
			}

			if (!newPointAvailable)
				break; //end of the file (or cancel requested)

			//otherwise, we must create a new cloud
			fileChunkPos = pointsRead;
			fileChunkSize = ccMin(nbOfPoints-pointsRead,CC_MAX_NUMBER_OF_POINTS_PER_CLOUD);
			loadedCloud = new ccPointCloud();
			if (!loadedCloud->reserveThePointsTable(fileChunkSize))
			{
				ccLog::Warning("[LASFilter::loadFile] Not enough memory!");
				delete loadedCloud;
				delete reader;
				ifs.close();
				return CC_FERR_NOT_ENOUGH_MEMORY;
			}
			loadedCloud->setOriginalShift(Pshift[0],Pshift[1],Pshift[2]);

			//DGM: from now on, we only enable scalar fields when we detect a valid value!
			if (hasClassif)
			{
				assert(!classifSF);
				firstClassifValue = 0;
			}

			if (hasTime)
			{
				assert(!timeSF);
				firstTime = 0.0;
			}

			if (hasIntensity)
			{
				assert(!intensitySF);
				firstIntensity=0;
			}

			if (hasReturnNumber)
			{
				assert(!returnNumberSF);
				firstReturnNumber = 0;
			}
		}

		assert(newPointAvailable);
		const liblas::Point& p = reader->GetPoint();

		//first point: check for 'big' coordinates
		if (pointsRead==0)
		{
			double P[3]={p.GetX(),p.GetY(),p.GetZ()};
			bool shiftAlreadyEnabled = (coordinatesShiftEnabled && *coordinatesShiftEnabled && coordinatesShift);
			if (shiftAlreadyEnabled)
				memcpy(Pshift,coordinatesShift,sizeof(double)*3);
			bool applyAll=false;
			if (ccCoordinatesShiftManager::Handle(P,0,alwaysDisplayLoadDialog,shiftAlreadyEnabled,Pshift,0,applyAll))
			{
				loadedCloud->setOriginalShift(Pshift[0],Pshift[1],Pshift[2]);
				ccConsole::Warning("[LASFilter::loadFile] Cloud has been recentered! Translation: (%.2f,%.2f,%.2f)",Pshift[0],Pshift[1],Pshift[2]);

				//we save coordinates shift information
				if (applyAll && coordinatesShiftEnabled && coordinatesShift)
				{
					*coordinatesShiftEnabled = true;
					coordinatesShift[0] = Pshift[0];
					coordinatesShift[1] = Pshift[1];
					coordinatesShift[2] = Pshift[2];
				}
			}
		}

		CCVector3 P(p.GetX()+Pshift[0],p.GetY()+Pshift[1],p.GetZ()+Pshift[2]);
		loadedCloud->addPoint(P);

		//color field
		if (hasColor)
		{
			//Warning: LAS colors are stored on 16 bits!
			liblas::Color col = p.GetColor();
			col[0] &= rgbColorMask[0];
			col[1] &= rgbColorMask[1];
			col[2] &= rgbColorMask[2];

			//if we don't have reserved a color field yet, we check first that color is not black
			bool pushColor = true;
			if (!loadedCloud->hasColors())
			{
				//if the color is not black, we are sure it's a valid color field!
				if (col[0] || col[1] || col[2])
				{
					if (loadedCloud->reserveTheRGBTable())
					{
						//we must set the color (black) of all the precedently skipped points
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							loadedCloud->addRGBColor(ccColor::black);
					}
					else
					{
						ccConsole::Warning("[LAS FILE] Not enough memory: color field will be ignored!");
						hasColor = false; //no need to retry with the other chunks anyway
						pushColor = false;
					}
				}
				else //otherwise we ignore it for the moment (we'll add it later if necessary)
				{
					pushColor = false;
				}
			}

			//do we need to push this color?
			if (pushColor)
			{
				//we test if the color components are on 16 bits (standard) or only on 8 bits (it happens ;)
				if (colorCompBitDec==0)
				{
					if (	(col[0] & 0xFF00)
						||  (col[1] & 0xFF00)
						||  (col[2] & 0xFF00))
					{
						//the color components are on 16 bits!
						ccLog::Print("[LAS FILE] Color components are coded on 16 bits");
						colorCompBitDec = 8;
						//we fix all the precedently read colors
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							loadedCloud->setPointColor(i,ccColor::black); //255 >> 8 = 0!
					}
				}
				
				rgb[0]=(colorType)(col[0]>>colorCompBitDec);
				rgb[1]=(colorType)(col[1]>>colorCompBitDec);
				rgb[2]=(colorType)(col[2]>>colorCompBitDec);

				loadedCloud->addRGBColor(rgb);
			}
		}

		if (hasClassif)
		{
			uint8_t intValue = p.GetClassification().GetClass();
			if (classifSF)
			{
				classifSF->addElement(intValue);
			}
			else
			{
				//first point? we track its value
				if (loadedCloud->size()==1)
				{
					firstClassifValue = intValue;
				}
				else if (intValue != firstClassifValue)
				{
					classifSF = new ccScalarField(CC_LAS_CLASSIFICATION_FIELD_NAME,true);
					if (classifSF->reserve(fileChunkSize))
					{
						classifSF->link();
						//we must set the classification value (firstClassifValue) of all the precedently skipped points
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							classifSF->addElement(firstClassifValue);
						classifSF->addElement(intValue);
					}
					else
					{
						ccConsole::Warning("[LAS FILE] Not enough memory: classificaiton field will be ignored!");
						hasClassif = false; //no need to retry with the other chunks anyway
						classifSF->release();
						classifSF=0;
					}
				}
			}
		}

		if (hasTime)
		{
			double timeValue = p.GetTime();

			if (timeSF)
			{
				timeSF->addElement(timeValue);
			}
			else
			{
				//first point? we track its value
				if (loadedCloud->size()==1)
				{
					firstTime = timeValue;
				}
				else if (timeValue != firstIntensity)
				{
					timeSF = new ccScalarField("Time",true);
					if (timeSF->reserve(fileChunkSize))
					{
						timeSF->link();
						//we must set the timestamp value (firstTime) of all the precedently skipped points
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							timeSF->addElement(firstTime);
						timeSF->addElement(timeValue);
					}
					else
					{
						ccConsole::Warning("[LAS FILE] Not enough memory: 'time' field will be ignored!");
						hasTime = false; //no need to retry with the other chunks anyway
						timeSF->release();
						timeSF=0;
					}
				}
			}
		}

		if (hasIntensity)
		{
			uint16_t intValue = p.GetIntensity();
			if (intensitySF)
			{
				intensitySF->addElement(intValue);
			}
			else
			{
				//first point? we track its value
				if (loadedCloud->size()==1)
				{
					firstIntensity = intValue;
				}
				else if (intValue != firstIntensity)
				{
					intensitySF = new ccScalarField("Intensity",true);
					if (intensitySF->reserve(fileChunkSize))
					{
						intensitySF->link();
						//we must set the intensity (firstIntensity) of all the precedently skipped points
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							intensitySF->addElement(firstIntensity);
						intensitySF->addElement(intValue);
					}
					else
					{
						ccConsole::Warning("[LAS FILE] Not enough memory: intensity field will be ignored!");
						hasIntensity = false; //no need to retry with the other chunks anyway
						intensitySF->release();
						intensitySF=0;
					}
				}
			}
		}

		if (hasReturnNumber)
		{
			uint16_t intValue = p.GetReturnNumber();
			if (returnNumberSF)
			{
				returnNumberSF->addElement(intValue);
			}
			else
			{
				//first point? we track its value
				if (loadedCloud->size()==1)
				{
					firstReturnNumber = intValue;
				}
				else if (intValue != firstReturnNumber)
				{
					returnNumberSF = new ccScalarField("Return number",true);
					if (returnNumberSF->reserve(fileChunkSize))
					{
						returnNumberSF->link();
						//we must set the return index (firstReturnNumber) of all the precedently skipped points
						for (unsigned i=0;i<loadedCloud->size()-1;++i)
							returnNumberSF->addElement(firstReturnNumber);
						returnNumberSF->addElement(intValue);
					}
					else
					{
						ccConsole::Warning("[LAS FILE] Not enough memory: return number field will be ignored!");
						hasReturnNumber = false; //no need to retry with the other chunks anyway
						returnNumberSF->release();
						returnNumberSF=0;
					}
				}
			}

		}

		++pointsRead;
	}

	if (reader)
		delete reader;
	reader=0;
	ifs.close();

	return CC_FERR_NO_ERROR;
}
示例#4
0
文件: BinFilter.cpp 项目: eimix/trunk
CC_FILE_ERROR BinFilter::loadFileV1(QFile& in, ccHObject& container, unsigned nbScansTotal)
{
	if (nbScansTotal>99)
	{
		if (QMessageBox::question(0, QString("Oups"), QString("Hum, do you really expect %1 point clouds?").arg(nbScansTotal))==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);

		//progress for this cloud
		CCLib::NormalizedProgress nprogress(&pdlg,nbOfPoints);
		pdlg.reset();
		char buffer[256];
		sprintf(buffer,"cloud %i/%i (%i points)",k+1,nbScansTotal,nbOfPoints);
		pdlg.setInfo(buffer);
		pdlg.start();
		QApplication::processEvents();

		if (nbOfPoints==0)
		{
			//Console::print("[BinFilter::loadModelFromBinaryFile] rien a faire !\n");
			continue;
		}

		//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 #%i",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 = ccMin(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();

		CCVector3 P;
		unsigned char C[3];
		double D;

		//does the associated scalar field is negative?
		bool negSF = false;

		unsigned lineReaded=0;
		int parts = 0;

		//lecture du fichier
		for (unsigned i=0;i<nbOfPoints;++i)
		{
			if (lineReaded == fileChunkPos+fileChunkSize)
			{
				if (header.scalarField)
					loadedCloud->getCurrentInScalarField()->computeMinAndMax();

				container.addChild(loadedCloud);
				fileChunkPos = lineReaded;
				fileChunkSize = ccMin(nbOfPoints-lineReaded,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();
			}

			if (in.read((char*)P.u,sizeof(float)*3)<0)
			{
				//Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity point !\n",k);
				return CC_FERR_READING;
			}
			loadedCloud->addPoint(P);

			if (header.colors)
			{
				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)
			{
				if (in.read((char*)P.u,sizeof(float)*3)<0)
				{
					//Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity norms !\n",k);
					return CC_FERR_READING;
				}
				loadedCloud->addNorm(P.u);
			}

			if (header.scalarField)
			{
				if (in.read((char*)&D,sizeof(double))<0)
				{
					//Console::print("[BinFilter::loadModelFromBinaryFile] Error reading the %ith entity distance !\n",k);
					return CC_FERR_READING;
				}
				DistanceType d = (DistanceType)D;
				//if there are negative values, we test if they are particular values (HIDDEN_VALUE, etc.)
				//or not particular (in which case we have a non strictly positive SF)
				if (d<0.0 && !negSF)
				{
					//we must test if the value is a particular one
					if (d != HIDDEN_VALUE &&
						d != OUT_VALUE &&
						d != SEGMENTED_VALUE)
						negSF = true;
				}
				loadedCloud->setPointScalarValue(i,d);
			}

			lineReaded++;

			if (!nprogress.oneStep())
			{
				loadedCloud->resize(i+1-fileChunkPos);
				k=nbScansTotal;
				i=nbOfPoints;
			}
		}

		if (header.scalarField)
		{
			CCLib::ScalarField* sf = loadedCloud->getCurrentInScalarField();
			assert(sf);
			sf->setName(sfName);
			sf->setPositive(!negSF);
			sf->computeMinAndMax();

			loadedCloud->setCurrentDisplayedScalarField(loadedCloud->getCurrentInScalarFieldIndex());
			loadedCloud->showSF(true);
		}

		container.addChild(loadedCloud);
	}

	return CC_FERR_NO_ERROR;
}