vtkWebGLPolyData.cxx 23.5 KB
Newer Older
Zach's avatar
Zach committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
/*=========================================================================

  Program:   Visualization Toolkit
  Module:    vtkWebGLPolyData.cxx

  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.

     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
     PURPOSE.  See the above copyright notice for more information.

=========================================================================*/

#include "vtkWebGLPolyData.h"

#include "vtkActor.h"
#include "vtkCell.h"
#include "vtkCellArray.h"
#include "vtkCellData.h"
#include "vtkCompositeDataGeometryFilter.h"
#include "vtkCompositeDataSet.h"
#include "vtkGenericCell.h"
#include "vtkMapper.h"
#include "vtkMatrix4x4.h"
#include "vtkObjectFactory.h"
#include "vtkPointData.h"
#include "vtkPoints.h"
#include "vtkPolyDataNormals.h"
#include "vtkProperty.h"
32
#include "vtkScalarsToColors.h"
Zach's avatar
Zach committed
33 34 35 36 37 38 39 40 41 42 43 44 45 46
#include "vtkSmartPointer.h"
#include "vtkTriangleFilter.h"
#include "vtkWebGLDataSet.h"
#include "vtkWebGLExporter.h"
#include "vtkWebGLObject.h"

#include <vector>
#include <map>
#include <string>
#include <sstream>

vtkStandardNewMacro(vtkWebGLPolyData);
//*****************************************************************************
class vtkWebGLPolyData::vtkInternal
47
{
Zach's avatar
Zach committed
48 49 50
public:
  std::vector<vtkWebGLDataSet*> Parts;
  std::map<long int, short> IndexMap;
51
};
Zach's avatar
Zach committed
52 53 54
//*****************************************************************************

vtkWebGLPolyData::vtkWebGLPolyData()
55
{
Zach's avatar
Zach committed
56 57 58
  this->webGlType = wTRIANGLES;
  this->iswidget = false;
  this->Internal = new vtkInternal();
59
}
Zach's avatar
Zach committed
60 61

vtkWebGLPolyData::~vtkWebGLPolyData()
62
{
Zach's avatar
Zach committed
63
  vtkWebGLDataSet* obj;
64
  while(!this->Internal->Parts.empty())
65
  {
Zach's avatar
Zach committed
66 67 68 69
    obj = this->Internal->Parts.back();
    this->Internal->Parts.pop_back();
    obj->Delete();
  }
70 71
  delete this->Internal;
}
Zach's avatar
Zach committed
72 73

