vtkCompositePolyDataMapper2.cxx 30 KB
Newer Older
Ken Martin's avatar
Ken Martin committed
1
/*=========================================================================
2
3
4
5
6
7
8
9
10
11
12
13
14

  Program:   Visualization Toolkit
  Module:    vtkCompositePolyDataMapper2.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.

=========================================================================*/
15
16
#include "vtk_glew.h"

17
18
#include "vtkCompositePolyDataMapper2.h"

19
20
#include "vtkCellArray.h"
#include "vtkCellData.h"
21
22
#include "vtkCommand.h"
#include "vtkCompositeDataDisplayAttributes.h"
23
24
#include "vtkDataObjectTreeIterator.h"
#include "vtkFloatArray.h"
25
#include "vtkHardwareSelector.h"
26
27
28
#include "vtkImageData.h"
#include "vtkMultiBlockDataSet.h"
#include "vtkMultiPieceDataSet.h"
29
#include "vtkObjectFactory.h"
Ken Martin's avatar
Ken Martin committed
30
#include "vtkOpenGLBufferObject.h"
Ken Martin's avatar
Ken Martin committed
31
#include "vtkOpenGLIndexBufferObject.h"
32
#include "vtkOpenGLRenderWindow.h"
33
#include "vtkOpenGLTexture.h"
Ken Martin's avatar
Ken Martin committed
34
#include "vtkOpenGLVertexBufferObject.h"
35
#include "vtkPointData.h"
36
37
38
39
#include "vtkPolyData.h"
#include "vtkProperty.h"
#include "vtkRenderer.h"
#include "vtkRenderWindow.h"
40
#include "vtkLookupTable.h"
41
#include "vtkShaderProgram.h"
42
#include "vtkTextureObject.h"
43
44

vtkStandardNewMacro(vtkCompositePolyDataMapper2);
45

46
47
48
//----------------------------------------------------------------------------
vtkCompositePolyDataMapper2::vtkCompositePolyDataMapper2()
{
49
  this->UseGeneric = true;
Ken Martin's avatar
Ken Martin committed
50
51
52
  this->MaximumFlatIndex = 0;
  this->CanUseTextureMapForColoringSet = false;
  this->CanUseTextureMapForColoringValue = false;
53
54
55
56
57
58
59
60
}

//----------------------------------------------------------------------------
vtkCompositePolyDataMapper2::~vtkCompositePolyDataMapper2()
{
}

//----------------------------------------------------------------------------
61
void vtkCompositePolyDataMapper2::PrintSelf(ostream& os, vtkIndent indent)
62
{
63
  this->Superclass::PrintSelf(os, indent);
64
65
}

66
void vtkCompositePolyDataMapper2::FreeStructures()
67
{
68
69
70
71
72
73
  this->VertexOffsets.resize(0);
  this->IndexOffsets.resize(0);
  this->IndexArray.resize(0);
  this->EdgeIndexArray.resize(0);
  this->EdgeIndexOffsets.resize(0);
  this->RenderValues.resize(0);
74
75
}

76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
void vtkCompositePolyDataMapper2::ReplaceShaderColor(
  std::map<vtkShader::Type, vtkShader *> shaders,
  vtkRenderer *ren, vtkActor *actor)
{
  std::string FSSource = shaders[vtkShader::Fragment]->GetSource();

  vtkShaderProgram::Substitute(FSSource,"//VTK::Color::Dec",
    "uniform bool OverridesColor;\n"
    "//VTK::Color::Dec",false);

  vtkShaderProgram::Substitute(FSSource,"//VTK::Color::Impl",
    "//VTK::Color::Impl\n"
    "  if (OverridesColor) {\n"
    "    ambientColor = ambientColorUniform;\n"
    "    diffuseColor = diffuseColorUniform; }\n",
    false);

  shaders[vtkShader::Fragment]->SetSource(FSSource);

  this->Superclass::ReplaceShaderColor(shaders,ren,actor);
}

98
99
100
101
102
103
// ---------------------------------------------------------------------------
// Description:
// Method initiates the mapping process. Generally sent by the actor
// as each frame is rendered.
void vtkCompositePolyDataMapper2::Render(
  vtkRenderer *ren, vtkActor *actor)
