Hello!
I want to save the coordinates to scalar fields with the bin file.And show the bin file with 'CCViewer.exe'.
Here is my code:
......
const QString defaultSFName[3] = { "Coord. X", "Coord. Y", "Coord. Z" };
bool exportDim[3] = { 0,0,true};
if (!exportDim[0] && !exportDim[1] && !exportDim[2]) //nothing to do?!
return 0;
//for each selected cloud (or vertices set)
size_t selNum = 1;
for (size_t i = 0; i<selNum; ++i)
{
ccGenericPointCloud* cloud = ccHObjectCaster::ToGenericPointCloud(&cpc);
if (cloud && cloud->isA(CC_TYPES::POINT_CLOUD))
{
ccPointCloud* pc = static_cast<ccPointCloud*>(cloud);
unsigned ptsCount = pc->size();
//test each dimension
for (unsigned d = 0; d<3; ++d)
{
if (exportDim[d])
{
int sfIndex = pc->getScalarFieldIndexByName(qPrintable(defaultSFName[d]));
if (sfIndex < 0)
sfIndex = pc->addScalarField(qPrintable(defaultSFName[d]));
if (sfIndex < 0)
{
ccLog::Error("Not enough memory!");
i = selNum;
break;
}
CCLib::ScalarField* sf = pc->getScalarField(sfIndex);
int sflen = sf->currentSize();
assert(sf && sf->currentSize() == ptsCount);
if (sf)
{
for (unsigned k = 0; k<sflen; ++k)
{
ScalarType s = static_cast<ScalarType>(pc->getPoint(k)->u[d]);
sf->setValue(k, s);
}
sf->computeMinAndMax();
pc->setCurrentDisplayedScalarField(sfIndex);
cpc.showSF(true);
cpc.refreshDisplay_recursive();
}
}
}
}
}
FileIOFilter *fio = FileIOFilter::CreateFilter(BIN);
fio->SaveToFile(&cpc, "C:\\Users\\Fengzt\\Desktop\\TestModel.bin", BIN);
There has a problem that I can't solve it . The variable 'cpc' is a ccPointCloud object.Why is sf->currentSize() != ptsCount.
Why sf->currentSize() != pc->size()
Re: Why sf->currentSize() != pc->size()
When you create a new scalar field (with addScalarField) it's empty by default (so sf->currentSize() == 0). However the memory is already reserved (so sf->capacity() != 0). So you should check instead that 'sf->capacity() == sf->currentSize()'.
On an empty scalar field we generally pushes values the first time (with 'addElement'). But in your case, as you also want to use an already existing scalar field, you won't be able to do that in a simple way. So just after you create a new scalar field, you must fill it with default values (e.g. 'sf->fill(NAN_VALUE);'). This way in both case the scalar field will be full (and your test 'sf->currentSize() == ptsCount' will be ok by the way).
On an empty scalar field we generally pushes values the first time (with 'addElement'). But in your case, as you also want to use an already existing scalar field, you won't be able to do that in a simple way. So just after you create a new scalar field, you must fill it with default values (e.g. 'sf->fill(NAN_VALUE);'). This way in both case the scalar field will be full (and your test 'sf->currentSize() == ptsCount' will be ok by the way).
Daniel, CloudCompare admin