Skip to content

Commit

Permalink
Merge pull request #171 from sylvainthery/catmullclark
Browse files Browse the repository at this point in the history
Catmullclark
  • Loading branch information
pierrekraemer committed Mar 30, 2016
2 parents 5c4bb4f + a7d6907 commit 7211440
Show file tree
Hide file tree
Showing 28 changed files with 740 additions and 101 deletions.
1 change: 1 addition & 0 deletions cgogn/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
add_subdirectory(core)
add_subdirectory(io)
add_subdirectory(geometry)
add_subdirectory(modeling)

if(CGOGN_USE_QT)
add_subdirectory(rendering)
Expand Down
5 changes: 0 additions & 5 deletions cgogn/core/basic/cell.h
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,6 @@ class Cell
//TODO
// Cell(Cell<ORBIT>&& ) = delete;

/**
* \brief Cast operator.
* \return the dart
*/
inline operator Dart() const { return dart; }

/**
* \brief Tests the validity of the cell.
Expand Down
49 changes: 46 additions & 3 deletions cgogn/core/cmap/cmap1.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,25 @@
namespace cgogn
{

namespace internal
{
template<uint64 N>
struct check_multi_phi
{
static const bool value_cmap1 = (N<10)?(N%10>0) && (N%10<=1):(N%10>0) && (N%10<=2) && check_multi_phi<N/10>::value_cmap1;
static const bool value_cmap2 = (N<10)?(N%10>0) && (N%10<=2):(N%10>0) && (N%10<=2) && check_multi_phi<N/10>::value_cmap2;
static const bool value_cmap3 = (N<10)?(N%10>0) && (N%10<=3):(N%10>0) && (N%10<=3) && check_multi_phi<N/10>::value_cmap3;

};
template<>
struct check_multi_phi<0>
{
static const bool value_cmap1 = true;
static const bool value_cmap2 = true;
static const bool value_cmap3 = true;
};
}

template <typename MAP_TRAITS, typename MAP_TYPE>
class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
{
Expand Down Expand Up @@ -196,6 +215,29 @@ class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
return (*phi_1_)[d.index];
}



/**
* \brief phi composition
* @param d
* @return applied composition of phi in order of declaration
*/
template <uint64 N>
inline Dart phi(Dart d) const
{
static_assert(internal::check_multi_phi<N>::value_cmap1, "composition on phi1 only");

if (N >=10)
return this->phi1(phi<N/10>(d));

if (N == 1)
return this->phi1(d);

return d;
}



/*******************************************************************************
* High-level embedded and topological operations
*******************************************************************************/
Expand Down Expand Up @@ -297,7 +339,7 @@ class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
{
CGOGN_CHECK_CONCRETE_TYPE;

const Vertex nv(split_vertex_topo(v));
const Vertex nv(split_vertex_topo(v.dart));

if (this->template is_embedded<Vertex>())
this->new_orbit_embedding(nv);
Expand All @@ -317,7 +359,7 @@ class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
{
CGOGN_CHECK_CONCRETE_TYPE;

Dart e = phi_1(v);
Dart e = phi_1(v.dart);
if (e != v.dart) phi1_unsew(e);
this->remove_dart(v.dart);
}
Expand Down Expand Up @@ -400,7 +442,7 @@ class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
switch (ORBIT)
{
case Orbit::DART: f(c.dart); break;
case Orbit::PHI1: foreach_dart_of_PHI1(c, f); break;
case Orbit::PHI1: foreach_dart_of_PHI1(c.dart, f); break;
case Orbit::PHI2:
case Orbit::PHI1_PHI2:
case Orbit::PHI1_PHI3:
Expand Down Expand Up @@ -458,6 +500,7 @@ class CMap1_T : public CMap0_T<MAP_TRAITS, MAP_TYPE>
}
};


template <typename MAP_TRAITS>
struct CMap1Type
{
Expand Down
49 changes: 36 additions & 13 deletions cgogn/core/cmap/cmap2.h
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,24 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
return (*phi2_)[d.index];
}