104
105
106
107
{
  vtkCompositeDataSet *input = vtkCompositeDataSet::SafeDownCast(
    this->GetInputDataObject(0, 0));

108
109
  // do we need to do a generic render?
  bool lastUseGeneric = this->UseGeneric;
110
111
112
  int foundScalars = 0;  // 0 = unknown, 1 has 2 doesn't
  int foundNormals = 0;
  int foundTCoords = 0;
113
114
  if (this->GenericTestTime < this->GetInputDataObject(0, 0)->GetMTime() ||
      this->GenericTestTime < this->MTime)
115
    {
116
    int cellFlag = 0;
117
    this->UseGeneric = false;
Ken Martin's avatar
Ken Martin committed
118
119
120

    // is the data not composite
    if (!input)
121
      {
Ken Martin's avatar
Ken Martin committed
122
123
124
125
126
127
128
129
130
131
132
      this->UseGeneric = true;
      }
    else
      {
      vtkSmartPointer<vtkDataObjectTreeIterator> iter =
        vtkSmartPointer<vtkDataObjectTreeIterator>::New();
      iter->SetDataSet(input);
      iter->SkipEmptyNodesOn();
      iter->VisitOnlyLeavesOn();
      for (iter->InitTraversal(); !iter->IsDoneWithTraversal();
          iter->GoToNextItem())
133
        {
Ken Martin's avatar
Ken Martin committed
134
135
136
137
138
        vtkDataObject *dso = iter->GetCurrentDataObject();
        vtkPolyData *pd = vtkPolyData::SafeDownCast(dso);
        if (!pd ||
            pd->GetVerts()->GetNumberOfCells() ||
            pd->GetLines()->GetNumberOfCells() ||
139
140
141
            pd->GetStrips()->GetNumberOfCells() ||
            pd->GetPointData()->GetAttribute(
                        vtkDataSetAttributes::EDGEFLAG))
Ken Martin's avatar
Ken Martin committed
142
143
144
145
          {
          this->UseGeneric = true;
          break;
          }
146
147
148
149
150
151
152
153
154
        // is the scalar coloring OK?  If some blocks are missing
        // the scalars we switch to generic
        if (pd && this->ScalarVisibility)
          {
          vtkAbstractArray *scalars =
            vtkAbstractMapper::GetAbstractScalars(
              pd, this->ScalarMode, this->ArrayAccessMode,
              this->ArrayId, this->ArrayName,
              cellFlag);
155
          if (!foundScalars)
156
            {
157
            foundScalars = scalars ? 1 : 2;
158
            }
159
          if (foundScalars != (scalars ? 1 : 2))
160
161
162
163
164
            {
            this->UseGeneric = true;
            break;
            }
          }
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
        // watch for heterogeneous normals
        if (!foundNormals)
          {
          foundNormals =
            (pd->GetPointData()->GetNormals() || pd->GetCellData()->GetNormals()) ? 1 : 2;
          }
        if (foundNormals !=
          ((pd->GetPointData()->GetNormals() || pd->GetCellData()->GetNormals()) ? 1 : 2))
          {
          this->UseGeneric = true;
          break;
          }
        // watch for heterogeneous tcoords
        if (!foundTCoords)
          {
          foundTCoords = pd->GetPointData()->GetTCoords() ? 1 : 2;
          }
        if (foundTCoords != (pd->GetPointData()->GetTCoords() ? 1 : 2))
          {
          this->UseGeneric = true;
          break;
          }
187
        }
188
189
      }

190
191
192
193
194
195
196
197
198
199
200
201
202
    // check if this system is subject to the apple primID bug
    // if so don't even try using the fast path, just go slow

#ifdef __APPLE__
    std::string vendor = (const char *)glGetString(GL_VENDOR);
    if (vendor.find("ATI") != std::string::npos ||
        vendor.find("AMD") != std::string::npos ||
        vendor.find("amd") != std::string::npos)
      {
      this->UseGeneric = true;
      }
#endif

203
204
    // clear old structures if the render method changed
    if (lastUseGeneric != this->UseGeneric)
205
      {
206
      if (lastUseGeneric)
207
        {
208
209
210
211
212
        this->FreeGenericStructures();
        }
      else
        {
        this->FreeStructures();
213
214
        }
      }
215
    this->GenericTestTime.Modified();
216
217
    }

218
  if (this->UseGeneric)
219
    {
220
    this->RenderGeneric(ren,actor);
221
222
223
    }
  else
    {
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
    vtkProperty* prop = actor->GetProperty();

    // Push base-values on the state stack.
    this->BlockState.Visibility.push(true);
    this->BlockState.Opacity.push(prop->GetOpacity());
    this->BlockState.AmbientColor.push(vtkColor3d(prop->GetAmbientColor()));
    this->BlockState.DiffuseColor.push(vtkColor3d(prop->GetDiffuseColor()));
    this->BlockState.SpecularColor.push(vtkColor3d(prop->GetSpecularColor()));

    // set current input
    this->CurrentInput = 0;
    vtkSmartPointer<vtkDataObjectTreeIterator> iter =
      vtkSmartPointer<vtkDataObjectTreeIterator>::New();
    iter->SetDataSet(input);
    iter->SkipEmptyNodesOn();
    iter->VisitOnlyLeavesOn();
    for (iter->InitTraversal();
        !iter->IsDoneWithTraversal() && !this->CurrentInput;
        iter->GoToNextItem())
      {
      vtkDataObject *dso = iter->GetCurrentDataObject();
      vtkPolyData *pd = vtkPolyData::SafeDownCast(dso);
      if (pd && pd->GetPoints())
        {
        this->CurrentInput = pd;
        }
      }
251

252
253
254
255
256
     if (this->CurrentInput)
      {
      // render using the composite data attributes
      this->RenderPiece(ren, actor);
      }
257

258
259
260
261
262
    this->BlockState.Visibility.pop();
    this->BlockState.Opacity.pop();
    this->BlockState.AmbientColor.pop();
    this->BlockState.DiffuseColor.pop();
    this->BlockState.SpecularColor.pop();
263

264
    this->UpdateProgress(1.0);
265
266
267
    }
}

