first release version

This commit is contained in:
Nico Pietroni 2004-12-17 11:17:36 +00:00
parent 409ceaf11f
commit 7c59d90735
10 changed files with 3258 additions and 0 deletions

View File

@ -0,0 +1,131 @@
#ifndef COLLISION_DETECTION
#define COLLISION_DETECTION
#include <set>
#include <vcg/space/index/spatial_hashing.h>
#include <vcg/space/intersection3.h>
template <class ContSimplex>
class Collision_Detector{
public:
typedef typename ContSimplex::value_type SimplexType;
typedef typename ContSimplex::value_type* SimplexPointer;
typedef typename ContSimplex::iterator SimplexIterator;
typedef typename SimplexType::CoordType Point3x;
typedef typename Point3x::ScalarType ScalarType;
typedef SpatialHashTable<SimplexType> HashingTable;
Collision_Detector(ContSimplex & r_):_simplex(r_){};
~Collision_Detector(){};
ContSimplex & _simplex;
HashingTable *HTable;
std::set<Point3i> vactive;
int active;
//control if two faces share an edge
bool ShareEdge(SimplexType *f0,SimplexType *f1)
{
for (int i=0;i<3;i++)
if (f0->FFp(i)==f1)
return (true);
return(false);
}
///initialize the box for collision detection and the dimension of a cell
void Init(Point3x _min,Point3x _max,ScalarType _l)
{
HTable=new HashingTable();
HTable->Init(_min,_max,_l);
}
//control if two faces share a vertex
bool ShareVertex(SimplexType *f0,SimplexType *f1)
{
for (int i=0;i<3;i++)
for (int j=0;j<3;j++)
if (f0->V(i)==f1->V(j))
return (true);
return(false);
}
//test real intersection between faces
bool TestRealIntersection(SimplexType *f0,SimplexType *f1)
{
if ((!f0->IsActive())&&(!f1->IsActive()))
return false;
//no adiacent faces
if ((f0!=f1)&& (!ShareEdge(f0,f1))
&& (!ShareVertex(f0,f1)))
return (vcg::Intersection<SimplexType>((*f0),(*f1)));
return false;
}
///refresh the elemnt of spatial hashing table
void RefreshElements()
{
HTable->Clear();
for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si)
{
if ((!(*si).IsD())&&(!(*si).IsActive()))
HTable->addSimplex(&*si);
}
UpdateStep();
}
///put active cells on apposite structure
void UpdateStep()
{
vactive.clear();
for (SimplexIterator si=_simplex.begin();si<_simplex.end();++si)
{
if ((((!(*si).IsD()))&&(*si).IsActive()))
{
std::vector<Point3i> cells=HTable->addSimplex(&*si);
for(std::vector<Point3i>::iterator it=cells.begin();it<cells.end();it++)
vactive.insert(*it);
}
}
}
///control the real self intersection in the mesh and returns the elements that intersect with someone
std::vector<SimplexType*> computeSelfIntersection()
{
std::vector<SimplexType*> ret;
std::set<Point3i>::iterator act;
for (act=vactive.begin();act!=vactive.end();act++)
{
Point3i p=*act;
if (HTable->numElemCell(p)>=2)
{
std::vector<SimplexType*> inCell=HTable->getAtCell(p);
int nelem=inCell.size();
if (nelem>=2)
{
//test combinations of elements
for (int i=0;i<nelem-1;i++)
for (int j=i+1;j<nelem;j++)
if ((!inCell[i]->IsD())&&(!inCell[j]->IsD())&&(TestRealIntersection(inCell[i],inCell[j])))
{
ret.push_back(inCell[i]);
ret.push_back(inCell[j]);
}
}
}
}
return ret;
}
};
#endif

View File

@ -0,0 +1,43 @@
#include <qapplication.h>
#include <qimage.h>
#include <segmentform.h>
#include <segmentator.h>
#include <qdir.h>
#include <qcolor.h>
#include <SimpleGLWidget.h>
#include <qtimer.h>
Segmentator *s;
QTimer *timer;
int main( int argc, char ** argv )
{
//s=new Segmentator();
//s->LoadFromDir("./venacava/","prova.txt");//to chANGE
////s->InitSegmentation(0.5,0.2,20,10.f);
//
QApplication a( argc, argv );
SegmentForm w;
w.show();
//assign pointer to pricipal form
w.simpleGLWidget1->w=&w;
s=new Segmentator();
//s->LoadFromDir("./venacava/","prova.txt");//to chANGE
//s->InitSegmentation(0.5,0.2,20,10.f);
timer = new QTimer(w.simpleGLWidget1 );
QTimer::connect( timer, SIGNAL(timeout()), w.simpleGLWidget1, SLOT(Update()) );
timer->start(0); // 2 seconds single-shot timer
a.connect( &a, SIGNAL( lastWindowClosed() ), &a, SLOT( quit() ) );
return a.exec();
}

View File

@ -0,0 +1,137 @@
/****************************************************************************
** SimpleGLWidget meta object code from reading C++ file 'simpleglwidget.h'
**
** Created: Fri Dec 17 12:16:05 2004
** by: The Qt MOC ($Id: moc_simpleglwidget.cpp,v 1.1 2004-12-17 11:17:36 pietroni Exp $)
**
** WARNING! All changes made in this file will be lost!
*****************************************************************************/
#undef QT_NO_COMPAT
#include "simpleglwidget.h"
#include <qmetaobject.h>
#include <qapplication.h>
#include <private/qucomextra_p.h>
#if !defined(Q_MOC_OUTPUT_REVISION) || (Q_MOC_OUTPUT_REVISION != 26)
#error "This file was generated using the moc from 3.3.2. It"
#error "cannot be used with the include files from this version of Qt."
#error "(The moc has changed too much.)"
#endif
const char *SimpleGLWidget::className() const
{
return "SimpleGLWidget";
}
QMetaObject *SimpleGLWidget::metaObj = 0;
static QMetaObjectCleanUp cleanUp_SimpleGLWidget( "SimpleGLWidget", &SimpleGLWidget::staticMetaObject );
#ifndef QT_NO_TRANSLATION
QString SimpleGLWidget::tr( const char *s, const char *c )
{
if ( qApp )
return qApp->translate( "SimpleGLWidget", s, c, QApplication::DefaultCodec );
else
return QString::fromLatin1( s );
}
#ifndef QT_NO_TRANSLATION_UTF8
QString SimpleGLWidget::trUtf8( const char *s, const char *c )
{
if ( qApp )
return qApp->translate( "SimpleGLWidget", s, c, QApplication::UnicodeUTF8 );
else
return QString::fromUtf8( s );
}
#endif // QT_NO_TRANSLATION_UTF8
#endif // QT_NO_TRANSLATION
QMetaObject* SimpleGLWidget::staticMetaObject()
{
if ( metaObj )
return metaObj;
QMetaObject* parentObject = QGLWidget::staticMetaObject();
static const QUMethod slot_0 = {"Open", 0, 0 };
static const QUMethod slot_1 = {"ShowSlides", 0, 0 };
static const QUMethod slot_2 = {"SetWire", 0, 0 };
static const QUMethod slot_3 = {"SetShowBlocked", 0, 0 };
static const QUMethod slot_4 = {"ShowExternalForces", 0, 0 };
static const QUMethod slot_5 = {"ShowInternalForces", 0, 0 };
static const QUMethod slot_6 = {"ShowResultForces", 0, 0 };
static const QUMethod slot_7 = {"Smooth", 0, 0 };
static const QUMethod slot_8 = {"SavePly", 0, 0 };
static const QUMethod slot_9 = {"Apply", 0, 0 };
static const QUMethod slot_10 = {"Extract", 0, 0 };
static const QUMethod slot_11 = {"Update", 0, 0 };
static const QUMethod slot_12 = {"Clear", 0, 0 };
static const QMetaData slot_tbl[] = {
{ "Open()", &slot_0, QMetaData::Public },
{ "ShowSlides()", &slot_1, QMetaData::Public },
{ "SetWire()", &slot_2, QMetaData::Public },
{ "SetShowBlocked()", &slot_3, QMetaData::Public },
{ "ShowExternalForces()", &slot_4, QMetaData::Public },
{ "ShowInternalForces()", &slot_5, QMetaData::Public },
{ "ShowResultForces()", &slot_6, QMetaData::Public },
{ "Smooth()", &slot_7, QMetaData::Public },
{ "SavePly()", &slot_8, QMetaData::Public },
{ "Apply()", &slot_9, QMetaData::Public },
{ "Extract()", &slot_10, QMetaData::Public },
{ "Update()", &slot_11, QMetaData::Public },
{ "Clear()", &slot_12, QMetaData::Public }
};
metaObj = QMetaObject::new_metaobject(
"SimpleGLWidget", parentObject,
slot_tbl, 13,
0, 0,
#ifndef QT_NO_PROPERTIES
0, 0,
0, 0,
#endif // QT_NO_PROPERTIES
0, 0 );
cleanUp_SimpleGLWidget.setMetaObject( metaObj );
return metaObj;
}
void* SimpleGLWidget::qt_cast( const char* clname )
{
if ( !qstrcmp( clname, "SimpleGLWidget" ) )
return this;
return QGLWidget::qt_cast( clname );
}
bool SimpleGLWidget::qt_invoke( int _id, QUObject* _o )
{
switch ( _id - staticMetaObject()->slotOffset() ) {
case 0: Open(); break;
case 1: ShowSlides(); break;
case 2: SetWire(); break;
case 3: SetShowBlocked(); break;
case 4: ShowExternalForces(); break;
case 5: ShowInternalForces(); break;
case 6: ShowResultForces(); break;
case 7: Smooth(); break;
case 8: SavePly(); break;
case 9: Apply(); break;
case 10: Extract(); break;
case 11: Update(); break;
case 12: Clear(); break;
default:
return QGLWidget::qt_invoke( _id, _o );
}
return TRUE;
}
bool SimpleGLWidget::qt_emit( int _id, QUObject* _o )
{
return QGLWidget::qt_emit(_id,_o);
}
#ifndef QT_NO_PROPERTIES
bool SimpleGLWidget::qt_property( int id, int f, QVariant* v)
{
return QGLWidget::qt_property( id, f, v);
}
bool SimpleGLWidget::qt_static_property( QObject* , int , int , QVariant* ){ return FALSE; }
#endif // QT_NO_PROPERTIES

