first release version
This commit is contained in:
parent
409ceaf11f
commit
7c59d90735
|
@ -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
|
|
@ -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();
|
||||||
|
}
|
|
@ -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
|
|
@ -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
|
|
@ -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
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -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
|
|
@ -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="&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>&Open...</string>
|
||||||
|
</property>
|
||||||
|
<property name="menuText">
|
||||||
|
<string>&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>&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 &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&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>
|
|
@ -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);
|
||||||
|
|
||||||
|
}
|
|
@ -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();
|
||||||
|
}
|
||||||
|
};
|
|
@ -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)]);
|
||||||
|
}
|
||||||
|
|
||||||
|
};
|
Loading…
Reference in New Issue