void vtkWebGLPolyData::SetMesh(float* _vertices, int _numberOfVertices, int* _index, int _numberOfIndexes, float* _normals, unsigned char* _colors, float* _tcoords, int maxSize)
74
{
Zach's avatar
Zach committed
75 76 77
  this->webGlType = wTRIANGLES;

  vtkWebGLDataSet* obj;
78
  while(!this->Internal->Parts.empty())
79
  {
Zach's avatar
Zach committed
80 81 82
    obj = this->Internal->Parts.back();
    this->Internal->Parts.pop_back();
    obj->Delete();
83
  }
Zach's avatar
Zach committed
84 85 86 87

  short* index;
  int div = maxSize*3;
  if (_numberOfVertices < div)
88
  {
Zach's avatar
Zach committed
89 90 91 92 93 94 95 96 97 98
    index = new short[_numberOfIndexes];
    for (int i=0; i<_numberOfIndexes; i++) index[i] = (short)_index[i];

    obj = vtkWebGLDataSet::New();
    obj->SetVertices(_vertices, _numberOfVertices);
    obj->SetIndexes(index, _numberOfIndexes);
    obj->SetNormals(_normals);
    obj->SetColors(_colors);
    obj->SetMatrix(this->Matrix);
    this->Internal->Parts.push_back(obj);
99
  }
Zach's avatar
Zach committed
100
  else
101
  {
Zach's avatar
Zach committed
102 103 104 105 106
    int total = _numberOfIndexes;
    int curr = 0;
    int size = 0;

    while(curr < total)
107
    {
Zach's avatar
Zach committed
108 109 110 111 112 113 114
      if (div+curr > total) size = total - curr;
      else size = div;

      float* vertices = new float[size*3];
      float* normals = new float[size*3];
      unsigned char* colors = new unsigned char[size*4];
      short* indexes = new short[size];
115
      float* tcoord = nullptr;
Zach's avatar
Zach committed
116 117 118 119 120
      if (_tcoords) tcoord = new float[size*2];

      this->Internal->IndexMap.clear();
      int count = 0;
      for(int j=0; j<size; j++)
121
      {
Zach's avatar
Zach committed
122 123
        int ind = _index[curr+j];
        if (this->Internal->IndexMap.find(ind) == this->Internal->IndexMap.end())
124
        {
Zach's avatar
Zach committed
125 126 127 128 129 130 131 132 133 134 135 136 137 138
          vertices[count*3+0] = _vertices[ind*3+0];
          vertices[count*3+1] = _vertices[ind*3+1];
          vertices[count*3+2] = _vertices[ind*3+2];

          normals[count*3+0] = _normals[ind*3+0];
          normals[count*3+1] = _normals[ind*3+1];
          normals[count*3+2] = _normals[ind*3+2];

          colors[count*4+0] = _colors[ind*4+0];
          colors[count*4+1] = _colors[ind*4+1];
          colors[count*4+2] = _colors[ind*4+2];
          colors[count*4+3] = _colors[ind*4+3];

          if (_tcoords)
139
          {
Zach's avatar
Zach committed
140 141
            tcoord[count*2+0] = _tcoords[ind*2+0];
            tcoord[count*2+1] = _tcoords[ind*2+1];
142
          }
Zach's avatar
Zach committed
143 144
          this->Internal->IndexMap[ind] = count;
          indexes[j] = count++;
145
        }
Zach's avatar
Zach committed
146
        else
147
        {
Zach's avatar
Zach committed
148 149
          indexes[j] = this->Internal->IndexMap[ind];
        }
150
      }
Zach's avatar
Zach committed
151 152 153 154 155 156 157 158 159 160
      curr += size;
      float* v = new float[count*3]; memcpy(v, vertices, count*3*sizeof(float)); delete[] vertices;
      float* n = new float[count*3]; memcpy(n, normals, count*3*sizeof(float)); delete[] normals;
      unsigned char* c = new unsigned char[count*4]; memcpy(c, colors, count*4); delete[] colors;
      obj = vtkWebGLDataSet::New();
      obj->SetVertices(v, count);
      obj->SetIndexes(indexes, size);
      obj->SetNormals(n);
      obj->SetColors(c);
      if (_tcoords)
161
      {
Zach's avatar
Zach committed
162 163
        float* tc = new float[count*2]; memcpy(tc, tcoord, count*2*sizeof(float)); delete[] tcoord;
        obj->SetTCoords(tc);
164
      }
Zach's avatar
Zach committed
165 166
      obj->SetMatrix(this->Matrix);
      this->Internal->Parts.push_back(obj);
167
    }
Zach's avatar
Zach committed
168 169 170 171 172

    delete[] _vertices;
    delete[] _index;
    delete[] _normals;
    delete[] _colors;
173
    delete[] _tcoords;
Zach's avatar
Zach committed
174
  }
175
}
Zach's avatar
Zach committed
176 177

void vtkWebGLPolyData::SetLine(float *_points, int _numberOfPoints, int *_index, int _numberOfIndex, unsigned char *_colors, int maxSize)
178
{
Zach's avatar
Zach committed
179 180 181
  this->webGlType = wLINES;

  vtkWebGLDataSet* obj;
182
  while(!this->Internal->Parts.empty())
183
  {
Zach's avatar
Zach committed
184 185 186
    obj = this->Internal->Parts.back();
    this->Internal->Parts.pop_back();
    obj->Delete();
187
  }
Zach's avatar
Zach committed
188 189 190 191

  short* index;
  int div = maxSize*2;
  if (_numberOfPoints < div)
192
  {
Zach's avatar
Zach committed
193 194 195 196 197 198 199 200
    index = new short[_numberOfIndex];
    for (int i=0; i<_numberOfIndex; i++) index[i] = (short)((unsigned int)_index[i]);
    obj = vtkWebGLDataSet::New();
    obj->SetPoints(_points, _numberOfPoints);
    obj->SetIndexes(index, _numberOfIndex);
    obj->SetColors(_colors);
    obj->SetMatrix(this->Matrix);
    this->Internal->Parts.push_back(obj);
201
  }
Zach's avatar
Zach committed
202
  else
203
  {
Zach's avatar
Zach committed
204 205 206 207 208
    int total = _numberOfIndex;
    int curr = 0;
    int size = 0;

    while(curr < total)
209
    {
Zach's avatar
Zach committed
210 211 212 213 214 215 216 217
      if (div+curr > total) size = total - curr;
      else size = div;

      float* points = new float[size*3];
      unsigned char* colors = new unsigned char[size*4];
      short* indexes = new short[size];

      for(int j=0; j<size; j++)
218
      {
Zach's avatar
Zach committed
219 220 221 222 223 224 225 226 227 228
        indexes[j] = j;

        points[j*3+0] = _points[_index[curr+j]*3+0];
        points[j*3+1] = _points[_index[curr+j]*3+1];
        points[j*3+2] = _points[_index[curr+j]*3+2];

        colors[j*4+0] = _colors[_index[curr+j]*4+0];
        colors[j*4+1] = _colors[_index[curr+j]*4+1];
        colors[j*4+2] = _colors[_index[curr+j]*4+2];
        colors[j*4+3] = _colors[_index[curr+j]*4+3];
229
      }
Zach's avatar
Zach committed
230 231 232 233 234 235 236
      curr += size;
      obj = vtkWebGLDataSet::New();
      obj->SetPoints(points, size);
      obj->SetIndexes(indexes, size);
      obj->SetColors(colors);
      obj->SetMatrix(this->Matrix);
      this->Internal->Parts.push_back(obj);
237
    }
Zach's avatar
Zach committed
238 239 240 241
    delete[] _points;
    delete[] _index;
    delete[] _colors;
  }
242
}
Zach's avatar
Zach committed
243 244