View File

@ -0,0 +1,53 @@
#ifndef __PARTIALCONT__
#define __PARTIALCONT__
#include<vector>
template <class STL_CONT, class ELEM>
struct Partial_Container : STL_CONT
{
typedef typename STL_CONT::iterator ite_father;
typedef ELEM value_type;
public:
struct iterator{
ite_father i;
iterator (){}
iterator (ite_father i_):i(i_){}
ELEM &operator *(){return *(*i);}
void operator ++()
{
///((i!=(STL_CONT::end()))&& da controllare la fine
//while ((*i)->IsInvalid())++i;
++i;
}
iterator operator =(const iterator & oth){
i=oth.i;
return *this;
}
bool operator ==(const iterator & oth){
return (i==oth.i);
}
bool operator !=(const iterator & oth){
return (i!=oth.i);
}
bool operator <(const iterator & oth){
return (i<oth.i);
}
};
Partial_Container(){};
iterator begin(){return iterator(STL_CONT::begin());}
iterator end(){return iterator(STL_CONT::end());}
};
#endif

View File

@ -0,0 +1,245 @@
TEMPLATE = app
LANGUAGE = C++
CONFIG += qt warn_on release
HEADERS += D:/sf/apps/test/segmentation3d/simpleglwidget.h
SOURCES += main.cpp \
D:/sf/apps/test/segmentation3d/simpleglwidget.cpp
FORMS = segmentform.ui \
d:\segmentation\segmentform.ui
unix {
UI_DIR = .ui
MOC_DIR = .moc
OBJECTS_DIR = .obj
}

View File