/**
* \brief phi composition
* @param d
* @return applied composition of phi in order of declaration
*/
template <uint64 N>
inline Dart phi(Dart d) const
{
static_assert(internal::check_multi_phi<N>::value_cmap2, "composition on phi1/phi2/only");
switch(N%10)
{
case 1 : return this->phi1(phi<N/10>(d)) ;
case 2 : return this->phi2(phi<N/10>(d)) ;
default : return d ;
}
}

/*******************************************************************************
* High-level embedded and topological operations
*******************************************************************************/
Expand Down Expand Up @@ -329,7 +347,7 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
CGOGN_CHECK_CONCRETE_TYPE;

const Dart v = cut_edge_topo(e.dart);
const Dart nf = phi2(e);
const Dart nf = phi2(e.dart);
const Dart f = phi2(v);

if (this->template is_embedded<CDart>())
Expand Down Expand Up @@ -427,10 +445,9 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
CGOGN_CHECK_CONCRETE_TYPE;

cgogn_message_assert(!this->is_boundary(d.dart), "cut_face: should not cut a boundary face");

cut_face_topo(d, e);
Dart nd = this->phi_1(d);
Dart ne = this->phi_1(e);
cut_face_topo(d.dart,e.dart);
Dart nd = this->phi_1(d.dart);
Dart ne = this->phi_1(e.dart);

if (this->template is_embedded<CDart>())
{
Expand Down Expand Up @@ -565,10 +582,10 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
switch (ORBIT)
{
case Orbit::DART: f(c.dart); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1(c, f); break;
case Orbit::PHI2: foreach_dart_of_PHI2(c, f); break;
case Orbit::PHI1_PHI2: foreach_dart_of_PHI1_PHI2(c, f); break;
case Orbit::PHI21: foreach_dart_of_PHI21(c, f); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1(c.dart, f); break;
case Orbit::PHI2: foreach_dart_of_PHI2(c.dart, f); break;
case Orbit::PHI1_PHI2: foreach_dart_of_PHI1_PHI2(c.dart, f); break;
case Orbit::PHI21: foreach_dart_of_PHI21(c.dart, f); break;
case Orbit::PHI2_PHI3:
case Orbit::PHI1_PHI3:
case Orbit::PHI21_PHI31:
Expand Down Expand Up @@ -643,10 +660,10 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
switch (ORBIT)
{
case Orbit::DART: f(c.dart); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1_until(c, f); break;
case Orbit::PHI2: foreach_dart_of_PHI2_until(c, f); break;
case Orbit::PHI1_PHI2: foreach_dart_of_PHI1_PHI2_until(c, f); break;
case Orbit::PHI21: foreach_dart_of_PHI21_until(c, f); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1_until(c.dart, f); break;
case Orbit::PHI2: foreach_dart_of_PHI2_until(c.dart, f); break;
case Orbit::PHI1_PHI2: foreach_dart_of_PHI1_PHI2_until(c.dart, f); break;
case Orbit::PHI21: foreach_dart_of_PHI21_until(c.dart, f); break;
case Orbit::PHI2_PHI3:
case Orbit::PHI1_PHI3:
case Orbit::PHI21_PHI31:
Expand Down Expand Up @@ -866,6 +883,12 @@ class CMap2_T : public CMap1_T<MAP_TRAITS, MAP_TYPE>
func(Face(d2));
});
}

inline std::pair<Vertex,Vertex> vertices(Edge e)
{
return std::pair<Vertex,Vertex>(Vertex(e.dart),Vertex(this->phi1(e.dart)));
}

};

template <typename MAP_TRAITS>
Expand Down
62 changes: 46 additions & 16 deletions cgogn/core/cmap/cmap3.h
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,26 @@ class CMap3_T : public CMap2_T<MAP_TRAITS, MAP_TYPE>
return (*phi3_)[d.index];
}



/**
* \brief phi composition
* @param d
* @return applied composition of phi in order of declaration
*/
template <uint64 N>
inline Dart phi(Dart d) const
{
static_assert(internal::check_multi_phi<N>::value_cmap3, "composition on phi1/phi2/phi3 only");
switch(N%10)
{
case 1 : return this->phi1(phi<N/10>(d)) ;
case 2 : return this->phi2(phi<N/10>(d)) ;
case 3 : return this->phi3(phi<N/10>(d)) ;
default : return d ;
}
}

