diff --git a/contrib/arc/OctreeLSImage/OctreeLSImage.cpp b/contrib/arc/OctreeLSImage/OctreeLSImage.cpp new file mode 100644 index 0000000000000000000000000000000000000000..1a190359d74de0ee3ac576d466ed51a017f9c5f5 --- /dev/null +++ b/contrib/arc/OctreeLSImage/OctreeLSImage.cpp @@ -0,0 +1,728 @@ +// +// Description: +// +// +// Author: <Boris Sedji>, 12/2009 +// +// Copyright: See COPYING file that comes with this distribution +// +// + + +#ifndef _GMODEL_H_ +#include "GModel.h" +#define _GMODEL_H_ +#endif + +#include "OctreeLSImage.h" + + + +OctreeLSImage::OctreeLSImage(itk::Image< float, 3 >::Pointer image){ + + itk::Image< float, 3 >::RegionType region; + // Define a region to get size of the image + region = image->GetLargestPossibleRegion (); + + + // Size will be a power of two larger than the image size + + _size[0] = 1; + _size[1] = 1; + _size[2] = 1; + while (_size[0]<region.GetSize(0)){ + _size[0] = _size[0]*2; + } + while (_size[1]<region.GetSize(1)){ + _size[1] = _size[1]*2; + } + while (_size[2]<region.GetSize(2)){ + _size[2] = _size[2]*2; + } + + BoxData *data = new BoxData; + + // The window of the image root + data->boundingbox[0]=0; + data->boundingbox[1]=_size[0]; + data->boundingbox[2]=0; + data->boundingbox[3]=_size[1]; + data->boundingbox[4]=0; + data->boundingbox[5]=_size[2]; + + // initialisation of the octree + _root = new Box(data,NULL,this); + _root->FillLevelSetValue(image,data); + _image = image; + _LeafNumber = 0; + +} + + +void OctreeLSImage::Mesh(int maxsize,int minsize){ + + // taillemax //nombre de pixels max dans une direction + + if (this->_root->HaveChildren()){ + return; + } + if(_root->BoxSize()>maxsize || !_root->IsHomogeneous()){ + _root->Mesh( maxsize, minsize); + }; + +} + + +Box::Box(BoxData* data, Box* parent,OctreeLSImage* octree){ + + _data = data; + _parent = parent; + _children[0] = NULL; + _octree = octree; + +} + +bool Box::HaveChildren(){ + + if (this->_children[0]==NULL) return false; + else return true; + +} + + +void Box::FillLevelSetValue(itk::Image< float, 3 >::Pointer image, BoxData *data){ + + float pixelValue; + itk::Image< float, 3 >::IndexType pixelIndex; + itk::Image< float, 3 >::RegionType region; + region = image->GetLargestPossibleRegion (); + + // fill with pixel value, and if out of region size, fill with value at largest region size + for (int i=0;i<2;i++){ + for (int j=0;j<2;j++){ + for (int k=0;k<2;k++){ + + if (data->boundingbox[i] < region.GetSize(0)) pixelIndex[0] = data->boundingbox[i]; + else pixelIndex[0] = region.GetSize(0)-1; // x position + + if (data->boundingbox[2+j] < region.GetSize(1)) pixelIndex[1] = data->boundingbox[2+j]; + else pixelIndex[1] = region.GetSize(1)-1; // y position + + if (data->boundingbox[4+k] < region.GetSize(2)) pixelIndex[2] = data->boundingbox[4+k]; + else pixelIndex[2] = region.GetSize(2)-1; // z position + + pixelValue = image->GetPixel( pixelIndex ); + data->LevelSetValue[i][j][k] = pixelValue; + + } + } + } + +} + +int Box::BoxSize(){ + + int SizeX; + int SizeY; + int SizeZ; + int size; + + SizeX = this->_data->boundingbox[1] - this->_data->boundingbox[0]; + SizeY = this->_data->boundingbox[3] - this->_data->boundingbox[2]; + SizeZ = this->_data->boundingbox[5] - this->_data->boundingbox[4]; + + if (SizeX<SizeY) size = SizeX; + else size = SizeY; + + if (SizeZ<size) size = SizeZ; + + return size; + +} + +bool Box::IsHomogeneous(){ + + float OneValue = this->_data->LevelSetValue[0][0][0]; + + for (int i=0;i<2;i++){ + for (int j=0;j<2;j++){ + for (int k=0;k<2;k++){ + OneValue = OneValue*this->_data->LevelSetValue[i][j][k]; + if (OneValue<0) { + return false; // if sign change => not homogeneous + }; + OneValue = this->_data->LevelSetValue[i][j][k]; + } + } + } + return true; + +} + + +// Recursive dividing function - eight nodes + +void Box::Mesh(int & maxsize, int & minsize){ + + if(((this->BoxSize()<=maxsize) & (this->IsHomogeneous())) | (this->BoxSize()<=minsize)){ // (max size & homogenous) ou (min size) => dont divide + return; // dont divide + } + + // else we divide... + this->Divide(); + + for (int n = 0;n<8;n++){ + _children[n]->Mesh(maxsize,minsize); + } + +} + +void Box::PrintLevelSetValue(){ + + for (int i=0;i<2;i++){ + for (int j=0;j<2;j++){ + for (int k=0;k<2;k++){ + std::cout<<"\n "<< this->_data->LevelSetValue[i][j][k]; + } + } + } + +} + + + +GModel *OctreeLSImage::CreateGModel(){ + + this->FillMeshInfo(); + + std::map<int, MVertex*> vertexMap; + std::vector<MVertex*> vertexVector; + + std::vector<int> numElement; + std::vector<std::vector<int> > vertexIndices; + std::vector<int> elementType ; + std::vector<int> physical; + std::vector<int> elementary; + std::vector<int> partition; + + int numVertices; + numVertices = _ListNodes.size(); + int minVertex = numVertices+1; + int maxVertex = -1; + std::vector<std::vector<int> >::iterator it; + it = _ListNodes.begin(); + int i = 1; + while(it!=_ListNodes.end()){ + int num; + float xyz[3]; + xyz[0] = ((*it)[0])*1; + xyz[1] = ((*it)[1])*1.2; + xyz[2] = ((*it)[2])*1.5; + num = i; + MVertex* newVertex = new MVertex(xyz[0], xyz[1], xyz[2], 0, num); + vertexMap[num] = newVertex; + it++; + i++; + } + minVertex = 1; + maxVertex = numVertices; + i = 1; + it = _ListElements.begin(); + while(it!=_ListElements.end()) { + int num, type, phys = 0, ele = 0, part = 0, numVertices; + num = i; + type = 5; + ele = 26; + phys = 0; + part = 0; + numVertices = MElement::getInfoMSH(type); + std::vector <int> indices; + for(int j = 0; j < numVertices; j++){ + indices.push_back((*it)[j]); + } + numElement.push_back(i); + vertexIndices.push_back(indices); + elementType.push_back(type); + physical.push_back(phys); + elementary.push_back(ele); + partition.push_back(part); + indices.clear(); + it++; + i++; + } + + GModel *gmod = GModel::createGModel(vertexMap,numElement,vertexIndices,elementType,physical,elementary,partition); + + return gmod; + +} + +PView *OctreeLSImage::CreateLSPView(GModel* m){ + + std::map<int, std::vector<double> > data; + std::vector<float>::iterator itf; + itf = _ListLSValue.begin(); + int i = 1; + + while (itf!=_ListLSValue.end()){ + std::vector<double> d; + d.push_back((*itf)) ; + data[i] = d; + d.clear(); + itf++; + i++; + } + std::string postTypeName = "LevelSet Value" ; + PView *pv = new PView (postTypeName, "NodeData", m, data, 0.0); + + return pv; + +} + +void OctreeLSImage::FillMeshInfo(){ + + if (!_ListNodes.empty()){ + return; + } + + _root->FillMeshInfo(_ListNodes,_ListElements,_ListLSValue); + +} + + + +// fonction par balayage de région + + +void Box::FillMeshInfo(std::vector< std::vector<int> > &ListNodes, std::vector< std::vector<int> > &ListElements, std::vector<float> &ListLSValue){ + + int pas = 1; + + int* size = _octree->GetSize(); + + int xpas = size[0]/size[2]*pas; // à modifier si sizeZ n'est pas le plus petit + int ypas = size[1]/size[2]*pas; + int zpas = size[2]/size[2]*pas; + + std::cout<<"\nxyzpas :"<< xpas << " " << ypas << " " << zpas; + + std::vector<std::vector<int> >::iterator it; + + it = ListNodes.begin(); + int iti=0; + + for(int z = 0;z<=size[2];z+=zpas) + for(int y = 0;y<=size[1];y+=ypas) + for(int x = 0;x<=size[0]; x+=xpas) + { + std::vector<Box*> Leafs; + Leafs.clear(); + GetLeafsWith(Leafs, x, y, z); + std::map<int,std::vector< int > > ElementsNodes; + std::vector<int> NodesIn; + + bool added = false; + for(unsigned int l=0;l<Leafs.size();l++){ + if (!added){ + std::vector<int> XYZ; + XYZ.push_back(x); + XYZ.push_back(y); + XYZ.push_back(z); + for (int i = 0 ; i<2;i++ ) + for (int j = 0 ; j<2;j++ ) + for (int k = 0 ; k<2;k++ ){ + if (x == Leafs[l]->GetData()->boundingbox[i] & y == Leafs[l]->GetData()->boundingbox[j+2] & z == Leafs[l]->GetData()->boundingbox[4+k] ){ + ListLSValue.push_back(Leafs[l]->GetData()->LevelSetValue[i][j][k]); + ListNodes.push_back(XYZ); + added = true; + iti++; + } + } + }else break; + } + if (added){ + for(unsigned int l=0;l<Leafs.size();l++){ + for (int i = 0 ; i<2;i++ ) + for (int k = 0 ; k<2;k++ ) + for (int j = 0 ; j<2;j++ ){ + int pos ; + pos = i*4+k*2+j*1; + if (x == Leafs[l]->GetData()->boundingbox[i] & y == Leafs[l]->GetData()->boundingbox[j+2] & z == Leafs[l]->GetData()->boundingbox[k+4]){ + Leafs[l]->SetElementNode(pos,iti); + } + } + } + } + } + std::cout<<"\nNumber Nodes : "<< ListNodes.size(); + _octree->GetRoot()->FillElementsNode(ListElements); + +} + +void Box::FillElementsNode(std::vector< std::vector<int> > &ListElements){ + + // if it s a leaf then fill list node if node dont exist in list + if (!this->HaveChildren()) { + std::vector<int> ElementNodes; + for (int i = 0 ; i < 8 ; i++) ElementNodes.push_back(_ElementNodes[i]); + ListElements.push_back(ElementNodes); + std::cout<<"\n Nodes :"; + for (int i = 0 ; i < 8 ; i++) + std::cout<<" " << ElementNodes[i]; + return; + } + + for (int n = 0 ; n < 8 ; n++){ + this->_children[n]->FillElementsNode(ListElements); + } + +} + + + + +/* +void Box::FillMeshInfo(std::vector< std::vector<int> > &ListNodes, std::vector< std::vector<int> > &ListElements, std::vector<float> &ListLSValue){ + + // if it s a leaf then fill list node if node dont exist in list + if (!this->HaveChildren()) { + std::vector<int> NodesIn; + NodesIn.clear(); + int temp; + for (int i = 0 ; i<2;i++ ){ + for (int k = 0 ; k<2;k++ ) + for (int j = 0 ; j<2;j++ ){ + std::vector<int> XYZ; + float LSValue; + XYZ.push_back(this->GetData()->boundingbox[i]); + XYZ.push_back(this->GetData()->boundingbox[2+j]); + XYZ.push_back(this->GetData()->boundingbox[4+k]); + LSValue = this->GetData()->LevelSetValue[i][j][k]; + std::vector<std::vector<int> >::iterator it; + it = ListNodes.begin(); + bool add = true; + int l; + l = 1; + while (it!=ListNodes.end()){ // attention segmentation & pas opti + if (((*it)[0] == XYZ[0]) & ((*it)[1] == XYZ[1]) & ((*it)[2] == XYZ[2])){ + add = false; + NodesIn.push_back(l); + break; + } + it++; + l++; + } + if (add) { + ListNodes.push_back(XYZ); + ListLSValue.push_back(LSValue); + NodesIn.push_back(l); + } + XYZ.clear(); + } + } + temp = NodesIn[3]; + NodesIn[3] = NodesIn[2]; + NodesIn[2] = temp; + temp = NodesIn[7]; + NodesIn[7] = NodesIn[6]; + NodesIn[6] = temp; + ListElements.push_back(NodesIn); + return; + } + + for (int n = 0 ; n < 8 ; n++){ + this->_children[n]->FillMeshInfo(ListNodes,ListElements,ListLSValue); + } + +}*/ + +/* +std::vector< std::vector <int> > *OctreeLSImage::GetListElements(){ + + if (!_ListElements.empty()){ + return &_ListElements; + } + + _root->GetLeafElements(_ListElements); + + return &_ListElements; + +}*/ + + +/* +void Box::GetLeafElements(std::vector< std::vector<int> > &ListElements){ + +// if (!this->HaveChildren()) { +// std::vector<std::vector<int> >::iterator it; +// std::vector<std::vector<int> > *ListNodes; +// ListNodes = this->_octree->GetListNodes(); +// it = ListNodes->begin(); +// std::vector<int> NodesIn; +// int l = 1; +// while (it!=ListNodes->end()) { +// for (int i = 0 ; i<2;i++ ){ +// for (int j = 0 ; j<2;j++ ){ +// for (int k = 0 ; k<2;k++ ){ +// if ((_data->boundingbox[i] == (*it)[0]) & (_data->boundingbox[2+j] == (*it)[1]) & (_data->boundingbox[4+k] == (*it)[2])) +// NodesIn.push_back(l); +// } +// } +// } +// it++; +// l++; +// } +// ListElements.push_back(NodesIn); +// return; +// } +// +// for (int n = 0 ; n < 8 ; n++){ +// this->_children[n]->GetLeafElements(ListElements); +// } + +} +*/ + + + + +void OctreeLSImage::SetLeafNumber(){ + _LeafNumber = 0; + _root->CountLeafNumber(_LeafNumber); +} + +void Box::CountLeafNumber(int &LeafNumber){ + + if (this->GetChild(0)==NULL) { + LeafNumber = LeafNumber + 1; + return; + } + + for (int n = 0 ; n < 8 ; n++){ + this->_children[n]->CountLeafNumber(LeafNumber); + } + +} + +// Divide function + +void Box::Divide(){ + +// box divide in 8 boxes whit limite xl = (xmin + xmax)/2 ; yl = (ymin + ymax)/2 ; zl = (zmin + zmax)/2 + + int n; + + // Box 1 : < xl ; < yl ; < zl + + n = 0; + BoxData* data1 = new BoxData; + + data1->boundingbox[0]=this->_data->boundingbox[0]; + data1->boundingbox[1]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data1->boundingbox[2]=this->_data->boundingbox[2]; + data1->boundingbox[3]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data1->boundingbox[4]=this->_data->boundingbox[4]; + data1->boundingbox[5]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + + this->_children[n] = new Box(data1,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 2 : > xl ; < yl ; < zl + + n = 1; + BoxData* data2 = new BoxData; + + data2->boundingbox[0]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data2->boundingbox[1]=this->_data->boundingbox[1]; + data2->boundingbox[2]=this->_data->boundingbox[2]; + data2->boundingbox[3]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data2->boundingbox[4]=this->_data->boundingbox[4]; + data2->boundingbox[5]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + + this->_children[n] = new Box(data2,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 3 : < xl ; > yl ; < zl + + n = 2; + BoxData* data3 = new BoxData; + + data3->boundingbox[0]=this->_data->boundingbox[0]; + data3->boundingbox[1]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data3->boundingbox[2]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data3->boundingbox[3]=this->_data->boundingbox[3]; + data3->boundingbox[4]=this->_data->boundingbox[4]; + data3->boundingbox[5]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + + this->_children[n] = new Box(data3,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 4 : > xl ; > yl ; < zl + + n = 3; + BoxData* data4 = new BoxData; + + data4->boundingbox[0]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data4->boundingbox[1]=this->_data->boundingbox[1]; + data4->boundingbox[2]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data4->boundingbox[3]=this->_data->boundingbox[3]; + data4->boundingbox[4]=this->_data->boundingbox[4]; + data4->boundingbox[5]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + + this->_children[n] = new Box(data4,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 5 : < xl ; < yl ; > zl + + n = 4; + BoxData* data5 = new BoxData; + + data5->boundingbox[0]=this->_data->boundingbox[0]; + data5->boundingbox[1]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data5->boundingbox[2]=this->_data->boundingbox[2]; + data5->boundingbox[3]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data5->boundingbox[4]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + data5->boundingbox[5]=this->_data->boundingbox[5]; + + this->_children[n] = new Box(data5,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 6 : > xl ; < yl ; > zl + + n = 5; + BoxData* data6 = new BoxData; + + data6->boundingbox[0]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data6->boundingbox[1]=this->_data->boundingbox[1]; + data6->boundingbox[2]=this->_data->boundingbox[2]; + data6->boundingbox[3]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data6->boundingbox[4]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + data6->boundingbox[5]=this->_data->boundingbox[5]; + + this->_children[n] = new Box(data6,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 7 : < xl ; > yl ; > zl + + n = 6; + BoxData* data7 = new BoxData; + + data7->boundingbox[0]=this->_data->boundingbox[0]; + data7->boundingbox[1]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data7->boundingbox[2]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data7->boundingbox[3]=this->_data->boundingbox[3]; + data7->boundingbox[4]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + data7->boundingbox[5]=this->_data->boundingbox[5]; + + this->_children[n] = new Box(data7,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); + + // Box 8 : > xl ; > yl ; > zl + + n = 7; + BoxData* data8 = new BoxData; + + data8->boundingbox[0]=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2; + data8->boundingbox[1]=this->_data->boundingbox[1]; + data8->boundingbox[2]=(this->_data->boundingbox[3]+this->_data->boundingbox[2])/2; + data8->boundingbox[3]=this->_data->boundingbox[3]; + data8->boundingbox[4]=(this->_data->boundingbox[5]+this->_data->boundingbox[4])/2; + data8->boundingbox[5]=this->_data->boundingbox[5]; + + this->_children[n] = new Box(data8,this,this->_octree); + this->_children[n]->FillLevelSetValue(_children[n]->_octree->GetImage(),_children[n]->GetData()); +} + +bool OctreeLSImage::Smooth(){ + + return _root->Smooth(); + +} + + +bool Box::Smooth(){ + + + if (!this->HaveChildren()) { + bool smoothed = true; + BoxData*data = this->GetData(); + std::vector<Box*> Leafs; + for (int i = 0 ; i<2;i++ ){ + for (int j = 0 ; j<2;j++ ){ + for (int k = 0 ; k<2;k++ ){ + Leafs.clear(); + _octree->GetRoot()->GetLeafsWith(Leafs,data->boundingbox[i],data->boundingbox[2+j],data->boundingbox[4+k]); + if (Leafs.size()!=8){ + int min = Leafs[0]->BoxSize(); + for(unsigned int l=0;l<Leafs.size();l++){ + if(min>Leafs[l]->BoxSize()) min = Leafs[l]->BoxSize(); + } + for(unsigned int l=0;l<Leafs.size();l++){ + if(min<=(Leafs[l]->BoxSize())/4){ + Leafs[l]->Divide(); + smoothed = false; + } + } + } + } + } + } + return smoothed; + } + + bool smoothed = true; + for (int n = 0 ; n < 8 ; n++){ + if(!this->_children[n]->Smooth()) smoothed = false; + } + return smoothed; +} + +// Octree research, box specialisation from root + +void Box::GetLeafsWith(std::vector<Box*> &Leafs, int x, int y, int z){ + + if (!this->HaveChildren()){ + Box* parent = this; + BoxData* data; + while(parent->GetParent()!=NULL){ + data = parent->GetParent()->GetData(); + parent=parent->GetParent(); + } + Leafs.push_back(this); + return; + } + + + if ((x<=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y <= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z <= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[0]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x>=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y <= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z <= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[1]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x<=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y >= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z <= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[2]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x>=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y >= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z <= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[3]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x<=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y <= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z >= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[4]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x>=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y <= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z >= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[5]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x<=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y >= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z >= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[6]->GetLeafsWith(Leafs,x,y,z); + } + + if ((x>=(this->_data->boundingbox[1]+this->_data->boundingbox[0])/2) & (y >= (this->_data->boundingbox[3]+this->_data->boundingbox[2])/2) & (z >= (this->_data->boundingbox[5]+this->_data->boundingbox[4])/2) ){ + _children[7]->GetLeafsWith(Leafs,x,y,z); + } + +} diff --git a/contrib/arc/OctreeLSImage/OctreeLSImage.h b/contrib/arc/OctreeLSImage/OctreeLSImage.h new file mode 100644 index 0000000000000000000000000000000000000000..7688c8eaa2cf438fcdc3c125565cce72208f8063 --- /dev/null +++ b/contrib/arc/OctreeLSImage/OctreeLSImage.h @@ -0,0 +1,131 @@ +// +// Description: +// +// +// Author: <Boris Sedji>, 12/2009 +// +// Copyright: See COPYING file that comes with this distribution +// +// + + + +#ifndef _ITK_H_ +#include "itkImage.h" +#include "itkImageFileReader.h" +#include "itkImageFileWriter.h" +#define _ITK_H_ +#endif + +#ifndef _PVIEW_H_ +#include "PView.h" +#define _PVIEW_H_ +#endif + +#ifndef _PVIEWDATA_H_ +#include "PViewData.h" +#define _PVIEWDATA_H_ +#endif + + + + +//data defining a box + +class BoxData{ + public: + int boundingbox[6]; // x1, x2, y1, y2, z1, z2 + float LevelSetValue[2][2][2]; // LevelSetValue[x][y][z] +}; + +class OctreeLSImage; +class Box; + +// Octree class to decompose a float valued 3d image + +class OctreeLSImage +{ + + private : + + // Octree's root + Box* _root; + // Octree's image + itk::Image< float, 3 >::Pointer _image; + // Window size + int _size[3]; + // Mesh list of nodes + std::vector< std::vector <int> > _ListNodes; + // Mesh list of elements + std::vector< std::vector <int> > _ListElements; + // Mesh list of levelsetvalue + std::vector< float > _ListLSValue; + // Number of box leafs + int _LeafNumber; + // Count octree's leafs + void SetLeafNumber(); + void FillMeshInfo(); + + public : + + OctreeLSImage(itk::Image< float, 3 >::Pointer image); + //~OctreeLSImage(); + void Erase(); + Box* GetRoot(){return _root;} + // Refine with related mesh conditions (see implementation) + void Mesh(int maxsize, int minsize); + itk::Image< float, 3 >::Pointer GetImage(){return _image;} + int GetLeafNumber(){this->SetLeafNumber();return _LeafNumber;} + // Refine if too much generations between adjacent leafs + bool Smooth(); + //std::vector< std::vector <int> > *GetListElements(); + // Create GModel + GModel* CreateGModel(); + // Create PView representation of the level set + PView* CreateLSPView(GModel* m); + int* GetSize(){return _size;} + +}; + + +class Box{ + private : + + // children pointers + Box* _children[8]; + Box* _parent; + BoxData* _data; + OctreeLSImage* _octree; + int _ElementNodes[8]; // utilisé seulement par balayage + + public : + + Box(BoxData* data,Box* parent,OctreeLSImage* octree); + BoxData* GetData(){return _data;} + // Does it have children + bool HaveChildren(); + // Fill level set value in data with image values + void FillLevelSetValue(itk::Image< float, 3 >::Pointer image, BoxData *data); + // The smallest length of the box + int BoxSize(); + // Is the box crossed by the iso zero levelset + bool IsHomogeneous(); + // Recursive function to refine until condition is reached (see implementation) + void Mesh(int & maxsize, int & minsize); + // Divide by eight the box leaf + void Divide(); + void PrintLevelSetValue(); + Box* GetParent(){return _parent;}; + Box* GetChild(int n){return _children[n];}; + // Recursive function to count the leafs from the root + void CountLeafNumber(int &LeafNumber); + // Recursive function to smoothed the octree (see OctreeLSImage::Smooth) + bool Smooth(); + // Give all the leafs containing this node + void GetLeafsWith(std::vector<Box*> &Leafs, int x, int y, int z); + // Recursive function to create the list of the mesh nodes, elements and levelset values + void FillMeshInfo(std::vector<std::vector<int> > &ListNodes, std::vector< std::vector<int> > &ListElements, std::vector< float > &ListLSValue); + // Recursive function to create the list of mesh elements in relation with the list of nodes + void SetElementNode(int pos,int iti){_ElementNodes[pos]=iti;} + void FillElementsNode(std::vector< std::vector<int> > &ListElements); + };