@ -0,0 +1,736 @@
#ifndef SEGMENTATOR
#define SEGMENTATOR
//#include <vcg/simplex/vertex/with/afvn.h>
//#include <vcg/simplex/face/with/afav.h>
#include <vcg/simplex/vertex/with/vn.h>
#include <vcg/simplex/face/with/af.h>
#include <sim/particle/with/basic_physics.h>
#include <sim/methods/mass_spring/triangle.h>
#include <vcg/complex/trimesh/base.h>
#include <vcg/complex/trimesh/allocate.h>
#include <vcg/complex/trimesh/update/topology.h>
#include <vcg/complex/trimesh/update/normal.h>
#include <vcg/complex/trimesh/refine.h>
#include <vcg/complex/trimesh/platonic.h>
#include <volume_dataset.h>
//#include <vcg/simplex/face/pos.h>
#include <vcg/space/point3.h>
#include <vcg/space/box3.h>
#include <sim/pde_integrator.h>
#include <partial_container.h>
#include <vector>
#include <time.h>
#include <math.h>
#include <collision_detection.h>
#include <vcg/complex/trimesh/smooth.h>
class Segmentator{
public:
struct DummyEdge;
struct DummyTetra;
struct MyFace;
struct MyVertex: public ParticleBasic<vcg::VertexVNf<DummyEdge,MyFace,DummyTetra> >
{
public:
bool blocked;//optimize after with vertex flags
bool stopped;
MyVertex()
{
blocked=false;
stopped=false;
Acc()=Point3f(0,0,0);
Vel()=Point3f(0,0,0);
//neeed call of the super class
}
void UpdateAcceleration()
{
//if ((!IsBlocked(this))&&(!IsStopped(this)))
if ((!blocked)&&(!stopped))
{
Acc()=(IntForce()+ExtForce())/Mass();
}
else
{
Acc()=Point3f(0,0,0);
Vel()=Point3f(0,0,0);
}
}
void Reset()
{
IntForce()=Point3f(0.f,0.f,0.f);
}
};
///this class implements the deformable triangle in a mass spring system
struct MyFace : public TriangleMassSpring< vcg::FaceAF<MyVertex,DummyEdge,MyFace> >
{
public:
bool intersected;
float kdihedral;
MyFace()
{
intersected=false;
}
void Init ( double k, double mass,float k_dihedral )
{
__super::Init(k,mass);
kdihedral=k_dihedral;
}
bool IsActive()
{
return(!(((V(0)->blocked)||(V(0)->stopped))&&
((V(1)->blocked)||(V(1)->stopped))&&
((V(2)->blocked)||(V(2)->stopped))));
}
bool IsBlocked()
{
return((V(0)->blocked)&&(V(1)->blocked)&&(V(2)->blocked));
}
double DiedralAngle(int edge)
{
MyFace *fopp=FFp(edge);
CoordType norm1=NormalizedNormal();
CoordType norm2=fopp->NormalizedNormal();
return (NormalizedNormal()*fopp->NormalizedNormal());
}
///update of the internal forces using the dihedral angle
bool Update ( void )
{
for (int i=0;i<3;i++)
{
MyFace *fopp=FFp(i);
MyFace *myAddr=fopp->FFp(FFi(i));
if ((fopp!=0)||(fopp<myAddr))//test do not duplicate updates per edge
{
//normal and area based diadedral angle calcolus
CoordType DirEdge=(V(i)->P()-V((i+1)%3)->P()).Normalize();
fopp=FFp(i);
CoordType Ver=(NormalizedNormal()^fopp->NormalizedNormal()).Normalize();
ScalarType diaedral=DiedralAngle(i);
if ((Ver*DirEdge)<=0)///convex
{
ScalarType Force=(((-diaedral)+1.f)*kdihedral);
V((i+2)%3)->IntForce()+=NormalizedNormal()*(Force);
V(i)->IntForce()-=NormalizedNormal()*(Force)/2.f;
V((i+1)%3)->IntForce()-=NormalizedNormal()*(Force)/2.f;
}
else ///non-convex
{
ScalarType Force=(((-diaedral)+1.f)*kdihedral);
V((i+2)%3)->IntForce()-=NormalizedNormal()*(Force);
V(i)->IntForce()+=NormalizedNormal()*(Force)/2.f;
V((i+1)%3)->IntForce()+=NormalizedNormal()*(Force)/2.f;
}
}
}
return(__super::Update());
}
};
struct MyTriMesh: public vcg::tri::TriMesh<std::vector<MyVertex>,std::vector<MyFace> >{};
typedef Partial_Container<std::vector<MyVertex*>,MyVertex> Part_VertexContainer;
typedef Partial_Container<std::vector<MyFace*>,MyFace> Part_FaceContainer;
typedef PDEIntegrator<Part_FaceContainer,Part_VertexContainer,float> myIntegrator;
typedef Collision_Detector<std::vector<MyFace> > Collision;
public:
Point3f scale;
//VolumetricDataset<int> d;
MyTriMesh m;
Part_FaceContainer P_Faces;
Part_VertexContainer P_Vertex;
Part_VertexContainer V_Stopped;
myIntegrator *TrINT;
MyTriMesh::CoordType InitialBarycenter;
float mass;
float k_elanst;
float k_dihedral;
float edge_size;
int tolerance;
int gray_init;
float time_stamp;
float edge_precision;
bool end_loop;
bool refined;
clock_t interval_reinit;
clock_t interval_selfcollision;
Collision *CollDet;
//Volume_Dataset_Optimized<short> V;
Volume_Dataset <short> V;
vcg::Box3<float> bbox;
char *inDir;
char *outDir;
//attention static members
/*int BlockFlag;
int StoppedFlag;*/
Segmentator()
{
CollDet=new Collision(m.face);
}
~Segmentator()
{
}
private:
/////return integer coordinete in volumetric dataset
//Point3i MapToDataset(MyTriMesh::CoordType p)
//{
// MyTriMesh::ScalarType x=((MyTriMesh::ScalarType)p.V(0));
// MyTriMesh::ScalarType y=((MyTriMesh::ScalarType)p.V(1));
// MyTriMesh::ScalarType z=((MyTriMesh::ScalarType)p.V(2));
// return Point3i((int)p.V(0),(int)p.V(1),(int)p.V(2));
//}
//
///map to space coordinate from dataset coordinates
MyTriMesh::CoordType MapToSpace(Point3i p)
{
MyTriMesh::ScalarType x=((MyTriMesh::ScalarType)p.V(0));
MyTriMesh::ScalarType y=((MyTriMesh::ScalarType)p.V(1));
MyTriMesh::ScalarType z=((MyTriMesh::ScalarType)p.V(2));
return (MyTriMesh::CoordType(x,y,z));
}
///return integer coordinete in volumetric dataset
float getColor(MyTriMesh::CoordType p)
{
float lx=p.V(0)-(int)p.V(0);//da rivedere bene per lo scale
float ly=p.V(1)-(int)p.V(1);//da rivedere bene per lo scale
float lz=p.V(2)-(int)p.V(2);//da rivedere bene per lo scale
Point3i base=Point3i((int)p.V(0),(int)p.V(1),(int)p.V(2));
float v[8];
Point3i px;
for (int i=0;i<8;i++)
{
px=base+Point3i((i%2),(i/4),((i/2)%2));
v[i]=(float)V.getAt(px);
}
float color=lx*v[1]+v[0]+lz*v[0]*lx-v[0]*lx-ly*v[0]+ly*v[2]-lz*v[0]+ly*v[0]*lx-ly*lx*v[1]-ly*v[2]*lx
-lz*ly*v[0]*lx+lz*ly*lx*v[1]+lz*ly*v[2]*lx-lz*ly*lx*v[3]+lz*ly*lx*v[4]-lz*ly*lx*v[5]-lz*ly*
v[6]*lx+lz*ly*lx*v[7]+ly*lx*v[3]-lz*lx*v[1]+lz*ly*v[0]-lz*ly*v[2]-lz*lx*v[4]+lz*lx*v[5]-lz*ly*
v[4]+lz*ly*v[6]+lz*v[4];
return color;
}
///maximixe the gradient of the movement
MyTriMesh::CoordType Gradient(MyTriMesh::CoordType p,float h=0.01f)
{
float value=getColor(p);
MyTriMesh::CoordType h0=MyTriMesh::CoordType(h,0,0);
MyTriMesh::CoordType h1=MyTriMesh::CoordType(0,h,0);
MyTriMesh::CoordType h2=MyTriMesh::CoordType(0,0,h);
float dx=(getColor(p+h0)-value)/h;
/*dx=v[1]+lz*v[0]-v[0]*lx+ly*v[0]-ly*v[1]-ly*v[2]
-lz*ly*v[0]+lz*ly*v[1]+lz*ly*v[2]-lz*ly*v[3]+lz*ly*v[4]-lz*ly*v[5]-lz*ly*
v[6]+lz*ly*v[7]+ly*v[3]-lz*v[1]-lz*v[4]+lz*v[5]-lz*ly*v[4]+lz*ly*v[6]+lz*v[4];
dy=-v[0]+v[2]+v[0]*lx-lx*v[1]-v[2]*lx
-lz*v[0]*lx+lz*lx*v[1]+lz*v[2]*lx-lz*lx*v[3]+lz*lx*v[4]-lz*lx*v[5]-lz*v[6]*lx+lz*ly*lx*v[7]+ly*lx*v[3]-lz*lx*v[1]+lz*ly*v[0]-lz*ly*v[2]-lz*lx*v[4]+lz*lx*v[5]-lz*ly*
v[4]+lz*ly*v[6]+lz*v[4];*/
float dy=(getColor(p+h1)-value)/h;
float dz=(getColor(p+h2)-value)/h;
MyTriMesh::CoordType ret=MyTriMesh::CoordType(dx,dy,dz);
return (ret);
}
///scale the coordinates of a point
MyTriMesh::CoordType Scale(MyTriMesh::CoordType p)
{
MyTriMesh::ScalarType x=(p.V(0))/scale.V(0);
MyTriMesh::ScalarType y=(p.V(1))/scale.V(1);
MyTriMesh::ScalarType z=(p.V(2))/scale.V(2);
return (MyTriMesh::CoordType(x,y,z));
}
///return true if a coordinate is out of limits
bool OutOfLimits(MyTriMesh::CoordType p)
{
Point3f max=Scale(MapToSpace(V.Max()));
Point3f min=Scale(MapToSpace(V.Min()));
Point3f test=(Scale(p));
for (int i=0;i<3;i++)
{
if(((test.V(i)>=max.V(i))||(test.V(i)<=min.V(i))))
return true;
}
return false;
}
bool IsBlocked(MyVertex *v)
{
//return ((v->Flags()& BlockFlag!=0));
return (v->blocked);
}
void SetBlocked(MyVertex *v)
{
//v->Flags()|= BlockFlag;
v->blocked=true;
//v->SetS();//for refine
}
void SetBlockedFace(MyFace *f)
{
SetBlocked(f->V(0));
SetBlocked(f->V(1));
SetBlocked(f->V(2));
}
void SetIntersectedFace(MyFace *f)
{
f->intersected=true;
}
bool IsStopped(MyVertex *v)
{
//return ((v->Flags()& StoppedFlag!=0));
return (v->stopped);
}
void SetStopped(MyVertex *v)
{
//v->Flags()|= StoppedFlag;
v->stopped=true;
V_Stopped.push_back(v);
}
void ClearStopped(MyVertex *v)
{
//v->Flags()&= ~StoppedFlag;
v->stopped=false;
}
///re-set physical pararmeters on the mesh
void InitPhysParam(float k_elanst,float mass,float k_dihedral)
{
for (unsigned int i=0;i<m.face.size();i++)
{
m.face[i].Init(k_elanst,mass,k_dihedral);
}
}
///set the initial mesh of deformable object
void InitMesh(MyTriMesh &m)
{
m.Clear();
vcg::tri::Icosahedron<MyTriMesh>(m);
vcg::tri::UpdateTopology<MyTriMesh>::FaceFace(m);
/* P_Vertex.clear();
P_Faces.clear();*/
for (unsigned int i=0;i<m.vert.size();i++)
{
m.vert[i].P()+=InitialBarycenter;
// P_Vertex.push_back(&m.vert[i]);
}
vcg::tri::UpdateNormals<MyTriMesh>::PerVertexNormalized(m);
}
///return true if the gray level of the vertex v differ from graylevel less than tolerance
bool InTolerance(MyTriMesh::VertexType *v)
{
return (abs(getColor(v->P())-gray_init)<tolerance);
}
///add to the vertex v a containing force basing on diffence from tolerance
MyTriMesh::CoordType ContainingForce(MyTriMesh::VertexType *v)
{
//float dinstance=fabs((FindGrayMedia(v))-gray_init);
float dinstance=fabs((getColor(v->P()))-(float)gray_init);
assert(dinstance<=tolerance);
MyTriMesh::CoordType ret=(-v->N()*((dinstance)/(float)tolerance));
return (ret);
}
///find the gradient factor
MyTriMesh::CoordType GradientFactor(MyTriMesh::VertexType *v)
{
MyTriMesh::CoordType value=Gradient(v->P());
/*float d0=getColor(v->P()+value);
float d1=getColor(v->P()-value);
if ((fabs(d0-(float)gray_init))>(fabs(d1-(float)gray_init)))
return (-value);
else */
return (value*(gray_init-getColor(v->P())));
}
///add the external forces to the deformable mesh
void AddExtForces()
{
Part_VertexContainer::iterator vi;
end_loop=true;
for (vi=P_Vertex.begin();vi<P_Vertex.end();++vi)
{
if (!(*vi).IsD())
{
if (OutOfLimits((*vi).P()))
//vi->blocked=true;
SetBlocked(&*vi);
if ((!IsBlocked(&*vi))&&(!IsStopped(&*vi)))
{
end_loop=false;
if (!InTolerance(&*vi))
{
SetBlocked(&*vi);
(*vi).ExtForce()=MyTriMesh::CoordType(0,0,0);
}
else
{
MyTriMesh::CoordType Inflating=(*vi).N();
MyTriMesh::CoordType Containing0=ContainingForce(&*vi);
//MyTriMesh::CoordType Containing1=GradientFactor(&*vi);
(*vi).ExtForce()=Inflating+Containing0*0.75;/*+Containing1+Containing0*/;
}
}
else
(*vi).ExtForce()=MyTriMesh::CoordType(0,0,0);
}
}
}
///reinit the partial integration vectors that describe active vertices
void Reinit_PVectors()
{
V_Stopped.clear();
P_Vertex.clear();
MyTriMesh::VertexIterator vi;
for (vi=m.vert.begin();vi<m.vert.end();vi++)
{
if ((!vi->IsD())&&(!vi->blocked))
P_Vertex.push_back(&(*vi));
if ((!vi->IsD())&&((*vi).stopped)&&(!vi->blocked))
V_Stopped.push_back(&(*vi));
}
P_Faces.clear();
MyTriMesh::FaceIterator fi;
for (fi=m.face.begin();fi<m.face.end();fi++)
{
//if ((!fi->IsBlocked()))
if ((!fi->IsD())&&(!fi->IsBlocked()))
P_Faces.push_back(&(*fi));
}
}
///erase the stopped entities from the partial containers
void Refresh_PVectors()
{
Part_FaceContainer P_FacesAux;
Part_VertexContainer P_VertexAux;
P_FacesAux.clear();
P_VertexAux.clear();
int i=0;
for (i=0;i<P_Vertex.size();i++)
{
if (!P_Vertex[i]->blocked)
P_VertexAux.push_back(P_Vertex[i]);
}
for (i=0;i<P_Faces.size();i++)
{
if (!P_Faces[i]->IsBlocked())
P_FacesAux.push_back(P_Faces[i]);
}
P_Faces.clear();
P_Vertex.clear();
P_Faces=P_FacesAux;
P_Vertex=P_VertexAux;
}
///add the new elements on partial vectors when allocate space for new vertices
void AddNewElements(MyTriMesh::VertexIterator vi,MyTriMesh::FaceIterator fi)
{
while (vi!=m.vert.end())
{
if (!(*vi).IsD())
P_Vertex.push_back(&(*vi));
vi++;
}
while (fi!=m.face.end())
{
if (!(*fi).IsD())
P_Faces.push_back(&(*fi));
fi++;
}
}
///verify and eventually stop the vertices of the mesh
void VerifyForces()
{
float proj;
Part_VertexContainer::iterator vi;
for (vi=P_Vertex.begin();vi<P_Vertex.end();++vi)
{
if (!IsStopped(&*vi))
{
MyTriMesh::CoordType accn=(*vi).Acc();
proj=accn*(*vi).N();
if ((proj)<=0)
SetStopped(&*vi);
}
}
}
bool TimeReinit()
{
static clock_t time=0;
clock_t elapsedsecs=abs(time-clock());
if (elapsedsecs>interval_reinit)
{
time=clock();
return true;
}
return false;
}
bool TimeSelfIntersection()
{
static clock_t time=0;
clock_t elapsedsecs=abs(time-clock());
if (elapsedsecs>interval_selfcollision)
{
time=clock();
return true;
}
return false;
}
///refine the mesh and re-update eventually
void RefineStep(float _edge_size)
{
MyTriMesh::VertexIterator vinit=m.vert.begin();
MyTriMesh::FaceIterator finit=m.face.begin();
MyTriMesh::VertexIterator vend=m.vert.end();
MyTriMesh::FaceIterator fend=m.face.end();
refined=vcg::Refine(m,MidPoint<MyTriMesh>(),_edge_size);
if (refined)
{
MyTriMesh::VertexIterator vinit2=m.vert.begin();
MyTriMesh::FaceIterator finit2=m.face.begin();
if ((vinit2!=vinit)||(finit2!=finit))
Reinit_PVectors();
else
AddNewElements(vend,fend);
vcg::tri::UpdateNormals<MyTriMesh>::PerVertexNormalized(m);
CollDet->RefreshElements();
}
}
///reset vertex position and unblock them
void ReinitPhysicMesh()
{
Part_FaceContainer::iterator pfi;
for (pfi=P_Faces.begin();pfi<P_Faces.end();++pfi)
(*pfi).Init(k_elanst,mass,k_dihedral);
/*for (MyTriMesh::VertexIterator vi=m.vert.begin();vi<m.vert.end();vi++)
ClearStopped(&*vi);*/
}
///clear the stopped vertex
void ClearStopped()
{
//for (MyTriMesh::VertexIterator vi=m.vert.begin();vi<m.vert.end();vi++)
// ClearStopped(&*vi);
Part_VertexContainer::iterator vi;
for (vi=V_Stopped.begin();vi<V_Stopped.end();++vi)
{
ClearStopped(&*vi);
}
V_Stopped.clear();
}
///do one step of controls for self collision detetction
void CollisionDetection()
{
CollDet->UpdateStep();
std::vector<MyFace*> coll=CollDet->computeSelfIntersection();
for (std::vector<MyFace*>::iterator it=coll.begin();it<coll.end();it++)
{
SetBlockedFace(*it);
SetIntersectedFace(*it);
}
}
public:
///set the initial barycenter where the triangle mesh start to expand
void SetInitialBarycenter(MyTriMesh::CoordType b)
{
InitialBarycenter=b;
gray_init=getColor(b);
InitMesh(m);
}
///set the input output directory of images
void LoadFromDir(char *in, char *out)
{
inDir=in;
outDir=out;
//caso optimized
/*V.Resample(inDir,outDir);
V.Init(1000,outDir);*/
V.Load(inDir);
bbox=vcg::Box3<float>(MapToSpace(V.Min()),MapToSpace(V.Max()));
}
///init the segmentation of the mesh
void InitSegmentation(int color,int tol,float Mass=0.5f,float K_elanst=0.2f,float Dihedral=0.2f,float Time_stamp=0.2f,
float Edge_precision=4.f,clock_t _interval=1000,clock_t _interval2=250,
MyTriMesh::CoordType ScaleFactor=MyTriMesh::CoordType(1.f,1.f,1.f) )
{
mass=Mass;
k_elanst=K_elanst;
tolerance=tol;
interval_reinit=_interval;
interval_selfcollision=_interval2;
edge_size=16.f;
edge_precision=Edge_precision;
time_stamp=Time_stamp;
k_dihedral=Dihedral;
scale=ScaleFactor;
TrINT= new myIntegrator(P_Faces,P_Vertex);
TrINT->SetPDESolver(PDESolvers::EULER_METHOD);
////caso optimized
///*V.Resample(inDir,outDir);
//V.Init(1000,outDir);*/
//V.Load(inDir);
//
/*bbox=vcg::Box3<float>(MapToSpace(V.Min()),MapToSpace(V.Max()));*/
//init the mesh with new
Reinit_PVectors();
ReinitPhysicMesh();
CollDet->Init(bbox.min,bbox.max,5.f);
}
///return the bounding box of the mesh
vcg::Box3<float> BBox()
{
return (bbox);
}
///one step of moving for the deformable object
void Step(float t,float _edge_size)
{
if (m.face.size()!=0)
{
AddExtForces();
TrINT->Step(t);
VerifyForces();
Refresh_PVectors();
if (end_loop)
{
RefineStep(_edge_size);
ReinitPhysicMesh();
ClearStopped();
}
if (TimeSelfIntersection())
CollisionDetection();
}
}
void Smooth()
{
ScaleLaplacianSmooth<MyTriMesh>(m,2,0.5);
}
void AutoStep()
{
refined=false;
Step(time_stamp,edge_size);
//test on 80% of the vertex blocked
if ((((float)P_Vertex.size()/(float)m.vn)<0.2)&&(end_loop)&&(!refined)&&(edge_size>edge_precision))
{
edge_size/=2.f;
if (edge_size<edge_precision)
edge_size=edge_precision;
time_stamp/=2.f;
}
}
};
#endif