void vtkWebGLPolyData::SetTransformationMatrix(vtkMatrix4x4* m)
245
{
Zach's avatar
Zach committed
246 247
  this->Superclass::SetTransformationMatrix(m);
  for (size_t i=0; i<this->Internal->Parts.size(); i++)
248
  {
Zach's avatar
Zach committed
249 250
    this->Internal->Parts[i]->SetMatrix(this->Matrix);
  }
251
}
Zach's avatar
Zach committed
252 253

unsigned char* vtkWebGLPolyData::GetBinaryData(int part)
254
{
Zach's avatar
Zach committed
255 256 257
  this->hasChanged = false;
  vtkWebGLDataSet* obj = this->Internal->Parts[part];
  return obj->GetBinaryData();
258
}
Zach's avatar
Zach committed
259 260

int vtkWebGLPolyData::GetBinarySize(int part)
261
{
Zach's avatar
Zach committed
262 263
  vtkWebGLDataSet* obj = this->Internal->Parts[part];
  return obj->GetBinarySize();
264
}
Zach's avatar
Zach committed
265 266

void vtkWebGLPolyData::GenerateBinaryData()
267
{
Zach's avatar
Zach committed
268 269 270 271
  vtkWebGLDataSet* obj;
  this->hasChanged = false;
  std::stringstream ss;
  for(size_t i=0; i<this->Internal->Parts.size(); i++)
272
  {
Zach's avatar
Zach committed
273 274 275
    obj = this->Internal->Parts[i];
    obj->GenerateBinaryData();
    ss << obj->GetMD5();
276
  }
277
  if(!this->Internal->Parts.empty())
278
  {
Zach's avatar
Zach committed
279
    std::string localMD5;
280
    vtkWebGLExporter::ComputeMD5((const unsigned char*)ss.str().c_str(), static_cast<int>(ss.str().size()), localMD5);
Zach's avatar
Zach committed
281 282 283
    this->hasChanged = this->MD5.compare(localMD5) != 0;
    this->MD5 = localMD5;
  }
284 285
  else cout << "Warning: GenerateBinaryData() @ vtkWebGLObject: This isn\'t supposed to happen.";
}
Zach's avatar
Zach committed
286 287

int vtkWebGLPolyData::GetNumberOfParts()
288
{
Zach's avatar
Zach committed
289
  return static_cast<int>(this->Internal->Parts.size());
290
}
Zach's avatar
Zach committed
291 292

void vtkWebGLPolyData::PrintSelf(ostream& os, vtkIndent indent)
293
{
Zach's avatar
Zach committed
294
  this->Superclass::PrintSelf(os, indent);
295
}
Zach's avatar
Zach committed
296 297

