vtkGlyph3D.cxx 26.4 KB
Newer Older
Will Schroeder's avatar
Will Schroeder committed
1 2
/*=========================================================================

Ken Martin's avatar
Ken Martin committed
3
  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkGlyph3D.cxx
Will Schroeder's avatar
Will Schroeder committed
5

6
  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7 8
  All rights reserved.
  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
Ken Martin's avatar
Ken Martin committed
9

10 11
     This software is distributed WITHOUT ANY WARRANTY; without even
     the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12
     PURPOSE.  See the above copyright notice for more information.
Will Schroeder's avatar
Will Schroeder committed
13 14

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkGlyph3D.h"
16

17
#include "vtkCellData.h"
18
#include "vtkCell.h"
19
#include "vtkFloatArray.h"
20 21
#include "vtkIdList.h"
#include "vtkIdTypeArray.h"
22 23
#include "vtkInformation.h"
#include "vtkInformationVector.h"
Ken Martin's avatar
Ken Martin committed
24
#include "vtkMath.h"
25
#include "vtkNew.h"
26
#include "vtkObjectFactory.h"
27
#include "vtkPointData.h"
28
#include "vtkPolyData.h"
29
#include "vtkSmartPointer.h"
30
#include "vtkStreamingDemandDrivenPipeline.h"
31
#include "vtkTransform.h"
32
#include "vtkTrivialProducer.h"
33
#include "vtkUniformGrid.h"
Berk Geveci's avatar
Berk Geveci committed
34
#include "vtkUnsignedCharArray.h"
35

Brad King's avatar
Brad King committed
36
vtkStandardNewMacro(vtkGlyph3D);
37
vtkCxxSetObjectMacro(vtkGlyph3D, SourceTransform, vtkTransform);
38

Mathieu Malaterre's avatar
Mathieu Malaterre committed
39
//----------------------------------------------------------------------------
40
// Construct object with scaling on, scaling mode is by scalar value,
Will Schroeder's avatar
Will Schroeder committed
41
// scale factor = 1.0, the range is (0,1), orient geometry is on, and
42 43
// orientation is by vector. Clamping and indexing are turned off. No
// initial sources are defined.
Ken Martin's avatar
Ken Martin committed
44
vtkGlyph3D::vtkGlyph3D()
Will Schroeder's avatar
Will Schroeder committed
45 46
{
  this->Scaling = 1;
Ken Martin's avatar
Ken Martin committed
47
  this->ColorMode = VTK_COLOR_BY_SCALE;
Ken Martin's avatar
Ken Martin committed
48
  this->ScaleMode = VTK_SCALE_BY_SCALAR;
Will Schroeder's avatar
Will Schroeder committed
49 50
  this->ScaleFactor = 1.0;
  this->Range[0] = 0.0;
Will Schroeder's avatar
Will Schroeder committed
51 52
  this->Range[1] = 1.0;
  this->Orient = 1;
Ken Martin's avatar
Ken Martin committed
53
  this->VectorMode = VTK_USE_VECTOR;
Ken Martin's avatar
Ken Martin committed
54
  this->Clamping = 0;
55
  this->IndexMode = VTK_INDEXING_OFF;
56
  this->GeneratePointIds = 0;
57
  this->PointIdsName = nullptr;
58
  this->SetPointIdsName("InputPointIds");
59
  this->SetNumberOfInputPorts(2);
60
  this->FillCellData = 0;
61
  this->SourceTransform = nullptr;
62
  this->OutputPointsPrecision = vtkAlgorithm::DEFAULT_PRECISION;
63 64 65 66 67 68 69 70 71 72 73 74 75

  // by default process active point scalars
  this->SetInputArrayToProcess(0,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::SCALARS);
  // by default process active point vectors
  this->SetInputArrayToProcess(1,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::VECTORS);
  // by default process active point normals
  this->SetInputArrayToProcess(2,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::NORMALS);
  // by default process active point scalars
  this->SetInputArrayToProcess(3,0,0,vtkDataObject::FIELD_ASSOCIATION_POINTS,
                               vtkDataSetAttributes::SCALARS);
Will Schroeder's avatar
Will Schroeder committed
76 77
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
78
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
79
vtkGlyph3D::~vtkGlyph3D()
80
{
81
  delete [] PointIdsName;
82
  this->SetSourceTransform(nullptr);
83 84 85
}

//----------------------------------------------------------------------------
Bill Lorensen's avatar
Bill Lorensen committed
86
vtkMTimeType vtkGlyph3D::GetMTime()
87
{
Bill Lorensen's avatar
Bill Lorensen committed
88 89
  vtkMTimeType mTime=this->Superclass::GetMTime();
  vtkMTimeType time;
90
  if ( this->SourceTransform != nullptr )
91
  {
92 93
    time = this->SourceTransform ->GetMTime();
    mTime = ( time > mTime ? time : mTime );
94
  }
95
  return mTime;
96 97
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
98
//----------------------------------------------------------------------------
99 100 101 102
int vtkGlyph3D::RequestData(
  vtkInformation *vtkNotUsed(request),
  vtkInformationVector **inputVector,
  vtkInformationVector *outputVector)
Will Schroeder's avatar
Will Schroeder committed
103
{
104
  // get the info objects
105 106
  vtkDataSet* input = vtkDataSet::GetData(inputVector[0], 0);
  vtkPolyData* output = vtkPolyData::GetData(outputVector, 0);
107

108
  return this->Execute(input, inputVector[1], output)? 1 : 0;
109 110 111 112 113 114
}

//----------------------------------------------------------------------------
bool vtkGlyph3D::Execute(
  vtkDataSet* input,
  vtkInformationVector* sourceVector,
115
  vtkPolyData* output)
116 117 118 119 120 121 122 123 124 125 126 127 128
{
  vtkDataArray *inSScalars = this->GetInputArrayToProcess(0, input);
  vtkDataArray *inVectors = this->GetInputArrayToProcess(1, input);
  return this->Execute(input, sourceVector, output, inSScalars, inVectors);
}

//----------------------------------------------------------------------------
bool vtkGlyph3D::Execute(
  vtkDataSet* input,
  vtkInformationVector* sourceVector,
  vtkPolyData* output,
  vtkDataArray *inSScalars,
  vtkDataArray *inVectors)
129 130
{
  assert(input && output);
131
  if (input == nullptr || output == nullptr)
132
  {
133 134
    // nothing to do.
    return true;
135
  }
136 137 138

  // this is used to respect blanking specified on uniform grids.
  vtkUniformGrid* inputUG = vtkUniformGrid::SafeDownCast(input);
139

Ken Martin's avatar
Ken Martin committed
140
  vtkPointData *pd;
141
  vtkDataArray *inCScalars; // Scalars for Coloring
142 143 144
  unsigned char* inGhostLevels=nullptr;
  vtkDataArray *inNormals, *sourceNormals = nullptr;
  vtkDataArray *sourceTCoords = nullptr;
Amy Squillacote's avatar
Amy Squillacote committed
145
  vtkIdType numPts, numSourcePts, numSourceCells, inPtId, i;
146
  vtkPoints *sourcePts = nullptr;
147
  vtkSmartPointer<vtkPoints> transformedSourcePts = vtkSmartPointer<vtkPoints>::New();
148
  vtkPoints *newPts;
149 150 151 152
  vtkDataArray *newScalars=nullptr;
  vtkDataArray *newVectors=nullptr;
  vtkDataArray *newNormals=nullptr;
  vtkDataArray *newTCoords = nullptr;
153
  double x[3], v[3], vNew[3], s = 0.0, vMag = 0.0, value, tc[3];
154
  vtkTransform *trans = vtkTransform::New();
155
  vtkNew<vtkIdList> pointIdList;
Ken Martin's avatar
Ken Martin committed
156
  vtkIdList *cellPts;
Will Schroeder's avatar
Will Schroeder committed
157
  int npts;
158
  vtkIdList *pts;
159
  vtkIdType ptIncr, cellIncr, cellId;
160
  int haveVectors, haveNormals, haveTCoords = 0;
Ken Martin's avatar
Ken Martin committed
161
  double scalex,scaley,scalez, den;
162 163
  vtkPointData* outputPD = output->GetPointData();
  vtkCellData* outputCD = output->GetCellData();
164
  int numberOfSources = this->GetNumberOfInputConnections(1);
165
  vtkIdTypeArray *pointIds=nullptr;
166
  vtkSmartPointer<vtkPolyData> source = this->GetSource(0, sourceVector);
167 168 169 170
  vtkNew<vtkIdList> srcPointIdList;
  vtkNew<vtkIdList> dstPointIdList;
  vtkNew<vtkIdList> srcCellIdList;
  vtkNew<vtkIdList> dstCellIdList;
John Biddiscombe's avatar
John Biddiscombe committed
171

Ken Martin's avatar
Ken Martin committed
172
  vtkDebugMacro(<<"Generating glyphs");
Will Schroeder's avatar
Will Schroeder committed
173

174 175 176
  pts = vtkIdList::New();
  pts->Allocate(VTK_CELL_SIZE);

177
  pd = input->GetPointData();
178 179
  inNormals = this->GetInputArrayToProcess(2, input);
  inCScalars = this->GetInputArrayToProcess(3, input);
180
  if (inCScalars == nullptr)
181
  {
182
    inCScalars = inSScalars;
183
  }
184

185
  vtkDataArray* temp = nullptr;
186
  if (pd)
187
  {
188
    temp = pd->GetArray(vtkDataSetAttributes::GhostArrayName());
189
  }
Berk Geveci's avatar
Berk Geveci committed
190 191
  if ( (!temp) || (temp->GetDataType() != VTK_UNSIGNED_CHAR)
    || (temp->GetNumberOfComponents() != 1))
192
  {
Berk Geveci's avatar
Berk Geveci committed
193
    vtkDebugMacro("No appropriate ghost levels field available.");
194
  }
Berk Geveci's avatar
Berk Geveci committed
195
  else
196
  {
197
    inGhostLevels =static_cast<vtkUnsignedCharArray *>(temp)->GetPointer(0);
198
  }
Berk Geveci's avatar
Berk Geveci committed
199

200

201
  numPts = input->GetNumberOfPoints();
202
  if (numPts < 1)
203
  {
204
    vtkDebugMacro(<<"No points to glyph!");
Berk Geveci's avatar
Berk Geveci committed
205 206
    pts->Delete();
    trans->Delete();
207
    return 1;
208
  }
209

210 211
  // Check input for consistency
  //
Bill Lorensen's avatar
Bill Lorensen committed
212
  if ( (den = this->Range[1] - this->Range[0]) == 0.0 )
213
  {
Bill Lorensen's avatar
Bill Lorensen committed
214
    den = 1.0;
215
  }
216
  if ( this->VectorMode != VTK_VECTOR_ROTATION_OFF &&
217 218
       ((this->VectorMode == VTK_USE_VECTOR && inVectors != nullptr) ||
        (this->VectorMode == VTK_USE_NORMAL && inNormals != nullptr)) )
219
  {
220
    haveVectors = 1;
221
  }
222
  else
223
  {
224
    haveVectors = 0;
225
  }
Will Schroeder's avatar
Will Schroeder committed
226

227
  if ( (this->IndexMode == VTK_INDEXING_BY_SCALAR && !inSScalars) ||
228
       (this->IndexMode == VTK_INDEXING_BY_VECTOR &&
Bill Lorensen's avatar
Bill Lorensen committed
229
       ((!inVectors && this->VectorMode == VTK_USE_VECTOR) ||
230
        (!inNormals && this->VectorMode == VTK_USE_NORMAL))) )
231
  {
232
    if ( source == nullptr )
233
    {
234
      vtkErrorMacro(<<"Indexing on but don't have data to index with");
235
      pts->Delete();
Berk Geveci's avatar
Berk Geveci committed
236
      trans->Delete();
237
      return true;
238
    }
239
    else
240
    {
241 242
      vtkWarningMacro(<<"Turning indexing off: no data to index with");
      this->IndexMode = VTK_INDEXING_OFF;
Will Schroeder's avatar
Will Schroeder committed
243
    }
244
  }
245

246 247
  // Allocate storage for output PolyData
  //
248 249
  outputPD->CopyVectorsOff();
  outputPD->CopyNormalsOff();
250
  outputPD->CopyTCoordsOff();
251

252
  if ( source == nullptr )
253
  {
254
    vtkNew<vtkPolyData> defaultSource;
255
    defaultSource->Allocate();
256
    vtkNew<vtkPoints> defaultPoints;
257 258 259
    defaultPoints->Allocate(6);
    defaultPoints->InsertNextPoint(0, 0, 0);
    defaultPoints->InsertNextPoint(1, 0, 0);
260
    vtkIdType defaultPointIds[2];
261 262
    defaultPointIds[0] = 0;
    defaultPointIds[1] = 1;
263
    defaultSource->SetPoints(defaultPoints);
264
    defaultSource->InsertNextCell(VTK_LINE, 2, defaultPointIds);
265
    source = defaultSource;
266
  }
267

268
  if ( this->IndexMode != VTK_INDEXING_OFF )
269
  {
270
    pd = nullptr;
271
    haveNormals = 1;
272
    for (numSourcePts=numSourceCells=i=0; i < numberOfSources; i++)
273
    {
274
      source = this->GetSource(i, sourceVector);
275
      if ( source != nullptr )
276
      {
277
        if (source->GetNumberOfPoints() > numSourcePts)
278
        {
279
          numSourcePts = source->GetNumberOfPoints();
280
        }
281
        if (source->GetNumberOfCells() > numSourceCells)
282
        {
283
          numSourceCells = source->GetNumberOfCells();
284
        }
285
        if ( !(sourceNormals = source->GetPointData()->GetNormals()) )
286
        {
287 288 289
          haveNormals = 0;
        }
      }
Will Schroeder's avatar
Will Schroeder committed
290
    }
291
  }
292
  else
293
  {
294
    sourcePts = source->GetPoints();
295
    numSourcePts = sourcePts->GetNumberOfPoints();
296
    numSourceCells = source->GetNumberOfCells();
297

298
    sourceNormals = source->GetPointData()->GetNormals();
Bill Lorensen's avatar
Bill Lorensen committed
299
    if ( sourceNormals )
300
    {
Bill Lorensen's avatar
Bill Lorensen committed
301
      haveNormals = 1;
302
    }
Bill Lorensen's avatar
Bill Lorensen committed
303
    else
304
    {
Bill Lorensen's avatar
Bill Lorensen committed
305
      haveNormals = 0;
306
    }
307

308
    sourceTCoords = source->GetPointData()->GetTCoords();
309
    if (sourceTCoords)
310
    {
311
      haveTCoords = 1;
312
    }
313
    else
314
    {
315
      haveTCoords = 0;
316
    }
317

318
    // Prepare to copy output.
319
    pd = input->GetPointData();
320
    outputPD->CopyAllocate(pd,numPts*numSourcePts);
321
    if (this->FillCellData)
322
    {
323
      outputCD->CopyAllocate(pd,numPts*numSourceCells);
Will Schroeder's avatar
Will Schroeder committed
324
    }
325
  }
326

327 328 329 330 331
  srcPointIdList->SetNumberOfIds(numSourcePts);
  dstPointIdList->SetNumberOfIds(numSourcePts);
  srcCellIdList->SetNumberOfIds(numSourceCells);
  dstCellIdList->SetNumberOfIds(numSourceCells);

332
  newPts = vtkPoints::New();
333 334 335 336 337 338 339 340 341 342 343 344 345 346 347

  // Set the desired precision for the points in the output.
  if(this->OutputPointsPrecision == vtkAlgorithm::DEFAULT_PRECISION)
  {
    newPts->SetDataType(VTK_FLOAT);
  }
  else if(this->OutputPointsPrecision == vtkAlgorithm::SINGLE_PRECISION)
  {
    newPts->SetDataType(VTK_FLOAT);
  }
  else if(this->OutputPointsPrecision == vtkAlgorithm::DOUBLE_PRECISION)
  {
    newPts->SetDataType(VTK_DOUBLE);
  }

Will Schroeder's avatar
Will Schroeder committed
348
  newPts->Allocate(numPts*numSourcePts);
349
  if ( this->GeneratePointIds )
350
  {
351
    pointIds = vtkIdTypeArray::New();
352
    pointIds->SetName(this->PointIdsName);
353 354
    pointIds->Allocate(numPts*numSourcePts);
    outputPD->AddArray(pointIds);
Mathieu Malaterre's avatar
Mathieu Malaterre committed
355
    pointIds->Delete();
356
  }
357
  if ( this->ColorMode == VTK_COLOR_BY_SCALAR && inCScalars )
358
  {
359 360 361 362
    newScalars = inCScalars->NewInstance();
    newScalars->SetNumberOfComponents(inCScalars->GetNumberOfComponents());
    newScalars->Allocate(inCScalars->GetNumberOfComponents()*numPts*numSourcePts);
    newScalars->SetName(inCScalars->GetName());
363
  }
364
  else if ( (this->ColorMode == VTK_COLOR_BY_SCALE) && inSScalars)
365
  {
366
    newScalars = vtkFloatArray::New();
367
    newScalars->Allocate(numPts*numSourcePts);
368
    newScalars->SetName("GlyphScale");
369
    if (this->ScaleMode == VTK_SCALE_BY_SCALAR)
370
    {
371
      newScalars->SetName(inSScalars->GetName());
372
    }
373
  }
374
  else if ( (this->ColorMode == VTK_COLOR_BY_VECTOR) && haveVectors)
375
  {
376
    newScalars = vtkFloatArray::New();
Will Schroeder's avatar
Will Schroeder committed
377
    newScalars->Allocate(numPts*numSourcePts);
378
    newScalars->SetName("VectorMagnitude");
379
  }
380
  if ( haveVectors )
381
  {
382 383 384 385
    newVectors = vtkFloatArray::New();
    newVectors->SetNumberOfComponents(3);
    newVectors->Allocate(3*numPts*numSourcePts);
    newVectors->SetName("GlyphVector");
386
  }
Will Schroeder's avatar
Will Schroeder committed
387
  if ( haveNormals )
388
  {
389 390 391 392
    newNormals = vtkFloatArray::New();
    newNormals->SetNumberOfComponents(3);
    newNormals->Allocate(3*numPts*numSourcePts);
    newNormals->SetName("Normals");
393
  }
394
  if (haveTCoords)
395
  {
396 397 398 399 400
    newTCoords = vtkFloatArray::New();
    int numComps = sourceTCoords->GetNumberOfComponents();
    newTCoords->SetNumberOfComponents(numComps);
    newTCoords->Allocate(numComps*numPts*numSourcePts);
    newTCoords->SetName("TCoords");
401
  }
402

403
  // Setting up for calls to PolyData::InsertNextCell()
404
  if (this->IndexMode != VTK_INDEXING_OFF )
405
  {
406
    output->Allocate(3*numPts*numSourceCells,numPts*numSourceCells);
407
  }
408
  else
409
  {
410
    output->Allocate(source,
411
                     3*numPts*numSourceCells, numPts*numSourceCells);
412
  }
413

414 415 416
  transformedSourcePts->SetDataTypeToDouble();
  transformedSourcePts->Allocate(numSourcePts);

417
  // Traverse all Input points, transforming Source points and copying
418 419
  // point attributes.
  //
420
  ptIncr=0;
421
  cellIncr=0;
422
  for (inPtId=0; inPtId < numPts; inPtId++)
423
  {
424 425
    scalex = scaley = scalez = 1.0;
    if ( ! (inPtId % 10000) )
426
    {
427
      this->UpdateProgress(static_cast<double>(inPtId)/numPts);
Bill Lorensen's avatar
Bill Lorensen committed
428
      if (this->GetAbortExecute())
429
      {
Amy Squillacote's avatar
Amy Squillacote committed
430
        break;
431
      }
432
    }
433

434
    // Get the scalar and vector data
435
    if ( inSScalars )
436
    {
437
      s = inSScalars->GetComponent(inPtId, 0);
438
      if ( this->ScaleMode == VTK_SCALE_BY_SCALAR ||
Amy Squillacote's avatar
Amy Squillacote committed
439
           this->ScaleMode == VTK_DATA_SCALING_OFF )
440
      {
441
        scalex = scaley = scalez = s;
442
      }
443
    }
444

445
    if ( haveVectors )
446
    {
447 448
      vtkDataArray *array3D = this->VectorMode == VTK_USE_NORMAL? inNormals : inVectors;
      if(array3D->GetNumberOfComponents()>3)
449
      {
450
        vtkErrorMacro(<<"vtkDataArray "<<array3D->GetName()<<" has more than 3 components.\n");
451 452
        pts->Delete();
        trans->Delete();
Yuanxin Liu's avatar
Yuanxin Liu committed
453
        if(newPts)
454
        {
Yuanxin Liu's avatar
Yuanxin Liu committed
455
          newPts->Delete();
456
        }
Yuanxin Liu's avatar
Yuanxin Liu committed
457
        if(newVectors)
458
        {
Yuanxin Liu's avatar
Yuanxin Liu committed
459
          newVectors->Delete();
460
        }
461 462
        return false;
      }
463

464 465 466
      v[0] = 0;
      v[1] = 0;
      v[2] = 0;
467
      array3D->GetTuple(inPtId, v);
468
      vMag = vtkMath::Norm(v);
469
      if ( this->ScaleMode == VTK_SCALE_BY_VECTORCOMPONENTS )
470
      {
471 472 473
        scalex = v[0];
        scaley = v[1];
        scalez = v[2];
474
      }
475
      else if ( this->ScaleMode == VTK_SCALE_BY_VECTOR )
476
      {
477
        scalex = scaley = scalez = vMag;
478
      }
479
    }
480

481 482
    // Clamp data scale if enabled
    if ( this->Clamping )
483
    {
484
      scalex = (scalex < this->Range[0] ? this->Range[0] :
485
                (scalex > this->Range[1] ? this->Range[1] : scalex));
486 487
      scalex = (scalex - this->Range[0]) / den;
      scaley = (scaley < this->Range[0] ? this->Range[0] :
488
                (scaley > this->Range[1] ? this->Range[1] : scaley));
489 490
      scaley = (scaley - this->Range[0]) / den;
      scalez = (scalez < this->Range[0] ? this->Range[0] :
491
                (scalez > this->Range[1] ? this->Range[1] : scalez));
492
      scalez = (scalez - this->Range[0]) / den;
493
    }
494

495
    // Compute index into table of glyphs
496
    if ( this->IndexMode != VTK_INDEXING_OFF )
497
    {
Bill Lorensen's avatar
Bill Lorensen committed
498
      if ( this->IndexMode == VTK_INDEXING_BY_SCALAR )
499
      {
500
        value = s;
501
      }
Bill Lorensen's avatar
Bill Lorensen committed
502
      else
503
      {
504
        value = vMag;
505
      }
506

507
      int index = static_cast<int>((value - this->Range[0])*numberOfSources / den);
508
      index = (index < 0 ? 0 :
509
              (index >= numberOfSources ? (numberOfSources-1) : index));
510

511
      source = this->GetSource(index, sourceVector);
512
      if ( source != nullptr )
513
      {
514 515
        sourcePts = source->GetPoints();
        sourceNormals = source->GetPointData()->GetNormals();
516
        numSourcePts = sourcePts->GetNumberOfPoints();
517
        numSourceCells = source->GetNumberOfCells();
518
      }
519
    }
520

521
    // Make sure we're not indexing into empty glyph
522
    if ( source == nullptr )
523
    {
Bill Lorensen's avatar
Bill Lorensen committed
524
      continue;
525
    }
526

527
    // Check ghost points.
528
    // If we are processing a piece, we do not want to duplicate
529 530 531
    // glyphs on the borders.
    if (inGhostLevels &&
        inGhostLevels[inPtId] & vtkDataSetAttributes::DUPLICATEPOINT)
532
    {
533
      continue;
534
    }
535

536
    if (inputUG && !inputUG->IsPointVisible(inPtId))
537
    {
538 539 540
      // input is a vtkUniformGrid and the current point is blanked. Don't glyph
      // it.
      continue;
541
    }
542

543
    if (!this->IsPointVisible(input, inPtId))
544
    {
545
      continue;
546
    }
547

548
    // Now begin copying/transforming glyph
549
    trans->Identity();
550

551
    // Copy all topology (transformation independent)
Will Schroeder's avatar
Will Schroeder committed
552
    for (cellId=0; cellId < numSourceCells; cellId++)
553
    {
554 555
      source->GetCellPoints(cellId, pointIdList);
      cellPts = pointIdList;
Will Schroeder's avatar
Will Schroeder committed
556
      npts = cellPts->GetNumberOfIds();
557
      for (pts->Reset(), i=0; i < npts; i++)
558
      {
559
        pts->InsertId(i, cellPts->GetId(i) + ptIncr);
Will Schroeder's avatar
Will Schroeder committed
560
      }
561 562
      output->InsertNextCell(source->GetCellType(cellId), pts);
    }
563

Will Schroeder's avatar
Will Schroeder committed
564
    // translate Source to Input point
565
    input->GetPoint(inPtId, x);
566
    trans->Translate(x[0], x[1], x[2]);
567

568
    if ( haveVectors )
569
    {
Will Schroeder's avatar
Will Schroeder committed
570
      // Copy Input vector
571
      for (i=0; i < numSourcePts; i++)
572
      {
573
        newVectors->InsertTuple(i+ptIncr, v);
574
      }
575
      if (this->Orient && (vMag > 0.0))
576
      {
577 578
        // if there is no y or z component
        if ( v[1] == 0.0 && v[2] == 0.0 )
579
        {
580
          if (v[0] < 0) //just flip x if we need to
581
          {
582
            trans->RotateWXYZ(180.0,0,1,0);
583
          }
584
        }
585
        else
586
        {
587 588 589
          vNew[0] = (v[0]+vMag) / 2.0;
          vNew[1] = v[1] / 2.0;
          vNew[2] = v[2] / 2.0;
590
          trans->RotateWXYZ(180.0,vNew[0],vNew[1],vNew[2]);
Will Schroeder's avatar
Will Schroeder committed
591 592
        }
      }
593
    }
594

595
    if (haveTCoords)
596
    {
597
      for (i = 0; i < numSourcePts; i++)
598
      {
599
        sourceTCoords->GetTuple(i, tc);
600 601
        newTCoords->InsertTuple(i+ptIncr, tc);
      }
602
    }
603

Will Schroeder's avatar
Will Schroeder committed
604
    // determine scale factor from scalars if appropriate
605 606
    // Copy scalar value
    if (inSScalars && (this->ColorMode == VTK_COLOR_BY_SCALE))
607
    {
608
      for (i=0; i < numSourcePts; i++)
609
      {
610 611
        newScalars->InsertTuple(i+ptIncr, &scalex); // = scaley = scalez
      }
612
    }
613
    else if (inCScalars && (this->ColorMode == VTK_COLOR_BY_SCALAR))
614
    {
615
      for (i=0; i < numSourcePts; i++)
616
      {
617
        outputPD->CopyTuple(inCScalars, newScalars, inPtId, ptIncr+i);
Ken Martin's avatar
Ken Martin committed
618
      }
619
    }
Ken Martin's avatar
Ken Martin committed
620
    if (haveVectors && this->ColorMode == VTK_COLOR_BY_VECTOR)
621
    {
622
      for (i=0; i < numSourcePts; i++)
623
      {
624
        newScalars->InsertTuple(i+ptIncr, &vMag);
Will Schroeder's avatar
Will Schroeder committed
625
      }
626
    }
627

Will Schroeder's avatar
Will Schroeder committed
628
    // scale data if appropriate
629
    if ( this->Scaling )
630
    {
Bill Lorensen's avatar
Bill Lorensen committed
631
      if ( this->ScaleMode == VTK_DATA_SCALING_OFF )
632
      {
633
        scalex = scaley = scalez = this->ScaleFactor;
634
      }
Bill Lorensen's avatar
Bill Lorensen committed
635
      else
636
      {
637 638 639
        scalex *= this->ScaleFactor;
        scaley *= this->ScaleFactor;
        scalez *= this->ScaleFactor;
640
      }
641

642
      if ( scalex == 0.0 )
643
      {
644
        scalex = 1.0e-10;
645
      }
646
      if ( scaley == 0.0 )
647
      {
648
        scaley = 1.0e-10;
649
      }
650
      if ( scalez == 0.0 )
651
      {
652
        scalez = 1.0e-10;
Will Schroeder's avatar
Will Schroeder committed
653
      }
654 655
      trans->Scale(scalex,scaley,scalez);
    }
656

Will Schroeder's avatar
Will Schroeder committed
657
    // multiply points and normals by resulting matrix
658
    if (this->SourceTransform)
659
    {
660 661 662
      transformedSourcePts->Reset();
      this->SourceTransform->TransformPoints(sourcePts, transformedSourcePts);
      trans->TransformPoints(transformedSourcePts, newPts);
663
    }
664
    else
665
    {
666
      trans->TransformPoints(sourcePts,newPts);
667
    }
668

Bill Lorensen's avatar
Bill Lorensen committed
669
    if ( haveNormals )
670
    {
671
      trans->TransformNormals(sourceNormals,newNormals);
672
    }
673

674
    // Copy point data from source (if possible)
675
    if ( pd )
676
    {
677
      for (i = 0; i < numSourcePts; ++i)
678
      {
679 680
        srcPointIdList->SetId(i, inPtId);
        dstPointIdList->SetId(i, ptIncr + i);
681
      }
682
      outputPD->CopyData(pd, srcPointIdList, dstPointIdList);