View File

@ -0,0 +1,871 @@
<!DOCTYPE UI><UI version="3.3" stdsetdef="1">
<class>SegmentForm</class>
<widget class="QMainWindow">
<property name="name">
<cstring>SegmentForm</cstring>
</property>
<property name="geometry">
<rect>
<x>0</x>
<y>0</y>
<width>1232</width>
<height>981</height>
</rect>
</property>
<property name="caption">
<string>Segmentation</string>
</property>
<widget class="QButtonGroup">
<property name="name">
<cstring>buttonGroup1</cstring>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>0</y>
<width>1030</width>
<height>50</height>
</rect>
</property>
<property name="title">
<string></string>
</property>
<widget class="QPushButton">
<property name="name">
<cstring>SlidesButton</cstring>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>10</y>
<width>80</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Slides</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>ResultButton</cstring>
</property>
<property name="geometry">
<rect>
<x>740</x>
<y>10</y>
<width>110</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>ResultForces</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>InternalButton</cstring>
</property>
<property name="geometry">
<rect>
<x>590</x>
<y>10</y>
<width>110</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>InternalForces</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>ExternalButton</cstring>
</property>
<property name="geometry">
<rect>
<x>420</x>
<y>10</y>
<width>120</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>ExternalForces</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>BlockedButton</cstring>
</property>
<property name="geometry">
<rect>
<x>270</x>
<y>10</y>
<width>110</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>BlockedFaces</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>WireButton</cstring>
</property>
<property name="geometry">
<rect>
<x>130</x>
<y>10</y>
<width>100</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Wire</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
<property name="on">
<bool>true</bool>
</property>
<property name="default">
<bool>true</bool>
</property>
</widget>
</widget>
<widget class="QButtonGroup">
<property name="name">
<cstring>buttonGroup2</cstring>
</property>
<property name="geometry">
<rect>
<x>1040</x>
<y>0</y>
<width>191</width>
<height>930</height>
</rect>
</property>
<property name="title">
<string></string>
</property>
<widget class="QPushButton">
<property name="name">
<cstring>SaveButton</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>560</y>
<width>140</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>SavePly</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>SmoothButton</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>520</y>
<width>140</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="cursor">
<cursor>1</cursor>
</property>
<property name="text">
<string>Smooth</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>SegmentButton</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>480</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Extract</string>
</property>
<property name="toggleButton">
<bool>true</bool>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>Color</cstring>
</property>
<property name="enabled">
<bool>false</bool>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>390</y>
<width>70</width>
<height>30</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="frameShape">
<enum>LineEditPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
<property name="text">
<string></string>
</property>
<property name="cursorPosition">
<number>0</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_2_2_2_2</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>370</y>
<width>116</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>color</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>Tolerance</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>330</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>10</string>
</property>
<property name="cursorPosition">
<number>2</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_2_2_2</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>310</y>
<width>116</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>tolerance</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>E_size</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>270</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>4</string>
</property>
<property name="cursorPosition">
<number>1</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_2_2</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>250</y>
<width>116</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>minimum edge size</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>T_step</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>210</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>0.2</string>
</property>
<property name="cursorPosition">
<number>3</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_2</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>190</y>
<width>90</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>initial time step</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>D_angle</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>150</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>0.2</string>
</property>
<property name="cursorPosition">
<number>3</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_4</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>130</y>
<width>150</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>dihedral angle constant</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>K_elanst</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>90</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="frameShape">
<enum>LineEditPanel</enum>
</property>
<property name="frameShadow">
<enum>Sunken</enum>
</property>
<property name="text">
<string>0.2</string>
</property>
<property name="cursorPosition">
<number>3</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>70</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>spring constant</string>
</property>
</widget>
<widget class="QLineEdit">
<property name="name">
<cstring>M_particles</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>30</y>
<width>70</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="lineWidth">
<number>2</number>
</property>
<property name="text">
<string>0.5</string>
</property>
<property name="cursorPosition">
<number>3</number>
</property>
</widget>
<widget class="QLabel">
<property name="name">
<cstring>textLabel1_3</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>10</y>
<width>131</width>
<height>21</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>mass of particles</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>ApplyButton</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>440</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Apply</string>
</property>
</widget>
<widget class="QPushButton">
<property name="name">
<cstring>ClearButton</cstring>
</property>
<property name="geometry">
<rect>
<x>30</x>
<y>600</y>
<width>141</width>
<height>31</height>
</rect>
</property>
<property name="font">
<font>
<pointsize>10</pointsize>
</font>
</property>
<property name="text">
<string>Clear</string>
</property>
</widget>
</widget>
<widget class="SimpleGLWidget">
<property name="name">
<cstring>simpleGLWidget1</cstring>
</property>
<property name="geometry">
<rect>
<x>10</x>
<y>70</y>
<width>1030</width>
<height>880</height>
</rect>
</property>
</widget>
</widget>
<menubar>
<property name="name">
<cstring>MenuBar</cstring>
</property>
<item text="&amp;File" name="fileMenu">
<action name="fileOpenAction"/>
<action name="fileSaveAction"/>
<separator/>
<separator/>
<action name="fileExitAction"/>
</item>
</menubar>
<toolbars>
</toolbars>
<customwidgets>
<customwidget>
<class>SimpleGLWidget</class>
<header location="global">D:/sf/apps/test/segmentation3d/simpleglwidget.h</header>
<sizehint>
<width>-1</width>
<height>-1</height>
</sizehint>
<container>0</container>
<sizepolicy>
<hordata>5</hordata>
<verdata>5</verdata>
<horstretch>0</horstretch>
<verstretch>0</verstretch>
</sizepolicy>
<pixmap>image0</pixmap>
<slot access="public" specifier="">ShowSlides()</slot>
<slot access="public" specifier="">SetWire()</slot>
<slot access="public" specifier="">SetShowBlocked()</slot>
<slot access="public" specifier="">ShowExternalForces()</slot>
<slot access="public" specifier="">ShowInternalForces()</slot>
<slot access="public" specifier="">ShowResultForces()</slot>
<slot access="public" specifier="">Smooth()</slot>
<slot access="public" specifier="">SavePly()</slot>
<slot access="public" specifier="">Extract()</slot>
<slot access="public" specifier="">Apply()</slot>
<slot access="public" specifier="">Clear()</slot>
<slot access="public" specifier="">slot()</slot>
<slot access="public" specifier="">Open()</slot>
</customwidget>
</customwidgets>
<actions>
<action>
<property name="name">
<cstring>fileOpenAction</cstring>
</property>
<property name="on">
<bool>false</bool>
</property>
<property name="iconSet">
<iconset></iconset>
</property>
<property name="text">
<string>&amp;Open...</string>
</property>
<property name="menuText">
<string>&amp;Open...</string>
</property>
<property name="accel">
<string>Ctrl+O</string>
</property>
</action>
<action>
<property name="name">
<cstring>fileSaveAction</cstring>
</property>
<property name="iconSet">
<iconset></iconset>
</property>
<property name="text">
<string>Save</string>
</property>
<property name="menuText">
<string>&amp;Save</string>
</property>
<property name="accel">
<string>Ctrl+S</string>
</property>
</action>
<action>
<property name="name">
<cstring>Segmentation</cstring>
</property>
<property name="text">
<string>Save As</string>
</property>
<property name="menuText">
<string>Save &amp;As...</string>
</property>
<property name="accel">
<string></string>
</property>
</action>
<action>
<property name="name">
<cstring>fileExitAction</cstring>
</property>
<property name="text">
<string>Exit</string>
</property>
<property name="menuText">
<string>E&amp;xit</string>
</property>
<property name="accel">
<string></string>
</property>
</action>
<action>
<property name="name">
<cstring>fileOpennew_itemAction</cstring>
</property>
<property name="text">
<string>new item</string>
</property>
<property name="menuText">
<string>new item</string>
</property>
</action>
</actions>
<images>
<image name="image0">
<data format="PNG" length="1002">89504e470d0a1a0a0000000d4948445200000016000000160806000000c4b46c3b000003b149444154789cad94514c5b5518c77fe7dc4b7b4b6150bb96324418ca32358bee6192609c51d883892ce083f1718b3ebb185f8dc91e972cf39d2d6a78d0b027b3cd07d9e68c81c625a6c139408a4384f416100aed6d4b7bdb7b8e0fc0921a70c6ed7b3ae7e43bbff3fffedfc927e2f138bbd1dbdbab7902118fc785d8058f8d8de9aeae2e72b91cb66de338ce7f82e47239666767492412b8aefbf0dcdc553a323242f4501d918e2d3a8f15a9784584100809a609526eafd1a0f54e6142e029c5c21f3ef41583bb77a805efbe1ce9d86279e32619678eaab7853fa0f02a16abb64166ad0cdac75307eb3874b84cb0a14aa5a24108cc0688c48c9a4a1e826ddbe6f0b12219678e8ace610502ccdfafe3f68d3c33bf6c01c59dcc209d472c4e0d35d2f3ba81d205d06005e4de60c77170bd2255af80150870f70e8c0eaf009260a349577714e913a4175d16925b5cbe50607931cc3b677c68ca28a5f7066f5b26f00760febec9e8f032a0e81b68a17fc0201415989647a9d8c4c498cbe8f05f5cff3a4d4bac8bfe210b290b35e01afd428257b1b875cd01aaf4bd1de5dd0fea688e1530ad1c1bab16b7af17393558cf997311c0e49bafd670d6258621f6576c9ab09a3248fe5ae6c08103f49f36517213d33070369bf8e2529ee9c90ceb2b2eef7f14617c2c48722a4b7226845143fa87622905ebeb6514253a9eb5084504a66950c88618bee0303d99217cb09e9ed71a09369538fa523d00e9a50a42eed3bc6d8f41281fa0903e8561796cac86f8f2b33c33930ea0f0fb4d5adbeb30ad22866ffbbad226d2a805d7ee0484220208925aaa50deaa67e27b97e9c90ccdcdf5c462cdd8a94d2e7e62f3603244ea410989a4ed191f52a8fd156b056d9d553a9e0bf0e7ef45c6bf7339fd5e90ec7a88575e6d20d6e6e7e2a755ec854dce7fb8885b2cd014f6f3c2714d3a550bae55ac35c1068fb7061b00b87a7995899b25ce9e0b73e24d8fae97b37c7cbe9370b499fce6066eb54adf6098f6ee2a9a7ff9c70841a5023d270deca510d746537c7e29cdf8ad20475fb4307c82d4fc324ec6859d66fdfc6381e44014b36e9fe6e572393ca54068aa22cfd0598b686b3737aeae90bc9725796f0350802414b6e81b7c9a9f7e70708a2e6e5991cfeee3f1ecec2c0b0b3e8c068142a2a8d23728397132c6dc6f2e2b8b0a8da4b5ddc7f3c735ed47146f0cb4502983693a4c25ca7b83138904fa8a412466e00f48b4271086c2901263676c4a6990b615b6ade15b85694af239984a94585bf6f606bbae5b334f1f37e4a3531e031c8fc7c5a312ff17f849c3e3f1b8f81b8be6900aca9b61c90000000049454e44ae426082</data>
</image>
</images>
<connections>
<connection>
<sender>SlidesButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>ShowSlides()</slot>
</connection>
<connection>
<sender>WireButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>SetWire()</slot>
</connection>
<connection>
<sender>BlockedButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>SetShowBlocked()</slot>
</connection>
<connection>
<sender>ExternalButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>ShowExternalForces()</slot>
</connection>
<connection>
<sender>InternalButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>ShowInternalForces()</slot>
</connection>
<connection>
<sender>ResultButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>ShowResultForces()</slot>
</connection>
<connection>
<sender>SaveButton</sender>
<signal>clicked()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>SavePly()</slot>
</connection>
<connection>
<sender>SmoothButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>Smooth()</slot>
</connection>
<connection>
<sender>SegmentButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>Extract()</slot>
</connection>
<connection>
<sender>ApplyButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>Apply()</slot>
</connection>
<connection>
<sender>ClearButton</sender>
<signal>pressed()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>Clear()</slot>
</connection>
<connection>
<sender>fileOpenAction</sender>
<signal>activated()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>Open()</slot>
</connection>
<connection>
<sender>fileSaveAction</sender>
<signal>activated()</signal>
<receiver>simpleGLWidget1</receiver>
<slot>SavePly()</slot>
</connection>
</connections>
<pixmapinproject/>
<layoutdefaults spacing="6" margin="11"/>
<includehints>
<includehint>simpleglwidget.h</includehint>
</includehints>
</UI>

