6 #ifndef CNOID_UTIL_TRIANGULATOR_H
7 #define CNOID_UTIL_TRIANGULATOR_H
15 typedef typename TVector3Array::value_type TVector3;
17 enum Convexity { FLAT, CONVEX, CONCAVE };
19 const TVector3Array* vertices;
20 const std::vector<int>* orgPolygon;
21 std::vector<int> triangles_;
22 std::vector<int> workPolygon;
24 std::vector<char> earMask;
26 const TVector3& vertex(
int localIndex)
28 return (*vertices)[(*orgPolygon)[localIndex]];
31 const TVector3& workVertex(
int workPolygonIndex)
33 return (*vertices)[(*orgPolygon)[workPolygon[workPolygonIndex]]];
36 Convexity calcConvexity(
int ear)
38 int n = workPolygon.size();
40 const TVector3& p0 = workVertex((ear + n - 1) % n);
41 TVector3 a = workVertex(ear) - p0;
42 TVector3 b = workVertex((ear + 1) % n) - p0;
43 TVector3 ccs = a.cross(b);
47 if((ccs.norm() / (a.norm() + b.norm())) < 1.0e-4f){
50 convexity = (this->ccs.dot(ccs) > 0.0f) ? CONVEX : CONCAVE;
56 bool checkIfEarContainsOtherVertices(
int ear)
58 bool contains =
false;
60 const int n = workPolygon.size();
63 const int prev = (ear + n -1) % n;
64 const int next = (ear+1) % n;
65 const TVector3& a = workVertex(prev);
66 const TVector3& b = workVertex(ear);
67 const TVector3& c = workVertex(next);
69 earMask[prev] = earMask[ear] = earMask[next] = 1;
71 for(
size_t i=0; i < workPolygon.size(); ++i){
73 const TVector3& p = workVertex(i);
74 if(((a - p).cross(b - p)).dot(ccs) <= 0.0f){
77 if(((b - p).cross(c - p)).dot(ccs) <= 0.0f){
80 if(((c - p).cross(a - p)).dot(ccs) <= 0.0f){
88 earMask[prev] = earMask[ear] = earMask[next] = 0;
97 this->vertices = &vertices;
103 int apply(
const std::vector<int>& polygon)
107 size_t numOrgVertices = polygon.size();
109 if(numOrgVertices > earMask.size()){
110 earMask.resize(numOrgVertices, 0);
113 if(numOrgVertices < 3){
115 }
else if(numOrgVertices == 3){
116 triangles_.push_back(0);
117 triangles_.push_back(1);
118 triangles_.push_back(2);
122 orgPolygon = &polygon;
124 workPolygon.resize(numOrgVertices);
125 for(
size_t i=0; i < numOrgVertices; ++i){
130 const TVector3& o = vertex(0);
131 for(
size_t i=1; i < numOrgVertices - 1; ++i){
132 ccs += (vertex(i) - o).cross(vertex((i+1) % numOrgVertices) - o);
135 int numTriangles = 0;
138 int n = workPolygon.size();
143 for(
int i=0; i < n; ++i){
144 Convexity convexity = calcConvexity(i);
145 if(convexity == FLAT){
148 }
else if(convexity == CONVEX){
149 if(!checkIfEarContainsOtherVertices(i)){
150 triangles_.push_back(workPolygon[(i + n - 1) % n]);
151 triangles_.push_back(workPolygon[i]);
152 triangles_.push_back(workPolygon[(i + 1) % n]);
162 for(
int i = target + 1; i < n; ++i){
163 workPolygon[target++] = workPolygon[i];
165 workPolygon.pop_back();