268
269
270
//-----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::RenderPiece(
  vtkRenderer* ren, vtkActor *actor)
271
{
272
273
  // Make sure that we have been properly initialized.
  if (ren->GetRenderWindow()->CheckAbortStatus())
274
    {
275
    return;
276
277
    }

278
279
  this->InvokeEvent(vtkCommand::StartEvent,NULL);
  if (!this->Static)
280
    {
281
    this->GetInputAlgorithm()->Update();
282
    }
283
  this->InvokeEvent(vtkCommand::EndEvent,NULL);
284

285
286
287
288
  this->RenderPieceStart(ren, actor);
  this->RenderPieceDraw(ren, actor);
  this->RenderEdges(ren, actor);
  this->RenderPieceFinish(ren, actor);
289
290
291
292
293
}



//-----------------------------------------------------------------------------
294
295
296
297
298
299
300
301
void vtkCompositePolyDataMapper2::BuildRenderValues(
  vtkRenderer *renderer,
  vtkActor *actor,
  vtkDataObject *dobj,
  unsigned int &flat_index,
  unsigned int &lastVertex,
  unsigned int &lastIndex,
  unsigned int &lastEdgeIndex)
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
{
  vtkHardwareSelector *selector = renderer->GetSelector();
  vtkCompositeDataDisplayAttributes* cda = this->GetCompositeDataDisplayAttributes();
  bool overrides_visibility = (cda && cda->HasBlockVisibility(flat_index));
  if (overrides_visibility)
    {
    this->BlockState.Visibility.push(cda->GetBlockVisibility(flat_index));
    }

  bool overrides_opacity = (cda && cda->HasBlockOpacity(flat_index));
  if (overrides_opacity)
    {
    this->BlockState.Opacity.push(cda->GetBlockOpacity(flat_index));
    }

  bool overrides_color = (cda && cda->HasBlockColor(flat_index));
  if (overrides_color)
    {
    vtkColor3d color = cda->GetBlockColor(flat_index);
    this->BlockState.AmbientColor.push(color);
    this->BlockState.DiffuseColor.push(color);
    this->BlockState.SpecularColor.push(color);
    }

  unsigned int my_flat_index = flat_index;
  // Advance flat-index. After this point, flat_index no longer points to this
  // block.
  flat_index++;

  vtkMultiBlockDataSet *mbds = vtkMultiBlockDataSet::SafeDownCast(dobj);
  vtkMultiPieceDataSet *mpds = vtkMultiPieceDataSet::SafeDownCast(dobj);
  if (mbds || mpds)
    {
    unsigned int numChildren = mbds? mbds->GetNumberOfBlocks() :
      mpds->GetNumberOfPieces();
    for (unsigned int cc=0 ; cc < numChildren; cc++)
      {
      vtkDataObject* child = mbds ? mbds->GetBlock(cc) : mpds->GetPiece(cc);
      if (child == NULL)
        {
        // speeds things up when dealing with NULL blocks (which is common with
        // AMRs).
        flat_index++;
        continue;
        }
347
348
      this->BuildRenderValues(renderer, actor, child,
        flat_index, lastVertex, lastIndex, lastEdgeIndex);
349
350
      }
    }
351
  else
352
    {
353
354
    double op = this->BlockState.Opacity.top();
    bool vis = this->BlockState.Visibility.top();
355
356
    vtkColor3d acolor = this->BlockState.AmbientColor.top();
    vtkColor3d dcolor = this->BlockState.DiffuseColor.top();
357
    if (this->RenderValues.size() == 0)
358
      {
359
360
361
362
363
364
      vtkCompositePolyDataMapper2::RenderValue rv;
      rv.StartVertex = 0;
      rv.StartIndex = 0;
      rv.StartEdgeIndex = 0;
      rv.Opacity = op;
      rv.Visibility = vis;
365
366
      rv.AmbientColor = acolor;
      rv.DiffuseColor = dcolor;
367
      rv.PickId = my_flat_index;
368
      rv.OverridesColor = (this->BlockState.AmbientColor.size() > 1);
369
      this->RenderValues.push_back(rv);
370
371
      }

372
373
374
    // has something changed?
    if (this->RenderValues.back().Opacity != op ||
        this->RenderValues.back().Visibility != vis ||
375
376
        this->RenderValues.back().AmbientColor != acolor ||
        this->RenderValues.back().DiffuseColor != dcolor ||
377
        selector)
378
      {
379
380
381
382
383
384
385
386
387
388
389
      // close old group
      this->RenderValues.back().EndVertex = lastVertex - 1;
      this->RenderValues.back().EndIndex = lastIndex - 1;
      this->RenderValues.back().EndEdgeIndex = lastEdgeIndex - 1;
      // open a new group
      vtkCompositePolyDataMapper2::RenderValue rv;
      rv.StartVertex = lastVertex;
      rv.StartIndex = lastIndex;
      rv.StartEdgeIndex = lastEdgeIndex;
      rv.Opacity = op;
      rv.Visibility = vis;
390
391
      rv.AmbientColor = acolor;
      rv.DiffuseColor = dcolor;
392
      rv.PickId = my_flat_index;
393
      rv.OverridesColor = (this->BlockState.AmbientColor.size() > 1);
394
      this->RenderValues.push_back(rv);
395
      }
396
397
398
    lastVertex = this->VertexOffsets[my_flat_index];
    lastIndex = this->IndexOffsets[my_flat_index];
    lastEdgeIndex = this->EdgeIndexOffsets[my_flat_index];
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
    }

  if (overrides_color)
    {
    this->BlockState.AmbientColor.pop();
    this->BlockState.DiffuseColor.pop();
    this->BlockState.SpecularColor.pop();
    }
  if (overrides_opacity)
    {
    this->BlockState.Opacity.pop();
    }
  if (overrides_visibility)
    {
    this->BlockState.Visibility.pop();
    }
}