/*******************************************************************************
* High-level embedded and topological operations
*******************************************************************************/
Expand Down Expand Up @@ -469,13 +489,13 @@ class CMap3_T : public CMap2_T<MAP_TRAITS, MAP_TYPE>
switch (ORBIT)
{
case Orbit::DART: f(c.dart); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1(c, f); break;
case Orbit::PHI2: this->foreach_dart_of_PHI2(c, f); break;
case Orbit::PHI1_PHI2: this->foreach_dart_of_PHI1_PHI2(c, f); break;
case Orbit::PHI1_PHI3: foreach_dart_of_PHI1_PHI3(c, f); break;
case Orbit::PHI2_PHI3: foreach_dart_of_PHI2_PHI3(c, f); break;
case Orbit::PHI21: this->foreach_dart_of_PHI21(c, f); break;
case Orbit::PHI21_PHI31: foreach_dart_of_PHI21_PHI31(c, f); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1(c.dart, f); break;
case Orbit::PHI2: this->foreach_dart_of_PHI2(c.dart, f); break;
case Orbit::PHI1_PHI2: this->foreach_dart_of_PHI1_PHI2(c.dart, f); break;
case Orbit::PHI1_PHI3: foreach_dart_of_PHI1_PHI3(c.dart, f); break;
case Orbit::PHI2_PHI3: foreach_dart_of_PHI2_PHI3(c.dart, f); break;
case Orbit::PHI21: this->foreach_dart_of_PHI21(c.dart, f); break;
case Orbit::PHI21_PHI31: foreach_dart_of_PHI21_PHI31(c.dart, f); break;
default: cgogn_assert_not_reached("This orbit is not handled"); break;
}
}
Expand Down Expand Up @@ -555,13 +575,13 @@ class CMap3_T : public CMap2_T<MAP_TRAITS, MAP_TYPE>
switch (ORBIT)
{
case Orbit::DART: f(c.dart); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1_until(c, f); break;
case Orbit::PHI2: this->foreach_dart_of_PHI2_until(c, f); break;
case Orbit::PHI1_PHI2: this->foreach_dart_of_PHI1_PHI2_until(c, f); break;
case Orbit::PHI1_PHI3: foreach_dart_of_PHI1_PHI3_until(c, f); break;
case Orbit::PHI2_PHI3: foreach_dart_of_PHI2_PHI3_until(c, f); break;
case Orbit::PHI21: this->foreach_dart_of_PHI21_until(c, f); break;
case Orbit::PHI21_PHI31: foreach_dart_of_PHI21_PHI31_until(c, f); break;
case Orbit::PHI1: this->foreach_dart_of_PHI1_until(c.dart, f); break;
case Orbit::PHI2: this->foreach_dart_of_PHI2_until(c.dart, f); break;
case Orbit::PHI1_PHI2: this->foreach_dart_of_PHI1_PHI2_until(c.dart, f); break;
case Orbit::PHI1_PHI3: foreach_dart_of_PHI1_PHI3_until(c.dart, f); break;
case Orbit::PHI2_PHI3: foreach_dart_of_PHI2_PHI3_until(c.dart, f); break;
case Orbit::PHI21: this->foreach_dart_of_PHI21_until(c.dart, f); break;
case Orbit::PHI21_PHI31: foreach_dart_of_PHI21_PHI31_until(c.dart, f); break;
default: cgogn_assert_not_reached("This orbit is not handled"); break;
}
}
Expand Down Expand Up @@ -630,14 +650,14 @@ class CMap3_T : public CMap2_T<MAP_TRAITS, MAP_TYPE>
inline void foreach_incident_face(Edge e, const FUNC& func) const
{
static_assert(check_func_parameter_type(FUNC, Face), "Wrong function cell parameter type");
foreach_dart_of_PHI23(e, [&func] (Dart d) { func(Face(d)); });
foreach_dart_of_PHI23(e.dart, [&func] (Dart d) { func(Face(d)); });
}

