list<tIndexDist> ClsTopologySparse::getCellsForArborization(double fXCenter, double fYCenter, ClsBaseArborization *clsBaseArborization) { #ifdef DEBUG_CLSTOPOLOGYSPARSE cout << "ClsTopologySparse::getCellsForArborization(double fXCenter, double fYCenter, ClsBaseArborization *clsBaseArborization)" << endl; #endif list<tIndexDist> lst; list<pair<int, int> > lstPointsLocal; lstPointsLocal = ClsBaseTopology::getCellsForArborizationRect(fXCenter, fYCenter, clsBaseArborization); /* calculate distance */ int iGroupHeight = 0; list<tiPoint >::iterator it; for(it=lstPoints.begin(); it!=lstPoints.end();it++){ int iY = (*it).second; iGroupHeight = (iY > iGroupHeight ? iY : iGroupHeight); } for(it=lstPointsLocal.begin();it!=lstPointsLocal.end();it++){ int iX = (*it).first; int iY = (*it).second; /* only use points within the group boundaries */ if(isValidCell(iX, iY) && iX>0 && iX<=iGroupWidth && iY>0 && iY<=iGroupHeight){ double fDist = calculateDistance(fXCenter, fYCenter, iX, iY); int iIndex = pos2index(iX, iY); tIndexDist tid(iIndex, fDist); lst.push_back(tid); } } return lst; }
list<int> ClsTopologyRect::getPoints4Rect(int iGroupWidth, int iRectXStart, int iRectYStart, int iRectWidth, int iRectHeight) { list<int> lstIndexReturn; int iPosStart = pos2index(iGroupWidth, iRectXStart, iRectYStart); for(int ii=0; ii<iRectHeight; ii++){ for(int jj=iPosStart; jj<iPosStart+iRectWidth; jj++){ lstIndexReturn.push_back(jj); } iPosStart += iGroupWidth; } return lstIndexReturn; }
list<int> ClsTopologyRect::posList2indexList(list<tiPoint > lstIn) { list<int> lstReturn; int iGroupWidth = pclsWidth->getValue(); list<tiPoint >::iterator it; for(it=lstIn.begin(); it!=lstIn.end();it++){ int iX = (*it).first; int iY = (*it).second; int iIndex = pos2index(iGroupWidth, iX, iY); lstReturn.push_back(iIndex); } return lstReturn; }
list<int> ClsTopologySparse::posList2indexList(const list<tiPoint >& lstIn) { #ifdef DEBUG_CLSTOPOLOGYSPARSE cout << "ClsTopologySparse::posList2indexList(const list<tiPoint >& lstIn)" << endl; #endif list<int> lstReturn; list<tiPoint >::const_iterator it; for(it=lstIn.begin(); it!=lstIn.end();it++){ int iX = (*it).first; int iY = (*it).second; int iIndex = pos2index(iGroupWidth, iX, iY); lstReturn.push_back(iIndex); } return lstReturn; }
int ccFastMarchingForNormsDirection::init( ccGenericPointCloud* cloud, NormsIndexesTableType* theNorms, ccOctree* theOctree, unsigned char level) { int result = initGridWithOctree(theOctree, level); if (result < 0) return result; //fill the grid with the octree CCLib::DgmOctree::cellCodesContainer cellCodes; theOctree->getCellCodes(level,cellCodes,true); CCLib::ReferenceCloud Yk(theOctree->associatedCloud()); while (!cellCodes.empty()) { if (!theOctree->getPointsInCell(cellCodes.back(),level,&Yk,true)) { //not enough memory return -1; } //convert the octree cell code to grid position Tuple3i cellPos; theOctree->getCellPos(cellCodes.back(),level,cellPos,true); //convert it to FM cell pos index unsigned gridPos = pos2index(cellPos); //create corresponding cell DirectionCell* aCell = new DirectionCell; { //aCell->signConfidence = 1; aCell->cellCode = cellCodes.back(); aCell->N = ComputeRobustAverageNorm(&Yk,cloud); aCell->C = *CCLib::Neighbourhood(&Yk).getGravityCenter(); } m_theGrid[gridPos] = aCell; cellCodes.pop_back(); } m_initialized = true; return 0; }
list<tIndexDist> ClsTopologyRect::getCellsForArborization(double fXCenter, double fYCenter, ClsBaseArborization *clsBaseArborization) { // cout << "ClsTopologyRect::getCellsForArborization(double fXCenter, double fYCenter, ClsBaseArborization *clsBaseArborization)" << endl; list<tIndexDist> lst; list<tiPoint > lstPointsLocal; lstPointsLocal = ClsBaseTopology::getCellsForArborizationRect(fXCenter, fYCenter, clsBaseArborization); /* calculate distance */ int iGroupWidth = pclsWidth->getValue(); int iGroupHeight = pclsHeight->getValue(); bool bVerticalCylinder = clsBoolParameterVerticalCylinder->getValue(); bool bHorizontalCylinder = clsBoolParameterHorizontalCylinder->getValue(); list<tiPoint >::iterator it; for(it=lstPointsLocal.begin();it!=lstPointsLocal.end();it++){ int iX = (*it).first; int iY = (*it).second; /* 1. only use points within the group boundaries */ /* 20050319 */ double fDist = calculateDistance(fXCenter, fYCenter, iX, iY); /* vertical cylinder */ if(bVerticalCylinder){ iX = (iX <= iGroupWidth ? iX : iX-iGroupWidth); iX = (iX > 0 ? iX : iGroupWidth+iX); } /* horizontal cylinder */ if(bHorizontalCylinder){ iY = (iY <= iGroupHeight ? iY : iY-iGroupHeight); iY = (iY > 0 ? iY : iGroupHeight+iY); } if(iX>0 && iX<=iGroupWidth && iY>0 && iY<=iGroupHeight){ int iIndex = pos2index(iX, iY); tIndexDist tid(iIndex, fDist); lst.push_back(tid); } } return lst; }
bool FastMarchingForFacetExtraction::setSeedCell(const Tuple3i& pos) { if (!CCLib::FastMarching::setSeedCell(pos)) return false; if (m_octree) { if (!m_currentFacetPoints) { m_currentFacetPoints = new CCLib::ReferenceCloud(m_octree->associatedCloud()); } unsigned index = pos2index(pos); m_currentFacetError = addCellToCurrentFacet(index); if (m_currentFacetError < 0) //invalid error? return false; } return true; }
std::string CGameMap::initialize() { assert( !mCells ); /* Format of map data: string Tissue Name int32 Tissue Bitmap Length byte[] Tissue Bitmap (200*200) string Entites text file string Streams text file string Walls text files */ const BYTE* data; // // parse name mName = bu::receiveStr(); // TBD: workaround around Richard's funky stuff int lastSlash = mName.find_last_of( "\\//" ); if( lastSlash >= 0 ) mName = mName.substr( lastSlash+1, mName.length()-lastSlash ); CONS << "Game map name: " << mName << endl; // // read map bitmap int bmpSize = bu::receiveInt(); net::receiveChunk( data, bmpSize, true ); // compute CRC of the bitmap const char* bmpFile = (const char*)data; mCRC = boost::crc<32,0xFFFFFFFF,0,0,false,false>( bmpFile, bmpSize ); HRESULT hr; D3DXIMAGE_INFO bitmapInfo; hr = D3DXGetImageInfoFromFileInMemory( bmpFile, bmpSize, &bitmapInfo ); if( FAILED(hr) ) { return "Error in game map - incorrect tissue bitmap format"; } assert( bitmapInfo.Width > 10 && bitmapInfo.Height > 10 ); assert( bitmapInfo.Width * bitmapInfo.Height <= 256*256 ); if( bitmapInfo.Width < 10 || bitmapInfo.Height < 10 ) { return "Error in game map - map is too small"; } if( bitmapInfo.Width * bitmapInfo.Height > 256*256 ) { return "Error in game map - map is too large"; } mCellsX = bitmapInfo.Width; mCellsY = bitmapInfo.Height; mCells = new SCell[ mCellsX * mCellsY ]; CD3DDevice& dx = CD3DDevice::getInstance(); IDirect3DSurface9* surface = 0; hr = dx.getDevice().CreateOffscreenPlainSurface( bitmapInfo.Width, bitmapInfo.Height, D3DFMT_A8R8G8B8, D3DPOOL_SCRATCH, &surface, NULL ); assert( SUCCEEDED(hr) ); hr = D3DXLoadSurfaceFromFileInMemory( surface, NULL, NULL, bmpFile, bmpSize, NULL, D3DX_DEFAULT, 0, NULL ); if( FAILED(hr) ) { return "Error in game map - incorrect cells map format"; } D3DLOCKED_RECT lr; surface->LockRect( &lr, NULL, D3DLOCK_READONLY ); const char* linePtr = (const char*)lr.pBits; for( int y = 0; y < mCellsY; ++y ) { const D3DCOLOR* p = (const D3DCOLOR*)linePtr; for( int x = 0; x < mCellsX; ++x ) { SCell& cell = mCells[y*mCellsX+x]; switch( *p ) { case 0xFFff0000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_BLOOD; break; case 0xFF00ff00: cell.type = CELL_BLOOD2; cell.color = CCOLOR_BLOOD; break; case 0xFF0000ff: cell.type = CELL_BLOOD3; cell.color = CCOLOR_BLOOD; break; case 0xFF800000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_BONE; break; case 0xFF008000: cell.type = CELL_BLOOD2; cell.color = CCOLOR_BONE; break; case 0xFF000080: cell.type = CELL_BLOOD3; cell.color = CCOLOR_BONE; break; case 0xFFC80000: cell.type = CELL_BLOOD1; cell.color = CCOLOR_NEURON; break; case 0xFF00C800: cell.type = CELL_BLOOD2; cell.color = CCOLOR_NEURON; break; case 0xFF0000C8: cell.type = CELL_BLOOD3; cell.color = CCOLOR_NEURON; break; default: cell.type = CELL_BONE; cell.color = CCOLOR_BLOOD; } cell.height = MIN_CELL_HEIGHT; cell.nearBone = true; ++p; } linePtr += lr.Pitch; } surface->UnlockRect(); surface->Release(); // check map validity if( !checkMapValidity() ) return "Tissue contains invalid topology (cells adjacent only diagonally)"; // // read entities std::string pts = bu::receiveStr(); char* ptsFile = (char*)pts.c_str(); // HACK const char* tokens = "\n\r"; const char* pline = strtok( ptsFile, tokens ); do { if( !pline ) break; int etype, eposx, eposy; int fread = sscanf( pline, "%i:%i:%i", &eposx, &eposy, &etype ); if( fread != 3 ) break; mPoints.push_back( SPoint(ePointType(etype), eposx, eposy ) ); } while( pline = strtok( NULL, tokens ) ); // // read streams std::string strms = bu::receiveStr(); // streams char* strmsFile = (char*)strms.c_str(); // HACK pline = strtok( strmsFile, tokens ); do { if( !pline ) break; int sx, sy, sw, sh, sdir; int fread = sscanf( pline, "%i:%i:%i:%i:%i", &sx, &sy, &sw, &sh, &sdir ); assert( sx >= 0 && sx < mCellsX ); assert( sy >= 0 && sy < mCellsY ); assert( sx+sw <= mCellsX ); assert( sy+sh <= mCellsY ); assert( sdir >= 0 && sdir <= 3 ); assert( fread == 5 ); if( fread != 5 ) break; SStream strm; strm.x = sx; strm.y = sy; strm.width = sw; strm.height = sh; switch( sdir ) { case 0: strm.deltaX = 0; strm.deltaY = 1; break; case 1: strm.deltaX = 0; strm.deltaY = -1; break; case 2: strm.deltaX = 1; strm.deltaY = 0; break; case 3: strm.deltaX = -1; strm.deltaY = 0; break; } mStreams.push_back( strm ); } while( pline = strtok( NULL, tokens ) ); // TBD: walls bu::receiveStr(); // walls // // all is loaded now // calculate cell heights calcCellHeights(); // add some decorative elements static int DECOR_TYPES_IN_TISSUE[DECOR_POINT_TYPE_COUNT] = { (1<<CCOLOR_BLOOD), (1<<CCOLOR_BLOOD), (1<<CCOLOR_BLOOD), (1<<CCOLOR_BONE), (1<<CCOLOR_BONE), (1<<CCOLOR_BONE) | (1<<CCOLOR_BLOOD), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON), (1<<CCOLOR_NEURON)|(1<<CCOLOR_BLOOD)|(1<<CCOLOR_BONE), }; const int DECOR_PTS_COUNT = 125; const int MAX_TRY_COUNT = DECOR_PTS_COUNT * 10; int decPtsCounter = 0; int tryCounter = 0; while( decPtsCounter < DECOR_PTS_COUNT && tryCounter < MAX_TRY_COUNT ) { ++tryCounter; int x = gRandom.getUInt() % mCellsX; int y = gRandom.getUInt() % mCellsY; const SCell& cell = mCells[pos2index(x,y)]; if( !isBlood(cell.type) || cell.nearBone ) continue; if( cell.height < 2.0f ) continue; int ptType = gRandom.getUInt() % DECOR_POINT_TYPE_COUNT; if( !(DECOR_TYPES_IN_TISSUE[ptType] & (1<<cell.color)) ) continue; mPoints.push_back( SPoint(PT_DECORATIVE,x,y, ptType) ); decPtsCounter++; } // register level texture CSharedTextureBundle::getInstance().registerTexture( RID_TEX_LEVEL, *new CGameMapTextureCreator( *this ) ); return ""; // all ok! }
int FastMarchingForFacetExtraction::init( ccGenericPointCloud* cloud, CCLib::DgmOctree* theOctree, unsigned char level, ScalarType maxError, CCLib::DistanceComputationTools::ERROR_MEASURES errorMeasure, bool useRetroProjectionError, CCLib::GenericProgressCallback* progressCb/*=0*/) { m_maxError = maxError; m_errorMeasure = errorMeasure; m_useRetroProjectionError = useRetroProjectionError; if (progressCb) { if (progressCb->textCanBeEdited()) { progressCb->setMethodTitle("Fast Marching grid initialization"); progressCb->setInfo(qPrintable(QString("Level: %1").arg(level))); } progressCb->update(0); progressCb->start(); } int result = initGridWithOctree(theOctree, level); if (result < 0) return result; //fill the grid with the octree CCLib::DgmOctree::cellCodesContainer cellCodes; theOctree->getCellCodes(level,cellCodes,true); size_t cellCount = cellCodes.size(); CCLib::NormalizedProgress nProgress(progressCb, static_cast<unsigned>(cellCount)); if (progressCb) { progressCb->setInfo(qPrintable(QString("Level: %1\nCells: %2").arg(level).arg(cellCount))); } CCLib::ReferenceCloud Yk(theOctree->associatedCloud()); while (!cellCodes.empty()) { if (theOctree->getPointsInCell(cellCodes.back(),level,&Yk,true)) { //convert the octree cell code to grid position Tuple3i cellPos; theOctree->getCellPos(cellCodes.back(),level,cellPos,true); CCVector3 N,C; ScalarType error; if (ComputeCellStats(&Yk,N,C,error,m_errorMeasure)) { //convert octree cell pos to FM cell pos index unsigned gridPos = pos2index(cellPos); //create corresponding cell PlanarCell* aCell = new PlanarCell; aCell->cellCode = cellCodes.back(); aCell->N = N; aCell->C = C; aCell->planarError = error; m_theGrid[gridPos] = aCell; } else { //an error occurred?! return -10; } } cellCodes.pop_back(); if (progressCb && !nProgress.oneStep()) { //process cancelled by user progressCb->stop(); return -1; } } if (progressCb) { progressCb->stop(); } m_initialized = true; return 0; }