417
418
419
420
421
422
423
424
425
426
427
//-----------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::RenderPieceDraw(
  vtkRenderer* ren, vtkActor *actor)
{
  int representation = actor->GetProperty()->GetRepresentation();

  // render points for point picking in a special way
  // all cell types should be rendered as points
  vtkHardwareSelector* selector = ren->GetSelector();
  if (selector && this->PopulateSelectionSettings &&
      selector->GetFieldAssociation() == vtkDataObject::FIELD_ASSOCIATION_POINTS &&
428
      selector->GetCurrentPass() >= vtkHardwareSelector::ID_LOW24)
429
430
431
432
433
434
    {
    representation = VTK_POINTS;
    }

  // rebuild the render values if needed
  if (this->RenderValuesBuildTime < this->GetMTime() ||
435
      this->RenderValuesBuildTime < actor->GetProperty()->GetMTime() ||
436
      this->RenderValuesBuildTime < this->VBOBuildTime ||
437
      this->RenderValuesBuildTime < this->SelectionStateChanged)
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
    {
    vtkCompositeDataSet *input = vtkCompositeDataSet::SafeDownCast(
      this->GetInputDataObject(0, 0));
    unsigned int lastVertex = 0;
    unsigned int lastIndex = 0;
    unsigned int lastEdgeIndex = 0;
    this->RenderValues.resize(0);
    unsigned int flat_index = 0;
    this->BuildRenderValues(ren, actor, input,
      flat_index, lastVertex, lastIndex, lastEdgeIndex);
    // close last group
    this->RenderValues.back().EndVertex = lastVertex - 1;
    this->RenderValues.back().EndIndex = lastIndex - 1;
    this->RenderValues.back().EndEdgeIndex = lastEdgeIndex - 1;
    this->RenderValuesBuildTime.Modified();
    }

  // draw polygons
Ken Martin's avatar
Ken Martin committed
456
  if (this->Tris.IBO->IndexCount)
457
458
    {
    // First we do the triangles, update the shader, set uniforms, etc.
459
    this->UpdateShaders(this->Tris, ren, actor);
Ken Martin's avatar
Ken Martin committed
460
461
462
463
    if (!this->HaveWideLines(ren,actor) && representation == VTK_WIREFRAME)
      {
      glLineWidth(actor->GetProperty()->GetLineWidth());
      }
Ken Martin's avatar
Ken Martin committed
464
    this->Tris.IBO->Bind();
465
466
    GLenum mode = (representation == VTK_POINTS) ? GL_POINTS :
      (representation == VTK_WIREFRAME) ? GL_LINES : GL_TRIANGLES;
467
468
    unsigned int modeDenom = (representation == VTK_POINTS) ? 1 :
      (representation == VTK_WIREFRAME) ? 2 : 3;
469
470
471
472
473
474
475
476

    vtkProperty *ppty = actor->GetProperty();
    double aIntensity = this->DrawingEdges ? 1.0 : ppty->GetAmbient();
    double dIntensity = this->DrawingEdges ? 0.0 : ppty->GetDiffuse();
    vtkShaderProgram *prog = this->Tris.Program;

    std::vector<
      vtkCompositePolyDataMapper2::RenderValue>::iterator it;
477
478
    // reset the offset so each composite starts at 0
    this->PrimitiveIDOffset = 0;
479
480
481
482
    for (it = this->RenderValues.begin(); it != this->RenderValues.end(); it++)
      {
      if (it->Visibility)
        {
483
484
485
        if (selector &&
            selector->GetCurrentPass() ==
              vtkHardwareSelector::COMPOSITE_INDEX_PASS)
486
487
          {
          selector->RenderCompositeIndex(it->PickId);
488
          prog->SetUniform3f("mapperIndex", selector->GetPropColorValue());
489
490
491
          }
        // override the opacity and color
        prog->SetUniformf("opacityUniform", it->Opacity);
492
        vtkColor3d &aColor = it->AmbientColor;
493
494
495
        float ambientColor[3] = {static_cast<float>(aColor[0] * aIntensity),
          static_cast<float>(aColor[1] * aIntensity),
          static_cast<float>(aColor[2] * aIntensity)};
496
        vtkColor3d &dColor = it->DiffuseColor;
497
498
499
500
501
        float diffuseColor[3] = {static_cast<float>(dColor[0] * dIntensity),
          static_cast<float>(dColor[1] * dIntensity),
          static_cast<float>(dColor[2] * dIntensity)};
        prog->SetUniform3f("ambientColorUniform", ambientColor);
        prog->SetUniform3f("diffuseColorUniform", diffuseColor);
502
503
        prog->SetUniformi("PrimitiveIDOffset",
          this->PrimitiveIDOffset);
504
        prog->SetUniformi("OverridesColor", it->OverridesColor);
505
506
507
508
509
510
511
        glDrawRangeElements(mode,
          static_cast<GLuint>(it->StartVertex),
          static_cast<GLuint>(it->EndVertex),
          static_cast<GLsizei>(it->EndIndex - it->StartIndex + 1),
          GL_UNSIGNED_INT,
          reinterpret_cast<const GLvoid *>(it->StartIndex*sizeof(GLuint)));
        }
512
513
      this->PrimitiveIDOffset +=
        ((it->EndIndex - it->StartIndex + 1)/modeDenom);
514
      }
Ken Martin's avatar
Ken Martin committed
515
    this->Tris.IBO->Release();
516
    }
517
518
519
520
521
522
523
  if (selector && (
        selector->GetCurrentPass() == vtkHardwareSelector::ID_LOW24 ||
        selector->GetCurrentPass() == vtkHardwareSelector::ID_MID24 ||
        selector->GetCurrentPass() == vtkHardwareSelector::ID_HIGH16))
    {
    selector->RenderAttributeId(this->PrimitiveIDOffset);
    }
524
525

}
526