View File

@ -0,0 +1,418 @@
#include <SimpleGLWidget.h>
#include <qlineedit.h>
#include <qfiledialog.h>
#include <qdir.h>
#include <qmessagebox.h>
extern Segmentator *s;
SimpleGLWidget::SimpleGLWidget( QWidget * parent, const char * name, const QGLWidget * shareWidget, WFlags f ):
QGLWidget(parent, name)
{
///grabKeyboard();
_showslides=false;
blocked=false;
wire=true;
extForces=false;
intForces=false;
resultForces=false;
continue_int=false;
_numslide=0;
Track.center=Point3f(0,0,0);
Track.Reset();
Track.radius= 100;
zoom=1;
}
void SimpleGLWidget::SaveMatrix()
{
glGetDoublev(GL_PROJECTION_MATRIX ,projection);
glGetDoublev(GL_MODELVIEW_MATRIX ,modelMatrix);
glGetIntegerv(GL_VIEWPORT,viewport);
}
void SimpleGLWidget::LoadMatrix()
{
glMatrixMode(GL_PROJECTION);
glLoadMatrixd(projection);
glMatrixMode(GL_MODELVIEW);
glLoadMatrixd(modelMatrix);
}
void SimpleGLWidget::drawSlide()
{
glBegin(GL_QUADS);
for (int x=0;x<((s->V.dimX())-1);x++)
for (int y=0;y<((s->V.dimY())-1);y++)
{
glNormal(Point3d(0,0,1));
Point3<int> p0=Point3<int>(x,y,_numslide);
double color=((double)s->V.getAt(p0))/256.f;
glColor3d(color,color,color);
glVertex(p0);
Point3<int> p1=Point3<int>(x+1,y,_numslide);
color=((double)s->V.getAt(p1))/256.f;
glColor3d(color,color,color);
glVertex(p1);
Point3<int> p2=Point3<int>(x+1,y+1,_numslide);
color=((double)s->V.getAt(p2))/256.f;
glColor3d(color,color,color);
glVertex(p2);
Point3<int> p3=Point3<int>(x,y+1,_numslide);
color=((double)s->V.getAt(p3))/256.f;
glColor3d(color,color,color);
glVertex(p3);
}
glEnd();
}
void drawForces(Segmentator::Part_VertexContainer *pv,int typeForce)
{
Segmentator::Part_VertexContainer::iterator vi;
glPushAttrib(GL_ALL_ATTRIB_BITS);
glLineWidth(0.3);
glDisable(GL_NORMALIZE);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
if (typeForce==0)
glColor3d(1,0,0);
else
if (typeForce==1)
glColor3d(0,0,1);
else
if (typeForce==2)
glColor3d(0,1,0);
for (vi=pv->begin();vi<pv->end();vi++)
{
glBegin(GL_LINE_LOOP);
vcg::glVertex((*vi).P());
if (typeForce==0)
vcg::glVertex((*vi).P()+((*vi).IntForce()*4.f));
else
if (typeForce==1)
vcg::glVertex((*vi).P()+((*vi).ExtForce()*4.f));
else
if (typeForce==2)
vcg::glVertex((*vi).P()+(((*vi).ExtForce()+(*vi).IntForce())*4.f));
glEnd();
}
glPopAttrib();
}
void SimpleGLWidget::Save()
{
QString filename = QFileDialog::getSaveFileName("prova.ply",
"Ply files (*.ply)",
this,
"save file dialog",
"Choose a filename to save under" );
if (filename!=NULL)
{
const char *path=filename.ascii();
vcg::tri::io::ExporterPLY<Segmentator::MyTriMesh>::Save(s->m,path);
}
}
bool TimeSelfIntersection()
{
static clock_t time=0;
clock_t elapsedsecs=abs(time-clock());
if (elapsedsecs>500)
{
time=clock();
return true;
}
return false;
}
//void SimpleGLWidget::WriteInfo()
//{
//
// if (s!=0)
// {
//
// glPushAttrib(0xffffffff);
//
// glEnable(GL_BLEND);
// glBlendFunc(GL_SRC_ALPHA, GL_SRC_ALPHA);
// glEnable(GL_LIGHTING);
// glEnable(GL_NORMALIZE);
// glEnable(GL_COLOR_MATERIAL);
// glDisable(GL_CLIP_PLANE0);
// glColor4d(0.7,0,0.7,0.6);
//
// glDepthRange(0.0,0.1);
//
// glBegin(GL_QUADS);
// glVertex3d(-0.5,-0.5,0);
// glVertex3d(-0.5,-0.3,0);
// glVertex3d(0.5,-0.3,0);
// glVertex3d(0.5,-0.5,0);
// glEnd();
//
// renderText( (width() - 10) / 2, 15, "a" );
//
// QFont f( "arial", 12 );
// QFontMetrics fmc( f );
// glColor3d(1,1,1);
//
// QString str="";
// int level=0;
//
// glDisable( GL_LIGHTING );
// glDisable( GL_TEXTURE_2D );
//
// level++;
// str.sprintf( "Triangles : %i Vertex: %i ",s->m.fn,s->m.vn);
// renderText( 20, height() - level*20, str, f );
// }
//}
void SimpleGLWidget::SmoothMesh()
{
s->Smooth();
}
void SimpleGLWidget::glDraw(){
glClearColor(0.2,0.2,0.2,1);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(45,1,0.01,20);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(0,0,1,0,0,0,0,10,0);
if (s!=0){
glPushMatrix();
if (_showslides)
{
vcg::Point3f p=Point3f((float)s->BBox().Center().V(0),(float)s->BBox().Center().V(1),(float)s->BBox().Center().V(2));
Track.radius=s->BBox().Diag();
Track.GetView();
Track.Apply();
Track.Draw();
glScalef(1/s->BBox().Diag(),1/s->BBox().Diag(),1/s->BBox().Diag());
glScalef(GLfloat(zoom),GLfloat(zoom),GLfloat(zoom));
glTranslate(-p);
//save transformation matrixes
SaveMatrix();
}
else
{
vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(s->m);
vcg::Point3f p=s->m.bbox.Center();
Track.radius=s->m.bbox.Diag();
Track.GetView();
Track.Apply();
Track.Draw();
glScalef(1/s->m.bbox.Diag(),1/s->m.bbox.Diag(),1/s->m.bbox.Diag());
glScalef(GLfloat(zoom),GLfloat(zoom),GLfloat(zoom));
glTranslate(-p);
}
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
if (_showslides)
drawSlide();
if (intForces)
drawForces(&s->P_Vertex,0);
if (extForces)
drawForces(&s->P_Vertex,1);
if (resultForces)
drawForces(&s->P_Vertex,2);
//draw faces
glEnable(GL_NORMALIZE);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glEnable(GL_COLOR_MATERIAL);
Segmentator::MyTriMesh::FaceIterator fi;
if (wire)
{
glDisable(GL_NORMALIZE);
glDisable(GL_LIGHTING);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
}
else
glPolygonMode(GL_FRONT,GL_FILL);
int i=0;
glBegin(GL_TRIANGLES);
for (fi=s->m.face.begin();fi<s->m.face.end();fi++)
{
glColor3d(0.4,0.8,0.8);
if (fi->intersected)
glColor3d(1.f,0,0);
if (((blocked)&&(!fi->IsBlocked()))||(!blocked))
{
if (!wire)
vcg::glNormal(fi->Normal());
vcg::glVertex(fi->V(0)->P());
vcg::glVertex(fi->V(1)->P());
vcg::glVertex(fi->V(2)->P());
}
}
glEnd();
glPopMatrix();
//WriteInfo();
}
QGLWidget::glDraw();
}
///open the directiry and initialize dataset
void SimpleGLWidget::OpenDirectory()
{
QString filename = QFileDialog::getExistingDirectory(
".",
this,
"open file dialog"
"Choose a Directory" );
if (filename!=NULL)
{
const char *path=filename.ascii();
char *p=(char*)path;
s->LoadFromDir(p,"prova.txt");
}
}
void SimpleGLWidget::resizeGL( int w, int h )
{
// setup viewport, projection etc.:
glMatrixMode (GL_PROJECTION);
glLoadIdentity ();
float ratio=(float)w/(float)h;
gluPerspective(45,ratio,1,20);
_W=w;
_H=h;
glViewport (0, 0, (GLsizei) w, (GLsizei) h);
glMatrixMode (GL_MODELVIEW);
repaint();
}
void SimpleGLWidget::ClearMesh()
{
s->m.Clear();
repaint();
}
void SimpleGLWidget::mousePressEvent ( QMouseEvent * e )
{
if (e->button()==Qt::LeftButton )
Track.MouseDown(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
else
//test mass spring model
if ((e->button()==Qt::RightButton)&&(_showslides))
{
float winz;
double x;
double y;
double z;
//LoadMatrix();
glReadPixels(e->x(),_H-e->y(),1,1,GL_DEPTH_COMPONENT,GL_FLOAT,&winz);
gluUnProject(e->x(),_H-e->y(),winz,modelMatrix,projection,viewport,&x,&y,&z);
s->SetInitialBarycenter(Point3f(x,y,_numslide));
QString color="";
color.sprintf("%i",s->gray_init);
//w->Color->text()=color;
SetExtractionParameters();
repaint();
}
//vcg::tri::UpdateBounding<Segmentator::MyTriMesh>::Box(s->m);
}
void SimpleGLWidget::wheelEvent(QWheelEvent *e)
{
if (!_showslides)
{
zoom+=e->delta()/120.f;
repaint();
}
else
{
int oldnum=_numslide;
_numslide+=e->delta()/120.f;
if ((_numslide<0)||(_numslide>=s->V.dimZ()))
_numslide=oldnum;
}
repaint();
}
void SimpleGLWidget::mouseReleaseEvent(QMouseEvent * e )
{
Track.MouseUp(e->x(),_H-e->y(),vcg::Trackball::BUTTON_LEFT);
repaint();
}
void SimpleGLWidget::Step()
{
if ((s!=0)&&(continue_int))
{
s->AutoStep();
repaint();
}
}
void SimpleGLWidget::SetExtractionParameters()
{
float mass=atof(w->M_particles->text());
float k_elanst=atof(w->K_elanst->text());
float dihedral=atof(w->D_angle->text());
float timestep=atof(w->T_step->text());
float edge=atof(w->E_size->text());
float tolerance=atof(w->Tolerance->text());
//int color =atoi(w->Color->text());
///to modify
s->InitSegmentation(s->gray_init,tolerance,mass,k_elanst,dihedral,timestep,edge);
}
void SimpleGLWidget::mouseMoveEvent ( QMouseEvent * e )
{
Track.MouseMove(e->x(),_H-e->y());
repaint();
}
void SimpleGLWidget::initializeGL(){
GLfloat f[4]={0.2,0.2,0.2,1.f};
GLfloat p[4]={3,3,5,0};
glLightfv(GL_LIGHT0, GL_AMBIENT,f);
glLightfv(GL_LIGHT1, GL_POSITION,p);
glLightfv(GL_LIGHT1, GL_DIFFUSE,f);
glLightfv(GL_LIGHT1, GL_SPECULAR,f);
glEnable(GL_LIGHT0);
glEnable(GL_LIGHT1);
glEnable(GL_LIGHTING);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LESS);
glPolygonMode(GL_FRONT,GL_FILL);
glEnable(GL_BACK);
glCullFace(GL_BACK);
}

