Commit 9ec64050 authored by Sylvain Thery's avatar Sylvain Thery

Merge cgogn:~untereiner/CGoGN

parents fb9c7943 c6ed99c2
This diff is collapsed.
......@@ -194,7 +194,12 @@ void MyQT::createMap(int n)
m_render_topo->setDartWidth(4.0f);
m_render_topo->setInitialDartsColor(0.0f,0.0f,0.0f);
m_render_topo->setInitialBoundaryDartsColor(0.0f,0.0f,0.0f);
m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f,true); // nb
#ifdef PRIMAL_TOPO
m_render_topo->updateData<PFP>(myMap, position, 0.9);
#else
m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f,true);
#endif
for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d))
{
......@@ -213,7 +218,12 @@ void MyQT::createMap(int n)
void MyQT::updateMap()
{
m_render_topo->setInitialBoundaryDartsColor(0.0f,0.0f,0.0f);
m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f,true); // nb
#ifdef PRIMAL_TOPO
m_render_topo->updateData<PFP>(myMap, position, 0.9);
#else
m_render_topo->updateData<PFP>(myMap, position, 0.9f, 0.9f,true);
#endif
for (Dart d=myMap.begin(); d!=myMap.end(); myMap.next(d))
{
if (dm.isMarked(d) && (!myMap.isBoundaryMarked2(d)))
......@@ -229,7 +239,11 @@ void MyQT::updateMap()
void MyQT::cb_initGL()
{
glClearColor(1.0f,1.0f,1.0f,1.0f);
m_render_topo = new Algo::Render::GL2::TopoRender(0.01f) ;
#ifdef PRIMAL_TOPO
m_render_topo = new Algo::Render::GL2::TopoPrimalRender() ;
#else
m_render_topo = new Algo::Render::GL2::TopoRender(0.01f) ;
#endif
}
// redraw GL callback (clear and swap already done)
......
......@@ -27,6 +27,7 @@
//#define USE_GMAP
//#define PRIMAL_TOPO 1
#include "Topology/generic/parameters.h"
......@@ -36,8 +37,11 @@
#include "Topology/map/embeddedMap2.h"
#endif
#include "Algo/Render/GL2/topoRender.h"
#ifdef PRIMAL_TOPO
#include "Algo/Render/GL2/topoPrimalRender.h"
#else
#include "Algo/Render/GL2/topoRender.h"
#endif
#include "ui_tuto_oper2.h"
#include "Utils/Qt/qtui.h"
......@@ -88,7 +92,11 @@ protected:
DartAttribute<VEC3> colorDarts;
// render (for the topo)
Algo::Render::GL2::TopoRender* m_render_topo;
#ifdef PRIMAL_TOPO
Algo::Render::GL2::TopoPrimalRender* m_render_topo;
#else
Algo::Render::GL2::TopoRender* m_render_topo;
#endif
Dart m_selected;
Dart m_selected2;
DartMarker dm;
......
This diff is collapsed.
......@@ -27,6 +27,7 @@
//#define USE_GMAP
//#define PRIMAL_TOPO 1
#include "Topology/generic/parameters.h"
......@@ -36,7 +37,12 @@
#include "Topology/map/embeddedMap3.h"
#endif
#include "Algo/Render/GL2/topo3Render.h"
#ifdef PRIMAL_TOPO
#include "Algo/Render/GL2/topo3PrimalRender.h"
#else
#include "Algo/Render/GL2/topo3Render.h"
#endif
#include "Algo/Render/GL2/topoRender.h"
#include "Algo/Geometry/boundingbox.h"
......@@ -71,7 +77,7 @@ class MyQT: public Utils::QT::SimpleQT
{
Q_OBJECT
public:
MyQT():m_render_topo(NULL),m_selected(NIL),m_selected2(NIL),dm(myMap),m_shift(0.01f),m_ex1(0.9f),m_ex2(0.9f),m_ex3(0.9f), clip_volume(true) , hide_clipping(false) {}
MyQT():m_render_topo(NULL),m_selected(NIL),m_selected2(NIL),m_shift(0.01f),m_ex1(0.9f),m_ex2(0.9f),m_ex3(0.9f), clip_volume(true) , hide_clipping(false) {}
void cb_redraw();
void cb_initGL();
......@@ -95,12 +101,15 @@ protected:
Geom::BoundingBox<PFP::VEC3> bb;
// render (for the topo)
#ifdef PRIMAL_TOPO
Algo::Render::GL2::Topo3PrimalRender* m_render_topo;
#else
Algo::Render::GL2::Topo3Render* m_render_topo;
#endif
Algo::Render::GL2::TopoRender* m_render_topo_boundary;
Dart m_selected;
Dart m_selected2;
std::vector<Dart> m_selecteds;
DartMarker dm;
float m_shift;
float m_ex1, m_ex2, m_ex3;
......@@ -136,6 +145,7 @@ protected:
public:
// example of simple map creation
void createMap(int n);
void createMapTets();
void updateMap();
void importMesh(std::string& filename);
......
......@@ -150,6 +150,11 @@
<string>unsewVolumes</string>
</property>
</item>
<item>
<property name="text">
<string>deleteVolume</string>
</property>
</item>
</widget>
</item>
<item row="6" column="0">
......
......@@ -529,9 +529,11 @@ Dart flip1To3(typename PFP::MAP& map, Dart d)
edges.push_back(dit);
map.splitVolume(edges);
map.splitFace(map.phi1(map.phi2(edges[0])),map.phi1(map.phi2(edges[2])));
// Cut the 2nd Tetrahedron
map.splitFace(map.phi1(map.phi2(edges[0])),map.phi1(map.phi2(edges[2])));
// Cut the 3rd Tetrahedron
dit = map.phi1(map.phi2(edges[0]));
edges.clear();
edges.push_back(dit);
......
......@@ -50,10 +50,11 @@ namespace Masks
/* MJ96 basic functions : polyhedral meshes
*********************************************************************************/
template <typename PFP, typename EMBV, typename EMB>
template <typename PFP, typename EMBV>
class MJ96VertexVertexFunctor : public FunctorType
{
protected:
typedef typename EMBV::DATA_TYPE EMB;
typename PFP::MAP& m_map ;
EMBV& m_attribut;
//Algo::Volume::IHM::AttributeHandler_IHM<typename PFP::VEC3, VERTEX>& m_position ;
......@@ -118,7 +119,7 @@ public:
Traversor3VW<typename PFP::MAP> travVW(m_map, d);
for(Dart dit = travVW.begin() ; dit != travVW.end() ; dit = travVW.next())
{
Cavg += Algo::Surface::Geometry::volumeCentroidGen<PFP, EMBV, EMB>(m_map, dit, m_attribut);
Cavg += Algo::Surface::Geometry::volumeCentroid<PFP, EMBV>(m_map, dit, m_attribut);
++degree;
}
Cavg /= degree;
......@@ -128,7 +129,7 @@ public:
Traversor3VF<typename PFP::MAP> travVF(m_map, d);
for(Dart dit = travVF.begin() ; dit != travVF.end() ; dit = travVF.next())
{
Aavg += Algo::Surface::Geometry::faceCentroidGen<PFP, EMBV, EMB>(m_map, dit, m_attribut);
Aavg += Algo::Surface::Geometry::faceCentroid<PFP, EMBV>(m_map, dit, m_attribut);
++degree;
}
Aavg /= degree;
......@@ -156,10 +157,11 @@ public:
}
};
template <typename PFP, typename EMBV, typename EMB>
template <typename PFP, typename EMBV>
class MJ96EdgeVertexFunctor : public FunctorType
{
protected:
typedef typename EMBV::DATA_TYPE EMB;
typename PFP::MAP& m_map ;
EMBV& m_attribut;
//Algo::Volume::IHM::AttributeHandler_IHM<typename PFP::VEC3, VERTEX>& m_position ;
......@@ -217,7 +219,7 @@ public:
Traversor3EW<typename PFP::MAP> travEW(m_map, d2);
for(Dart dit = travEW.begin() ; dit != travEW.end() ; dit = travEW.next())
{
Cavg += Algo::Surface::Geometry::volumeCentroidGen<PFP, EMBV, EMB>(m_map, dit, m_attribut);
Cavg += Algo::Surface::Geometry::volumeCentroid<PFP, EMBV>(m_map, dit, m_attribut);
++degree;
}
Cavg /= degree;
......@@ -227,7 +229,7 @@ public:
Traversor3EF<typename PFP::MAP> travEF(m_map, d2);
for(Dart dit = travEF.begin() ; dit != travEF.end() ; dit = travEF.next())
{
Aavg += Algo::Surface::Geometry::faceCentroidGen<PFP, EMBV, EMB>(m_map, dit, m_attribut);
Aavg += Algo::Surface::Geometry::faceCentroid<PFP, EMBV>(m_map, dit, m_attribut);
++degree;
}
Aavg /= degree;
......@@ -247,10 +249,11 @@ public:
}
};
template <typename PFP, typename EMBV, typename EMB>
template <typename PFP, typename EMBV>
class MJ96FaceVertexFunctor : public FunctorType
{
protected:
typedef typename EMBV::DATA_TYPE EMB;
typename PFP::MAP& m_map ;
EMBV& m_attribut;
//Algo::Volume::IHM::AttributeHandler_IHM<typename PFP::VEC3, VERTEX>& m_position ;
......@@ -291,10 +294,10 @@ public:
m_map.decCurrentLevel() ;
//face points
EMB C0 = Algo::Surface::Geometry::volumeCentroidGen<PFP, EMBV, EMB>(m_map, df, m_attribut);
EMB C1 = Algo::Surface::Geometry::volumeCentroidGen<PFP, EMBV, EMB>(m_map, m_map.phi3(df), m_attribut);
EMB C0 = Algo::Surface::Geometry::volumeCentroid<PFP, EMBV>(m_map, df, m_attribut);
EMB C1 = Algo::Surface::Geometry::volumeCentroid<PFP, EMBV>(m_map, m_map.phi3(df), m_attribut);
EMB A = Algo::Surface::Geometry::faceCentroidGen<PFP, EMBV, EMB>(m_map, df, m_attribut);
EMB A = Algo::Surface::Geometry::faceCentroid<PFP, EMBV>(m_map, df, m_attribut);
EMB fp = C0 + A * 2 + C1;
fp /= 4;
......@@ -309,10 +312,11 @@ public:
};
template <typename PFP, typename EMBV, typename EMB>
template <typename PFP, typename EMBV>
class MJ96VolumeVertexFunctor : public FunctorType
{
protected:
typedef typename EMBV::DATA_TYPE EMB;
typename PFP::MAP& m_map ;
EMBV& m_attribut;
//Algo::Volume::IHM::AttributeHandler_IHM<typename PFP::VEC3, VERTEX>& m_position ;
......@@ -332,7 +336,7 @@ public:
//cell points : these points are the average of the
//vertices of the lattice that bound the cell
EMB p = Algo::Surface::Geometry::volumeCentroidGen<PFP, EMBV, EMB>(m_map,df,m_attribut);
EMB p = Algo::Surface::Geometry::volumeCentroid<PFP, EMBV>(m_map,df,m_attribut);
m_map.incCurrentLevel() ;
......
......@@ -90,6 +90,8 @@ public:
void swapEdges(Dart d, Dart e);
Dart swap2To2(Dart d);
void swap4To4(Dart d);
Dart swap2To3(Dart d);
void swapGen3To2(Dart d);
......
......@@ -171,6 +171,61 @@ Dart Map3MR<PFP>::swap2To3(Dart d)
return m_map.phi1(d2_1);
}
template <typename PFP>
Dart Map3MR<PFP>::swap2To2(Dart d)
{
std::vector<Dart> edges;
Dart d2_1 = m_map.phi_1(m_map.phi2(d));
m_map.mergeVolumes(d,false);
Dart d2 = m_map.phi1(d2_1);
Dart d3 = m_map.phi3(d2);
m_map.flipEdge(d2);
m_map.flipBackEdge(d3);
Dart e = m_map.phi2(d2) ;
m_map.template copyDartEmbedding<VERTEX>(d2, m_map.phi1(e)) ;
m_map.template copyDartEmbedding<VERTEX>(e, m_map.phi1(d2)) ;
Dart e3 = m_map.phi2(d3);
m_map.template copyDartEmbedding<VERTEX>(d3, m_map.phi1(e3)) ;
m_map.template copyDartEmbedding<VERTEX>(e3, m_map.phi1(d3)) ;
Dart stop = m_map.phi_1(d2_1);
Dart dit = stop;
do
{
edges.push_back(dit);
dit = m_map.phi1(m_map.phi2(m_map.phi1(dit)));
}
while(dit != stop);
m_map.splitVolumeWithFace(edges,m_map.phi_1(m_map.phi3(d)));
return m_map.phi2(stop);
}
template <typename PFP>
void Map3MR<PFP>::swap4To4(Dart d)
{
Dart e = m_map.phi2(m_map.phi3(d));
Dart dd = m_map.phi2(d);
//unsew middle crossing darts
m_map.unsewVolumes(d);
m_map.unsewVolumes(m_map.phi2(m_map.phi3(dd)));
Dart d1 = swap2To2(dd);
Dart d2 = swap2To2(e);
//sew middle darts so that they do not cross
m_map.sewVolumes(m_map.phi2(d1),m_map.phi2(m_map.phi3(d2)));
m_map.sewVolumes(m_map.phi2(m_map.phi3(d1)),m_map.phi2(d2));
}
template <typename PFP>
void Map3MR<PFP>::swapGen3To2(Dart d)
......@@ -187,7 +242,7 @@ void Map3MR<PFP>::swapGen3To2(Dart d)
dit = m_map.phi2(swap2To3(dit));
}
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, dit);
swap2To2(dit);
}
else
{
......@@ -195,17 +250,19 @@ void Map3MR<PFP>::swapGen3To2(Dart d)
{
dit = m_map.phi2(swap2To3(dit));
}
//Volume::Modelisation::Tetrahedralization::swap4To4<PFP>(m_map, m_map.alpha2(dit));
std::cout << "balalbalabaaaaaaaaaaaaaaaaaaa" << std::endl;
swap4To4(m_map.alpha2(dit));
}
}
else if (n == 3)
{
Dart dres = swap2To3(d);
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, m_map.phi2(dres));
swap2To2(m_map.phi2(dres));
}
else // si (n == 2)
{
//Volume::Modelisation::Tetrahedralization::swap2To2<PFP>(m_map, d);
std::cout << "arrrrrrghhhhhhhhhhhh" << std::endl;
swap2To2(d);
}
}
......@@ -244,8 +301,23 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typena
m_map.setCurrentLevel(m_map.getMaxLevel());
DartMarkerStore m(m_map);
DartMarkerStore newBoundaryV(m_map);
DartMarkerStore newV(m_map);
if(embedNewVertices)
{
TraversorV<typename PFP::MAP> tW(m_map);
for(Dart dit = tW.begin() ; dit != tW.end() ; dit = tW.next())
{
m_map.decCurrentLevel();
unsigned int emb = m_map.template getEmbedding<VERTEX>(dit);
m_map.incCurrentLevel();
unsigned int newemb = m_map.template setOrbitEmbeddingOnNewCell<VERTEX>(dit) ;
m_map.template copyCell<VERTEX>(newemb, emb);
}
}
//
// 1-4 flip of all tetrahedra
......@@ -269,6 +341,8 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typena
Dart dres = Volume::Modelisation::Tetrahedralization::flip1To4<PFP>(m_map, dit);
position[dres] = volCenter;
newV.markOrbit<VERTEX>(dres);
}
......@@ -278,13 +352,14 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typena
//TraversorF<typename PFP::MAP> tF(m_map);
for(Dart dit = m_map.begin() ; dit != m_map.end() ; m_map.next(dit))
{
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
swap2To3(dit);
}
if(m.isMarked(dit))
{
m.unmarkOrbit<FACE>(dit);
swap2To3(dit);
}
}
//
// 1-3 flip of all boundary tetrahedra
//
......@@ -313,49 +388,88 @@ void Map3MR<PFP>::addNewLevelSqrt3(bool embedNewVertices, VertexAttribute<typena
}
}
/*
TraversorV<typename PFP::MAP> tVg(m_map);
for(Dart dit = tVg.begin() ; dit != tVg.end() ; dit = tVg.next())
{
if(m_map.isBoundaryVertex(dit) && !newBoundaryV.isMarked(dit))
{
Dart db = m_map.findBoundaryFaceOfVertex(dit);
typename PFP::VEC3 P = position[db] ;
typename PFP::VEC3 newP(0) ;
unsigned int val = 0 ;
Dart vit = db ;
do
{
newP += position[m_map.phi_1(m_map.phi2(m_map.phi1(vit)))] ;
++val ;
vit = m_map.phi2(m_map.phi_1(vit)) ;
} while(vit != db) ;
typename PFP::REAL K = sqrt3_K(val) ;
newP *= typename PFP::REAL(3) ;
newP -= typename PFP::REAL(val) * P ;
newP *= K / typename PFP::REAL(2 * val) ;
newP += (typename PFP::REAL(1) - K) * P ;
position[db] = newP ;
m_map.decCurrentLevel() ;
Dart db = m_map.findBoundaryFaceOfVertex(dit);
typename PFP::VEC3 np(0) ;
unsigned int degree = 0 ;
Traversor2VVaE<typename PFP::MAP> trav(m_map, db) ;
for(Dart it = trav.begin(); it != trav.end(); it = trav.next())
{
++degree ;
np += position[it] ;
}
float alpha = 1.0/9.0 * ( 4.0 - 2.0 * cos(2.0 * M_PI / degree));
np *= alpha / degree ;
typename PFP::VEC3 vp = position[db] ;
vp *= 1.0 - alpha ;
m_map.incCurrentLevel() ;
position[dit] = np + vp;
// Dart db = m_map.findBoundaryFaceOfVertex(dit);
// typename PFP::VEC3 P = position[db] ;
// typename PFP::VEC3 newP(0) ;
// unsigned int val = 0 ;
// Dart vit = db ;
// do
// {
// newP += position[m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi1(vit))))] ;
// ++val ;
// vit = m_map.phi2(m_map.phi_1(vit)) ;
// } while(vit != db) ;
// typename PFP::REAL K = sqrt3_K(val) ;
// newP *= typename PFP::REAL(3) ;
// newP -= typename PFP::REAL(val) * P ;
// newP *= K / typename PFP::REAL(2 * val) ;
// newP += (typename PFP::REAL(1) - K) * P ;
// position[db] = newP ;
}
}
*/
// else if(!m_map.isBoundaryVertex(dit) && !newV.isMarked(dit))
// {
// m_map.decCurrentLevel() ;
// typename PFP::VEC3 np(0) ;
// unsigned int degree = 0 ;
// Traversor3VVaE<typename PFP::MAP> trav(m_map, dit) ;
// for(Dart it = trav.begin(); it != trav.end(); it = trav.next())
// {
// ++degree ;
// np += position[it] ;
// }
// np /= degree;
//
// edge-removal on all old boundary edges
//
TraversorE<typename PFP::MAP> tE(m_map);
for(Dart dit = tE.begin() ; dit != tE.end() ; dit = tE.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<EDGE>(dit);
Dart d = m_map.phi2(m_map.phi3(m_map.findBoundaryFaceOfEdge(dit)));
swapGen3To2(d);
// m_map.incCurrentLevel() ;
}
// position[dit] = np;
// }
}
//
// edge-removal on all old boundary edges
//
TraversorE<typename PFP::MAP> tE(m_map);
for(Dart dit = tE.begin() ; dit != tE.end() ; dit = tE.next())
{
if(m.isMarked(dit))
{
m.unmarkOrbit<EDGE>(dit);
Dart d = m_map.phi2(m_map.phi3(m_map.findBoundaryFaceOfEdge(dit)));
swapGen3To2(d);
}
}
m_map.setCurrentLevel(m_map.getMaxLevel());
m_map.popLevel() ;
}
......@@ -551,43 +665,50 @@ void Map3MR<PFP>::addNewLevelTetraOcta()
}
m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ;
for(Dart dit = traW.begin(); dit != traW.end(); dit = traW.next())
{
Traversor3WV<typename PFP::MAP> traWV(m_map, dit);
for(Dart dit = traW.begin(); dit != traW.end(); dit = traW.next())
{
Traversor3WV<typename PFP::MAP> traWV(m_map, dit);
for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next())
{
m_map.setCurrentLevel(m_map.getMaxLevel()) ;
Dart x = m_map.phi_1(m_map.phi2(m_map.phi1(ditWV)));
for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next())
{
m_map.setCurrentLevel(m_map.getMaxLevel()) ;
Dart x = m_map.phi_1(m_map.phi2(m_map.phi1(ditWV)));
if(!Algo::Volume::Modelisation::Tetrahedralization::isTetrahedron<PFP>(m_map,x))
{
DartMarkerStore me(m_map);
if(!Algo::Volume::Modelisation::Tetrahedralization::isTetrahedron<PFP>(m_map,x))
{
DartMarkerStore me(m_map);
Dart f = x;
Dart f = x;
do
{
Dart f3 = m_map.phi3(f);
do
{
Dart f3 = m_map.phi3(f);
if(!me.isMarked(f3))
{
Dart tmp = m_map.phi_1(m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi_1(f3))))); //future voisin par phi2
if(!me.isMarked(f3))
{
Dart tmp = m_map.phi_1(m_map.phi2(m_map.phi_1(m_map.phi2(m_map.phi_1(f3))))); //future voisin par phi2
Dart f32 = m_map.phi2(f3);
swapEdges(f3, tmp);
Dart f32 = m_map.phi2(f3);
swapEdges(f3, tmp);
me.markOrbit<EDGE>(f3);
me.markOrbit<EDGE>(f32);
}
me.markOrbit<EDGE>(f3);
me.markOrbit<EDGE>(f32);
}
f = m_map.phi2(m_map.phi_1(f));
}while(f != x);
f = m_map.phi2(m_map.phi_1(f));
}while(f != x);
//<<<<<<< HEAD
// }
// m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ;
// }
// }
//=======
}
m_map.setCurrentLevel(m_map.getMaxLevel() - 1) ;
}
}
//>>>>>>> 9780158bea73b64320fab77469ce9df7ebe85387
m_map.popLevel() ;
}
......
......@@ -131,25 +131,57 @@ void filterBandPass(typename PFP::MAP& map, VertexAttribute<T>& attIn, unsigned
map.setCurrentLevel(cur);
}
template <typename PFP, typename T>
void frequencyDeformation(typename PFP::MAP& map, VertexAttribute<T>& attIn, unsigned int cutoffLevel)
template <typename PFP>
typename PFP::VEC3 doTwist(typename PFP::VEC3 pos, float t )
{
unsigned int cur = map.getCurrentLevel();
unsigned int max = map.getMaxLevel();
typedef typename PFP::VEC3 VEC3;
map.setCurrentLevel(max);
float st = std::sin(t);
float ct = std::cos(t);
VEC3 new_pos;
new_pos[0] = pos[0]*ct - pos[2]*st;
new_pos[2] = pos[0]*st + pos[2]*ct;
new_pos[1] = pos[1];
return new_pos;
}
template <typename PFP>
void frequencyDeformation(typename PFP::MAP& map, VertexAttribute<typename PFP::VEC3>& attIn, unsigned int cutoffLevel)
{
float time = 1.0;
//float angle_deg_max = 0.4;
//float height = 0.4;
float A = 20.0;
float frequency = 1.0;
float phase = time * 2.0;
TraversorV<typename PFP::MAP> tv(map);
for (Dart d = tv.begin(); d != tv.end(); d = tv.next())
{
if(vertexLevel<PFP>(map,d) == cutoffLevel)
attIn[d] += T(0.0,0.0,0.2);
}
map.setCurrentLevel(cur);
typename PFP::VEC3 p = attIn[d];
float dist = std::sqrt(p[0]*p[0] + p[2]*p[2]);
p[1] += A * std::sin(frequency * dist + phase);
// float angle_deg = angle_deg_max * std::sin(time);
// float angle_rad = angle_deg * 3.14159 / 180.0;
// float ang = (height*0.5 + attIn[d][1])/height * angle_rad;
// attIn[d] = doTwist<PFP>(attIn[d], ang);
}
}