527
528
void vtkCompositePolyDataMapper2::RenderEdges(
  vtkRenderer* ren, vtkActor *actor)
529
{
530
531
532
533
534
535
536
537
538
539
540
541
  vtkProperty *prop = actor->GetProperty();
  bool draw_surface_with_edges =
    (prop->GetEdgeVisibility() && prop->GetRepresentation() == VTK_SURFACE);

  if (!draw_surface_with_edges)
    {
    return;
    }

  this->DrawingEdges = true;

  // draw polygons
Ken Martin's avatar
Ken Martin committed
542
  if (this->TrisEdges.IBO->IndexCount)
543
544
    {
    // First we do the triangles, update the shader, set uniforms, etc.
545
    this->UpdateShaders(this->TrisEdges, ren, actor);
546
547
548
549
    if (!this->HaveWideLines(ren,actor))
      {
      glLineWidth(actor->GetProperty()->GetLineWidth());
      }
Ken Martin's avatar
Ken Martin committed
550
    this->TrisEdges.IBO->Bind();
551
552
553
554
555
556
557
558
559
560
561
562
563
564
    std::vector<
      vtkCompositePolyDataMapper2::RenderValue>::iterator it;
    for (it = this->RenderValues.begin(); it != this->RenderValues.end(); it++)
      {
      if (it->Visibility)
        {
        glDrawRangeElements(GL_LINES,
          static_cast<GLuint>(it->StartVertex),
          static_cast<GLuint>(it->EndVertex),
          static_cast<GLsizei>(it->EndEdgeIndex - it->StartEdgeIndex + 1),
          GL_UNSIGNED_INT,
          reinterpret_cast<const GLvoid *>(it->StartEdgeIndex*sizeof(GLuint)));
        }
      }
Ken Martin's avatar
Ken Martin committed
565
    this->TrisEdges.IBO->Release();
566
567
568
569
570
571
572
573
574
575
576
577
    }

  this->DrawingEdges = false;

/*
    // Disable textures when rendering the surface edges.
    // This ensures that edges are always drawn solid.
    glDisable(GL_TEXTURE_2D);

    this->Information->Set(vtkPolyDataPainter::DISABLE_SCALAR_COLOR(), 1);
    this->Information->Remove(vtkPolyDataPainter::DISABLE_SCALAR_COLOR());
    */
578
579
}

