vtkProp.cxx 10.6 KB
Newer Older
1 2 3
/*=========================================================================

  Program:   Visualization Toolkit
Ken Martin's avatar
Ken Martin committed
4
  Module:    vtkProp.cxx
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.
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.
13 14

=========================================================================*/
Ken Martin's avatar
Ken Martin committed
15
#include "vtkProp.h"
16
#include "vtkObjectFactory.h"
Will Schroeder's avatar
Will Schroeder committed
17
#include "vtkAssemblyPaths.h"
18
#include "vtkCommand.h"
19 20 21
#include "vtkInformation.h"
#include "vtkInformationIterator.h"
#include "vtkInformationKey.h"
Ken Martin's avatar
Ken Martin committed
22
#include "vtkInformationIntegerKey.h"
23
#include "vtkInformationDoubleVectorKey.h"
24
#include "vtkShaderProperty.h"
25
#include <cassert>
26

27
vtkCxxSetObjectMacro(vtkProp,PropertyKeys,vtkInformation);
28

Ken Martin's avatar
Ken Martin committed
29
vtkInformationKeyMacro(vtkProp,GeneralTextureUnit,Integer);
30
vtkInformationKeyMacro(vtkProp,GeneralTextureTransform,DoubleVector);
Ken Martin's avatar
Ken Martin committed
31