View File

@ -0,0 +1,135 @@
#include <GL\glew.h>
#include <qgl.h>
#include <wrap\gl\trimesh.h>
#include <wrap\gui\trackball.h>
#include <segmentator.h>
#include <sim/tri_pde_integrator.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <vcg/complex/trimesh/update/bounding.h>
#include <wrap/io_trimesh/export_ply.h>
#include <segmentform.h>
class SimpleGLWidget: public QGLWidget{
Q_OBJECT
private :
int _H;
int _W;
vcg::Trackball Track;
double zoom;
GLdouble projection[16];
GLdouble modelMatrix[16];
GLint viewport[4];
bool _showslides;
int _numslide;
bool wire;
bool blocked;
bool extForces;
bool intForces;
bool resultForces;
bool continue_int;
//vcg::GlTrimesh<Segmentator::MyTriMesh> *Wrap;
public:
SegmentForm *w;
SimpleGLWidget( QWidget * parent = 0, const char * name = 0, const QGLWidget * shareWidget = 0, WFlags f = 0 );
virtual void glDraw();
//virtual void paintEvent ( QPaintEvent * ) ;
void resizeGL( int w, int h );
virtual void mousePressEvent ( QMouseEvent * e );
virtual void mouseReleaseEvent(QMouseEvent * e );
virtual void mouseMoveEvent ( QMouseEvent * e );
virtual void wheelEvent ( QWheelEvent * e );
//virtual void keyPressEvent(QKeyEvent *k);
virtual void initializeGL();
virtual void SaveMatrix();
virtual void Save();
void LoadMatrix();
void drawSlide();
void SmoothMesh();
void Step();
void SetExtractionParameters();
void WriteInfo();
void ClearMesh();
void OpenDirectory();
//virtual void keyPressEvent(QKeyEvent *qk);
public slots:
void Open()
{
OpenDirectory();
}
void ShowSlides()
{
_showslides=!_showslides;
repaint();
}
void SetWire()
{
wire=!wire;
repaint();
}
void SetShowBlocked()
{
blocked=!blocked;
repaint();
}
void ShowExternalForces()
{
extForces=!extForces;
repaint();
}
void ShowInternalForces()
{
intForces=!intForces;
repaint();
}
void ShowResultForces()
{
resultForces=!resultForces;
repaint();
}
void Smooth()
{
SmoothMesh();
repaint();
}
void SavePly()
{
Save();
}
void Apply()
{
SetExtractionParameters();
}
void Extract()
{
continue_int=!continue_int;
}
void Update()
{
Step();
}
void Clear()
{
ClearMesh();
}
};

