29 #include <pcl/console/print.h>
82 int i,j,*remapTable,*pointCount,idx[3];
85 double Ratio=12.0/sqrt(3.0);
87 remapTable=
new int[positions.size()];
88 pointCount=
new int[positions.size()];
89 for(i=0;i<int(positions.size());i++){
93 for(i=
int(triangles.size()-1);i>=0;i--){
95 idx[j]=triangles[i].idx[j];
96 while(remapTable[idx[j]]<idx[j]){idx[j]=remapTable[idx[j]];}
98 if(idx[0]==idx[1] || idx[0]==idx[2] || idx[1]==idx[2]){
99 triangles[i]=triangles[triangles.size()-1];
100 triangles.pop_back();
104 p[j].
coords[0]=positions[idx[j]].coords[0]/pointCount[idx[j]];
105 p[j].
coords[1]=positions[idx[j]].coords[1]/pointCount[idx[j]];
106 p[j].
coords[2]=positions[idx[j]].coords[2]/pointCount[idx[j]];
116 if((d[0]+d[1]+d[2])*edgeRatio > a*Ratio){
123 if(idx[j]<idx[(j+1)%3]){
131 positions[idx1].coords[0]+=positions[idx2].coords[0];
132 positions[idx1].coords[1]+=positions[idx2].coords[1];
133 positions[idx1].coords[2]+=positions[idx2].coords[2];
135 (*normals)[idx1].coords[0]+=(*normals)[idx2].coords[0];
136 (*normals)[idx1].coords[1]+=(*normals)[idx2].coords[1];
137 (*normals)[idx1].coords[2]+=(*normals)[idx2].coords[2];
139 pointCount[idx1]+=pointCount[idx2];
140 remapTable[idx2]=idx1;
141 triangles[i]=triangles[triangles.size()-1];
142 triangles.pop_back();
146 for(i=0;i<int(positions.size());i++){
147 for(j=0;j<3;j++){positions[i].coords[j]/=pointCount[i];}
150 for(j=0;j<3;j++){(*normals)[i].coords[j]/=l;}
152 if(remapTable[i]==i){
153 positions[pCount]=positions[i];
154 if(normals){(*normals)[pCount]=(*normals)[i];}
155 pointCount[i]=pCount;
159 positions.resize(pCount);
160 for(i=
int(triangles.size()-1);i>=0;i--){
162 idx[j]=triangles[i].idx[j];
163 while(remapTable[idx[j]]<idx[j]){idx[j]=remapTable[idx[j]];}
164 triangles[i].idx[j]=pointCount[idx[j]];
166 if(idx[0]==idx[1] || idx[0]==idx[2] || idx[1]==idx[2]){
167 triangles[i]=triangles[triangles.size()-1];
168 triangles.pop_back();
178 int i,j,*remapTable,*pointCount,idx[3];
181 double Ratio=12.0/sqrt(3.0);
183 remapTable=
new int[positions.size()];
184 pointCount=
new int[positions.size()];
185 for(i=0;i<int(positions.size());i++){
189 for(i=
int(triangles.size()-1);i>=0;i--){
191 idx[j]=triangles[i].idx[j];
192 while(remapTable[idx[j]]<idx[j]){idx[j]=remapTable[idx[j]];}
194 if(idx[0]==idx[1] || idx[0]==idx[2] || idx[1]==idx[2]){
195 triangles[i]=triangles[triangles.size()-1];
196 triangles.pop_back();
200 p[j].
coords[0]=positions[idx[j]].coords[0]/pointCount[idx[j]];
201 p[j].
coords[1]=positions[idx[j]].coords[1]/pointCount[idx[j]];
202 p[j].
coords[2]=positions[idx[j]].coords[2]/pointCount[idx[j]];
212 if((d[0]+d[1]+d[2])*edgeRatio > a*Ratio){
243 positions[idx1].coords[0]+=positions[idx2].coords[0]+positions[idx3].coords[0];
244 positions[idx1].coords[1]+=positions[idx2].coords[1]+positions[idx3].coords[1];
245 positions[idx1].coords[2]+=positions[idx2].coords[2]+positions[idx3].coords[2];
247 (*normals)[idx1].coords[0]+=(*normals)[idx2].coords[0]+(*normals)[idx3].coords[0];
248 (*normals)[idx1].coords[1]+=(*normals)[idx2].coords[1]+(*normals)[idx3].coords[1];
249 (*normals)[idx1].coords[2]+=(*normals)[idx2].coords[2]+(*normals)[idx3].coords[2];
251 pointCount[idx1]+=pointCount[idx2]+pointCount[idx3];
252 remapTable[idx2]=idx1;
253 remapTable[idx3]=idx1;
254 triangles[i]=triangles[triangles.size()-1];
255 triangles.pop_back();
259 for(i=0;i<int(positions.size());i++){
260 for(j=0;j<3;j++){positions[i].coords[j]/=pointCount[i];}
263 for(j=0;j<3;j++){(*normals)[i].coords[j]/=l;}
265 if(remapTable[i]==i){
266 positions[pCount]=positions[i];
267 if(normals){(*normals)[pCount]=(*normals)[i];}
268 pointCount[i]=pCount;
272 positions.resize(pCount);
273 for(i=
int(triangles.size()-1);i>=0;i--){
275 idx[j]=triangles[i].idx[j];
276 while(remapTable[idx[j]]<idx[j]){idx[j]=remapTable[idx[j]];}
277 triangles[i].idx[j]=pointCount[idx[j]];
279 if(idx[0]==idx[1] || idx[0]==idx[2] || idx[1]==idx[2]){
280 triangles[i]=triangles[triangles.size()-1];
281 triangles.pop_back();
294 if(p1>p2) {
return ((
long long)(p1)<<32) | ((
long long)(p2));}
295 else {
return ((
long long)(p2)<<32) | ((
long long)(p1));}
300 if(triangles[tIndex].eIndex[0]<0 || triangles[tIndex].eIndex[1]<0 || triangles[tIndex].eIndex[2]<0){
return 0;}
301 if(edges[triangles[tIndex].eIndex[0]].tIndex[0]==tIndex){p1=edges[triangles[tIndex].eIndex[0]].pIndex[0];}
302 else {p1=edges[triangles[tIndex].eIndex[0]].pIndex[1];}
303 if(edges[triangles[tIndex].eIndex[1]].tIndex[0]==tIndex){p2=edges[triangles[tIndex].eIndex[1]].pIndex[0];}
304 else {p2=edges[triangles[tIndex].eIndex[1]].pIndex[1];}
305 if(edges[triangles[tIndex].eIndex[2]].tIndex[0]==tIndex){p3=edges[triangles[tIndex].eIndex[2]].pIndex[0];}
306 else {p3=edges[triangles[tIndex].eIndex[2]].pIndex[1];}
313 for(
int i=0;i<3;i++){
314 q1.
coords[i]=points[p2].coords[i]-points[p1].coords[i];
315 q2.
coords[i]=points[p3].coords[i]-points[p1].coords[i];
324 factor(tIndex,p1,p2,p3);
325 return area(p1,p2,p3);
331 for(
int i=0;i<int(triangles.size());i++){a+=area(i);}
342 tIdx=int(triangles.size())-1;
346 long long e =
EdgeIndex(p[i],p[(i+1)%3]);
347 if(edgeMap.count(e) == 0)
351 edge.
pIndex[1]=p[(i+1)%3];
352 edges.push_back(edge);
353 eIdx=int(edges.size())-1;
355 edges[eIdx].tIndex[0]=tIdx;
359 if(edges[eIdx].pIndex[0]==p[i]){
360 if(edges[eIdx].tIndex[0]<0){edges[eIdx].tIndex[0]=tIdx;}
361 else{PCL_DEBUG(
"Edge Triangle in use 1\n");
return 0;}
364 if(edges[eIdx].tIndex[1]<0){edges[eIdx].tIndex[1]=tIdx;}
365 else{PCL_DEBUG(
"Edge Triangle in use 2\n");
return 0;}
369 triangles[tIdx].eIndex[i]=eIdx;
376 double oldArea,newArea;
377 int oldP[3],oldQ[3],newP[3],newQ[3];
380 if(edges[eIndex].tIndex[0]<0 || edges[eIndex].tIndex[1]<0){
return 0;}
382 if(!factor(edges[eIndex].tIndex[0],oldP[0],oldP[1],oldP[2])){
return 0;}
383 if(!factor(edges[eIndex].tIndex[1],oldQ[0],oldQ[1],oldQ[2])){
return 0;}
385 oldArea=area(oldP[0],oldP[1],oldP[2])+area(oldQ[0],oldQ[1],oldQ[2]);
387 for(idxP=0;idxP<3;idxP++){
389 for(i=0;i<3;i++){
if(oldP[idxP]==oldQ[i]){
break;}}
392 for(idxQ=0;idxQ<3;idxQ++){
394 for(i=0;i<3;i++){
if(oldP[i]==oldQ[idxQ]){
break;}}
397 if(idxP==3 || idxQ==3){
return 0;}
399 newP[1]=oldP[(idxP+1)%3];
402 newQ[1]=oldP[(idxP+2)%3];
405 newArea=area(newP[0],newP[1],newP[2])+area(newQ[0],newQ[1],newQ[2]);
406 if(oldArea<=newArea){
return 0;}
409 edgeMap.erase(
EdgeIndex(edges[eIndex].pIndex[0],edges[eIndex].pIndex[1]));
411 edges[eIndex].pIndex[0]=newP[0];
412 edges[eIndex].pIndex[1]=newQ[0];
414 edgeMap[
EdgeIndex(newP[0],newQ[0])]=eIndex;
416 for(
int i=0;i<3;i++){
418 idx=edgeMap[
EdgeIndex(newQ[i],newQ[(i+1)%3])];
419 triangles[edges[eIndex].tIndex[0]].eIndex[i]=idx;
421 if(edges[idx].tIndex[0]==edges[eIndex].tIndex[1]){edges[idx].tIndex[0]=edges[eIndex].tIndex[0];}
422 if(edges[idx].tIndex[1]==edges[eIndex].tIndex[1]){edges[idx].tIndex[1]=edges[eIndex].tIndex[0];}
425 idx=edgeMap[
EdgeIndex(newP[i],newP[(i+1)%3])];
426 triangles[edges[eIndex].tIndex[1]].eIndex[i]=idx;
428 if(edges[idx].tIndex[0]==edges[eIndex].tIndex[0]){edges[idx].tIndex[0]=edges[eIndex].tIndex[1];}
429 if(edges[idx].tIndex[1]==edges[eIndex].tIndex[0]){edges[idx].tIndex[1]=edges[eIndex].tIndex[1];}
int flipMinimize(int eIndex)
static long long EdgeIndex(int p1, int p2)
int factor(int tIndex, int &p1, int &p2, int &p3)
int addTriangle(int p1, int p2, int p3)
pcl::detail::MeshIndex< struct EdgeIndexTag > EdgeIndex
Index used to access elements in the half-edge mesh.
double Distance(const Point3D< Real > &p1, const Point3D< Real > &p2)
double SquareDistance(const Point3D< Real > &p1, const Point3D< Real > &p2)
void CrossProduct(const Point3D< Real > &p1, const Point3D< Real > &p2, Point3D< Real > &p)
Point3D< Real > RandomSpherePoint(void)
double SquareLength(const Point3D< Real > &p)
void TriangleCollapse(const Real &edgeRatio, std::vector< TriangleIndex > &triangles, std::vector< Point3D< Real > > &positions, std::vector< Point3D< Real > > *normals)
void EdgeCollapse(const Real &edgeRatio, std::vector< TriangleIndex > &triangles, std::vector< Point3D< Real > > &positions, std::vector< Point3D< Real > > *normals)
Point3D< Real > RandomBallPoint(void)
double Length(const Point3D< Real > &p)