Mathieu Malaterre's avatar
Mathieu Malaterre committed
32
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
33 34
// Creates an Prop with the following defaults: visibility on.
vtkProp::vtkProp()
35 36
{
  this->Visibility = 1;  // ON
37 38 39

  this->Pickable   = 1;
  this->Dragable   = 1;
40

41
  this->UseBounds=true;
42

Ken Martin's avatar
Ken Martin committed
43
  this->AllocatedRenderTime = 10.0;
44
  this->EstimatedRenderTime = 0.0;
45
  this->RenderTimeMultiplier = 1.0;
Will Schroeder's avatar
Will Schroeder committed
46

47
  this->Paths = nullptr;
Ken Martin's avatar
Ken Martin committed
48 49

  this->NumberOfConsumers = 0;
50
  this->Consumers = nullptr;
51

52
  this->PropertyKeys=nullptr;
53 54

  this->ShaderProperty = nullptr;
55 56
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
57
//----------------------------------------------------------------------------
58 59
vtkProp::~vtkProp()
{
Will Schroeder's avatar
Will Schroeder committed
60
  if ( this->Paths )
61
  {
Will Schroeder's avatar
Will Schroeder committed
62
    this->Paths->Delete();
63
  }
64 65

  delete [] this->Consumers;
66

67
  if(this->PropertyKeys!=nullptr)
68
  {
69
    this->PropertyKeys->Delete();
70
  }
71 72 73 74 75

  if (this->ShaderProperty)
  {
    this->ShaderProperty->UnRegister(this);
  }
76 77
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
78
//----------------------------------------------------------------------------
79 80
// This method is invoked if the prop is picked.
void vtkProp::Pick()
Ken Martin's avatar
Ken Martin committed
81
{
82
  this->InvokeEvent(vtkCommand::PickEvent,nullptr);
Ken Martin's avatar
Ken Martin committed
83
}
84

Mathieu Malaterre's avatar
Mathieu Malaterre committed
85
//----------------------------------------------------------------------------
86
// Shallow copy of vtkProp.
Will Schroeder's avatar
Will Schroeder committed
87 88 89 90 91
void vtkProp::ShallowCopy(vtkProp *prop)
{
  this->Visibility = prop->GetVisibility();
  this->Pickable   = prop->GetPickable();
  this->Dragable   = prop->GetDragable();
92
  this->SetShaderProperty(prop->GetShaderProperty());
Will Schroeder's avatar
Will Schroeder committed
93 94
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
95
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
96
void vtkProp::InitPathTraversal()
97
{
98
  if ( this->Paths == nullptr )
99
  {
Will Schroeder's avatar
Will Schroeder committed
100 101
    this->Paths = vtkAssemblyPaths::New();
    vtkAssemblyPath *path = vtkAssemblyPath::New();
102
    path->AddNode(this,nullptr);
Will Schroeder's avatar
Will Schroeder committed
103 104
    this->BuildPaths(this->Paths,path);
    path->Delete();
105
  }
Will Schroeder's avatar
Will Schroeder committed
106 107
  this->Paths->InitTraversal();
}
108

Mathieu Malaterre's avatar
Mathieu Malaterre committed
109
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
110 111
vtkAssemblyPath *vtkProp::GetNextPath()
{
112
  if ( ! this->Paths)
113
  {
114
    return nullptr;
115
  }
Will Schroeder's avatar
Will Schroeder committed
116 117 118
  return this->Paths->GetNextItem();
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
119
//----------------------------------------------------------------------------
Will Schroeder's avatar
Will Schroeder committed
120
// This method is used in conjunction with the assembly object to build a copy
121
// of the assembly hierarchy. This hierarchy can then be traversed for
Will Schroeder's avatar
Will Schroeder committed
122 123 124 125 126 127 128 129 130 131 132
// rendering, picking or other operations.
void vtkProp::BuildPaths(vtkAssemblyPaths *paths, vtkAssemblyPath *path)
{
  // This is a leaf node in the assembly hierarchy so we
  // copy the path in preparation to assingning it to paths.
  vtkAssemblyPath *childPath = vtkAssemblyPath::New();
  childPath->ShallowCopy(path);

  // We can add this path to the list of paths
  paths->AddItem(childPath);
  childPath->Delete(); //okay, reference counting
133 134
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
135
//----------------------------------------------------------------------------
136
void vtkProp::PrintSelf(ostream& os, vtkIndent indent)
137
{
Brad King's avatar
Brad King committed
138
  this->Superclass::PrintSelf(os,indent);
139

140 141 142
  os << indent << "Dragable: " << (this->Dragable ? "On\n" : "Off\n");
  os << indent << "Pickable: " << (this->Pickable ? "On\n" : "Off\n");

143
  os << indent << "AllocatedRenderTime: "
144
     << this->AllocatedRenderTime << endl;
145
  os << indent << "EstimatedRenderTime: "
146
     << this->EstimatedRenderTime << endl;
Ken Martin's avatar
Ken Martin committed
147
  os << indent << "NumberOfConsumers: " << this->NumberOfConsumers << endl;
148
  os << indent << "RenderTimeMultiplier: "
149
     << this->RenderTimeMultiplier << endl;
150
  os << indent << "Visibility: " << (this->Visibility ? "On\n" : "Off\n");
151

152
  os << indent << "PropertyKeys: ";
153
  if(this->PropertyKeys!=nullptr)
154
  {
155 156
    this->PropertyKeys->PrintSelf(os,indent);
    os << endl;
157
  }
158
  else
159
  {
160
    os << "none." << endl;
161
  }
162

163
  os << indent << "useBounds: " << this->UseBounds <<endl;
164 165 166
}


Mathieu Malaterre's avatar
Mathieu Malaterre committed
167
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
168 169 170 171
void vtkProp::AddConsumer(vtkObject *c)
{
  // make sure it isn't already there
  if (this->IsConsumer(c))
172
  {
Ken Martin's avatar
Ken Martin committed
173
    return;
174
  }
Ken Martin's avatar
Ken Martin committed
175 176 177 178 179
  // add it to the list, reallocate memory
  vtkObject **tmp = this->Consumers;
  this->NumberOfConsumers++;
  this->Consumers = new vtkObject* [this->NumberOfConsumers];
  for (int i = 0; i < (this->NumberOfConsumers-1); i++)
180
  {
Ken Martin's avatar
Ken Martin committed
181
    this->Consumers[i] = tmp[i];
182
  }
Ken Martin's avatar
Ken Martin committed
183 184 185 186 187
  this->Consumers[this->NumberOfConsumers-1] = c;
  // free old memory
  delete [] tmp;
}

Mathieu Malaterre's avatar
Mathieu Malaterre committed
188
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
189 190 191 192
void vtkProp::RemoveConsumer(vtkObject *c)
{
  // make sure it is already there
  if (!this->IsConsumer(c))
193
  {
Ken Martin's avatar
Ken Martin committed
194
    return;
195
  }
Ken Martin's avatar
Ken Martin committed
196 197 198 199 200 201 202
  // remove it from the list, reallocate memory
  vtkObject **tmp = this->Consumers;
  this->NumberOfConsumers--;
  this->Consumers = new vtkObject* [this->NumberOfConsumers];
  int cnt = 0;
  int i;
  for (i = 0; i <= this->NumberOfConsumers; i++)
203
  {
Ken Martin's avatar
Ken Martin committed
204
    if (tmp[i] != c)
205
    {
Ken Martin's avatar
Ken Martin committed
206 207 208
      this->Consumers[cnt] = tmp[i];
      cnt++;
    }
209
  }
Ken Martin's avatar
Ken Martin committed
210 211 212
  // free old memory
  delete [] tmp;
}
213

Mathieu Malaterre's avatar
Mathieu Malaterre committed
214
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
215 216 217 218
int vtkProp::IsConsumer(vtkObject *c)
{
  int i;
  for (i = 0; i < this->NumberOfConsumers; i++)
219
  {
Ken Martin's avatar
Ken Martin committed
220
    if (this->Consumers[i] == c)
221
    {
Ken Martin's avatar
Ken Martin committed
222 223
      return 1;
    }
224
  }
Ken Martin's avatar
Ken Martin committed
225 226
  return 0;
}
227

Mathieu Malaterre's avatar
Mathieu Malaterre committed
228
//----------------------------------------------------------------------------
Ken Martin's avatar
Ken Martin committed
229 230 231
vtkObject *vtkProp::GetConsumer(int i)
{
  if (i >= this->NumberOfConsumers)
232
  {
233
    return nullptr;
234
  }
Ken Martin's avatar
Ken Martin committed
235 236
  return this->Consumers[i];
}
237 238 239 240 241 242 243

// ----------------------------------------------------------------------------
// Description:
// Tells if the prop has all the required keys.
// \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
bool vtkProp::HasKeys(vtkInformation *requiredKeys)
{
244
  bool result=requiredKeys==nullptr;
245
  if(!result)
246
  {
247 248 249 250 251
    vtkInformationIterator *it=vtkInformationIterator::New();
    it->SetInformation(requiredKeys);
    it->GoToFirstItem();
    result=true;
    while(result && !it->IsDoneWithTraversal())
252
    {
253
      vtkInformationKey *k=it->GetCurrentKey();
254
      result=this->PropertyKeys!=nullptr && this->PropertyKeys->Has(k);
255 256
      it->GoToNextItem();
    }
257 258
    it->Delete();
  }
259 260 261 262 263 264 265 266 267 268 269 270 271 272 273
  return result;
}

// ----------------------------------------------------------------------------
// Description:
// Render the opaque geometry only if the prop has all the requiredKeys.
// This is recursive for composite props like vtkAssembly.
// An implementation is provided in vtkProp but each composite prop
// must override it.
// It returns if the rendering was performed.
// \pre v_exists: v!=0
// \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
bool vtkProp::RenderFilteredOpaqueGeometry(vtkViewport *v,
                                           vtkInformation *requiredKeys)
{
274
  assert("pre: v_exists" && v!=nullptr);
275 276
  bool result;
  if(this->HasKeys(requiredKeys))
277
  {
278
    result=this->RenderOpaqueGeometry(v)==1;
279
  }
280
  else
281
  {
282
    result=false;
283
  }
284 285
  return result;
}
286

287 288 289 290 291 292 293 294 295 296 297 298 299 300
// ----------------------------------------------------------------------------
// Description:
// Render the translucent polygonal geometry only if the prop has all the
// requiredKeys.
// This is recursive for composite props like vtkAssembly.
// An implementation is provided in vtkProp but each composite prop
// must override it.
// It returns if the rendering was performed.
// \pre v_exists: v!=0
// \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
bool vtkProp::RenderFilteredTranslucentPolygonalGeometry(
  vtkViewport *v,
  vtkInformation *requiredKeys)
{
301
  assert("pre: v_exists" && v!=nullptr);
302 303
  bool result;
  if(this->HasKeys(requiredKeys))
304
  {
305
    result=this->RenderTranslucentPolygonalGeometry(v)==1;
306
  }
307
  else
308
  {
309
    result=false;
310
  }
311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
  return result;
}

// ----------------------------------------------------------------------------
// Description:
// Render the volumetric geometry only if the prop has all the
// requiredKeys.
// This is recursive for composite props like vtkAssembly.
// An implementation is provided in vtkProp but each composite prop
// must override it.
// It returns if the rendering was performed.
// \pre v_exists: v!=0
// \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
bool vtkProp::RenderFilteredVolumetricGeometry(vtkViewport *v,
                                               vtkInformation *requiredKeys)
{
327
  assert("pre: v_exists" && v!=nullptr);
328 329
  bool result;
  if(this->HasKeys(requiredKeys))
330
  {
331
    result=this->RenderVolumetricGeometry(v)==1;
332
  }
333
  else
334
  {
335
    result=false;
336
  }
337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352
  return result;
}

// ----------------------------------------------------------------------------
// Description:
// Render in the overlay of the viewport only if the prop has all the
// requiredKeys.
// This is recursive for composite props like vtkAssembly.
// An implementation is provided in vtkProp but each composite prop
// must override it.
// It returns if the rendering was performed.
// \pre v_exists: v!=0
// \pre keys_can_be_null: requiredKeys==0 || requiredKeys!=0
bool vtkProp::RenderFilteredOverlay(vtkViewport *v,
                                    vtkInformation *requiredKeys)
{
353
  assert("pre: v_exists" && v!=nullptr);
354 355
  bool result;
  if(this->HasKeys(requiredKeys))
356
  {
357
    result=this->RenderOverlay(v)==1;
358
  }
359
  else
360
  {
361
    result=false;
362
  }
363 364
  return result;
}
365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389

void vtkProp::SetShaderProperty(vtkShaderProperty *property)
{
  if( this->ShaderProperty != property )
  {
    if (this->ShaderProperty != nullptr) {this->ShaderProperty->UnRegister(this);}
    this->ShaderProperty = property;
    if (this->ShaderProperty != nullptr)
    {
      this->ShaderProperty->Register(this);
    }
    this->Modified();
  }
}

vtkShaderProperty *vtkProp::GetShaderProperty()
{
  if( this->ShaderProperty == nullptr )
  {
    this->ShaderProperty = vtkShaderProperty::New();
    this->ShaderProperty->Register(this);
    this->ShaderProperty->Delete();
  }
  return this->ShaderProperty;
}