View File

@ -0,0 +1,489 @@
#include <qimage.h>
#include <qdir.h>
#include <qcolor.h>
#include <stdio.h>
#include <list>
#include <algorithm>
#define LimX 512
#define LimY 512
#define LimZ 240
#define dimXCell 20
#define dimYCell 20
#define dimZCell 20
#define TLBx 30
#define TLBy 30
#define TLBz 30
template <class ScalarType>
class Volume_Dataset_Optimized{
public:
Volume_Dataset_Optimized(){pFile=0;};
~Volume_Dataset_Optimized(){};
private:
class Cell
{
public:
void Clear()
{
for (int i=0;i<dimZCell;i++)
for (int j=0;j<dimYCell;j++)
for (int k=0;k<dimXCell;k++)
Data[i][j][k]=0;
}
ScalarType Data[dimXCell][dimYCell][dimZCell] ;
///operatorn to perform sorting
inline bool operator <(const Cell &c)
{
return (c.timestamp>timestamp);
}
///operatorn to perform sorting
inline bool operator ==(const Cell &c)
{
return (c.timestamp==timestamp);
}
Point3i index;
int timestamp;
};
typedef typename std::list<Cell> StackType;
typedef typename StackType::iterator IteStack;
///the class of grid of iterator to stack structure (corrispondence grid - stack)
struct TLBelem
{
private:
IteStack StackPoint;
public:
inline IteStack & I()
{
return StackPoint;
}
bool inMem;
};
FILE * pFile;
StackType CurrStack;
TLBelem TLB[TLBx][TLBy][TLBz];
Cell buffer[TLBx][TLBy] ;
int n_element;
int max_element;
int timestamp;
int lx;
int ly;
int lz;
int TLBdx;
int TLBdy;
int TLBdz;
int timesort;
void SortStack()
{
/*std::sort<Cell>(CurrStack.begin(),CurrStack.end());
timestamp=0;
for (IteStack i=CurrStack.begin();i!=CurrStack.end();i++)
(*i).timestamp=0;*/
}
///allocate momory for the buffer
void InitBuffer(Cell _buffer[TLBx][TLBy])
{
for (int j=0;j<TLBy;j++)
for (int i=0;i<TLBx;i++)
_buffer[i][j].Clear();
}
///set total size of the dataset
void Resize(int _lx,int _ly,int _lz)
{
lx=_lx;
ly=_ly;
lz=_lz;
TLBdx=ceil(((float)_lx)/((float)dimXCell));
TLBdy=ceil(((float)_ly)/((float)dimYCell));
TLBdz=ceil(((float)_lz)/((float)dimZCell));
}
///return a pair made by cell coordinate an coordinate relative to the cell
std::pair<vcg::Point3i,vcg::Point3i> GetCoordinate(int x,int y, int z)
{
int xd=(int) x/dimXCell;
int yd=(int) y/dimYCell;
int zd=(int) z/dimZCell;
int xx= x%dimXCell;
int yy= y%dimYCell;
int zz= z%dimZCell;
return (std::pair<vcg::Point3i,vcg::Point3i> (Point3i(xd,yd,zd),Point3i(xx,yy,zz)));
}
///add an element to the structure
void Add(Cell _buffer[TLBx][TLBy],int x, int y, int z, ScalarType value)
{
assert(value<256);
std::pair<vcg::Point3i,vcg::Point3i> coords=GetCoordinate(x,y,z);
Point3i cell=coords.first;
Point3i inter=coords.second;
_buffer[cell.V(0)][cell.V(1)].Data[inter.V(0)][inter.V(1)][inter.V(2)]=value;
}
///store a cell in the file
void SaveCell(Cell &cell)
{
int size_unit=sizeof( ScalarType );
int dim=dimXCell*dimYCell*dimZCell;
int numwritten = fwrite(cell.Data, size_unit,dim,pFile );
}
///save to file the current buffer
void SwapBuffer(Cell _buffer[TLBx][TLBy])
{
for (int x=0;x<TLBdx;x++)
for (int y=0;y<TLBdy;y++)
SaveCell(_buffer[x][y]);
}
///load a cell from file
Cell& loadFromFile(Point3i p)
{
if (pFile!=0)
{
//8 for the 2 initial integer that describe the data set
/*long offset=2*sizeof( ScalarType );*/
long sizeCell=dimXCell*dimYCell*dimZCell;
long offset=0;
int index=(p.V(2)*TLBdx*TLBdy)+(p.V(1)*TLBdx)+p.V(0);
offset+=sizeCell*(index)*sizeof( ScalarType );
fseek(pFile,offset,SEEK_SET);
Cell c;
fread(c.Data, sizeof( ScalarType ),dimXCell*dimYCell*dimZCell,pFile);
//assert(!ControlCell(c));
c.index=p;
return c;
}
}
///funtion used to control correct values of a cell use only for debbugging
bool ControlCell(Cell &c)
{
for (int i=0;i<dimXCell;i++)
for (int j=0;j<dimYCell;j++)
for (int k=0;k<dimZCell;k++)
if (c.Data[i][j][k]>=256)
return true;
return false;
}
public:
///build and save the strucure made fo blocks
void Resample(char *path,char *_newFile)
{
pFile=fopen (_newFile,"w+b");
//std::vector<Cell> buffer;
/*Cell buffer[TLBx][TLBy] ;*/
//load first one image to see dimensions
QImage qI=QImage();
QDir Qd=QDir(path);
QString qformat;
QString Path=QString(path);
Qd.setNameFilter("*.jpg");
int levels=Qd.count();
Qd.setSorting(QDir::Name);
QString PathFile=Path;
if (PathFile.right(1)!="/")
PathFile.append("/");
PathFile.append(Qd[0]);
bool b=qI.load(PathFile,qformat);
Resize(qI.width(),qI.height(),levels);
InitBuffer(buffer);
for (int z=0;z<levels; z++)
{
PathFile=Path;
PathFile.append(Qd[z]);
qformat=qI.imageFormat(PathFile);
bool gray=qI.allGray();
b=qI.load(PathFile,qformat);
//first time I set limits of scalar field
for (int x=0;x<qI.width();x++)
for (int y=0;y<qI.height();y++)
{
QRgb color=qI.pixel(x,y);
if (gray)//all tree component are the same
Add(buffer,x,y,z,qRed (color));
else ///otherwise transform
Add(buffer,x,y,z,qGray (color));
}
//if they are the last i swap the buffer
if (((z%dimZCell)==(dimZCell-1))||(z==levels-1))
{
SwapBuffer(buffer);
InitBuffer(buffer);
}
}
fclose(pFile);
pFile=0;
}
///set initial size of buffer in terms of cell
void Init(int size,char* archive,int timeSort=3000)
{
timestamp=0;
n_element=0;
max_element=size;
CurrStack.clear();
pFile=fopen (archive,"r+b");
timestamp=0;
for(int z=0;z<TLBz;z++)
for(int x=0;x<TLBx;x++)
for(int y=0;y<TLBy;y++)
TLB[x][y][z].inMem=false;
}
///control if i must sort the buffer
bool TimeSort()
{
static clock_t time;
clock_t elapsedsecs=abs(time-clock());
if (elapsedsecs>timesort)
{
time=clock();
return true;
}
return false;
}
inline Point3i Min()//to change in case of difefrent space between sections
{return Point3i(0,0,0);}
inline Point3i Max()//to change in case of difefrent space between sections
{return Point3i(lx,ly,lz);}
///return the x dimension of the dataset
inline int dimX()
{return lx;}
///return the y dimension of the dataset
inline int dimY()
{return ly;}
///return the z dimension of the dataset
inline int dimZ()
{return lz;}
///return the lenght of the diagonal
inline float Diag()
{
Point3f diag=Point3f((float) _X,(float) _Y,(float) _Z);
return (diag.Norm());
}
/////erase the element not used for long time
//void EraseLastUsed()
//{
// if (TimeSort())
// SortStack();
// int mint=TLB[0][0][0].timestamp;
// Point3i minElem=Point3i(0,0,0);
// for(int z=0;z<TLBdz;z++)
// for(int x=0;x<TLBdx;x++)
// for(int y=0;y<TLBdy;y++)
// {
// if ((TLB[x][y][z].timestamp<mint)&&(TLB[x][y][z].inMem==true))
// {
// mint=TLB[x][y][z].timestamp;
// minElem=Point3i(x,y,z);
// }
// }
// TLB[minElem.V(0)][minElem.V(1)][minElem.V(2)].inMem=false;
// IteStack ite=TLB[minElem.V(0)][minElem.V(1)][minElem.V(2)].I();
// CurrStack.erase(ite);
//}
///return the value of the element in position point3i(i0,i1,i2)
ScalarType getAt(Point3i p)
{
assert ((p.V(0)<dimX())&&(p.V(1)<dimY())&&(p.V(2)<dimZ()));
assert ((p.V(0)>=0)&&(p.V(1)>=0)&&(p.V(2)>=0));
std::pair<vcg::Point3i,vcg::Point3i> co=GetCoordinate(p.V(0),p.V(1),p.V(2));
Point3i cell=co.first;
Point3i inter=co.second;
TLBelem e=TLB[cell.V(0)][cell.V(1)][cell.V(2)];
if (e.inMem)///the element is in the buffer
{
IteStack i=e.I();
ScalarType ret=(*i).Data[inter.V(1)][inter.V(0)][inter.V(2)];
timestamp++;
(*i).timestamp=timestamp;
return (ret);
}
else///element fault, must load from file ///
{
//insert new element in the TLB table
Cell c=loadFromFile(cell);
CurrStack.push_front(c);
TLB[cell.V(0)][cell.V(1)][cell.V(2)].I()=CurrStack.begin();
TLB[cell.V(0)][cell.V(1)][cell.V(2)].inMem=true;
(*CurrStack.begin()).timestamp=timestamp;
n_element++;
///if the number of element is the meximum , then erase one with second chanche algorithm
if (n_element>=max_element)
{
if (TimeSort())
SortStack();
CurrStack.pop_back();
n_element--;
}
ScalarType ret=(*CurrStack.begin()).Data[inter.V(1)][inter.V(0)][inter.V(2)];
return ret;
}
}
};
template <class ScalarType>
class Volume_Dataset{
public:
Volume_Dataset(){};
~Volume_Dataset(){};
ScalarType Data[LimX][LimY][LimZ] ;
int lx;
int ly;
int lz;
///set total size of the dataset
void Resize(int _lx,int _ly,int _lz)
{
lx=_lx;
ly=_ly;
lz=_lz;
}
public:
///build and save the strucure made fo blocks
void Load(char *path)
{
//load first one image to see dimensions
QImage qI=QImage();
QDir Qd=QDir(path);
QString qformat;
QString Path=QString(path);
Qd.setNameFilter("*.jpg");
int levels=Qd.count();
Qd.setSorting(QDir::Name);
QString PathFile=Path;
if (PathFile.right(1)!="/")
PathFile.append("/");
PathFile.append(Qd[0]);
bool b=qI.load(PathFile,qformat);
Resize(qI.width(),qI.height(),levels);
for (int z=0;z<levels; z++)
{
PathFile=Path;
PathFile.append(Qd[z]);
qformat=qI.imageFormat(PathFile);
bool gray=qI.allGray();
b=qI.load(PathFile,qformat);
//first time I set limits of scalar field
for (int x=0;x<qI.width();x++)
for (int y=0;y<qI.height();y++)
{
QRgb color=qI.pixel(x,y);
if (gray)//all tree component are the same
Data[x][y][z]=qRed (color);
else ///otherwise transform
Data[x][y][z]=qGray (color);
}
}
}
inline Point3i Min()//to change in case of difefrent space between sections
{return Point3i(0,0,0);}
inline Point3i Max()//to change in case of different space between sections
{return Point3i(lx,ly,lz);}
///return the x dimension of the dataset
inline int dimX()
{return lx;}
///return the y dimension of the dataset
inline int dimY()
{return ly;}
///return the z dimension of the dataset
inline int dimZ()
{return lz;}
///return the lenght of the diagonal
inline float Diag()
{
Point3f diag=Point3f((float) _X,(float) _Y,(float) _Z);
return (diag.Norm());
}
///return the value of the element in position point3i(i0,i1,i2)
ScalarType getAt(Point3i p)
{
assert ((p.V(0)<dimX())&&(p.V(1)<dimY())&&(p.V(2)<dimZ()));
assert ((p.V(0)>=0)&&(p.V(1)>=0)&&(p.V(2)>=0));
return (Data[p.V(0)][p.V(1)][p.V(2)]);
}
};