Commit 1ff6b8b3 authored by untereiner's avatar untereiner

Regular Refinement ok - lerp filters

parent 88a0b0c1
......@@ -52,6 +52,7 @@
#include "Algo/Geometry/boundingbox.h"
#include "Algo/Geometry/normal.h"
#include "Algo/Geometry/convexity.h"
using namespace CGoGN ;
......
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#ifndef __ALGO_GEOMETRY_CONVEXITY_H__
#define __ALGO_GEOMETRY_CONVEXITY_H__
namespace CGoGN
{
namespace Algo
{
namespace Geometry
{
/**
* Test if an edge bounded by 2 faces is convex or concave
*/
template <typename PFP>
bool isEdgeConvexe(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position) ;
} // namespace Geometry
} // namespace Algo
} // namespace CGoGN
#include "Algo/Geometry/convexity.hpp"
#endif
/*******************************************************************************
* CGoGN: Combinatorial and Geometric modeling with Generic N-dimensional Maps *
* version 0.1 *
* Copyright (C) 2009-2012, IGG Team, LSIIT, University of Strasbourg *
* *
* This library is free software; you can redistribute it and/or modify it *
* under the terms of the GNU Lesser General Public License as published by the *
* Free Software Foundation; either version 2.1 of the License, or (at your *
* option) any later version. *
* *
* This library is distributed in the hope that it will be useful, but WITHOUT *
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or *
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License *
* for more details. *
* *
* You should have received a copy of the GNU Lesser General Public License *
* along with this library; if not, write to the Free Software Foundation, *
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. *
* *
* Web site: http://cgogn.unistra.fr/ *
* Contact information: cgogn@unistra.fr *
* *
*******************************************************************************/
#include "Geometry/basic.h"
#include "Algo/Geometry/normal.h"
#include <limits>
namespace CGoGN
{
namespace Algo
{
namespace Geometry
{
template <typename PFP>
bool isEdgeConvexe(typename PFP::MAP& map, Dart d, const VertexAttribute<typename PFP::VEC3>& position)
{
typedef typename PFP::VEC3 VEC3 ;
const VEC3 n = faceNormal<PFP>(map, d, position);
const VEC3 e = Algo::Geometry::vectorOutOfDart<PFP>(map, map.phi1(map.phi2(d)), position) ;
if((e * n) > 0)
return false;
else
return true;
}
} // namespace Geometry
} // namespace Algo
} // namespace CGoGN
......@@ -125,6 +125,20 @@ Dart createQuadrangularPyramid(typename PFP::MAP& map, bool withBoundary = true)
template <typename PFP>
Dart createOctahedron(typename PFP::MAP& map, bool withBoundary = true);
//TODO optimize
template <typename PFP>
bool isPyra(typename PFP::MAP& map, Dart d, unsigned int thread = 0);
//TODO optimize
template <typename PFP>
bool isPrism(typename PFP::MAP& map, Dart d, unsigned int thread = 0);
/**
......
......@@ -201,6 +201,62 @@ Dart createOctahedron(typename PFP::MAP& map, bool withBoundary)
template <typename PFP>
bool isPyra(typename PFP::MAP& map, Dart d, unsigned int thread)
{
unsigned int nbFacesT = 0;
unsigned int nbFacesQ = 0;
//Test the number of faces end its valency
Traversor3WF<typename PFP::MAP> travWF(map, d, false, thread);
for(Dart dit = travWF.begin() ; dit != travWF.end(); dit = travWF.next())
{
//increase the number of faces
if(map.faceDegree(dit) == 3)
nbFacesT++;
else if(map.faceDegree(dit) == 4)
nbFacesQ++;
else
return false;
}
if((nbFacesT != 4) || (nbFacesQ != 1)) //too much faces
return false;
return true;
}
template <typename PFP>
bool isPrism(typename PFP::MAP& map, Dart d, unsigned int thread)
{
unsigned int nbFacesT = 0;
unsigned int nbFacesQ = 0;
//Test the number of faces end its valency
Traversor3WF<typename PFP::MAP> travWF(map, d, false, thread);
for(Dart dit = travWF.begin() ; dit != travWF.end(); dit = travWF.next())
{
//increase the number of faces
if(map.faceDegree(dit) == 3)
nbFacesT++;
else if(map.faceDegree(dit) == 4)
nbFacesQ++;
else
return false;
}
if((nbFacesT != 2) || (nbFacesQ != 3)) //too much faces
return false;
return true;
}
template <typename PFP>
void explodPolyhedron(typename PFP::MAP& map, Dart d, VertexAttribute<typename PFP::VEC3>& position)
{
......
......@@ -46,64 +46,232 @@ namespace Filters
/*********************************************************************************
* SYNTHESIS FILTERS
*********************************************************************************/
// Quad refinement
template <typename PFP>
class LerpEdgeSynthesisFilter : public Filter
class LerpQuadOddSynthesisFilter : public Filter
{
protected:
typename PFP::MAP& m_map ;
VertexAttribute<typename PFP::VEC3>& m_position ;
public:
LerpEdgeSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
LerpQuadOddSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
void operator() ()
{
TraversorE<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
TraversorF<typename PFP::MAP> travF(m_map) ;
for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
{
typename PFP::VEC3 p = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5);
typename PFP::VEC3 vf(0.0);
typename PFP::VEC3 ef(0.0);
unsigned int count = 0;
Traversor2FE<typename PFP::MAP> travFE(m_map, d);
for (Dart dit = travFE.begin(); dit != travFE.end(); dit = travFE.next())
{
vf += m_position[dit];
m_map.incCurrentLevel();
ef += m_position[m_map.phi1(dit)];
m_map.decCurrentLevel();
++count;
}
ef /= count;
ef *= 2.0;
vf /= count;
m_map.incCurrentLevel() ;
Dart midF = m_map.phi1(m_map.phi1(d));
m_position[midF] += vf + ef ;
m_map.decCurrentLevel() ;
}
Dart midV = m_map.phi1(d) ;
m_position[midV] = p ;
TraversorE<typename PFP::MAP> travE(m_map) ;
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
{
typename PFP::VEC3 ve = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi1(d) ;
m_position[midV] += ve ;
m_map.decCurrentLevel() ;
}
}
} ;
};
// Tri/quad refinement
template <typename PFP>
class LerpFaceSynthesisFilter : public Filter
class LerpTriQuadOddSynthesisFilter : public Filter
{
protected:
typename PFP::MAP& m_map ;
VertexAttribute<typename PFP::VEC3>& m_position ;
public:
LerpFaceSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
LerpTriQuadOddSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
void operator() ()
{
TraversorF<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
TraversorF<typename PFP::MAP> travF(m_map) ;
for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
{
typename PFP::VEC3 p = Algo::Geometry::faceCentroid<PFP>(m_map, d, m_position);
m_map.incCurrentLevel() ;
if(m_map.faceDegree(d) != 3)
{
typename PFP::VEC3 vf(0.0);
typename PFP::VEC3 ef(0.0);
unsigned int count = 0;
Traversor2FE<typename PFP::MAP> travFE(m_map, d);
for (Dart dit = travFE.begin(); dit != travFE.end(); dit = travFE.next())
{
vf += m_position[dit];
m_map.incCurrentLevel();
ef += m_position[m_map.phi1(dit)];
m_map.decCurrentLevel();
++count;
}
ef /= count;
ef *= 2.0;
vf /= count;
m_map.incCurrentLevel() ;
Dart midF = m_map.phi1(m_map.phi1(d));
m_position[midF] = p ;
m_position[midF] += vf + ef ;
m_map.decCurrentLevel() ;
}
}
TraversorE<typename PFP::MAP> travE(m_map) ;
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
{
typename PFP::VEC3 ve = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi1(d) ;
m_position[midV] += ve ;
m_map.decCurrentLevel() ;
}
}
};
/*********************************************************************************
* ANALYSIS FILTERS
*********************************************************************************/
// Quad refinement
template <typename PFP>
class LerpQuadOddAnalysisFilter : public Filter
{
protected:
typename PFP::MAP& m_map ;
VertexAttribute<typename PFP::VEC3>& m_position ;
public:
LerpQuadOddAnalysisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
void operator() ()
{
TraversorE<typename PFP::MAP> travE(m_map) ;
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
{
typename PFP::VEC3 ve = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi1(d) ;
m_position[midV] -= ve ;
m_map.decCurrentLevel() ;
}
TraversorF<typename PFP::MAP> travF(m_map) ;
for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
{
typename PFP::VEC3 vf(0.0);
typename PFP::VEC3 ef(0.0);
unsigned int count = 0;
Traversor2FE<typename PFP::MAP> travFE(m_map, d);
for (Dart dit = travFE.begin(); dit != travFE.end(); dit = travFE.next())
{
vf += m_position[dit];
m_map.incCurrentLevel();
ef += m_position[m_map.phi1(dit)];
m_map.decCurrentLevel();
++count;
}
ef /= count;
ef *= 2.0;
vf /= count;
m_map.incCurrentLevel() ;
Dart midF = m_map.phi1(m_map.phi1(d));
m_position[midF] -= vf + ef ;
m_map.decCurrentLevel() ;
}
}
} ;
};
// Tri/quad refinement
template <typename PFP>
class LerpTriQuadOddAnalysisFilter : public Filter
{
protected:
typename PFP::MAP& m_map ;
VertexAttribute<typename PFP::VEC3>& m_position ;
public:
LerpTriQuadOddAnalysisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
void operator() ()
{
TraversorE<typename PFP::MAP> travE(m_map) ;
for (Dart d = travE.begin(); d != travE.end(); d = travE.next())
{
typename PFP::VEC3 ve = (m_position[d] + m_position[m_map.phi1(d)]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi1(d) ;
m_position[midV] -= ve ;
m_map.decCurrentLevel() ;
}
TraversorF<typename PFP::MAP> travF(m_map) ;
for (Dart d = travF.begin(); d != travF.end(); d = travF.next())
{
if(m_map.faceDegree(d) != 3)
{
typename PFP::VEC3 vf(0.0);
typename PFP::VEC3 ef(0.0);
unsigned int count = 0;
Traversor2FE<typename PFP::MAP> travFE(m_map, d);
for (Dart dit = travFE.begin(); dit != travFE.end(); dit = travFE.next())
{
vf += m_position[dit];
m_map.incCurrentLevel();
ef += m_position[m_map.phi1(dit)];
m_map.decCurrentLevel();
++count;
}
ef /= count;
ef *= 2.0;
vf /= count;
m_map.incCurrentLevel() ;
Dart midF = m_map.phi1(m_map.phi1(d));
m_position[midF] -= vf + ef ;
m_map.decCurrentLevel() ;
}
}
}
};
} // namespace Filters
......
......@@ -28,6 +28,7 @@
#include <cmath>
#include "Algo/Geometry/centroid.h"
#include "Algo/Modelisation/tetrahedralization.h"
#include "Algo/Modelisation/polyhedron.h"
#include "Algo/Multiresolution/filter.h"
namespace CGoGN
......@@ -51,6 +52,69 @@ namespace Filters
/* Linear Interpolation
*********************************************************************************/
template <typename PFP>
class LerpOddSynthesisFilter : public Filter
{
protected:
typename PFP::MAP& m_map ;
VertexAttribute<typename PFP::VEC3>& m_position ;
public:
LerpOddSynthesisFilter(typename PFP::MAP& m, VertexAttribute<typename PFP::VEC3>& p) : m_map(m), m_position(p)
{}
void operator() ()
{
TraversorE<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
typename PFP::VEC3 p = (m_position[d] + m_position[m_map.phi2(d)]) * typename PFP::REAL(0.5);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi2(d) ;
m_position[midV] += p ;
m_map.decCurrentLevel() ;
}
TraversorF<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
typename PFP::VEC3 p = Algo::Geometry::faceCentroid<PFP>(m_map, d, m_position);
m_map.incCurrentLevel() ;
Dart midF = m_map.phi2(m_map.phi1(d));
m_position[midF] += p ;
m_map.decCurrentLevel() ;
}
TraversorW<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
if(!Algo::Modelisation::Tetrahedralization::isTetrahedron<PFP>(m_map,d) && !Algo::Modelisation::isPrism<PFP>(m_map,d) && !Algo::Modelisation::isPyra<PFP>(m_map,d))
{
typename PFP::VEC3 p = Algo::Geometry::volumeCentroid<PFP>(m_map, d, m_position);
m_map.incCurrentLevel() ;
Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d)));
m_position[midV] += p ;
m_map.decCurrentLevel() ;
}
}
}
};
template <typename PFP>
class LerpEdgeSynthesisFilter : public Filter
{
......@@ -156,20 +220,17 @@ public:
TraversorW<typename PFP::MAP> trav(m_map) ;
for (Dart d = trav.begin(); d != trav.end(); d = trav.next())
{
typename PFP::VEC3 p = Algo::Geometry::volumeCentroid<PFP>(m_map, d, m_position);
if(!Algo::Modelisation::Tetrahedralization::isTetrahedron<PFP>(m_map,d) && !Algo::Modelisation::isPrism<PFP>(m_map,d) && !Algo::Modelisation::isPyra<PFP>(m_map,d))
{
typename PFP::VEC3 p = Algo::Geometry::volumeCentroid<PFP>(m_map, d, m_position);
m_map.incCurrentLevel() ;
m_map.incCurrentLevel() ;
if(!Algo::Modelisation::Tetrahedralization::isTetrahedron<PFP>(m_map,d)) // && is not a pyramide && is not a prisme
{
Dart midV = m_map.phi_1(m_map.phi2(m_map.phi1(d)));
m_position[midV] = p ;
std::cout << "midV = " << midV << std::endl;
m_map.decCurrentLevel() ;
}
m_map.decCurrentLevel() ;
}
}
} ;
......@@ -203,6 +264,7 @@ public:
}
} ;
} // namespace Filters
} // namespace Primal
......
......@@ -543,15 +543,11 @@ void Map3MR<PFP>::addNewLevel()
if(fdeg == 4)
{
std::cout << "== 4" << std::endl;
if(m_map.PFP::MAP::ParentMap::vertexDegree(ditWV) == 3)
{
isocta = false;
ispyra = true;
std::cout << "pyra" << std::endl;
Dart it = ditWV;
if((m_map.faceDegree(it) == 3) && (m_map.faceDegree(m_map.phi2(it))) == 3)
{
......@@ -572,8 +568,6 @@ void Map3MR<PFP>::addNewLevel()
{
isocta = true;
std::cout << "octa" << std::endl;
Dart old = m_map.phi2(m_map.phi1(ditWV));
Dart dd = m_map.phi1(old) ;
m_map.splitFace(old,dd) ;
......@@ -599,8 +593,6 @@ void Map3MR<PFP>::addNewLevel()
}
else if(fdeg == 5)
{
std::cout << "== 5" << std::endl;
isprism = true;
Dart it = ditWV;
......@@ -620,7 +612,6 @@ void Map3MR<PFP>::addNewLevel()
}
if(fdeg == 6)
{
std::cout << "== 6" << std::endl;
ishex = true;
Dart dd = m_map.phi2(m_map.phi1(ditWV));;
......@@ -630,7 +621,6 @@ void Map3MR<PFP>::addNewLevel()
Dart ne = m_map.phi2(m_map.phi_1(dd)) ;
m_map.cutEdge(ne) ; // cut the new edge to insert the central vertex
centralDart = m_map.phi1(ne);
//m_map.template setOrbitEmbedding<VERTEX>(centralDart, m_map.template getEmbedding<VERTEX>(centralDart));
dd = m_map.phi1(m_map.phi1(next)) ;
while(dd != ne) // turn around the face and insert new edges
......@@ -687,21 +677,17 @@ void Map3MR<PFP>::addNewLevel()
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
swapEdges(f3, tmp);
std::cout << "plop : " << f3 << std::endl;
f = m_map.phi2(m_map.phi_1(f));
}while(f != x);
//replonger l'orbit de ditV.
m_map.template setOrbitEmbedding<VERTEX>(ditV, m_map.template getEmbedding<VERTEX>(ditV));
m_map.template setOrbitEmbedding<VERTEX>(x, m_map.template getEmbedding<VERTEX>(x));
m_map.decCurrentLevel() ;
}
if(isocta)
{
std::cout << "is octa " << std::endl;
Traversor3WV<typename PFP::MAP> traWV(m_map, dit);
for(Dart ditWV = traWV.begin(); ditWV != traWV.end(); ditWV = traWV.next())
......@@ -738,8 +724,6 @@ void Map3MR<PFP>::addNewLevel()
}
}
if(isprism)
{
m_map.incCurrentLevel();
......@@ -754,9 +738,31 @@ void Map3MR<PFP>::addNewLevel()
ditWV = m_map.phi1(m_map.phi2(dit));
}
ditWV = m_map.phi_1(m_map.phi2(m_map.phi1(ditWV)));
ditWV = m_map.phi3(m_map.phi_1(m_map.phi2(m_map.phi1(ditWV))));
std::vector<Dart> path;
Dart dtemp = ditWV;
do
{