580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
//-----------------------------------------------------------------------------
// Returns if we can use texture maps for scalar coloring. Note this doesn't say
// we "will" use scalar coloring. It says, if we do use scalar coloring, we will
// use a texture.
// When rendering multiblock datasets, if any 2 blocks provide different
// lookup tables for the scalars, then also we cannot use textures. This case can
// be handled if required.
int vtkCompositePolyDataMapper2::CanUseTextureMapForColoring(vtkDataObject*)
{
  if (!this->InterpolateScalarsBeforeMapping)
    {
    return 0; // user doesn't want us to use texture maps at all.
    }

  if (this->CanUseTextureMapForColoringSet)
    {
    return this->CanUseTextureMapForColoringValue;
    }

  vtkCompositeDataSet *cdInput = vtkCompositeDataSet::SafeDownCast(
    this->GetInputDataObject(0, 0));

  vtkSmartPointer<vtkDataObjectTreeIterator> iter =
    vtkSmartPointer<vtkDataObjectTreeIterator>::New();
  iter->SetDataSet(cdInput);
  iter->SkipEmptyNodesOn();
  iter->VisitOnlyLeavesOn();
  int cellFlag=0;
  this->CanUseTextureMapForColoringValue = 1;
  vtkScalarsToColors *scalarsLookupTable = 0;
  for (iter->InitTraversal();
       !iter->IsDoneWithTraversal() &&
          this->CanUseTextureMapForColoringValue == 1;
       iter->GoToNextItem())
    {
    vtkDataObject *dso = iter->GetCurrentDataObject();
    vtkPolyData *pd = vtkPolyData::SafeDownCast(dso);
    vtkDataArray* scalars = vtkAbstractMapper::GetScalars(pd,
      this->ScalarMode, this->ArrayAccessMode, this->ArrayId,
      this->ArrayName, cellFlag);

    if (scalars)
      {
      if (cellFlag)
        {
        this->CanUseTextureMapForColoringValue = 0;
        }
      if ((this->ColorMode == VTK_COLOR_MODE_DEFAULT &&
628
           vtkArrayDownCast<vtkUnsignedCharArray>(scalars)) ||
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
          this->ColorMode == VTK_COLOR_MODE_DIRECT_SCALARS)
        {
        // Don't use texture is direct coloring using RGB unsigned chars is
        // requested.
        this->CanUseTextureMapForColoringValue = 0;
        }

      if (scalarsLookupTable && scalars->GetLookupTable() &&
          (scalarsLookupTable != scalars->GetLookupTable()))
        {
        // Two datasets are requesting different lookup tables to color with.
        // We don't handle this case right now for composite datasets.
        this->CanUseTextureMapForColoringValue = 0;
        }
      if (scalars->GetLookupTable())
        {
        scalarsLookupTable = scalars->GetLookupTable();
        }
      }
    }

  if ((scalarsLookupTable &&
       scalarsLookupTable->GetIndexedLookup()) ||
      (!scalarsLookupTable &&
       this->LookupTable &&
       this->LookupTable->GetIndexedLookup()))
      {
      this->CanUseTextureMapForColoringValue = 0;
      }

  this->CanUseTextureMapForColoringSet = true;
  return this->CanUseTextureMapForColoringValue;
}

663
664
665
666
667
668
669
670
671
672
673
674
//-------------------------------------------------------------------------
bool vtkCompositePolyDataMapper2::GetNeedToRebuildBufferObjects(
  vtkRenderer *ren, vtkActor *act)
{
  if (vtkCompositePolyDataMapper2::Superclass::GetNeedToRebuildBufferObjects(ren, act) ||
      (this->GetInput() && this->VBOBuildTime < this->GetInput()->GetMTime()))
    {
    return true;
    }
  return false;
}

675
676
677
678
//-------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::BuildBufferObjects(
  vtkRenderer *ren,
  vtkActor *act)
