TriangleMeshShaper.cpp
Go to the documentation of this file.
1 /*
2  * Copyright (c) 2008, AIST, the University of Tokyo and General Robotix Inc.
3  * All rights reserved. This program is made available under the terms of the
4  * Eclipse Public License v1.0 which accompanies this distribution, and is
5  * available at http://www.eclipse.org/legal/epl-v10.html
6  * Contributors:
7  * National Institute of Advanced Industrial Science and Technology (AIST)
8  */
9 
15 #include "TriangleMeshShaper.h"
16 #include "Triangulator.h"
17 #include <iostream>
18 #include <cmath>
19 #include <vector>
20 #include <map>
21 #include <hrpUtil/Eigen3d.h>
22 
23 using namespace std;
24 using namespace boost;
25 using namespace hrp;
26 
27 namespace {
28  const double PI = 3.14159265358979323846;
29 }
30 
31 namespace hrp {
32 
33  class TMSImpl
34  {
35  public:
37 
39 
42 
43  typedef std::map<VrmlShapePtr, SFNode> ShapeToGeometryMap;
44  ShapeToGeometryMap shapeToOriginalGeometryMap;
45 
46  // for triangulation
48  std::vector<int> polygon;
49  std::vector<int> indexPositionMap;
50  std::vector<int> faceIndexMap;
51 
52  // for normal generation
53  std::vector<Vector3> faceNormals;
54  std::vector< std::vector<int> > vertexIndexToFaceIndicesMap;
55  std::vector< std::vector<int> > vertexIndexToNormalIndicesMap;
56 
57  enum RemapType { REMAP_COLOR, REMAP_NORMAL };
58 
59 
60  SFNode getOriginalGeometry(VrmlShapePtr shapeNode);
61  bool traverseShapeNodes(VrmlNode* node, AbstractVrmlGroup* parentNode, int indexInParent);
62  bool convertShapeNode(VrmlShape* shapeNode);
63  bool convertIndexedFaceSet(VrmlIndexedFaceSet* faceSet);
64 
65  template <class TArray>
66  bool remapDirectMapObjectsPerFaces(TArray& objects, const char* objectName);
67 
68  bool checkAndRemapIndices(RemapType type, unsigned int numElements, MFInt32& indices, bool perVertex,
69  VrmlIndexedFaceSet* triangleMesh);
70  void putError1(const char* valueName);
71 
72  bool convertBox(VrmlBox* box, VrmlIndexedFaceSetPtr& triangleMesh);
73  bool convertCone(VrmlCone* cone, VrmlIndexedFaceSetPtr& triangleMesh);
74  bool convertPointSet(VrmlPointSet* pointSet, VrmlIndexedFaceSetPtr& triangleMesh);
75  bool convertCylinder(VrmlCylinder* cylinder, VrmlIndexedFaceSetPtr& triangleMesh);
76  bool convertSphere(VrmlSphere* sphere, VrmlIndexedFaceSetPtr& triangleMesh);
77  bool convertElevationGrid(VrmlElevationGrid* grid, VrmlIndexedFaceSetPtr& triangleMesh);
78  bool convertExtrusion(VrmlExtrusion* extrusion, VrmlIndexedFaceSetPtr& triangleMesh);
79  void generateNormals(VrmlIndexedFaceSetPtr& triangleMesh);
80  void calculateFaceNormals(VrmlIndexedFaceSetPtr& triangleMesh);
81  void setVertexNormals(VrmlIndexedFaceSetPtr& triangleMesh);
82  void setFaceNormals(VrmlIndexedFaceSetPtr& triangleMesh);
83  bool setTexCoordIndex(VrmlIndexedFaceSetPtr faseSet );
84 
85  void putMessage(const std::string& message);
86  };
87 }
88 
89 
90 TriangleMeshShaper::TriangleMeshShaper()
91 {
92  impl = new TMSImpl(this);
93 }
94 
95 
96 TMSImpl::TMSImpl(TriangleMeshShaper* self) : self(self)
97 {
98  divisionNumber = 20;
100 }
101 
102 
104 {
105  delete impl;
106 }
107 
108 
117 {
118  impl->divisionNumber = std::max(4, n);
119 }
120 
121 
128 {
129  impl->isNormalGenerationMode = on;
130 }
131 
132 
141 {
142  return impl->getOriginalGeometry(shapeNode);
143 }
144 
145 
147 {
148  SFNode originalGeometryNode;
149  ShapeToGeometryMap::iterator p = shapeToOriginalGeometryMap.find(shapeNode);
150  if(p != shapeToOriginalGeometryMap.end()){
151  originalGeometryNode = p->second;
152  }
153  return originalGeometryNode;
154 }
155 
156 
170 {
171  bool resultOfTopNode = impl->traverseShapeNodes(topNode.get(), 0, 0);
172  return resultOfTopNode ? topNode : VrmlNodePtr();
173 }
174 
175 
176 bool TMSImpl::traverseShapeNodes(VrmlNode* node, AbstractVrmlGroup* parentNode, int indexInParent)
177 {
178  bool result = true;
179 
181  VrmlProtoInstance* protoInstance = static_cast<VrmlProtoInstance*>(node);
182  if(protoInstance->actualNode){
183  traverseShapeNodes(protoInstance->actualNode.get(), parentNode, indexInParent);
184  }
185 
186  } else if(node->isCategoryOf(GROUPING_NODE)){
187  AbstractVrmlGroup* group = static_cast<AbstractVrmlGroup*>(node);
188  int numChildren = group->countChildren();
189  for(int i = 0; i < numChildren; i++){
190  traverseShapeNodes(group->getChild(i), group, i);
191  }
192 
193  } else if(node->isCategoryOf(SHAPE_NODE)){
194  VrmlShape* shapeNode = static_cast<VrmlShape*>(node);
195  result = convertShapeNode(shapeNode);
196  if(!result){
197  if(parentNode){
198  putMessage("Node is inconvertible and removed from the scene graph");
199  parentNode->removeChild(indexInParent);
200  }
201  }
202  }
203 
204  return result;
205 }
206 
207 
209 {
210  bool result = false;
211 
212  VrmlNode *node = shapeNode->geometry.get();
213  VrmlGeometry* geometry = dynamic_cast<VrmlGeometry *>(node);
214  if (!geometry){
215  VrmlProtoInstance *protoInstance = dynamic_cast<VrmlProtoInstance *>(node);
216  if (protoInstance){
217  geometry = dynamic_cast<VrmlGeometry *>(protoInstance->actualNode.get());
218  }
219  }
220 
221  VrmlIndexedFaceSetPtr triangleMesh;
222 
223  if(VrmlIndexedFaceSet* faceSet = dynamic_cast<VrmlIndexedFaceSet*>(geometry)){
224  if(faceSet->coord){
225  result = convertIndexedFaceSet(faceSet);
226  triangleMesh = faceSet;
227  }
228 
229  } else {
230 
231  triangleMesh = new VrmlIndexedFaceSet();
232  triangleMesh->coord = new VrmlCoordinate();
233 
234  if(VrmlBox* box = dynamic_cast<VrmlBox*>(geometry)){
235  result = convertBox(box, triangleMesh);
236 
237  } else if(VrmlCone* cone = dynamic_cast<VrmlCone*>(geometry)){
238  result = convertCone(cone, triangleMesh);
239 
240  } else if(VrmlCylinder* cylinder = dynamic_cast<VrmlCylinder*>(geometry)){
241  result = convertCylinder(cylinder, triangleMesh);
242 
243  } else if(VrmlSphere* sphere = dynamic_cast<VrmlSphere*>(geometry)){
244  result = convertSphere(sphere, triangleMesh);
245 
246  } else if(VrmlElevationGrid* elevationGrid = dynamic_cast<VrmlElevationGrid*>(geometry)){
247  result = convertElevationGrid(elevationGrid, triangleMesh);
248 
249  } else if(VrmlExtrusion* extrusion = dynamic_cast<VrmlExtrusion*>(geometry)){
250  result = convertExtrusion(extrusion, triangleMesh);
251  } else if(VrmlPointSet* pointSet = dynamic_cast<VrmlPointSet*>(geometry)){
252  result = convertPointSet(pointSet, triangleMesh);
253  }
254  if(result){
255  shapeToOriginalGeometryMap[shapeNode] = node;
256  shapeNode->geometry = triangleMesh;
257  }
258  }
259 
260  if(result && !triangleMesh->normal && isNormalGenerationMode){
261  generateNormals(triangleMesh);
262  }
263 
264  return result;
265 }
266 
267 
269 {
270  MFVec3f& vertices = faceSet->coord->point;
271  int numVertices = vertices.size();
272 
273  MFInt32& indices = faceSet->coordIndex;
274  const MFInt32 orgIndices = indices;
275  indices.clear();
276 
277  const int numOrgIndices = orgIndices.size();
278 
279  int orgFaceIndex = 0;
280  int polygonTopIndexPosition = 0;
281 
282  indexPositionMap.clear();
283  faceIndexMap.clear();
284  polygon.clear();
285 
286  int triangleOrder[3];
287  if(faceSet->ccw){
288  triangleOrder[0] = 0; triangleOrder[1] = 1; triangleOrder[2] = 2;
289  } else {
290  triangleOrder[0] = 2; triangleOrder[1] = 1; triangleOrder[2] = 0;
291  }
292 
293  triangulator.setVertices(vertices);
294 
295  for(int i=0; i < numOrgIndices; ++i){
296  int index = orgIndices[i];
297  if(index >= numVertices){
298  putMessage("The coordIndex field has an index over the size of the vertices in the coord field");
299  } else if(index >= 0){
300  polygon.push_back(index);
301  } else {
302  int numTriangles = triangulator.apply(polygon);
303  const vector<int>& triangles = triangulator.triangles();
304  for(int j=0; j < numTriangles; ++j){
305  for(int k=0; k < 3; ++k){
306  int localIndex = triangles[j * 3 + triangleOrder[k]];
307  indices.push_back(polygon[localIndex]);
308  indexPositionMap.push_back(polygonTopIndexPosition + localIndex);
309  }
310  indices.push_back(-1);
311  indexPositionMap.push_back(-1);
312  faceIndexMap.push_back(orgFaceIndex);
313  }
314  polygonTopIndexPosition = i + 1;
315  orgFaceIndex++;
316  polygon.clear();
317  }
318  }
319 
320  bool result = true;
321 
322  int numColors = faceSet->color ? faceSet->color->color.size() : 0;
323  result &= checkAndRemapIndices
324  (REMAP_COLOR, numColors, faceSet->colorIndex, faceSet->colorPerVertex, faceSet);
325 
326  int numNormals = faceSet->normal ? faceSet->normal->vector.size() : 0;
327  result &= checkAndRemapIndices
328  (REMAP_NORMAL, numNormals, faceSet->normalIndex, faceSet->normalPerVertex, faceSet);
329 
330  if(numNormals > 0 && !faceSet->ccw){
331  // flip normal vectors
332  MFVec3f& normals = faceSet->normal->vector;
333  for(unsigned int i=0; i < normals.size(); ++i){
334  SFVec3f& n = normals[i];
335  n[0] = -n[0];
336  n[1] = -n[1];
337  n[2] = -n[2];
338  }
339  }
340  faceSet->ccw = true;
341 
342  setTexCoordIndex(faceSet);
343 
344  return (result && !indices.empty());
345 }
346 
347 
348 template <class TArray>
349 bool TMSImpl::remapDirectMapObjectsPerFaces(TArray& values, const char* valueName)
350 {
351  const TArray orgValues = values;
352  int numOrgValues = orgValues.size();
353  int numFaces = faceIndexMap.size();
354  values.resize(numFaces);
355  for(int i=0; i < numFaces; ++i){
356  int faceIndex = faceIndexMap[i];
357  if(faceIndex >= numOrgValues){
358  putMessage(string("The number of ") + valueName + " is less than the number of faces.");
359  return false;
360  }
361  values[i] = orgValues[faceIndex];
362  }
363  return true;
364 }
365 
366 
368 (RemapType type, unsigned int numElements, MFInt32& indices, bool perVertex, VrmlIndexedFaceSet* triangleMesh)
369 {
370  const char* valueName = (type==REMAP_COLOR) ? "colors" : "normals" ;
371 
372  bool result = true;
373 
374  if(numElements == 0){
375  if(!indices.empty()){
376  putMessage(string("An IndexedFaceSet has no ") + valueName +
377  ", but it has a non-empty index field of " + valueName + ".");
378  result = false;
379  }
380 
381  } else {
382 
383  if(indices.empty()){
384  if(perVertex){
385  if(numElements < triangleMesh->coord->point.size()){
386  putMessage(string("The number of ") + valueName +
387  " is less than the number of vertices.");
388  result = false;
389  }
390  } else {
391  if(type == REMAP_COLOR){
392  remapDirectMapObjectsPerFaces(triangleMesh->color->color, valueName);
393  } else if(type == REMAP_NORMAL){
394  remapDirectMapObjectsPerFaces(triangleMesh->normal->vector, valueName);
395  }
396  }
397  } else {
398  const MFInt32 orgIndices = indices;
399 
400  if(perVertex){
401  int numNewIndices = indexPositionMap.size();
402  indices.resize(numNewIndices);
403  for(int i=0; i < numNewIndices; ++i){
404  int orgPosition = indexPositionMap[i];
405  if(orgPosition < 0){
406  indices[i] = -1;
407  } else {
408  int index = orgIndices[orgPosition];
409  if(index < (int)numElements){
410  indices[i] = index;
411  } else {
412  putError1(valueName);
413  result = false;
414  }
415  }
416  }
417  } else {
418  int numNewIndices = faceIndexMap.size();
419  indices.resize(numNewIndices);
420  for(int i=0; i < numNewIndices; ++i){
421  int orgFaceIndex = faceIndexMap[i];
422  int index = orgIndices[orgFaceIndex];
423  if(index < (int)numElements){
424  indices[i] = index;
425  } else {
426  putError1(valueName);
427  result = false;
428  }
429  }
430  }
431  }
432  }
433 
434  return result;
435 }
436 
437 
439 {
440  bool result = true;
441  VrmlTextureCoordinatePtr texCoord = faseSet->texCoord;
442  MFInt32& texCoordIndex = faseSet->texCoordIndex;
443  MFInt32& coordIndex = faseSet->coordIndex;
444 
445  if(texCoord){
446  if(texCoordIndex.empty()){
447  texCoordIndex.resize(coordIndex.size());
448  copy( coordIndex.begin(), coordIndex.end(), texCoordIndex.begin() );
449  } else {
450  const MFInt32 orgIndices = texCoordIndex;
451  int numNewIndices = indexPositionMap.size();
452  texCoordIndex.resize(numNewIndices);
453  for(int i=0; i < numNewIndices; ++i){
454  if(indexPositionMap[i] == -1){
455  texCoordIndex[i] = -1;
456  } else {
457  int index = orgIndices[indexPositionMap[i]];
458  if(index < (int)texCoord->point.size()){
459  texCoordIndex[i] = index;
460  } else {
461  putError1("texCoordIndex");
462  result = false;
463  }
464  }
465  }
466  }
467  }
468  return result;
469 }
470 
471 
472 void TMSImpl::putError1(const char* valueName)
473 {
474  putMessage(string("There is an index of ") + valueName +
475  " beyond the size of " + valueName + ".");
476 }
477 
478 
479 namespace {
480 
481  inline int addVertex(MFVec3f& vertices, const double x, const double y, const double z)
482  {
483  SFVec3f v;
484  v[0] = x;
485  v[1] = y;
486  v[2] = z;
487  vertices.push_back(v);
488  return vertices.size() - 1;
489  }
490 
491  inline void addTriangle(MFInt32& indices, int x, int y, int z)
492  {
493  indices.push_back(x);
494  indices.push_back(y);
495  indices.push_back(z);
496  indices.push_back(-1);
497  }
498 }
499 
500 
502 {
503  const double x = box->size[0] / 2.0;
504  const double y = box->size[1] / 2.0;
505  const double z = box->size[2] / 2.0;
506 
507  if(x < 0.0 || y < 0.0 || z < 0.0 ){
508  putMessage("BOX : wrong value.");
509  return false;
510  }
511 
512  MFVec3f& vertices = triangleMesh->coord->point;
513  vertices.reserve(8);
514 
515  static const int numTriangles = 12;
516 
517  static const double xsigns[] = { -1.0, -1.0, -1.0, -1.0, 1.0, 1.0, 1.0, 1.0 };
518  static const double ysigns[] = { -1.0, -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0 };
519  static const double zsigns[] = { -1.0, 1.0, 1.0, -1.0, -1.0, 1.0, 1.0, -1.0 };
520 
521  static const int triangles[] = {
522  0, 1, 2,
523  2, 3, 0,
524  3, 2, 6,
525  3, 6, 7,
526  6, 2, 1,
527  1, 5, 6,
528  1, 0, 5,
529  5, 0, 4,
530  5, 4, 6,
531  6, 4, 7,
532  7, 4, 0,
533  0, 3, 7
534  };
535 
536  for(int i=0; i < 8; ++i){
537  addVertex(vertices, xsigns[i] * x, ysigns[i] * y, zsigns[i] * z);
538  }
539 
540  MFInt32& indices = triangleMesh->coordIndex;
541  indices.resize(numTriangles * 4);
542 
543  int di = 0;
544  int si = 0;
545  for(int i=0; i < numTriangles; i++){
546  indices[di++] = triangles[si++];
547  indices[di++] = triangles[si++];
548  indices[di++] = triangles[si++];
549  indices[di++] = -1;
550  }
551 
552  return true;
553 }
554 
555 
557 {
558  triangleMesh->coord = pointSet->coord;
559  triangleMesh->color = pointSet->color;
560 
561  return true;
562 }
563 
564 
566 {
567  const double radius = cone->bottomRadius;
568 
569  if(cone->height < 0.0 || radius < 0.0 ){
570  putMessage( "CONE : wrong value." );
571  return false;
572  }
573 
574  MFVec3f& vertices = triangleMesh->coord->point;
575  vertices.reserve(divisionNumber + 1);
576 
577  for(int i=0; i < divisionNumber; ++i){
578  const double angle = i * 2.0 * PI / divisionNumber;
579  addVertex(vertices, radius * cos(angle), -cone->height/2.0, radius * sin(angle));
580  }
581 
582  const int topIndex = addVertex(vertices, 0.0, cone->height/2.0, 0.0);
583  const int bottomCenterIndex = addVertex(vertices, 0.0, -cone->height/2.0, 0.0);
584 
585  MFInt32& indices = triangleMesh->coordIndex;
586  indices.reserve((divisionNumber * 2) * 4);
587 
588  for(int i=0; i < divisionNumber; ++i){
589  // side faces
590  if(cone->side)
591  addTriangle(indices, topIndex, (i + 1) % divisionNumber, i);
592  // bottom faces
593  if(cone->bottom)
594  addTriangle(indices, bottomCenterIndex, i, (i + 1) % divisionNumber);
595  }
596 
597  triangleMesh->creaseAngle = 3.14 / 2.0;
598 
599  return true;
600 }
601 
602 
604 {
605  if(cylinder->height < 0.0 || cylinder->radius < 0.0){
606  putMessage("CYLINDER : wrong value.");
607  return false;
608  }
609 
610  MFVec3f& vertices = triangleMesh->coord->point;
611  vertices.reserve(divisionNumber * 2 + 2);
612  vertices.resize(divisionNumber * 2);
613 
614  const double y = cylinder->height / 2.0;
615 
616  for(int i=0 ; i < divisionNumber ; i++ ){
617  const double angle = i * 2.0 * PI / divisionNumber;
618  SFVec3f& vtop = vertices[i];
619  SFVec3f& vbottom = vertices[i + divisionNumber];
620  vtop[0] = vbottom[0] = cylinder->radius * cos(angle);
621  vtop[2] = vbottom[2] = cylinder->radius * sin(angle);
622  vtop[1] = y;
623  vbottom[1] = -y;
624  }
625 
626  const int topCenterIndex = addVertex(vertices, 0.0, y, 0.0);
627  const int bottomCenterIndex = addVertex(vertices, 0.0, -y, 0.0);
628 
629  MFInt32& indices = triangleMesh->coordIndex;
630  indices.reserve((divisionNumber * 4) * 4);
631 
632  for(int i=0; i < divisionNumber; ++i){
633  // top face
634  if(cylinder->top)
635  addTriangle(indices, topCenterIndex, (i+1) % divisionNumber, i);
636  // side face (upward convex triangle)
637  if(cylinder->side){
638  addTriangle(indices, i, ((i+1) % divisionNumber) + divisionNumber, i + divisionNumber);
639  // side face (downward convex triangle)
640  addTriangle(indices, i, (i+1) % divisionNumber, ((i + 1) % divisionNumber) + divisionNumber);
641  }
642  // bottom face
643  if(cylinder->bottom)
644  addTriangle(indices, bottomCenterIndex, i + divisionNumber, ((i+1) % divisionNumber) + divisionNumber);
645  }
646 
647  triangleMesh->creaseAngle = 3.14 / 2.0;
648 
649  return true;
650 }
651 
652 
654 {
655  const double r = sphere->radius;
656 
657  if(r < 0.0) {
658  putMessage("SPHERE : wrong value.");
659  return false;
660  }
661 
662  const int vdn = divisionNumber / 2; // latitudinal division number
663  const int hdn = divisionNumber; // longitudinal division number
664 
665  MFVec3f& vertices = triangleMesh->coord->point;
666  vertices.reserve((vdn - 1) * hdn + 2);
667 
668  for(int i=1; i < vdn; i++){ // latitudinal direction
669  double tv = i * PI / vdn;
670  for(int j=0; j < hdn; j++){ // longitudinal direction
671  double th = j * 2.0 * PI / hdn;
672  addVertex(vertices, r*sin(tv)*cos(th), r*cos(tv), r*sin(tv)*sin(th));
673  }
674  }
675 
676  const int topIndex = addVertex(vertices, 0.0, r, 0.0);
677  const int bottomIndex = addVertex(vertices, 0.0, -r, 0.0);
678 
679  MFInt32& indices = triangleMesh->coordIndex;
680  indices.reserve(vdn * hdn * 2 * 4);
681 
682  // top faces
683  for(int i=0; i < hdn; ++i){
684  addTriangle(indices, topIndex, (i+1) % hdn, i);
685  }
686 
687  // side faces
688  for(int i=0; i < vdn - 2; ++i){
689  const int upper = i * hdn;
690  const int lower = (i + 1) * hdn;
691  for(int j=0; j < hdn; ++j) {
692  // upward convex triangle
693  addTriangle(indices, j + upper, ((j + 1) % hdn) + lower, j + lower);
694  // downward convex triangle
695  addTriangle(indices, j + upper, ((j + 1) % hdn) + upper, ((j + 1) % hdn) + lower);
696  }
697  }
698 
699  // bottom faces
700  const int offset = (vdn - 2) * hdn;
701  for(int i=0; i < hdn; ++i){
702  addTriangle(indices, bottomIndex, (i % hdn) + offset, ((i+1) % hdn) + offset);
703  }
704 
705  triangleMesh->creaseAngle = PI;
706 
707  return true;
708 }
709 
710 
715 {
716  if(grid->xDimension * grid->zDimension != static_cast<SFInt32>(grid->height.size())){
717  putMessage("ELEVATIONGRID : wrong value.");
718  return false;
719  }
720 
721  MFVec3f& vertices = triangleMesh->coord->point;
722  vertices.reserve(grid->zDimension * grid->xDimension);
723 
724  for(int z=0; z < grid->zDimension; z++){
725  for(int x=0; x < grid->xDimension; x++ ){
726  addVertex(vertices, x * grid->xSpacing, grid->height[z * grid->xDimension + x], z * grid->zSpacing);
727  }
728  }
729 
730  MFInt32& indices = triangleMesh->coordIndex;
731  indices.reserve((grid->zDimension - 1) * (grid->xDimension - 1) * 2 * 4);
732 
733  for(int z=0; z < grid->zDimension - 1; ++z){
734  const int current = z * grid->xDimension;
735  const int next = (z + 1) * grid->xDimension;
736  for(int x=0; x < grid->xDimension - 1; ++x){
737  if(grid->ccw){
738  addTriangle(indices, x + current, x + next, (x + 1) + next);
739  addTriangle(indices, x + current, (x + 1) + next, (x + 1) + current);
740  }else{
741  addTriangle(indices, x + current, (x + 1) + next, x + next);
742  addTriangle(indices, x + current, (x + 1) + current, (x + 1) + next);
743  }
744  }
745  }
746 
747  triangleMesh->creaseAngle = grid->creaseAngle;
748  triangleMesh->ccw = true;
749  //triangleMesh->normalPerVertex = grid->normalPerVertex;
750  triangleMesh->solid = grid->solid;
751 
752  if(grid->texCoord){
753  triangleMesh->texCoord->point.resize(grid->texCoord->point.size());
754  copy(grid->texCoord->point.begin(), grid->texCoord->point.end(), triangleMesh->texCoord->point.begin());
755  triangleMesh->texCoordIndex.resize(indices.size());
756  copy(indices.begin(), indices.end(), triangleMesh->texCoordIndex.begin());
757  }
758 
759  return true;
760 }
761 
762 
764 {
765  bool isClosed = false;
766  int numSpine = extrusion->spine.size();
767  int numcross = extrusion->crossSection.size();
768  if( extrusion->spine[0][0] == extrusion->spine[numSpine-1][0] &&
769  extrusion->spine[0][1] == extrusion->spine[numSpine-1][1] &&
770  extrusion->spine[0][2] == extrusion->spine[numSpine-1][2] )
771  isClosed = true;
772  bool crossSectionisClosed = false;
773  if( extrusion->crossSection[0][0] == extrusion->crossSection[numcross-1][0] &&
774  extrusion->crossSection[0][1] == extrusion->crossSection[numcross-1][1] )
775  crossSectionisClosed = true;
776 
777  MFVec3f& vertices = triangleMesh->coord->point;
778  vertices.reserve(numSpine*numcross);
779 
780  Vector3 preZaxis;
781  int definedZaxis=-1;
782  std::vector<Vector3> Yaxisarray;
783  std::vector<Vector3> Zaxisarray;
784  if(numSpine > 2){
785  for(int i=0; i<numSpine; i++){
786  Vector3 spine1, spine2, spine3;
787  Vector3 Yaxis, Zaxis;
788  if(i==0){
789  if(isClosed){
790  getVector3(spine1, extrusion->spine[numSpine-2]);
791  getVector3(spine2, extrusion->spine[0]);
792  getVector3(spine3, extrusion->spine[1]);
793  Yaxis = spine3-spine1;
794  Zaxis = (spine3-spine2).cross(spine1-spine2);
795  }else{
796  getVector3(spine1, extrusion->spine[0]);
797  getVector3(spine2, extrusion->spine[1]);
798  getVector3(spine3, extrusion->spine[2]);
799  Yaxis = spine2-spine1;
800  Zaxis = (spine3-spine2).cross(spine1-spine2);
801  }
802  }else if(i==numSpine-1){
803  if(isClosed){
804  getVector3(spine1, extrusion->spine[numSpine-2]);
805  getVector3(spine2, extrusion->spine[0]);
806  getVector3(spine3, extrusion->spine[1]);
807  Yaxis = spine3-spine1;
808  Zaxis = (spine3-spine2).cross(spine1-spine2);
809  }else{
810  getVector3(spine1, extrusion->spine[numSpine-3]);
811  getVector3(spine2, extrusion->spine[numSpine-2]);
812  getVector3(spine3, extrusion->spine[numSpine-1]);
813  Yaxis = spine3-spine2;
814  Zaxis = (spine3-spine2).cross(spine1-spine2);
815  }
816  }else{
817  getVector3(spine1, extrusion->spine[i-1]);
818  getVector3(spine2, extrusion->spine[i]);
819  getVector3(spine3, extrusion->spine[i+1]);
820  Yaxis = spine3-spine1;
821  Zaxis = (spine3-spine2).cross(spine1-spine2);
822  }
823  if(!Zaxis.norm()){
824  if(definedZaxis!=-1)
825  Zaxis=preZaxis;
826  }else{
827  if(definedZaxis==-1)
828  definedZaxis=i;
829  preZaxis = Zaxis;
830  }
831  Yaxisarray.push_back(Yaxis);
832  Zaxisarray.push_back(Zaxis);
833  }
834  }else{
835  Vector3 spine1, spine2;
836  Vector3 Yaxis;
837  getVector3(spine1, extrusion->spine[0]);
838  getVector3(spine2, extrusion->spine[1]);
839  Yaxis = spine2-spine1;
840  Yaxisarray.push_back(Yaxis);
841  Yaxisarray.push_back(Yaxis);
842  }
843  for(int i=0; i<numSpine; i++){
844  Matrix33 Scp;
845  if(definedZaxis==-1){
846  Vector3 y(Yaxisarray[i].normalized());
847  SFRotation R;
848  // R[0,1,2] = y X (0,1,0) cos(R[3]) = y.(0,1,0)
849  R[0] = y[2]; R[1] = 0.0; R[2] = -y[0]; R[3] = acos(y[1]);
850  Scp = rodrigues(Vector3(R[0],R[1],R[2]), R[3]);
851  }else{
852  if(i<definedZaxis)
853  Zaxisarray[i] = Zaxisarray[definedZaxis];
854  if( i && Zaxisarray[i].dot(Zaxisarray[i-1])<0 )
855  Zaxisarray[i] *= -1;
856  Vector3 y(Yaxisarray[i].normalized());
857  Vector3 z(Zaxisarray[i].normalized());
858  Vector3 x(y.cross(z));
859  Scp << x, y, z;
860  }
861 
862  Vector3 spine(extrusion->spine[i][0],
863  extrusion->spine[i][1],
864  extrusion->spine[i][2]);
865 
866  Vector3 scale;
867  if(extrusion->scale.size()==1)
868  scale = Vector3(extrusion->scale[0][0], 0, extrusion->scale[0][1]);
869  else
870  scale = Vector3(extrusion->scale[i][0], 0, extrusion->scale[i][1]);
871  Matrix33 orientation;
872  if(extrusion->orientation.size()==1)
873  orientation = rodrigues(Vector3(extrusion->orientation[0][0],extrusion->orientation[0][1],extrusion->orientation[0][2]),
874  extrusion->orientation[0][3]);
875  else
876  orientation = rodrigues(Vector3(extrusion->orientation[i][0],extrusion->orientation[i][1],extrusion->orientation[i][2]),
877  extrusion->orientation[i][3]);
878 
879  for(int j=0; j<numcross; j++){
880  Vector3 crossSection(extrusion->crossSection[j][0], 0, extrusion->crossSection[j][1] );
881  Vector3 v1(crossSection[0]*scale[0], 0, crossSection[2]*scale[2]);
882  Vector3 v2(Scp*orientation*v1+spine);
883  addVertex(vertices,v2[0], v2[1], v2[2]);
884  }
885  }
886 
887  MFInt32& indices = triangleMesh->coordIndex;
888  for(int i=0; i < numSpine-1 ; i++){
889  const int upper = i * numcross;
890  const int lower = (i + 1) * numcross;
891  for(int j=0; j < numcross-1; ++j) {
892  if(extrusion->ccw){
893  // upward convex triangle
894  addTriangle(indices, j + upper, (j + 1)+ lower, j + lower);
895  // downward convex triangle
896  addTriangle(indices, j + upper, (j + 1)+ upper, j + 1 + lower);
897  }else{
898  addTriangle(indices, j + upper, j + lower, (j + 1) + lower);
899  addTriangle(indices, j + upper, (j + 1)+ lower, j + 1 + upper);
900  }
901  }
902  }
903 
904  int j=0;
905  if(crossSectionisClosed)
906  j=1;
907  if(extrusion->beginCap && !isClosed){
908  triangulator.setVertices(vertices);
909  polygon.clear();
910  for(int i=0; i<numcross-j; i++)
911  polygon.push_back(i);
913  const vector<int>& triangles = triangulator.triangles();
914  for(unsigned int i=0; i<triangles.size(); i+=3 )
915  if(extrusion->ccw){
916  addTriangle(indices, polygon[triangles[i]], polygon[triangles[i+2]], polygon[triangles[i+1]]);
917  }else{
918  addTriangle(indices, polygon[triangles[i]], polygon[triangles[i+1]], polygon[triangles[i+2]]);
919  }
920  }
921 
922  if(extrusion->endCap && !isClosed){
923  triangulator.setVertices(vertices);
924  polygon.clear();
925  for(int i=0; i<numcross-j; i++)
926  polygon.push_back(numcross*(numSpine-1)+i);
928  const vector<int>& triangles = triangulator.triangles();
929  for(unsigned int i=0; i<triangles.size(); i+=3 )
930  if(extrusion->ccw){
931  addTriangle(indices, polygon[triangles[i]], polygon[triangles[i+1]], polygon[triangles[i+2]]);
932  }else{
933  addTriangle(indices, polygon[triangles[i]], polygon[triangles[i+2]], polygon[triangles[i+1]]);
934  }
935  }
936 
937  triangleMesh->creaseAngle = extrusion->creaseAngle;
938  triangleMesh->ccw = true;
939  triangleMesh->convex = true;
940  triangleMesh->solid = extrusion->solid;
941 
942  return true;
943 }
944 
945 
947 {
948  triangleMesh->normal = new VrmlNormal();
949  triangleMesh->normalPerVertex = (triangleMesh->creaseAngle > 0.0) ? true : false;
950 
951  calculateFaceNormals(triangleMesh);
952 
953  if(triangleMesh->normalPerVertex){
954  setVertexNormals(triangleMesh);
955  } else {
956  setFaceNormals(triangleMesh);
957  }
958 }
959 
960 
962 {
963  const MFVec3f& vertices = triangleMesh->coord->point;
964  const int numVertices = vertices.size();
965  const MFInt32& triangles = triangleMesh->coordIndex;
966  const int numFaces = triangles.size() / 4;
967 
968  faceNormals.clear();
969 
970  if(triangleMesh->normalPerVertex){
972  vertexIndexToFaceIndicesMap.resize(numVertices);
973  }
974 
975  for(int faceIndex=0; faceIndex < numFaces; ++faceIndex){
976 
977  Vector3Ref v0(getVector3Ref(vertices[triangles[faceIndex * 4 + 0]].data()));
978  Vector3Ref v1(getVector3Ref(vertices[triangles[faceIndex * 4 + 1]].data()));
979  Vector3Ref v2(getVector3Ref(vertices[triangles[faceIndex * 4 + 2]].data()));
980  Vector3 normal((v1 - v0).cross(v2 - v0));
981  if ( ! normal.isZero() ) {
982  normal.normalize();
983  }
984  faceNormals.push_back(normal);
985 
986  if(triangleMesh->normalPerVertex){
987  for(int i=0; i < 3; ++i){
988  int vertexIndex = triangles[faceIndex * 4 + i];
989  vector<int>& facesOfVertex = vertexIndexToFaceIndicesMap[vertexIndex];
990  bool isSameNormalFaceFound = false;
991  for(unsigned int j=0; j < facesOfVertex.size(); ++j){
992  const Vector3& otherNormal = faceNormals[facesOfVertex[j]];
993  const Vector3 d(otherNormal - normal);
994  // the same face is not appended
995  if(d.dot(d) <= numeric_limits<double>::epsilon()){
996  isSameNormalFaceFound = true;
997  break;
998  }
999  }
1000  if(!isSameNormalFaceFound){
1001  facesOfVertex.push_back(faceIndex);
1002  }
1003  }
1004  }
1005  }
1006 }
1007 
1008 
1010 {
1011  const MFVec3f& vertices = triangleMesh->coord->point;
1012  const int numVertices = vertices.size();
1013  const MFInt32& triangles = triangleMesh->coordIndex;
1014  const int numFaces = triangles.size() / 4;
1015 
1016  MFVec3f& normals = triangleMesh->normal->vector;
1017  MFInt32& normalIndices = triangleMesh->normalIndex;
1018  normalIndices.clear();
1019  normalIndices.reserve(triangles.size());
1020 
1022  vertexIndexToNormalIndicesMap.resize(numVertices);
1023 
1024  //const double cosCreaseAngle = cos(triangleMesh->creaseAngle);
1025 
1026  for(int faceIndex=0; faceIndex < numFaces; ++faceIndex){
1027 
1028  for(int i=0; i < 3; ++i){
1029 
1030  int vertexIndex = triangles[faceIndex * 4 + i];
1031  vector<int>& facesOfVertex = vertexIndexToFaceIndicesMap[vertexIndex];
1032  const Vector3& currentFaceNormal = faceNormals[faceIndex];
1033  Vector3 normal = currentFaceNormal;
1034  bool normalIsFaceNormal = true;
1035 
1036  // avarage normals of the faces whose crease angle is below the 'creaseAngle' variable
1037  for(unsigned int j=0; j < facesOfVertex.size(); ++j){
1038  int adjoiningFaceIndex = facesOfVertex[j];
1039  const Vector3& adjoiningFaceNormal = faceNormals[adjoiningFaceIndex];
1040  double currentFaceNormalLen = currentFaceNormal.norm();
1041  if (currentFaceNormalLen == 0) continue;
1042  double adjoiningFaceNormalLen = adjoiningFaceNormal.norm();
1043  if (adjoiningFaceNormalLen == 0) continue;
1044  double cosAngle = currentFaceNormal.dot(adjoiningFaceNormal)
1045  / (currentFaceNormalLen * adjoiningFaceNormalLen);
1046  if (cosAngle > 1.0) cosAngle = 1.0;
1047  if (cosAngle < -1.0) cosAngle = -1.0;
1048  double angle = acos(cosAngle);
1049  if(angle > 1.0e-6 && angle < triangleMesh->creaseAngle){
1050  normal += adjoiningFaceNormal;
1051  normalIsFaceNormal = false;
1052  }
1053 
1054  }
1055  if(!normalIsFaceNormal){
1056  normal.normalize();
1057  }
1058 
1059  int normalIndex = -1;
1060 
1061  for(int j=0; j < 3; ++j){
1062  int vertexIndex2 = triangles[faceIndex * 4 + j];
1063  vector<int>& normalIndicesOfVertex = vertexIndexToNormalIndicesMap[vertexIndex2];
1064  for(unsigned int k=0; k < normalIndicesOfVertex.size(); ++k){
1065  int index = normalIndicesOfVertex[k];
1066  const SFVec3f& norg = normals[index];
1067  const Vector3 d(Vector3(norg[0], norg[1], norg[2]) - normal);
1068  if(d.dot(d) <= numeric_limits<double>::epsilon()){
1069  normalIndex = index;
1070  goto normalIndexFound;
1071  }
1072  }
1073  }
1074  if(normalIndex < 0){
1075  SFVec3f n;
1076  n[0] = normal[0]; n[1] = normal[1]; n[2] = normal[2];
1077  normalIndex = normals.size();
1078  normals.push_back(n);
1079  vertexIndexToNormalIndicesMap[vertexIndex].push_back(normalIndex);
1080  }
1081 
1082  normalIndexFound:
1083  normalIndices.push_back(normalIndex);
1084  }
1085  normalIndices.push_back(-1);
1086  }
1087 }
1088 
1089 
1091 {
1092  const MFInt32& triangles = triangleMesh->coordIndex;
1093  const int numFaces = triangles.size() / 4;
1094 
1095  MFVec3f& normals = triangleMesh->normal->vector;
1096  MFInt32& normalIndices = triangleMesh->normalIndex;
1097  normalIndices.clear();
1098  normalIndices.reserve(numFaces);
1099 
1100  const int numVertices = triangleMesh->coord->point.size();
1102  vertexIndexToNormalIndicesMap.resize(numVertices);
1103 
1104  for(int faceIndex=0; faceIndex < numFaces; ++faceIndex){
1105 
1106  const Vector3& normal = faceNormals[faceIndex];
1107  int normalIndex = -1;
1108 
1109  // find the same normal from the existing normals
1110  for(int i=0; i < 3; ++i){
1111  int vertexIndex = triangles[faceIndex * 4 + i];
1112  vector<int>& normalIndicesOfVertex = vertexIndexToNormalIndicesMap[vertexIndex];
1113  for(unsigned int j=0; j < normalIndicesOfVertex.size(); ++j){
1114  int index = normalIndicesOfVertex[j];
1115  const SFVec3f& norg = normals[index];
1116  const Vector3 n(norg[0], norg[1], norg[2]);
1117  if((n - normal).norm() <= numeric_limits<double>::epsilon()){
1118  normalIndex = index;
1119  goto normalIndexFound2;
1120  }
1121  }
1122  }
1123  if(normalIndex < 0){
1124  SFVec3f n;
1125  n[0] = normal[0]; n[1] = normal[1]; n[2] = normal[2];
1126  normalIndex = normals.size();
1127  normals.push_back(n);
1128  for(int i=0; i < 3; ++i){
1129  int vertexIndex = triangles[faceIndex * 4 + i];
1130  vertexIndexToNormalIndicesMap[vertexIndex].push_back(normalIndex);
1131  }
1132  }
1133  normalIndexFound2:
1134  normalIndices.push_back(normalIndex);
1135  }
1136 }
1137 
1138 
1139 void TMSImpl::putMessage(const std::string& message)
1140 {
1141  if(!self->sigMessage.empty()){
1142  self->sigMessage(message + "\n" );
1143  }
1144 }
1145 
1146 
1148 {
1149  VrmlIndexedFaceSet* triangleMesh = dynamic_cast<VrmlIndexedFaceSet*>(shapeNode->geometry.get());
1150  if(!triangleMesh)
1151  return;
1152  VrmlNode* node = getOriginalGeometry(shapeNode).get();
1153  VrmlGeometry *originalGeometry = dynamic_cast<VrmlGeometry *>(node);
1154  if (!originalGeometry){
1155  VrmlProtoInstance *protoInstance = dynamic_cast<VrmlProtoInstance *>(node);
1156  if (protoInstance){
1157  originalGeometry = dynamic_cast<VrmlGeometry *>(protoInstance->actualNode.get());
1158  }
1159  }
1160  if(originalGeometry){
1161  if(dynamic_cast<VrmlBox*>(originalGeometry)){ //Box
1162  defaultTextureMappingBox(triangleMesh);
1163  }else if(dynamic_cast<VrmlCone*>(originalGeometry)){ //cone
1164  defaultTextureMappingCone(triangleMesh);
1165  }else if(dynamic_cast<VrmlCylinder*>(originalGeometry)){ //Cylinder
1166  defaultTextureMappingCylinder(triangleMesh);
1167  }else if(VrmlSphere* sphere = dynamic_cast<VrmlSphere*>(originalGeometry)){ //sphere
1168  defaultTextureMappingSphere(triangleMesh, sphere->radius);
1169  }else if(VrmlElevationGrid* grid = dynamic_cast<VrmlElevationGrid*>(originalGeometry)){ //ElevationGrid
1170  defaultTextureMappingElevationGrid(grid, triangleMesh);
1171  }else if(VrmlExtrusion* extrusion = dynamic_cast<VrmlExtrusion*>(originalGeometry)){ //Extrusion
1172  defaultTextureMappingExtrusion(triangleMesh, extrusion);
1173  }
1174  }else{ //IndexedFaceSet
1175  defaultTextureMappingFaceSet(triangleMesh);
1176  }
1177 }
1178 
1179 
1181 {
1182  if(!triangleMesh->texCoord){
1183  float max[3]={static_cast<float> (triangleMesh->coord->point[0][0]),
1184  static_cast<float> (triangleMesh->coord->point[0][1]),
1185  static_cast<float> (triangleMesh->coord->point[0][2])};
1186  float min[3]={static_cast<float> (triangleMesh->coord->point[0][0]),
1187  static_cast<float> (triangleMesh->coord->point[0][1]),
1188  static_cast<float> (triangleMesh->coord->point[0][2])};
1189  int n = triangleMesh->coord->point.size();
1190  for(int i=1; i<n; i++){
1191  for(int j=0; j<3; j++){
1192  float w = triangleMesh->coord->point[i][j];
1193  max[j] = std::max( max[j], w );
1194  min[j] = std::min( min[j], w );
1195  }
1196  }
1197  float size[3]={0,0,0};
1198  for(int j=0; j<3; j++)
1199  size[j] = max[j]-min[j];
1200  int s,t;
1201  size[0] >= size[1] ?
1202  ( size[0] >= size[2] ?
1203  ( s=0 , t=size[1] >= size[2] ? 1 : 2 )
1204  : ( s=2 , t=0) )
1205  : ( size[1] >= size[2] ?
1206  ( s=1 , t=size[0] >= size[2] ? 0 : 2 )
1207  : ( s=2 , t=1) ) ;
1208  triangleMesh->texCoord = new VrmlTextureCoordinate();
1209  double ratio = size[t]/size[s];
1210  for(int i=0; i<n; i++){
1211  SFVec2f point;
1212  point[0] = (triangleMesh->coord->point[i][s]-min[s])/size[s];
1213  point[1] = (triangleMesh->coord->point[i][t]-min[t])/size[t]*ratio;
1214  triangleMesh->texCoord->point.push_back(point);
1215  }
1216  triangleMesh->texCoordIndex.resize(triangleMesh->coordIndex.size());
1217  copy( triangleMesh->coordIndex.begin(), triangleMesh->coordIndex.end(),
1218  triangleMesh->texCoordIndex.begin() );
1219  }
1220 }
1221 
1222 
1224 {
1225  float xmax = grid->xSpacing * (grid->xDimension-1);
1226  float zmax = grid->zSpacing * (grid->zDimension-1);
1227  triangleMesh->texCoord = new VrmlTextureCoordinate();
1228  for(unsigned int i=0; i<triangleMesh->coord->point.size(); i++){
1229  SFVec2f point;
1230  point[0] = (triangleMesh->coord->point[i][0])/xmax;
1231  point[1] = (triangleMesh->coord->point[i][2])/zmax;
1232  triangleMesh->texCoord->point.push_back(point);
1233  }
1234  triangleMesh->texCoordIndex.resize(triangleMesh->coordIndex.size());
1235  copy( triangleMesh->coordIndex.begin(), triangleMesh->coordIndex.end(),
1236  triangleMesh->texCoordIndex.begin() );
1237 }
1238 
1239 
1241 {
1242  if(point[0][0] <= 0 && point[1][0] <= 0 && point[2][0] <= 0 ) return LEFT;
1243  if(point[0][0] > 0 && point[1][0] > 0 && point[2][0] > 0 ) return RIGHT;
1244  if(point[0][1] <= 0 && point[1][1] <= 0 && point[2][1] <= 0 ) return BOTTOM;
1245  if(point[0][1] > 0 && point[1][1] > 0 && point[2][1] > 0 ) return TOP;
1246  if(point[0][2] <= 0 && point[1][2] <= 0 && point[2][2] <= 0 ) return BACK;
1247  if(point[0][2] > 0 && point[1][2] > 0 && point[2][2] > 0 ) return FRONT;
1248  return -1;
1249 }
1250 
1251 
1253 {
1254  for(unsigned int i=0; i<points.size(); i++){
1255  if((points[i][0]-target[0])*(points[i][0]-target[0]) +
1256  (points[i][1]-target[1])*(points[i][1]-target[1]) < 1.0e-9 )
1257  return i;
1258  }
1259  return -1;
1260 }
1261 
1262 
1264 {
1265  double angle = atan2( point[2], point[0] );
1266  if(angle>=0) angle=1.5*PI-angle;
1267  else if(-0.5*PI<angle) angle=-angle+1.5*PI;
1268  else angle=-angle-0.5*PI;
1269  return angle;
1270 }
1271 
1272 
1274 {
1275  triangleMesh->texCoord = new VrmlTextureCoordinate();
1276  SFVec2f point ;
1277  point[0] = 0.0; point[1] = 0.0; //index=0
1278  triangleMesh->texCoord->point.push_back(point);
1279  point[0] = 1.0; point[1] = 0.0; //index=1
1280  triangleMesh->texCoord->point.push_back(point);
1281  point[0] = 0.0; point[1] = 1.0; //index=2
1282  triangleMesh->texCoord->point.push_back(point);
1283  point[0] = 1.0; point[1] = 1.0; //index=3
1284  triangleMesh->texCoord->point.push_back(point);
1285 
1286  for(int i=0; i<12; i++){
1287  SFVec3f point[3];
1288  for(int j=0; j<3; j++)
1289  point[j] = triangleMesh->coord->point[triangleMesh->coordIndex[i*4+j]];
1290  switch(faceofBox(point)){
1291  case LEFT:
1292  for(int j=0; j<3; j++){
1293  if(point[j][1] > 0 && point[j][2] > 0 ) triangleMesh->texCoordIndex.push_back(3);
1294  else if(point[j][1] > 0 && point[j][2] <= 0 ) triangleMesh->texCoordIndex.push_back(2);
1295  else if(point[j][1] <= 0 && point[j][2] > 0 ) triangleMesh->texCoordIndex.push_back(1);
1296  else if(point[j][1] <= 0 && point[j][2] <= 0 ) triangleMesh->texCoordIndex.push_back(0);
1297  }
1298  break;
1299  case RIGHT:
1300  for(int j=0; j<3; j++){
1301  if(point[j][1] > 0 && point[j][2] > 0 ) triangleMesh->texCoordIndex.push_back(2);
1302  else if(point[j][1] > 0 && point[j][2] <= 0 ) triangleMesh->texCoordIndex.push_back(3);
1303  else if(point[j][1] <= 0 && point[j][2] > 0 ) triangleMesh->texCoordIndex.push_back(0);
1304  else if(point[j][1] <= 0 && point[j][2] <= 0 ) triangleMesh->texCoordIndex.push_back(1);
1305  }
1306  break;
1307  case BOTTOM:
1308  for(int j=0; j<3; j++){
1309  if(point[j][2] > 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(3);
1310  else if(point[j][2] > 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(2);
1311  else if(point[j][2] <= 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(1);
1312  else if(point[j][2] <= 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(0);
1313  }
1314  break;
1315  case TOP:
1316  for(int j=0; j<3; j++){
1317  if(point[j][2] > 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(1);
1318  else if(point[j][2] > 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(0);
1319  else if(point[j][2] <= 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(3);
1320  else if(point[j][2] <= 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(2);
1321  }
1322  break;
1323  case BACK:
1324  for(int j=0; j<3; j++){
1325  if(point[j][1] > 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(2);
1326  else if(point[j][1] > 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(3);
1327  else if(point[j][1] <= 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(0);
1328  else if(point[j][1] <= 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(1);
1329  }
1330  break;
1331  case FRONT:
1332  for(int j=0; j<3; j++){
1333  if(point[j][1] > 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(3);
1334  else if(point[j][1] > 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(2);
1335  else if(point[j][1] <= 0 && point[j][0] > 0 ) triangleMesh->texCoordIndex.push_back(1);
1336  else if(point[j][1] <= 0 && point[j][0] <= 0 ) triangleMesh->texCoordIndex.push_back(0);
1337  }
1338  break;
1339  default:
1340  break;
1341  }
1342  triangleMesh->texCoordIndex.push_back(-1);
1343  }
1344 }
1345 
1346 
1348 {
1349  triangleMesh->texCoord = new VrmlTextureCoordinate();
1350  SFVec2f texPoint ;
1351  texPoint[0] = 0.5; texPoint[1] = 0.5; //center of bottom index=0
1352  triangleMesh->texCoord->point.push_back(texPoint);
1353  int texIndex = 1;
1354  for(unsigned int i=0; i<triangleMesh->coordIndex.size(); i++){
1355  SFVec3f point[3];
1356  int top=-1;
1357  int center=-1;
1358  for(int j=0; j<3; j++){
1359  point[j] = triangleMesh->coord->point[triangleMesh->coordIndex[i++]];
1360  if(point[j][1] > 0) top = j;
1361  if(point[j][0] == 0.0 && point[j][2] == 0.0) center = j;
1362  }
1363  if(top>=0){ //side
1364  double s[3]={0,0,0};
1365  int pre=-1;
1366  for(int j=0; j<3; j++){
1367  if(j!=top){
1368  double angle = calcangle(point[j]);
1369  s[j] = angle/2/PI;
1370  if(pre!=-1)
1371  if(s[pre] > 0.5 && s[j] < 1.0e-6)
1372  s[j] = 1.0;
1373  pre = j;
1374 
1375  }
1376  }
1377  for(int j=0; j<3; j++){
1378  if(j!=top){
1379  texPoint[0] = s[j];
1380  texPoint[1] = 0.0;
1381  }else{
1382  texPoint[0] = (s[0]+s[1]+s[2])/2.0;
1383  texPoint[1] = 1.0;
1384  }
1385  int k=findPoint(triangleMesh->texCoord->point, texPoint);
1386  if(k!=-1){
1387  triangleMesh->texCoordIndex.push_back(k);
1388  }else{
1389  triangleMesh->texCoord->point.push_back(texPoint);
1390  triangleMesh->texCoordIndex.push_back(texIndex++);
1391  }
1392  }
1393  triangleMesh->texCoordIndex.push_back(-1);
1394  }else{ // bottom
1395  for(int j=0; j<3; j++){
1396  if(j!=center){
1397  double angle = atan2( point[j][2], point[j][0] );
1398  texPoint[0] = 0.5 + 0.5*cos(angle);
1399  texPoint[1] = 0.5 + 0.5*sin(angle);
1400  int k=findPoint(triangleMesh->texCoord->point, texPoint);
1401  if(k!=-1){
1402  triangleMesh->texCoordIndex.push_back(k);
1403  }else{
1404  triangleMesh->texCoord->point.push_back(texPoint);
1405  triangleMesh->texCoordIndex.push_back(texIndex++);
1406  }
1407  }else{
1408  triangleMesh->texCoordIndex.push_back(0);
1409  }
1410  }
1411  triangleMesh->texCoordIndex.push_back(-1);
1412  }
1413  }
1414 }
1415 
1416 
1418 {
1419  triangleMesh->texCoord = new VrmlTextureCoordinate();
1420  SFVec2f texPoint ;
1421  texPoint[0] = 0.5; texPoint[1] = 0.5; //center of top(bottom) index=0
1422  triangleMesh->texCoord->point.push_back(texPoint);
1423  int texIndex = 1;
1424  for(unsigned int i=0; i<triangleMesh->coordIndex.size(); i++){
1425  SFVec3f point[3];
1426  bool notside=true;
1427  int center=-1;
1428  for(int j=0; j<3; j++){
1429  point[j] = triangleMesh->coord->point[triangleMesh->coordIndex[i++]];
1430  if(j){
1431  if(point[0][1] == point[j][1] ) notside &= true;
1432  else notside &= false;
1433  }
1434  if(point[j][0] == 0.0 && point[j][2] == 0.0) center = j;
1435  }
1436  if(!notside){ //side
1437  bool over=false;
1438  double s[3]={0,0,0};
1439  for(int j=0; j<3; j++){
1440  double angle = calcangle(point[j]);
1441  s[j] = angle/2/PI;
1442  if(s[j] > 0.5)
1443  over = true;
1444  }
1445  for(int j=0; j<3; j++){
1446  if(over && s[j]<1.0e-6)
1447  s[j] = 1.0;
1448  texPoint[0] = s[j];
1449  if(point[j][1] > 0) texPoint[1] = 1.0;
1450  else texPoint[1] = 0.0;
1451  int k=findPoint(triangleMesh->texCoord->point, texPoint);
1452  if(k!=-1){
1453  triangleMesh->texCoordIndex.push_back(k);
1454  }else{
1455  triangleMesh->texCoord->point.push_back(texPoint);
1456  triangleMesh->texCoordIndex.push_back(texIndex++);
1457  }
1458  }
1459  triangleMesh->texCoordIndex.push_back(-1);
1460  }else{ // top / bottom
1461  for(int j=0; j<3; j++){
1462  if(j!=center){
1463  double angle = atan2( point[j][2], point[j][0] );
1464  texPoint[0] = 0.5 + 0.5*cos(angle);
1465  if(point[0][1] > 0) //top
1466  texPoint[1] = 0.5 - 0.5*sin(angle);
1467  else //bottom
1468  texPoint[1] = 0.5 + 0.5*sin(angle);
1469  int k=findPoint(triangleMesh->texCoord->point, texPoint);
1470  if(k!=-1){
1471  triangleMesh->texCoordIndex.push_back(k);
1472  }else{
1473  triangleMesh->texCoord->point.push_back(texPoint);
1474  triangleMesh->texCoordIndex.push_back(texIndex++);
1475  }
1476  }else{
1477  triangleMesh->texCoordIndex.push_back(0);
1478  }
1479  }
1480  triangleMesh->texCoordIndex.push_back(-1);
1481  }
1482  }
1483 }
1484 
1485 
1487 {
1488  triangleMesh->texCoord = new VrmlTextureCoordinate();
1489  SFVec2f texPoint ;
1490  int texIndex = 0;
1491  for(unsigned int i=0; i<triangleMesh->coordIndex.size(); i++){
1492  SFVec3f point[3];
1493  bool over=false;
1494  double s[3]={0,0,0};
1495  for(int j=0; j<3; j++){
1496  point[j] = triangleMesh->coord->point[triangleMesh->coordIndex[i++]];
1497  double angle = calcangle(point[j]);
1498  s[j] = angle/2/PI;
1499  if(s[j] > 0.5)
1500  over = true;
1501  }
1502  for(int j=0; j<3; j++){
1503  if(over && s[j]<1.0e-6)
1504  s[j] = 1.0;
1505  texPoint[0] = s[j];
1506  double theta = acos(point[j][1]/radius);
1507  texPoint[1] = 1.0-theta/PI;
1508  int k=findPoint(triangleMesh->texCoord->point, texPoint);
1509  if(k!=-1){
1510  triangleMesh->texCoordIndex.push_back(k);
1511  }else{
1512  triangleMesh->texCoord->point.push_back(texPoint);
1513  triangleMesh->texCoordIndex.push_back(texIndex++);
1514  }
1515  }
1516  triangleMesh->texCoordIndex.push_back(-1);
1517  }
1518 }
1519 
1520 
1522 {
1523  int numSpine = extrusion->spine.size();
1524  int numcross = extrusion->crossSection.size();
1525 
1526  triangleMesh->texCoord = new VrmlTextureCoordinate();
1527  std::vector<double> s;
1528  std::vector<double> t;
1529  double slen=0;
1530  s.push_back(0);
1531  for(unsigned int i=1; i<extrusion->crossSection.size(); i++){
1532  double x=extrusion->crossSection[i][0]-extrusion->crossSection[i-1][0];
1533  double z=extrusion->crossSection[i][1]-extrusion->crossSection[i-1][1];
1534  slen += sqrt(x*x+z*z);
1535  s.push_back(slen);
1536  }
1537  double tlen=0;
1538  t.push_back(0);
1539  for(unsigned int i=1; i<extrusion->spine.size(); i++){
1540  double x=extrusion->spine[i][0]-extrusion->spine[i-1][0];
1541  double y=extrusion->spine[i][1]-extrusion->spine[i-1][1];
1542  double z=extrusion->spine[i][2]-extrusion->spine[i-1][2];
1543  tlen += sqrt(x*x+y*y+z*z);
1544  t.push_back(tlen);
1545  }
1546  for(unsigned int i=0; i<extrusion->spine.size(); i++){
1547  SFVec2f point;
1548  point[1] = t[i]/tlen;
1549  for(unsigned int j=0; j<extrusion->crossSection.size(); j++){
1550  point[0] = s[j]/slen;
1551  triangleMesh->texCoord->point.push_back(point);
1552  }
1553  }
1554 
1555  int endofspin = (numSpine-1)*(numcross-1)*2*4;
1556  triangleMesh->texCoordIndex.resize(endofspin);
1557  copy( triangleMesh->coordIndex.begin(), triangleMesh->coordIndex.begin()+endofspin,
1558  triangleMesh->texCoordIndex.begin() );
1559  int endofbegincap = endofspin;
1560  int endofpoint = triangleMesh->texCoord->point.size();
1561 
1562  if(extrusion->beginCap){
1563  if(extrusion->endCap)
1564  endofbegincap += (triangleMesh->coordIndex.size()-endofspin)/2;
1565  else
1566  endofbegincap = triangleMesh->coordIndex.size();
1567  double xmin, xmax;
1568  double zmin, zmax;
1569  xmin = xmax = extrusion->crossSection[0][0];
1570  zmin = zmax = extrusion->crossSection[0][1];
1571  for(unsigned int i=1; i<extrusion->crossSection.size(); i++){
1572  xmax = std::max(xmax,extrusion->crossSection[i][0]);
1573  xmin = std::min(xmin,extrusion->crossSection[i][0]);
1574  zmax = std::max(zmax,extrusion->crossSection[i][1]);
1575  zmin = std::min(xmin,extrusion->crossSection[i][1]);
1576  }
1577  double xsize = xmax-xmin;
1578  double zsize = zmax-zmin;
1579  for(int i=0; i<numcross; i++){
1580  SFVec2f point;
1581  point[0] = (extrusion->crossSection[i][0]-xmin)/xsize;
1582  point[1] = (extrusion->crossSection[i][1]-zmin)/zsize;
1583  triangleMesh->texCoord->point.push_back(point);
1584  }
1585  for(int i=endofspin; i<endofbegincap; i++){
1586  int k=triangleMesh->coordIndex[i];
1587  if(k != -1)
1588  triangleMesh->texCoordIndex.push_back(k+endofpoint);
1589  else
1590  triangleMesh->texCoordIndex.push_back(-1);
1591  }
1592  }
1593 
1594  if(extrusion->endCap){
1595  double xmax,xmin;
1596  double zmax,zmin;
1597  xmin = xmax = extrusion->crossSection[0][0];
1598  zmin = zmax = extrusion->crossSection[0][1];
1599  for(unsigned int i=1; i<extrusion->crossSection.size(); i++){
1600  xmax = std::max(xmax,extrusion->crossSection[i][0]);
1601  xmin = std::min(xmin,extrusion->crossSection[i][0]);
1602  zmax = std::max(zmax,extrusion->crossSection[i][1]);
1603  zmin = std::min(xmin,extrusion->crossSection[i][1]);
1604  }
1605  double xsize = xmax-xmin;
1606  double zsize = zmax-zmin;
1607  for(unsigned int i=0; i<extrusion->crossSection.size(); i++){
1608  SFVec2f point;
1609  point[0] = (extrusion->crossSection[i][0]-xmin)/xsize;
1610  point[1] = (extrusion->crossSection[i][1]-zmin)/zsize;
1611  triangleMesh->texCoord->point.push_back(point);
1612  }
1613  for(unsigned int i=endofbegincap; i<triangleMesh->coordIndex.size(); i++){
1614  int k=triangleMesh->coordIndex[i];
1615  if(k!=-1)
1616  triangleMesh->texCoordIndex.push_back(triangleMesh->texCoord->point.size()+k-endofpoint);
1617  else
1618  triangleMesh->texCoordIndex.push_back(-1);
1619  }
1620  }
1621 }
1622 
1624  return impl->convertBox(box, triangleMesh);
1625 }
MFVec2f crossSection
Definition: VrmlNodes.h:639
VrmlCoordinatePtr coord
Definition: VrmlNodes.h:467
png_infop png_charp png_int_32 png_int_32 int * type
Definition: png.h:2332
void defaultTextureMapping(VrmlShape *shapeNode)
Modifications controlling boost library behavior.
Definition: ColladaUtil.h:306
* x
Definition: IceUtils.h:98
int findPoint(MFVec2f &points, SFVec2f &target)
Abstract base class of all vrml nodes.
Definition: VrmlNodes.h:121
std::vector< int > polygon
int faceofBox(SFVec3f *point)
static int min(int a, int b)
png_uint_32 size
Definition: png.h:1521
SFVec3f size
Definition: VrmlNodes.h:377
boost::signal< void(const std::string &message)> sigMessage
VRML Shape node.
Definition: VrmlNodes.h:285
VRML Cone node.
Definition: VrmlNodes.h:383
void defaultTextureMappingExtrusion(VrmlIndexedFaceSet *triangleMesh, VrmlExtrusion *extrusion)
Base class of VRML geometry nodes.
Definition: VrmlNodes.h:366
VRML Coordinate node.
Definition: VrmlNodes.h:512
ShapeToGeometryMap shapeToOriginalGeometryMap
bool setTexCoordIndex(VrmlIndexedFaceSetPtr faseSet)
VRML IndexedFaseSet node.
Definition: VrmlNodes.h:483
string message
TriangleMeshShaper * self
w
VRML TextureCoordinate node.
Definition: VrmlNodes.h:521
bool convertBox(VrmlBox *box, VrmlIndexedFaceSetPtr &triangleMesh)
png_uint_32 i
Definition: png.h:2735
Vector3Ref getVector3Ref(const double *data)
Definition: Eigen3d.h:20
Eigen::Vector3d Vector3Ref
Definition: Eigen3d.h:19
std::vector< std::vector< int > > vertexIndexToFaceIndicesMap
boost::intrusive_ptr< VrmlShape > VrmlShapePtr
Definition: VrmlNodes.h:292
SFFloat creaseAngle
Definition: VrmlNodes.h:648
Eigen::Vector3d Vector3
Definition: EigenTypes.h:11
bool isCategoryOf(VrmlNodeCategory category)
Definition: VrmlNodes.cpp:60
Triangulator triangulator
void defaultTextureMappingBox(VrmlIndexedFaceSet *triangleMesh)
Eigen::Matrix3d Matrix33
Definition: EigenTypes.h:12
VrmlCoordinatePtr coord
Definition: VrmlNodes.h:562
void setFaceNormals(VrmlIndexedFaceSetPtr &triangleMesh)
bool convertSphere(VrmlSphere *sphere, VrmlIndexedFaceSetPtr &triangleMesh)
std::vector< Vector3 > faceNormals
bool convertCone(VrmlCone *cone, VrmlIndexedFaceSetPtr &triangleMesh)
void defaultTextureMappingCone(VrmlIndexedFaceSet *triangleMesh)
VrmlTextureCoordinatePtr texCoord
Definition: VrmlNodes.h:489
virtual VrmlNode * getChild(int index)=0
SFBool side
Definition: VrmlNodes.h:391
std::vector< int > faceIndexMap
Matrix33 rodrigues(const Vector3 &axis, double q)
Definition: Eigen3d.h:27
list index
virtual int countChildren()=0
VRML Box node.
Definition: VrmlNodes.h:373
std::vector< SFVec3f > MFVec3f
Definition: VrmlNodes.h:72
void putMessage(const std::string &message)
void defaultTextureMappingSphere(VrmlIndexedFaceSet *triangleMesh, double radius)
MFRotation orientation
Definition: VrmlNodes.h:642
VRML Sphere node.
Definition: VrmlNodes.h:412
bool convertElevationGrid(VrmlElevationGrid *grid, VrmlIndexedFaceSetPtr &triangleMesh)
boost::array< SFFloat, 2 > SFVec2f
Definition: VrmlNodes.h:54
t
VrmlNormalPtr normal
Definition: VrmlNodes.h:488
#define PI
PI.
Definition: IceTypes.h:32
self
void defaultTextureMappingElevationGrid(VrmlElevationGrid *grid, VrmlIndexedFaceSet *triangleMesh)
void calculateFaceNormals(VrmlIndexedFaceSetPtr &triangleMesh)
void removeChild(int childIndex)
Definition: VrmlNodes.cpp:127
void setVertices(const MFVec3f &vertices)
Definition: Triangulator.h:28
bool convertCylinder(VrmlCylinder *cylinder, VrmlIndexedFaceSetPtr &triangleMesh)
bool convertPointSet(VrmlPointSet *pointSet, VrmlIndexedFaceSetPtr &triangleMesh)
VrmlNodePtr actualNode
Definition: VrmlNodes.h:888
bool remapDirectMapObjectsPerFaces(TArray &objects, const char *objectName)
VrmlTextureCoordinatePtr texCoord
Definition: VrmlNodes.h:625
void defaultTextureMappingFaceSet(VrmlIndexedFaceSet *triangleMesh)
VRML node which is instance of VRML Prototype.
Definition: VrmlNodes.h:883
VrmlNodePtr apply(VrmlNodePtr topNode)
bool checkAndRemapIndices(RemapType type, unsigned int numElements, MFInt32 &indices, bool perVertex, VrmlIndexedFaceSet *triangleMesh)
SFNode getOriginalGeometry(VrmlShapePtr shapeNode)
SFFloat bottomRadius
Definition: VrmlNodes.h:389
std::vector< SFVec2f > MFVec2f
Definition: VrmlNodes.h:71
boost::intrusive_ptr< VrmlNode > VrmlNodePtr
Definition: VrmlNodes.h:155
bool convertBox(VrmlBox *box, VrmlIndexedFaceSetPtr &triangleMesh)
Vector3 cross(const Vector3 &v1, const Vector3 &v2)
Definition: Tvmet2Eigen.h:15
double dot(const Vector3 &v1, const Vector3 &v2)
Definition: Tvmet2Eigen.h:19
VRML Cylinder node.
Definition: VrmlNodes.h:397
void setVertexNormals(VrmlIndexedFaceSetPtr &triangleMesh)
SFFloat radius
Definition: VrmlNodes.h:416
bool traverseShapeNodes(VrmlNode *node, AbstractVrmlGroup *parentNode, int indexInParent)
boost::array< SFFloat, 3 > SFVec3f
Definition: VrmlNodes.h:55
bool convertExtrusion(VrmlExtrusion *extrusion, VrmlIndexedFaceSetPtr &triangleMesh)
const std::vector< int > & triangles()
Definition: Triangulator.h:42
SFVec4f SFRotation
Definition: VrmlNodes.h:59
void defaultTextureMappingCylinder(VrmlIndexedFaceSet *triangleMesh)
bool convertShapeNode(VrmlShape *shapeNode)
boost::intrusive_ptr< VrmlIndexedFaceSet > VrmlIndexedFaceSetPtr
Definition: VrmlNodes.h:498
std::map< VrmlShapePtr, SFNode > ShapeToGeometryMap
void getVector3(Vector3 &v3, const V &v, size_t top=0)
Definition: Eigen3d.h:138
VrmlColorPtr color
Definition: VrmlNodes.h:563
int apply(const std::vector< int > &polygon)
VrmlColorPtr color
Definition: VrmlNodes.h:466
std::vector< int > indexPositionMap
SFNode geometry
Definition: VrmlNodes.h:290
JSAMPIMAGE data
Definition: jpeglib.h:945
SFBool bottom
Definition: VrmlNodes.h:388
SFNode getOriginalGeometry(VrmlShapePtr shapeNode)
VRML PointSet node.
Definition: VrmlNodes.h:557
std::vector< std::vector< int > > vertexIndexToNormalIndicesMap
VRML ElevationGrid node.
Definition: VrmlNodes.h:608
* y
Definition: IceUtils.h:97
void generateNormals(VrmlIndexedFaceSetPtr &triangleMesh)
std::vector< SFInt32 > MFInt32
Definition: VrmlNodes.h:69
boost::intrusive_ptr< VrmlTextureCoordinate > VrmlTextureCoordinatePtr
Definition: VrmlNodes.h:478
SFFloat height
Definition: VrmlNodes.h:390
void putError1(const char *valueName)
static int max(int a, int b)
VrmlNodePtr SFNode
Definition: VrmlNodes.h:157
bool convertIndexedFaceSet(VrmlIndexedFaceSet *faceSet)
Definition: jquant2.c:258
double calcangle(SFVec3f &point)
VRML Normal node.
Definition: VrmlNodes.h:530
VRML Extrusion node.
Definition: VrmlNodes.h:634


openhrp3
Author(s): AIST, General Robotix Inc., Nakamura Lab of Dept. of Mechano Informatics at University of Tokyo
autogenerated on Thu Sep 8 2022 02:24:05