void vtkWebGLPolyData::GetLinesFromPolygon(vtkMapper *mapper, vtkActor *actor, int lineMaxSize, double* edgeColor)
298
{
Zach's avatar
Zach committed
299
  vtkWebGLPolyData *object = this;
300
  vtkDataSet* dataset = nullptr;
Zach's avatar
Zach committed
301 302 303 304
  vtkSmartPointer<vtkDataSet> tempDS;
  vtkDataObject* dObj = mapper->GetInputDataObject(0, 0);
  vtkCompositeDataSet* cd = vtkCompositeDataSet::SafeDownCast(dObj);
  if (cd)
305
  {
Zach's avatar
Zach committed
306 307 308 309 310 311
    vtkCompositeDataGeometryFilter* gf = vtkCompositeDataGeometryFilter::New();
    gf->SetInputData(cd);
    gf->Update();
    tempDS = gf->GetOutput();
    gf->Delete();
    dataset = tempDS;
312
  }
Zach's avatar
Zach committed
313
  else
314
  {
Zach's avatar
Zach committed
315
    dataset = mapper->GetInput();
316
  }
Zach's avatar
Zach committed
317 318 319 320 321 322 323 324 325 326 327 328 329 330

  int np = 0;
  int size = 0;
  for(int i=0; i<dataset->GetNumberOfCells(); i++) size += dataset->GetCell(i)->GetNumberOfPoints();

  float* points = new float[size*3];
  unsigned char* color = new unsigned char[size*4];
  int* index = new int[size*2];
  double* point;
  int pos = 0;

  vtkScalarsToColors* table = mapper->GetLookupTable();
  vtkDataArray* array;
  if (mapper->GetScalarMode() == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA)
331
  {
Zach's avatar
Zach committed
332 333 334 335 336
    vtkCellData* celldata = dataset->GetCellData();
    if (actor->GetMapper()->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
      array = celldata->GetArray(actor->GetMapper()->GetArrayId());
    else
      array = celldata->GetArray(actor->GetMapper()->GetArrayName());
337
  }
Zach's avatar
Zach committed
338
  else
339
  {
Zach's avatar
Zach committed
340 341 342 343 344
    vtkPointData* pointdata = dataset->GetPointData();
    if (actor->GetMapper()->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
      array = pointdata->GetArray(actor->GetMapper()->GetArrayId());
    else
      array = pointdata->GetArray(actor->GetMapper()->GetArrayName());
345
  }
Zach's avatar
Zach committed
346 347 348

  int colorComponent = table->GetVectorComponent();
  int numberOfComponents = 0;
349
  if (array != nullptr) numberOfComponents = array->GetNumberOfComponents();
Zach's avatar
Zach committed
350 351 352 353
  int mode = table->GetVectorMode();
  double mag=0, rgb[3];
  int curr=0;
  for(int i=0; i<dataset->GetNumberOfCells(); i++)
354
  {
Zach's avatar
Zach committed
355 356 357 358
    vtkCell* cell = dataset->GetCell(i);
    int b = pos;
    np = dataset->GetCell(i)->GetNumberOfPoints();
    for(int j=0; j<np; j++)
359
    {
Zach's avatar
Zach committed
360 361 362 363 364 365 366 367 368 369 370
      point = cell->GetPoints()->GetPoint(j);
      points[curr*3 + j*3 + 0] = point[0];
      points[curr*3 + j*3 + 1] = point[1];
      points[curr*3 + j*3 + 2] = point[2];

      index[curr*2 + j*2 + 0] = pos++;
      index[curr*2 + j*2 + 1] = pos;
      if(j==np-1) index[curr*2 + j*2 + 1] = b;

      vtkIdType pointId = cell->GetPointIds()->GetId(j);
      if (numberOfComponents == 0)
371
      {
Zach's avatar
Zach committed
372
        actor->GetProperty()->GetColor(rgb);
373
      }
Zach's avatar
Zach committed
374
      else
375
      {
Zach's avatar
Zach committed
376
        switch(mode)
377
        {
Zach's avatar
Zach committed
378 379 380 381 382 383 384 385 386 387 388 389 390
        case vtkScalarsToColors::MAGNITUDE:
            mag = 0; for (int w=0; w<numberOfComponents; w++) mag += (double)array->GetComponent(pointId, w)*(double)array->GetComponent(pointId, w);
            mag = sqrt(mag);
            table->GetColor(mag, &rgb[0]);
            break;
          case vtkScalarsToColors::COMPONENT:
            mag = array->GetComponent(pointId, colorComponent);
            table->GetColor(mag, &rgb[0]);
            break;
          case vtkScalarsToColors::RGBCOLORS:
            array->GetTuple(pointId, &rgb[0]);
            break;
        }
391
      }
392
      if (edgeColor != nullptr) memcpy(rgb, edgeColor, sizeof(double)*3);
Zach's avatar
Zach committed
393 394 395 396 397 398
      color[curr*4 + j*4 + 0] = (unsigned char)((int)(rgb[0]*255));
      color[curr*4 + j*4 + 1] = (unsigned char)((int)(rgb[1]*255));
      color[curr*4 + j*4 + 2] = (unsigned char)((int)(rgb[2]*255));
      color[curr*4 + j*4 + 3] = (unsigned char)255;

    }
399
    curr += np;
Zach's avatar
Zach committed
400
  }
401 402
  object->SetLine(points, size, index, size*2, color, lineMaxSize);
}
Zach's avatar
Zach committed
403 404

void vtkWebGLPolyData::GetLines(vtkTriangleFilter* polydata, vtkActor* actor, int lineMaxSize)
405
{
Zach's avatar
Zach committed
406 407 408 409 410 411 412 413 414 415 416 417
  vtkWebGLPolyData* object = this;
  vtkCellArray* lines = polydata->GetOutput(0)->GetLines();

  // Index
  //Array of 3 Values. [#number of index, i1, i2]
  //Discarting the first value
  int* index = new int[lines->GetData()->GetSize()*2/3];
  for (int i=0; i< lines->GetData()->GetSize(); i++) if (i%3 != 0) index[i*2/3] = lines->GetData()->GetValue(i);
  // Point
  double point[3];
  float* points = new float[polydata->GetOutput(0)->GetNumberOfPoints()*3];
  for (int i=0; i<polydata->GetOutput(0)->GetNumberOfPoints(); i++)
418
  {
Zach's avatar
Zach committed
419 420 421 422
    polydata->GetOutput(0)->GetPoint(i, point);
    points[i*3+0] = point[0];
    points[i*3+1] = point[1];
    points[i*3+2] = point[2];
423
  }
Zach's avatar
Zach committed
424 425 426 427 428
  // Colors
  unsigned char* color = new unsigned char[polydata->GetOutput(0)->GetNumberOfPoints()*4];
  this->GetColorsFromPolyData(color, polydata->GetOutput(0), actor);

  object->SetLine(points, polydata->GetOutput(0)->GetNumberOfPoints(), index, lines->GetData()->GetSize()*2/3, color, lineMaxSize);
429
}
Zach's avatar
Zach committed
430 431

void vtkWebGLPolyData::SetPoints(float *points, int numberOfPoints, unsigned char *colors, int maxSize)
432
{
Zach's avatar
Zach committed
433 434 435 436
  this->webGlType = wPOINTS;

  // Delete Old Objects
  vtkWebGLDataSet* obj;
437
  while(!this->Internal->Parts.empty())
438
  {
Zach's avatar
Zach committed
439 440 441
    obj = this->Internal->Parts.back();
    this->Internal->Parts.pop_back();
    obj->Delete();
442
  }
Zach's avatar
Zach committed
443 444 445 446 447 448

  // Create new objs
  int numObjs = (numberOfPoints/maxSize)+1;
  int offset = 0;
  int size = 0;
  for(int i=0; i<numObjs; i++)
449
  {
Zach's avatar
Zach committed
450 451 452 453 454 455 456 457 458 459 460 461 462 463 464 465
    size = numberOfPoints - offset;
    if (size > maxSize) size = maxSize;

    float* _points = new float[size*3];
    unsigned char* _colors = new unsigned char[size*4];
    memcpy(_points, &points[offset*3], size*3*sizeof(float));
    memcpy(_colors, &colors[offset*4], size*4*sizeof(unsigned char));

    obj = vtkWebGLDataSet::New();
    obj->SetPoints(_points, size);
    obj->SetColors(_colors);
    obj->SetType(wPOINTS);
    obj->SetMatrix(this->Matrix);
    this->Internal->Parts.push_back(obj);

    offset += size;
466
  }
Zach's avatar
Zach committed
467 468 469

  delete[] points;
  delete[] colors;
470
}
Zach's avatar
Zach committed
471 472

void vtkWebGLPolyData::GetPoints(vtkTriangleFilter *polydata, vtkActor *actor, int maxSize)
473
{
Zach's avatar
Zach committed
474 475 476 477 478 479
  vtkWebGLPolyData* object = this;

  // Points
  double point[3];
  float* points = new float[polydata->GetOutput(0)->GetNumberOfPoints()*3];
  for (int i=0; i<polydata->GetOutput(0)->GetNumberOfPoints(); i++)
480
  {
Zach's avatar
Zach committed
481 482 483 484
    polydata->GetOutput(0)->GetPoint(i, point);
    points[i*3+0] = point[0];
    points[i*3+1] = point[1];
    points[i*3+2] = point[2];
485
  }
Zach's avatar
Zach committed
486 487 488 489 490
  // Colors
  unsigned char* colors = new unsigned char[polydata->GetOutput(0)->GetNumberOfPoints()*4];
  this->GetColorsFromPolyData(colors, polydata->GetOutput(0), actor);

  object->SetPoints(points, polydata->GetOutput(0)->GetNumberOfPoints(), colors, maxSize);
491
}
Zach's avatar
Zach committed
492 493

void vtkWebGLPolyData::GetColorsFromPolyData(unsigned char* color, vtkPolyData* polydata, vtkActor* actor)
494
{
Zach's avatar
Zach committed
495 496 497 498
  int celldata;
  vtkDataArray* array = vtkAbstractMapper::GetScalars(polydata, actor->GetMapper()->GetScalarMode(),
                                                      actor->GetMapper()->GetArrayAccessMode(), actor->GetMapper()->GetArrayId(),
                                                      actor->GetMapper()->GetArrayName(), celldata);
499
  if (actor->GetMapper()->GetScalarVisibility() && array != nullptr)
500
  {
Zach's avatar
Zach committed
501 502 503 504 505
    vtkScalarsToColors* table = actor->GetMapper()->GetLookupTable();

    vtkUnsignedCharArray* cor = table->MapScalars(array, table->GetVectorMode(), table->GetVectorComponent());
    memcpy(color, cor->GetPointer(0), polydata->GetNumberOfPoints()*4);
    cor->Delete();
506
  }
Zach's avatar
Zach committed
507
  else
508
  {
Zach's avatar
Zach committed
509
    for (int i=0; i<polydata->GetNumberOfPoints(); i++)
510
    {
Zach's avatar
Zach committed
511 512 513 514 515 516
      color[i*4+0] = (unsigned char)255;
      color[i*4+1] = (unsigned char)255;
      color[i*4+2] = (unsigned char)255;
      color[i*4+3] = (unsigned char)255;
    }
  }
517
}
Zach's avatar
Zach committed
518 519

void vtkWebGLPolyData::GetPolygonsFromPointData(vtkTriangleFilter* polydata, vtkActor* actor, int maxSize)
520
{
Zach's avatar
Zach committed
521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538
  vtkWebGLPolyData* object = this;

  vtkPolyDataNormals* polynormals = vtkPolyDataNormals::New();
  polynormals->SetInputConnection(polydata->GetOutputPort(0));
  polynormals->Update();

  vtkPolyData* data = polynormals->GetOutput();

  vtkCellArray* poly = data->GetPolys();
  vtkPointData* point = data->GetPointData();
  vtkIdTypeArray* ndata = poly->GetData();
  vtkDataSetAttributes* attr = (vtkDataSetAttributes*)point;

  //Vertices
  float* vertices = new float[data->GetNumberOfPoints()*3];
  for (int i=0; i<data->GetNumberOfPoints()*3; i++) vertices[i] = data->GetPoint(i/3)[i%3];
  //Index
  // ndata contain 4 values for the normal: [number of values per index, index[3]]
Kunda's avatar
Kunda committed
539
  // We don't need the first value
Zach's avatar
Zach committed
540 541 542 543 544 545 546 547 548 549
  int* indexes = new int[ndata->GetSize()*3/4];
  for (int i=0; i<ndata->GetSize(); i++)
    if (i%4 != 0) indexes[i*3/4] = ndata->GetValue(i);
  //Normal
  float* normal = new float[attr->GetNormals()->GetSize()];
  for (int i=0; i< attr->GetNormals()->GetSize(); i++) normal[i] = attr->GetNormals()->GetComponent(0, i);
  //Colors
  unsigned char* color = new unsigned char[data->GetNumberOfPoints()*4];
  this->GetColorsFromPointData(color, point, data, actor);
  //TCoord
550
  float* tcoord = nullptr;
Zach's avatar
Zach committed
551
  if (attr->GetTCoords())
552
  {
Zach's avatar
Zach committed
553 554
    tcoord = new float[attr->GetTCoords()->GetSize()];
    for (int i=0; i<attr->GetTCoords()->GetSize(); i++) tcoord[i] = attr->GetTCoords()->GetComponent(0, i);
555
  }
Zach's avatar
Zach committed
556 557 558

  object->SetMesh(vertices, data->GetNumberOfPoints(), indexes, ndata->GetSize()*3/4, normal, color, tcoord, maxSize);
  polynormals->Delete();
559
}
Zach's avatar
Zach committed
560 561

void vtkWebGLPolyData::GetPolygonsFromCellData(vtkTriangleFilter* polydata, vtkActor* actor, int maxSize)
562
{
Zach's avatar
Zach committed
563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584 585 586 587 588 589 590 591 592 593 594 595 596
  vtkWebGLPolyData* object = this;

  vtkPolyDataNormals* polynormals = vtkPolyDataNormals::New();
  polynormals->SetInputConnection(polydata->GetOutputPort(0));
  polynormals->Update();

  vtkPolyData* data = polynormals->GetOutput();
  vtkCellData* celldata = data->GetCellData();

  vtkDataArray* array;
  if (actor->GetMapper()->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
    array = celldata->GetArray(actor->GetMapper()->GetArrayId());
  else
    array = celldata->GetArray(actor->GetMapper()->GetArrayName());
  vtkScalarsToColors* table = actor->GetMapper()->GetLookupTable();
  int colorComponent = table->GetVectorComponent();
  int mode = table->GetVectorMode();


  float* vertices = new float[data->GetNumberOfCells()*3*3];
  float* normals  = new float[data->GetNumberOfCells()*3*3];
  unsigned char* colors   = new unsigned char[data->GetNumberOfCells()*3*4];
  int* indexes  = new int[data->GetNumberOfCells()*3*3];

  vtkGenericCell* cell = vtkGenericCell::New();
  double tuple[3], normal[3], color[3];
  color[0] = 1.0; color[1] = 1.0; color[2] = 1.0;
  vtkPoints* points;
  int aux;
  double mag, alpha=1.0;
  int numberOfComponents = 0;
  if (array) numberOfComponents = array->GetNumberOfComponents();
  else mode = -1;
  for(int i=0; i<data->GetNumberOfCells(); i++)
597
  {
Zach's avatar
Zach committed
598 599 600 601 602 603
    data->GetCell(i, cell);
    points = cell->GetPoints();

    //getColors
    alpha = 1.0;
    switch(mode)
604
    {
Zach's avatar
Zach committed
605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
    case -1:
        actor->GetProperty()->GetColor(color);
        alpha = actor->GetProperty()->GetOpacity();
        break;
      case vtkScalarsToColors::MAGNITUDE:
        mag = 0; for (int w=0; w<numberOfComponents; w++) mag += (double)array->GetComponent(i, w)*(double)array->GetComponent(i, w);
        mag = sqrt(mag);
        table->GetColor(mag, &color[0]);
        alpha = table->GetOpacity(mag);
        break;
      case vtkScalarsToColors::COMPONENT:
        mag = array->GetComponent(i, colorComponent);
        table->GetColor(mag, &color[0]);
        alpha = table->GetOpacity(mag);
        break;
      case vtkScalarsToColors::RGBCOLORS:
        array->GetTuple(i, &color[0]);
        break;
623
    }
Zach's avatar
Zach committed
624 625 626
    //getNormals
    celldata->GetNormals()->GetTuple(i, &normal[0]);
    for(int j=0; j<3; j++)
627
    {
Zach's avatar
Zach committed
628 629 630 631 632 633 634 635 636 637 638 639
      aux = i*9+j*3;
      //Normals
      normals[aux+0] = normal[0]; normals[aux+1] = normal[1]; normals[aux+2] = normal[2];
      //getVertices
      points->GetPoint(j, &tuple[0]);
      vertices[aux+0] = tuple[0]; vertices[aux+1] = tuple[1]; vertices[aux+2] = tuple[2];
      //Colors
      colors[4*(3*i+j)+0] = (unsigned char)((int)(color[0]*255)); colors[4*(3*i+j)+1] = (unsigned char)((int)(color[1]*255));
      colors[4*(3*i+j)+2] = (unsigned char)((int)(color[2]*255)); colors[4*(3*i+j)+3] = (unsigned char)((int)(alpha*255));
      //getIndexes
      indexes[aux+0] = aux+0; indexes[aux+1] = aux+1; indexes[aux+2] = aux+2;
    }
640
  }
641
  object->SetMesh(vertices, data->GetNumberOfCells()*3, indexes, data->GetNumberOfCells()*3, normals, colors, nullptr, maxSize);
Zach's avatar
Zach committed
642 643
  cell->Delete();
  polynormals->Delete();
644
}
Zach's avatar
Zach committed
645 646

void vtkWebGLPolyData::GetColorsFromPointData(unsigned char* color, vtkPointData* pointdata, vtkPolyData* polydata, vtkActor* actor)
647
{
Zach's avatar
Zach committed
648 649 650 651 652 653 654 655 656 657
  vtkDataSetAttributes* attr = (vtkDataSetAttributes*)pointdata;

  int colorSize = attr->GetNormals()->GetSize()*4/3;

  vtkDataArray* array;
  if (actor->GetMapper()->GetArrayAccessMode() == VTK_GET_ARRAY_BY_ID)
    array = pointdata->GetArray(actor->GetMapper()->GetArrayId());
  else
    array = pointdata->GetArray(actor->GetMapper()->GetArrayName());

658
  if (array && actor->GetMapper()->GetScalarVisibility() && actor->GetMapper()->GetArrayName() != nullptr && actor->GetMapper()->GetArrayName()[0] != '\0')
659
  {
Zach's avatar
Zach committed
660 661 662 663 664 665 666
    vtkScalarsToColors* table = actor->GetMapper()->GetLookupTable();
    int colorComponent = table->GetVectorComponent(), numberOfComponents = array->GetNumberOfComponents();
    int mode = table->GetVectorMode();
    double mag=0, rgb[3];
    double alpha = 1.0;

    if (numberOfComponents == 1 && mode == vtkScalarsToColors::MAGNITUDE)
667
    {
Zach's avatar
Zach committed
668 669
      mode = vtkScalarsToColors::COMPONENT;
      colorComponent = 0;
670
    }
Zach's avatar
Zach committed
671
    for (int i=0; i<colorSize/4; i++)
672
    {
Zach's avatar
Zach committed
673
      switch(mode)
674
      {
Zach's avatar
Zach committed
675 676 677 678 679 680 681 682 683 684 685 686 687 688 689
      case vtkScalarsToColors::MAGNITUDE:
          mag = 0; for (int w=0; w<numberOfComponents; w++) mag += (double)array->GetComponent(i, w)*(double)array->GetComponent(i, w);
          mag = sqrt(mag);
          table->GetColor(mag, &rgb[0]);
          alpha = table->GetOpacity(mag);
          break;
        case vtkScalarsToColors::COMPONENT:
          mag = array->GetComponent(i, colorComponent);
          table->GetColor(mag, &rgb[0]);
          alpha = table->GetOpacity(mag);
          break;
        case vtkScalarsToColors::RGBCOLORS:
          array->GetTuple(i, &rgb[0]);
          alpha = actor->GetProperty()->GetOpacity();
          break;
690
      }
Zach's avatar
Zach committed
691 692 693 694 695
      color[i*4+0] = (unsigned char)((int)(rgb[0]*255));
      color[i*4+1] = (unsigned char)((int)(rgb[1]*255));
      color[i*4+2] = (unsigned char)((int)(rgb[2]*255));
      color[i*4+3] = (unsigned char)((int)(alpha*255));
    }
696
  }
Zach's avatar
Zach committed
697
  else
698
  {
Zach's avatar
Zach committed
699 700 701 702 703 704
    double rgb[3];
    double alpha = 0;
    int celldata;
    array = vtkAbstractMapper::GetScalars(polydata, actor->GetMapper()->GetScalarMode(),
                                          actor->GetMapper()->GetArrayAccessMode(), actor->GetMapper()->GetArrayId(),
                                          actor->GetMapper()->GetArrayName(), celldata);
705 706 707 708
    if (actor->GetMapper()->GetScalarVisibility() &&
        (actor->GetMapper()->GetColorMode() == VTK_COLOR_MODE_DEFAULT ||
         actor->GetMapper()->GetColorMode() == VTK_COLOR_MODE_DIRECT_SCALARS) &&
        array)
709
    {
Zach's avatar
Zach committed
710
      vtkScalarsToColors* table = actor->GetMapper()->GetLookupTable();
711
      vtkUnsignedCharArray* cor = table->MapScalars(array, actor->GetMapper()->GetColorMode(), table->GetVectorComponent());
Zach's avatar
Zach committed
712 713
      memcpy(color, cor->GetPointer(0), polydata->GetNumberOfPoints()*4);
      cor->Delete();
714
    }
Zach's avatar
Zach committed
715
    else
716
    {
Zach's avatar
Zach committed
717 718 719
      actor->GetProperty()->GetColor(rgb);
      alpha = actor->GetProperty()->GetOpacity();
      for (int i=0; i<colorSize/4; i++)
720
      {
Zach's avatar
Zach committed
721 722 723 724 725 726 727
        color[i*4+0] = (unsigned char)((int)(rgb[0]*255));
        color[i*4+1] = (unsigned char)((int)(rgb[1]*255));
        color[i*4+2] = (unsigned char)((int)(rgb[2]*255));
        color[i*4+3] = (unsigned char)((int)(alpha*255));
      }
    }
  }
728
}