679
{
680
681
682
683
  vtkCompositeDataSet *input = vtkCompositeDataSet::SafeDownCast(
    this->GetInputDataObject(0, 0));

  // render using the composite data attributes
Ken Martin's avatar
Ken Martin committed
684
  this->VBO->VertexCount = 0;
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699

  // compute the MaximumFlatIndex
  this->MaximumFlatIndex = 0;
  vtkSmartPointer<vtkDataObjectTreeIterator> iter =
    vtkSmartPointer<vtkDataObjectTreeIterator>::New();
  iter->SetDataSet(input);
  iter->SkipEmptyNodesOn();
  iter->VisitOnlyLeavesOn();
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
    {
    this->MaximumFlatIndex = iter->GetCurrentFlatIndex();
    }
  this->VertexOffsets.resize(this->MaximumFlatIndex+1);
  this->IndexOffsets.resize(this->MaximumFlatIndex+1);
  this->EdgeIndexOffsets.resize(this->MaximumFlatIndex+1);
700
  this->CanUseTextureMapForColoringSet = false;
701

702
  // create the cell scalar array adjusted for ogl Cells
703
704
705
  std::vector<unsigned char> newColors;
  std::vector<float> newNorms;

706
707
708
709
710
711
  unsigned int voffset = 0;
  for (iter->InitTraversal(); !iter->IsDoneWithTraversal(); iter->GoToNextItem())
    {
    unsigned int fidx = iter->GetCurrentFlatIndex();
    vtkDataObject *dso = iter->GetCurrentDataObject();
    vtkPolyData *pd = vtkPolyData::SafeDownCast(dso);
712
    this->AppendOneBufferObject(ren, act, pd, voffset, newColors, newNorms);
713
    this->VertexOffsets[fidx] =
Ken Martin's avatar
Ken Martin committed
714
715
      static_cast<unsigned int>(this->VBO->VertexCount);
    voffset = static_cast<unsigned int>(this->VBO->VertexCount);
716
717
718
719
720
721
    this->IndexOffsets[fidx] =
      static_cast<unsigned int>(this->IndexArray.size());
    this->EdgeIndexOffsets[fidx] =
      static_cast<unsigned int>(this->EdgeIndexArray.size());
    }

Ken Martin's avatar
Ken Martin committed
722
723
  this->VBO->Upload(this->VBO->PackedVBO, vtkOpenGLBufferObject::ArrayBuffer);
  this->VBO->PackedVBO.resize(0);
Ken Martin's avatar
Ken Martin committed
724
725
  this->Tris.IBO->Upload(this->IndexArray,
    vtkOpenGLBufferObject::ElementArrayBuffer);
Ken Martin's avatar
Ken Martin committed
726
  this->Tris.IBO->IndexCount = this->IndexArray.size();
727
  this->IndexArray.resize(0);
Ken Martin's avatar
Ken Martin committed
728
729
  this->TrisEdges.IBO->Upload(this->EdgeIndexArray,
    vtkOpenGLBufferObject::ElementArrayBuffer);
Ken Martin's avatar
Ken Martin committed
730
  this->TrisEdges.IBO->IndexCount = this->EdgeIndexArray.size();
731
732
733
734
  this->EdgeIndexArray.resize(0);

  // allocate as needed
  if (this->HaveCellScalars || this->HavePickScalars)
735
    {
736
737
738
    if (!this->CellScalarTexture)
      {
      this->CellScalarTexture = vtkTextureObject::New();
Ken Martin's avatar
Ken Martin committed
739
      this->CellScalarBuffer = vtkOpenGLBufferObject::New();
740
741
742
      }
    this->CellScalarTexture->SetContext(
      static_cast<vtkOpenGLRenderWindow*>(ren->GetVTKWindow()));
743
    this->CellScalarBuffer->Upload(newColors,
Ken Martin's avatar
Ken Martin committed
744
      vtkOpenGLBufferObject::TextureBuffer);
745
    this->CellScalarTexture->CreateTextureBuffer(
746
747
      static_cast<unsigned int>(newColors.size()/4),
      4,
748
749
750
751
752
753
      VTK_UNSIGNED_CHAR,
      this->CellScalarBuffer);
    }

  if (this->HaveCellNormals)
    {
754
755
756
    if (!this->CellNormalTexture)
      {
      this->CellNormalTexture = vtkTextureObject::New();
Ken Martin's avatar
Ken Martin committed
757
      this->CellNormalBuffer = vtkOpenGLBufferObject::New();
758
759
760
      }
    this->CellNormalTexture->SetContext(
      static_cast<vtkOpenGLRenderWindow*>(ren->GetVTKWindow()));
761
    this->CellNormalBuffer->Upload(newNorms,
Ken Martin's avatar
Ken Martin committed
762
      vtkOpenGLBufferObject::TextureBuffer);
763
    this->CellNormalTexture->CreateTextureBuffer(
764
765
      static_cast<unsigned int>(newNorms.size()/4),
      4, VTK_FLOAT,
766
767
      this->CellNormalBuffer);
    }
768
  this->VBOBuildTime.Modified();
769
770
771
772
773
774
775
}

//-------------------------------------------------------------------------
void vtkCompositePolyDataMapper2::AppendOneBufferObject(
  vtkRenderer *ren,
  vtkActor *act,
  vtkPolyData *poly,
776
777
778
779
  unsigned int voffset,
  std::vector<unsigned char> &newColors,
  std::vector<float> &newNorms
  )