template <typename FUNC>
inline void foreach_incident_volume(Edge e, const FUNC& func) const
{
static_assert(check_func_parameter_type(FUNC, Volume), "Wrong function cell parameter type");
foreach_dart_of_PHI23(e, [this, &func] (Dart d)
foreach_dart_of_PHI23(e.dart, [this, &func] (Dart d)
{
if (!this->is_boundary(d))
func(Volume(d));
Expand Down Expand Up @@ -1065,6 +1085,16 @@ class CMap3_T : public CMap2_T<MAP_TRAITS, MAP_TYPE>
func(Face2(d2));
});
}

inline std::pair<Vertex,Vertex> vertices(Edge e)
{
return std::pair<Vertex,Vertex>(Vertex(e.dart),Vertex(this->phi1(e.dart)));
}

inline std::array<Vertex,2> verts(Edge e)
{
return {{ Vertex(e.dart),Vertex(this->phi1(e.dart)) }};
}
};

template <typename MAP_TRAITS>
Expand Down
2 changes: 1 addition & 1 deletion cgogn/core/examples/map/map.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ int test1(MAP& map)
cgogn::get_uint_buffers()->release_buffer(uib);


Dart d1 = map.add_face(3);
Dart d1 = map.add_face(3).dart;

// get cell buffer typed
// std::vector<typename MAP::Vertex>* vert_b = cgogn::get_dart_buffers()->get_cell_buffer<typename MAP::Vertex>();
Expand Down
1 change: 1 addition & 0 deletions cgogn/core/tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ set(SOURCE_FILES
cmap/cmap1_test.cpp
cmap/cmap2_topo_test.cpp
cmap/cmap2_test.cpp
cmap/cmap3_topo_test.cpp

utils/name_types_test.cpp

Expand Down
16 changes: 8 additions & 8 deletions cgogn/core/tests/basic/cell_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -37,32 +37,32 @@ const Dart dmax(std::numeric_limits<uint32>::max());
TEST(CellTest, DefaultConstructor)
{
Cell<Orbit::DART> c;
Dart d = c;
Dart d = c.dart;
EXPECT_EQ(std::numeric_limits<uint32>::max(), d.index);
}

TEST(CellTest, Constructor)
{
Cell<Orbit::DART> c(dglobal);
Dart d = c;
Dart d = c.dart;
EXPECT_EQ(10u, d.index);
}

TEST(CellTest, OutOfLimitConstructor)
{
Cell<Orbit::DART> c1(dmax);
Dart d1 = c1;
Dart d1 = c1.dart;
Cell<Orbit::DART> c2;
Dart d2 = c2;
Dart d2 = c2.dart;
EXPECT_EQ(d1.index, d2.index);
}

TEST(CellTest, CopyConstructor)
{
Cell<Orbit::DART> c(dglobal);
Dart d = c;
Dart d = c.dart;
Cell<Orbit::DART> ccopy(c);
Dart dcopy = ccopy;
Dart dcopy = ccopy.dart;
EXPECT_EQ(d.index, dcopy.index);
}

Expand All @@ -78,7 +78,7 @@ TEST(CellTest, Assignation)
Cell<Orbit::DART> c2;
c2 = c1;

Dart d2 = c2;
Dart d2 = c2.dart;

EXPECT_EQ(d2.index, dglobal.index);
}
Expand All @@ -97,7 +97,7 @@ TEST(CellTest, ReadingIn)
std::istringstream s("10");
s >> c;

Dart d = c;
Dart d = c.dart;

EXPECT_EQ(10u, d.index);
}
Expand Down
2 changes: 1 addition & 1 deletion cgogn/core/tests/cmap/cmap0_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ class CMap0Test : public ::testing::Test
{
darts_.clear();
for (uint32 i = 0; i < n; ++i)
darts_.push_back(cmap_.add_vertex());
darts_.push_back(cmap_.add_vertex().dart);
}
};

Expand Down
2 changes: 1 addition & 1 deletion cgogn/core/tests/cmap/cmap0_topo_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ class CMap0TopoTest : public ::testing::Test
{
darts_.clear();
for (uint32 i = 0; i < n; ++i)
darts_.push_back(cmap_.add_vertex());
darts_.push_back(cmap_.add_vertex().dart);
}
};

Expand Down
Loading

0 comments on commit 7211440

Please sign in to comment.