780
{
781
782
783
784
785
786
  // if there are no cells then skip this piece
  if (poly->GetPolys()->GetNumberOfCells() == 0)
    {
    return;
    }

787
788
789
790
791
792
  // Get rid of old texture color coordinates if any
  if ( this->ColorCoordinates )
    {
    this->ColorCoordinates->UnRegister(this);
    this->ColorCoordinates = 0;
    }
Ken Martin's avatar
Ken Martin committed
793
794
795
796
797
798
  // Get rid of old texture color coordinates if any
  if ( this->Colors )
    {
    this->Colors->UnRegister(this);
    this->Colors = 0;
    }
799

800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
  // For vertex coloring, this sets this->Colors as side effect.
  // For texture map coloring, this sets ColorCoordinates
  // and ColorTextureMap as a side effect.
  // I moved this out of the conditional because it is fast.
  // Color arrays are cached. If nothing has changed,
  // then the scalars do not have to be regenerted.
  this->MapScalars(poly, 1.0);

  // If we are coloring by texture, then load the texture map.
  if (this->ColorTextureMap)
    {
    if (this->InternalColorTexture == 0)
      {
      this->InternalColorTexture = vtkOpenGLTexture::New();
      this->InternalColorTexture->RepeatOff();
      }
    this->InternalColorTexture->SetInputData(this->ColorTextureMap);
    }

819
  this->HaveCellScalars = false;
820
  vtkDataArray *c = this->Colors;
821
  if (this->ScalarVisibility)
822
    {
823
824
825
826
827
828
829
    // We must figure out how the scalars should be mapped to the polydata.
    if ( (this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_DATA ||
          this->ScalarMode == VTK_SCALAR_MODE_USE_CELL_FIELD_DATA ||
          this->ScalarMode == VTK_SCALAR_MODE_USE_FIELD_DATA ||
          !poly->GetPointData()->GetScalars() )
         && this->ScalarMode != VTK_SCALAR_MODE_USE_POINT_FIELD_DATA
         && this->Colors)
830
      {
831
      this->HaveCellScalars = true;
832
      c = NULL;
833
834
      }
    }
835

836
  this->HaveCellNormals = false;
837
838
839
840
841
  // Do we have cell normals?
  vtkDataArray *n =
    (act->GetProperty()->GetInterpolation() != VTK_FLAT) ? poly->GetPointData()->GetNormals() : NULL;
  if (n == NULL && poly->GetCellData()->GetNormals())
    {
842
    this->HaveCellNormals = true;
843
    n = NULL;
844
845
846
847
848
849
850
851
852
    }

  // if we have cell scalars then we have to
  // explode the data
  vtkCellArray *prims[4];
  prims[0] =  poly->GetVerts();
  prims[1] =  poly->GetLines();
  prims[2] =  poly->GetPolys();
  prims[3] =  poly->GetStrips();
853

854
855
856
857
858
  int representation = act->GetProperty()->GetRepresentation();
  vtkHardwareSelector* selector = ren->GetSelector();
  if (selector && this->PopulateSelectionSettings &&
      selector->GetFieldAssociation() == vtkDataObject::FIELD_ASSOCIATION_POINTS &&
      selector->GetCurrentPass() >= vtkHardwareSelector::ID_LOW24)
859
    {
860
    representation = VTK_POINTS;
861
862
    }

863
864
865
  this->AppendCellTextures(ren, act, prims, representation,
    newColors, newNorms, poly);

866
867
868
869
870
871
872
873
  // do we have texture maps?
  bool haveTextures = (this->ColorTextureMap || act->GetTexture() || act->GetProperty()->GetNumberOfTextures());

  // Set the texture if we are going to use texture
  // for coloring with a point attribute.
  // fixme ... make the existence of the coordinate array the signal.
  vtkDataArray *tcoords = NULL;
  if (haveTextures)
874
    {
875
    if (this->InterpolateScalarsBeforeMapping && this->ColorCoordinates)
876
      {
877
      tcoords = this->ColorCoordinates;
878
      }
879
    else
880
      {
881
      tcoords = poly->GetPointData()->GetTCoords();
882
883
884
      }
    }

885
  // Build the VBO
Ken Martin's avatar
Ken Martin committed
886
  this->VBO->AppendVBO(poly->GetPoints(),
887
            poly->GetPoints()->GetNumberOfPoints(),
888
            n, tcoords,
889
890
            c ? (unsigned char *)c->GetVoidPointer(0) : NULL,
            c ? c->GetNumberOfComponents() : 0);
891
892
893
894

  // now create the IBOs
  if (representation == VTK_POINTS)
    {
Ken Martin's avatar
Ken Martin committed
895
896
    vtkOpenGLIndexBufferObject::AppendPointIndexBuffer(
      this->IndexArray, prims[2], voffset);
897
898
899
900
901
    }
  else // WIREFRAME OR SURFACE
    {
    if (representation == VTK_WIREFRAME)
      {
Ken Martin's avatar
Ken Martin committed
902
      vtkOpenGLIndexBufferObject::AppendTriangleLineIndexBuffer(
903
904
905
906
        this->IndexArray, prims[2], voffset);
      }
   else // SURFACE
      {
Ken Martin's avatar
Ken Martin committed
907
      vtkOpenGLIndexBufferObject::AppendTriangleIndexBuffer(this->IndexArray,
908
909
910
911
912
        prims[2],
        poly->GetPoints(),
        voffset);
      }
    }
913

914
915
916
917
918
919
  // when drawing edges also build the edge IBOs
  vtkProperty *prop = act->GetProperty();
  bool draw_surface_with_edges =
    (prop->GetEdgeVisibility() && prop->GetRepresentation() == VTK_SURFACE);
  if (draw_surface_with_edges)
    {
Ken Martin's avatar
Ken Martin committed
920
    vtkOpenGLIndexBufferObject::AppendTriangleLineIndexBuffer(
921
922
      this->EdgeIndexArray, prims[2], voffset);
    }
923
924

}