vtkSMPVRepresentationProxy.cxx 41.5 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*=========================================================================

  Program:   ParaView
  Module:    vtkSMPVRepresentationProxy.cxx

  Copyright (c) Kitware, Inc.
  All rights reserved.
  See Copyright.txt or http://www.paraview.org/HTML/Copyright.html 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 "vtkSMPVRepresentationProxy.h"

17
#include "vtkCommand.h"
18
#include "vtkDataObject.h"
19
#include "vtkDoubleArray.h"
20
#include "vtkNew.h"
21
#include "vtkObjectFactory.h"
22
23
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
24
#include "vtkPVProminentValuesInformation.h"
25
#include "vtkPVTemporalDataInformation.h"
26
#include "vtkPVXMLElement.h"
27
#include "vtkSMArrayListDomain.h"
28
#include "vtkSMCoreUtilities.h"
29
#include "vtkSMOutputPort.h"
30
#include "vtkSMProperty.h"
31
#include "vtkSMPropertyHelper.h"
32
#include "vtkSMRenderViewProxy.h"
33
#include "vtkSMScalarBarWidgetRepresentationProxy.h"
34
#include "vtkSMSessionProxyManager.h"
35
#include "vtkSMSettings.h"
36
#include "vtkSMStringVectorProperty.h"
37
#include "vtkSMTrace.h"
38
#include "vtkSMTransferFunction2DProxy.h"
39
#include "vtkSMTransferFunctionManager.h"
40
#include "vtkSMTransferFunctionProxy.h"
41
#include "vtkStringList.h"
42
#include "vtksys/SystemTools.hxx"
43

44
#include <cmath>
45
#include <set>
46
#include <sstream>
47
#include <string>
48

Kitware Robot's avatar
Kitware Robot committed
49
50
51
class vtkSMPVRepresentationProxy::vtkStringSet : public std::set<std::string>
{
};
52

53
54
55
56
vtkStandardNewMacro(vtkSMPVRepresentationProxy);
//----------------------------------------------------------------------------
vtkSMPVRepresentationProxy::vtkSMPVRepresentationProxy()
{
57
  this->SetSIClassName("vtkSIPVRepresentationProxy");
58
  this->RepresentationSubProxies = new vtkStringSet();
59
  this->InReadXMLAttributes = false;
60
  this->LastLUTProxy = nullptr;
61
62
63
64
65
}

//----------------------------------------------------------------------------
vtkSMPVRepresentationProxy::~vtkSMPVRepresentationProxy()
{
66
  delete this->RepresentationSubProxies;
67
68
}

69
70
71
72
//----------------------------------------------------------------------------
void vtkSMPVRepresentationProxy::CreateVTKObjects()
{
  if (this->ObjectsCreated)
Kitware Robot's avatar
Kitware Robot committed
73
  {
74
    return;
Kitware Robot's avatar
Kitware Robot committed
75
  }
76
77
  this->Superclass::CreateVTKObjects();
  if (!this->ObjectsCreated)
Kitware Robot's avatar
Kitware Robot committed
78
  {
79
    return;
Kitware Robot's avatar
Kitware Robot committed
80
  }
81

82
83
84
85
86
  // Ensure that we update the RepresentationTypesInfo property and the domain
  // for "Representations" property before CreateVTKObjects() is finished. This
  // ensure that all representations have valid Representations domain.
  this->UpdatePropertyInformation();

87
88
  // Whenever the "Representation" property is modified, we ensure that the
  // this->InvalidateDataInformation() is called.
Kitware Robot's avatar
Kitware Robot committed
89
90
  this->AddObserver(
    vtkCommand::UpdatePropertyEvent, this, &vtkSMPVRepresentationProxy::OnPropertyUpdated);
91
92
93
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
94
void vtkSMPVRepresentationProxy::OnPropertyUpdated(vtkObject*, unsigned long, void* calldata)
95
96
97
{
  const char* pname = reinterpret_cast<const char*>(calldata);
  if (pname && strcmp(pname, "Representation") == 0)
Kitware Robot's avatar
Kitware Robot committed
98
  {
99
    this->InvalidateDataInformation();
Kitware Robot's avatar
Kitware Robot committed
100
  }
101
102
}

103
104
105
//----------------------------------------------------------------------------
void vtkSMPVRepresentationProxy::SetPropertyModifiedFlag(const char* name, int flag)
{
106
  if (!this->InReadXMLAttributes && name && strcmp(name, "Input") == 0)
Kitware Robot's avatar
Kitware Robot committed
107
  {
108
109
110
111
112
    // Whenever the input for the representation is set, we need to setup the
    // the input for the internal selection representation that shows the
    // extracted-selection. This is done at the proxy level so that whenever the
    // selection is changed in the application, the SelectionRepresentation is
    // 'MarkedModified' correctly, so that it updates itself cleanly.
113
    vtkSMProxy* selectionRepr = this->GetSubProxy("SelectionRepresentation");
114
    vtkSMPropertyHelper helper(this, name);
Kitware Robot's avatar
Kitware Robot committed
115
116
117
    for (unsigned int cc = 0; cc < helper.GetNumberOfElements(); cc++)
    {
      vtkSMSourceProxy* input = vtkSMSourceProxy::SafeDownCast(helper.GetAsProxy(cc));
118
      if (input && selectionRepr)
Kitware Robot's avatar
Kitware Robot committed
119
      {
120
        input->CreateSelectionProxies();
Kitware Robot's avatar
Kitware Robot committed
121
        vtkSMSourceProxy* esProxy = input->GetSelectionOutput(helper.GetOutputPort(cc));
122
        if (!esProxy)
Kitware Robot's avatar
Kitware Robot committed
123
        {
124
          vtkErrorMacro("Input proxy does not support selection extraction.");
Kitware Robot's avatar
Kitware Robot committed
125
        }
126
        else
Kitware Robot's avatar
Kitware Robot committed
127
        {
128
129
130
131
132
133
134
135
136
          int port = 0;
          if (vtkPVXMLElement* hints = selectionRepr->GetHints()
              ? selectionRepr->GetHints()->FindNestedElementByName("ConnectToPortIndex")
              : nullptr)
          {
            hints->GetScalarAttribute("value", &port);
          }

          vtkSMPropertyHelper(selectionRepr, "Input").Set(esProxy, port);
137
138
139
140
          selectionRepr->UpdateVTKObjects();
        }
      }
    }
Kitware Robot's avatar
Kitware Robot committed
141
  }
142
143
144
145
146
147

  this->Superclass::SetPropertyModifiedFlag(name, flag);
}

//----------------------------------------------------------------------------
int vtkSMPVRepresentationProxy::ReadXMLAttributes(
148
  vtkSMSessionProxyManager* pm, vtkPVXMLElement* element)
149
{
150
  this->InReadXMLAttributes = true;
Kitware Robot's avatar
Kitware Robot committed
151
152
  for (unsigned int cc = 0; cc < element->GetNumberOfNestedElements(); ++cc)
  {
153
    vtkPVXMLElement* child = element->GetNestedElement(cc);
Kitware Robot's avatar
Kitware Robot committed
154
    if (child->GetName() && strcmp(child->GetName(), "RepresentationType") == 0 &&
155
      child->GetAttribute("subproxy") != nullptr)
Kitware Robot's avatar
Kitware Robot committed
156
    {
157
      this->RepresentationSubProxies->insert(child->GetAttribute("subproxy"));
158
    }
Kitware Robot's avatar
Kitware Robot committed
159
  }
160

161
162
  int retVal = this->Superclass::ReadXMLAttributes(pm, element);
  this->InReadXMLAttributes = false;
163
164
165
166
167
168
169

  // Setup property links for sub-proxies. This ensures that whenever the
  // this->GetProperty("Input") changes (either checked or un-checked values),
  // all the sub-proxy's "Input" is also changed to the same value. This ensures
  // that the domains are updated correctly.
  vtkSMProperty* inputProperty = this->GetProperty("Input");
  if (inputProperty)
Kitware Robot's avatar
Kitware Robot committed
170
  {
171
    for (vtkStringSet::iterator iter = this->RepresentationSubProxies->begin();
Kitware Robot's avatar
Kitware Robot committed
172
173
         iter != this->RepresentationSubProxies->end(); ++iter)
    {
174
      vtkSMProxy* subProxy = this->GetSubProxy((*iter).c_str());
175
      vtkSMProperty* subProperty = subProxy ? subProxy->GetProperty("Input") : nullptr;
176
      if (subProperty)
Kitware Robot's avatar
Kitware Robot committed
177
      {
178
179
180
        this->LinkProperty(inputProperty, subProperty);
      }
    }
Kitware Robot's avatar
Kitware Robot committed
181
  }
182
  return retVal;
183
184
}

185
//----------------------------------------------------------------------------
186
bool vtkSMPVRepresentationProxy::GetUsingScalarColoring()
187
{
188
  if (this->GetProperty("ColorArrayName"))
Kitware Robot's avatar
Kitware Robot committed
189
  {
190
    vtkSMPropertyHelper helper(this->GetProperty("ColorArrayName"));
191
    return (helper.GetNumberOfElements() == 5 && helper.GetAsString(4) != nullptr &&
Kitware Robot's avatar
Kitware Robot committed
192
193
      strcmp(helper.GetAsString(4), "") != 0);
  }
194
  else
Kitware Robot's avatar
Kitware Robot committed
195
  {
196
    vtkWarningMacro("Missing 'ColorArrayName' property.");
Kitware Robot's avatar
Kitware Robot committed
197
  }
198
199
200
201
  return false;
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
202
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRange(bool extend, bool force)
203
204
{
  if (!this->GetUsingScalarColoring())
Kitware Robot's avatar
Kitware Robot committed
205
  {
206
207
    // we are not using scalar coloring, nothing to do.
    return false;
Kitware Robot's avatar
Kitware Robot committed
208
  }
209

210
211
212
213
  SM_SCOPED_TRACE(CallMethod)
    .arg(this)
    .arg("RescaleTransferFunctionToDataRange")
    .arg(extend)
214
    .arg(force)
215
    .arg("comment",
Kitware Robot's avatar
Kitware Robot committed
216
217
      (extend ? "rescale color and/or opacity maps used to include current data range"
              : "rescale color and/or opacity maps used to exactly fit the current data range"));
218
  return this->RescaleTransferFunctionToDataRange(
219
    this->GetArrayInformationForColorArray(), extend, force);
220
221
222
223
}

//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRange(
224
  const char* arrayname, int attribute_type, bool extend, bool force)
225
226
{
  vtkSMPropertyHelper inputHelper(this->GetProperty("Input"));
Kitware Robot's avatar
Kitware Robot committed
227
  vtkSMSourceProxy* inputProxy = vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy());
228
229
  int port = inputHelper.GetOutputPort();
  if (!inputProxy)
Kitware Robot's avatar
Kitware Robot committed
230
  {
231
232
233
    // no input.
    vtkWarningMacro("No input present. Cannot determine data ranges.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
234
  }
235

236
  vtkPVDataInformation* dataInfo = inputProxy->GetDataInformation(port);
Kitware Robot's avatar
Kitware Robot committed
237
  vtkPVArrayInformation* info = dataInfo->GetArrayInformation(arrayname, attribute_type);
238
  if (!info)
Kitware Robot's avatar
Kitware Robot committed
239
240
  {
    vtkPVDataInformation* representedDataInfo = this->GetRepresentedDataInformation();
241
    info = representedDataInfo->GetArrayInformation(arrayname, attribute_type);
Kitware Robot's avatar
Kitware Robot committed
242
  }
243

244
  return this->RescaleTransferFunctionToDataRange(info, extend, force);
245
246
}

247
248
249
250
//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRangeOverTime()
{
  if (!this->GetUsingScalarColoring())
Kitware Robot's avatar
Kitware Robot committed
251
  {
252
253
    // we are not using scalar coloring, nothing to do.
    return false;
Kitware Robot's avatar
Kitware Robot committed
254
  }
255

256
  vtkSMPropertyHelper helper(this->GetProperty("ColorArrayName"));
257

258
  return this->RescaleTransferFunctionToDataRangeOverTime(
259
    helper.GetAsString(4), helper.GetAsInt(3));
260
261
262
263
264
265
266
}

//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRangeOverTime(
  const char* arrayname, int attribute_type)
{
  vtkSMPropertyHelper inputHelper(this->GetProperty("Input"));
Kitware Robot's avatar
Kitware Robot committed
267
  vtkSMSourceProxy* inputProxy = vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy());
268
269
  int port = inputHelper.GetOutputPort();
  if (!inputProxy || !inputProxy->GetOutputPort(port))
Kitware Robot's avatar
Kitware Robot committed
270
  {
271
272
273
    // no input.
    vtkWarningMacro("No input present. Cannot determine data ranges.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
274
  }
275

276
277
  vtkPVTemporalDataInformation* dataInfo =
    inputProxy->GetOutputPort(port)->GetTemporalDataInformation();
Kitware Robot's avatar
Kitware Robot committed
278
279
  vtkPVArrayInformation* info = dataInfo->GetArrayInformation(arrayname, attribute_type);
  return info ? this->RescaleTransferFunctionToDataRange(info) : false;
280
281
282
283
}

//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToDataRange(
284
  vtkPVArrayInformation* info, bool extend, bool force)
285
286
{
  if (!info)
Kitware Robot's avatar
Kitware Robot committed
287
  {
288
289
    vtkWarningMacro("Could not determine array range.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
290
  }
291
292
293

  vtkSMProperty* lutProperty = this->GetProperty("LookupTable");
  vtkSMProperty* sofProperty = this->GetProperty("ScalarOpacityFunction");
294
295
  vtkSMProperty* tf2dProperty = this->GetProperty("TransferFunction2D");
  if (!lutProperty && !sofProperty && !tf2dProperty)
Kitware Robot's avatar
Kitware Robot committed
296
  {
297
298
    vtkWarningMacro("No 'LookupTable' and 'ScalarOpacityFunction' found.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
299
  }
300
301
302

  vtkSMProxy* lut = vtkSMPropertyHelper(lutProperty).GetAsProxy();
  vtkSMProxy* sof = vtkSMPropertyHelper(sofProperty).GetAsProxy();
303
  vtkSMProxy* tf2d = vtkSMPropertyHelper(tf2dProperty).GetAsProxy();
304

305
  if (force == false &&
306
307
    vtkSMPropertyHelper(lut, "AutomaticRescaleRangeMode", true).GetAsInt() ==
      vtkSMTransferFunctionManager::NEVER)
Kitware Robot's avatar
Kitware Robot committed
308
  {
309
310
    // nothing to change, range is locked.
    return true;
Kitware Robot's avatar
Kitware Robot committed
311
  }
312

313
314
315
  // We need to determine the component number to use from the lut.
  int component = -1;
  if (lut && vtkSMPropertyHelper(lut, "VectorMode").GetAsInt() != 0)
Kitware Robot's avatar
Kitware Robot committed
316
  {
317
    component = vtkSMPropertyHelper(lut, "VectorComponent").GetAsInt();
Kitware Robot's avatar
Kitware Robot committed
318
  }
319

320
  if (lut && component < info->GetNumberOfComponents())
Kitware Robot's avatar
Kitware Robot committed
321
  {
322
323
    int indexedLookup = vtkSMPropertyHelper(lut, "IndexedLookup").GetAsInt();
    if (indexedLookup)
Kitware Robot's avatar
Kitware Robot committed
324
    {
325
326
327
328
329
330
      vtkPVProminentValuesInformation* prominentValues =
        vtkSMPVRepresentationProxy::GetProminentValuesInformationForColorArray(this);
      vtkSmartPointer<vtkStringList> activeAnnotations = vtkSmartPointer<vtkStringList>::New();
      vtkSmartPointer<vtkDoubleArray> activeIndexedColors = vtkSmartPointer<vtkDoubleArray>::New();
      vtkSmartPointer<vtkAbstractArray> uniqueValues;

Kitware Robot's avatar
Kitware Robot committed
331
      uniqueValues.TakeReference(prominentValues->GetProminentComponentValues(component));
332

Kitware Robot's avatar
Kitware Robot committed
333
334
      vtkSMStringVectorProperty* allAnnotations =
        vtkSMStringVectorProperty::SafeDownCast(lut->GetProperty("Annotations"));
335
336
337
      vtkSMStringVectorProperty* activeAnnotatedValuesProperty =
        vtkSMStringVectorProperty::SafeDownCast(lut->GetProperty("ActiveAnnotatedValues"));
      if (uniqueValues && allAnnotations && activeAnnotatedValuesProperty)
Kitware Robot's avatar
Kitware Robot committed
338
      {
339
340
        vtkSmartPointer<vtkStringList> activeAnnotatedValues =
          vtkSmartPointer<vtkStringList>::New();
341
342

        if (extend)
Kitware Robot's avatar
Kitware Robot committed
343
        {
344
          activeAnnotatedValuesProperty->GetElements(activeAnnotatedValues);
Kitware Robot's avatar
Kitware Robot committed
345
        }
346

347
        for (int idx = 0; idx < uniqueValues->GetNumberOfTuples(); ++idx)
Kitware Robot's avatar
Kitware Robot committed
348
        {
349
          // Look up index of color corresponding to the annotation
Kitware Robot's avatar
Kitware Robot committed
350
351
352
          for (unsigned int j = 0; j < allAnnotations->GetNumberOfElements() / 2; ++j)
          {
            vtkVariant annotatedValue(allAnnotations->GetElement(2 * j + 0));
353
            if (annotatedValue == uniqueValues->GetVariantValue(idx))
Kitware Robot's avatar
Kitware Robot committed
354
355
            {
              activeAnnotatedValues->AddString(allAnnotations->GetElement(2 * j + 0));
356
357
              break;
            }
358
          }
Kitware Robot's avatar
Kitware Robot committed
359
        }
360
361
362
363

        activeAnnotatedValuesProperty->SetElements(activeAnnotatedValues);
        lut->UpdateVTKObjects();
      }
Kitware Robot's avatar
Kitware Robot committed
364
    }
365
    else
Kitware Robot's avatar
Kitware Robot committed
366
    {
367
368
369
      double rangeColor[2];
      double rangeOpacity[2];

370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
      bool useOpacityArray = false;
      if (auto uoaProperty = this->GetProperty("UseSeparateOpacityArray"))
      {
        useOpacityArray = vtkSMPropertyHelper(uoaProperty).GetAsInt() == 1;
      }

      if (useOpacityArray)
      {
        vtkSMPropertyHelper inputHelper(this->GetProperty("Input"));
        vtkSMSourceProxy* inputProxy = vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy());
        int port = inputHelper.GetOutputPort();
        if (!inputProxy)
        {
          // no input.
          vtkWarningMacro("No input present. Cannot determine opacity data range.");
          return false;
        }

        vtkPVDataInformation* dataInfo = inputProxy->GetDataInformation(port);
        vtkSMPropertyHelper opacityArrayNameHelper(this, "OpacityArrayName");
        int opacityArrayFieldAssociation = opacityArrayNameHelper.GetAsInt(3);
        const char* opacityArrayName = opacityArrayNameHelper.GetAsString(4);
        int opacityArrayComponent = vtkSMPropertyHelper(this, "OpacityComponent").GetAsInt();

        vtkPVArrayInformation* opacityArrayInfo =
          dataInfo->GetArrayInformation(opacityArrayName, opacityArrayFieldAssociation);
        if (opacityArrayComponent >= opacityArrayInfo->GetNumberOfComponents())
        {
          opacityArrayComponent = -1;
        }
        info->GetComponentFiniteRange(component, rangeColor);
        opacityArrayInfo->GetComponentFiniteRange(opacityArrayComponent, rangeOpacity);
      }
      else if (this->GetVolumeIndependentRanges())
Kitware Robot's avatar
Kitware Robot committed
404
      {
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
        info->GetComponentFiniteRange(0, rangeColor);
        info->GetComponentFiniteRange(1, rangeOpacity);
      }
      else
      {
        info->GetComponentFiniteRange(component, rangeColor);
        rangeOpacity[0] = rangeColor[0];
        rangeOpacity[1] = rangeColor[1];
      }

      // the range must be large enough, compared to values order of magnitude
      // If data range is too small then we tweak it a bit so scalar mapping
      // produces valid/reproducible results.
      vtkSMCoreUtilities::AdjustRange(rangeColor);
      vtkSMCoreUtilities::AdjustRange(rangeOpacity);

      if (lut && rangeColor[1] >= rangeColor[0])
      {
        vtkSMTransferFunctionProxy::RescaleTransferFunction(lut, rangeColor, extend);
        vtkSMProxy* sof_lut = vtkSMPropertyHelper(lut, "ScalarOpacityFunction", true).GetAsProxy();
        if (sof_lut && sof != sof_lut && rangeOpacity[1] >= rangeOpacity[0])
Kitware Robot's avatar
Kitware Robot committed
426
        {
427
          vtkSMTransferFunctionProxy::RescaleTransferFunction(sof_lut, rangeOpacity, extend);
Kitware Robot's avatar
Kitware Robot committed
428
        }
429
      }
430

431
432
433
      if (sof && rangeOpacity[1] >= rangeOpacity[0])
      {
        vtkSMTransferFunctionProxy::RescaleTransferFunction(sof, rangeOpacity, extend);
434
      }
435
436
437
438
439
440
441
442
443
444

      if (tf2d && rangeColor[1] >= rangeColor[0])
      {
        double range2D[4];
        vtkSMTransferFunction2DProxy::GetRange(tf2d, range2D);
        range2D[0] = rangeColor[0];
        range2D[1] = rangeColor[1];
        vtkSMTransferFunction2DProxy::RescaleTransferFunction(tf2d, range2D);
      }
      return (lut || sof || tf2d);
445
    }
Kitware Robot's avatar
Kitware Robot committed
446
  }
447
448
449
  return false;
}

450
//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
451
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToVisibleRange(vtkSMProxy* view)
452
453
{
  if (!this->GetUsingScalarColoring())
Kitware Robot's avatar
Kitware Robot committed
454
  {
455
456
    // we are not using scalar coloring, nothing to do.
    return false;
Kitware Robot's avatar
Kitware Robot committed
457
  }
458
459

  vtkSMPropertyHelper helper(this->GetProperty("ColorArrayName"));
Kitware Robot's avatar
Kitware Robot committed
460
461
  return this->RescaleTransferFunctionToVisibleRange(
    view, helper.GetAsString(4), helper.GetAsInt(3));
462
463
464
465
466
467
468
469
}

//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::RescaleTransferFunctionToVisibleRange(
  vtkSMProxy* view, const char* arrayname, int attribute_type)
{
  vtkSMRenderViewProxy* rview = vtkSMRenderViewProxy::SafeDownCast(view);
  if (!rview || !arrayname || arrayname[0] == 0)
Kitware Robot's avatar
Kitware Robot committed
470
  {
471
    return false;
Kitware Robot's avatar
Kitware Robot committed
472
  }
473
474

  vtkSMPropertyHelper inputHelper(this->GetProperty("Input"));
Kitware Robot's avatar
Kitware Robot committed
475
  vtkSMSourceProxy* inputProxy = vtkSMSourceProxy::SafeDownCast(inputHelper.GetAsProxy());
476
477
  int port = inputHelper.GetOutputPort();
  if (!inputProxy || !inputProxy->GetOutputPort(port))
Kitware Robot's avatar
Kitware Robot committed
478
  {
479
480
481
    // no input.
    vtkWarningMacro("No input present. Cannot determine data ranges.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
482
  }
483

Kitware Robot's avatar
Kitware Robot committed
484
  vtkPVDataInformation* dataInfo = inputProxy->GetOutputPort(port)->GetDataInformation();
485
486
  vtkPVArrayInformation* info = dataInfo->GetArrayInformation(arrayname, attribute_type);
  if (!info)
Kitware Robot's avatar
Kitware Robot committed
487
  {
488
    return false;
Kitware Robot's avatar
Kitware Robot committed
489
  }
490
491
492

  vtkSMProperty* lutProperty = this->GetProperty("LookupTable");
  vtkSMProperty* sofProperty = this->GetProperty("ScalarOpacityFunction");
493
494
  vtkSMProperty* useTransfer2DProperty = this->GetProperty("UseTransfer2D");
  vtkSMProperty* transfer2DProperty = this->GetProperty("TransferFunction2D");
495
  if ((!lutProperty && !sofProperty) && (!useTransfer2DProperty && !transfer2DProperty))
Kitware Robot's avatar
Kitware Robot committed
496
  {
497
    // No LookupTable and ScalarOpacityFunction found.
498
    // No UseTransfer2D and TransferFunction2D found.
499
    return false;
Kitware Robot's avatar
Kitware Robot committed
500
  }
501

502
503
  vtkSMProxy* lut = lutProperty ? vtkSMPropertyHelper(lutProperty).GetAsProxy() : nullptr;
  vtkSMProxy* sof = sofProperty ? vtkSMPropertyHelper(sofProperty).GetAsProxy() : nullptr;
504
505
506
507
508
  bool useTransfer2D =
    useTransfer2DProperty ? vtkSMPropertyHelper(useTransfer2DProperty).GetAsInt() == 1 : false;
  vtkSMProxy* tf2d = (useTransfer2D && transfer2DProperty)
    ? vtkSMPropertyHelper(transfer2DProperty).GetAsProxy()
    : nullptr;
509
510
511
512

  // We need to determine the component number to use from the lut.
  int component = -1;
  if (lut && vtkSMPropertyHelper(lut, "VectorMode").GetAsInt() != 0)
Kitware Robot's avatar
Kitware Robot committed
513
  {
514
    component = vtkSMPropertyHelper(lut, "VectorComponent").GetAsInt();
Kitware Robot's avatar
Kitware Robot committed
515
  }
516
  if (component >= info->GetNumberOfComponents())
Kitware Robot's avatar
Kitware Robot committed
517
  {
luz paz's avatar
luz paz committed
518
    // something amiss, the component request is not present in the dataset.
519
520
    // give up.
    return false;
Kitware Robot's avatar
Kitware Robot committed
521
  }
522
523
524

  double range[2];
  if (!rview->ComputeVisibleScalarRange(attribute_type, arrayname, component, range))
Kitware Robot's avatar
Kitware Robot committed
525
  {
526
    return false;
Kitware Robot's avatar
Kitware Robot committed
527
  }
528

529
  if (!useTransfer2D)
Kitware Robot's avatar
Kitware Robot committed
530
  {
531
532
533
534
535
536
537
538
539
540
    if (lut)
    {
      vtkSMTransferFunctionProxy::RescaleTransferFunction(lut, range, false);
      vtkSMProxy* sof_lut = vtkSMPropertyHelper(lut, "ScalarOpacityFunction", true).GetAsProxy();
      if (sof_lut && sof != sof_lut)
      {
        vtkSMTransferFunctionProxy::RescaleTransferFunction(sof_lut, range, false);
      }
    }
    if (sof)
Kitware Robot's avatar
Kitware Robot committed
541
    {
542
      vtkSMTransferFunctionProxy::RescaleTransferFunction(sof, range, false);
543
    }
Kitware Robot's avatar
Kitware Robot committed
544
  }
545
  else
Kitware Robot's avatar
Kitware Robot committed
546
  {
547
548
549
550
551
552
553
554
    if (tf2d)
    {
      double r[4];
      vtkSMTransferFunction2DProxy::GetRange(tf2d, r);
      r[0] = range[0];
      r[1] = range[1];
      vtkSMTransferFunction2DProxy::RescaleTransferFunction(tf2d, r, false);
    }
Kitware Robot's avatar
Kitware Robot committed
555
  }
556
557
558
  return true;
}

559
560
//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::SetScalarColoring(const char* arrayname, int attribute_type)
561
562
563
564
565
{
  return this->SetScalarColoringInternal(arrayname, attribute_type, false, -1);
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
566
567
bool vtkSMPVRepresentationProxy::SetScalarColoring(
  const char* arrayname, int attribute_type, int component)
568
569
570
571
572
{
  return this->SetScalarColoringInternal(arrayname, attribute_type, true, component);
}

//----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
573
574
bool vtkSMPVRepresentationProxy::SetScalarColoringInternal(
  const char* arrayname, int attribute_type, bool useComponent, int component)
575
{
576
  if (!this->GetUsingScalarColoring() && (arrayname == nullptr || arrayname[0] == 0))
Kitware Robot's avatar
Kitware Robot committed
577
  {
578
579
    // scalar coloring already off. Nothing to do.
    return true;
Kitware Robot's avatar
Kitware Robot committed
580
  }
581
582

  vtkSMProperty* colorArray = this->GetProperty("ColorArrayName");
583
  if (!colorArray)
Kitware Robot's avatar
Kitware Robot committed
584
  {
585
    vtkWarningMacro("No 'ColorArrayName' property found.");
586
    return false;
Kitware Robot's avatar
Kitware Robot committed
587
  }
588
589

  vtkSMPropertyHelper colorArrayHelper(colorArray);
590
  colorArrayHelper.SetInputArrayToProcess(attribute_type, arrayname);
591

592
  if (arrayname == nullptr || arrayname[0] == '\0')
Kitware Robot's avatar
Kitware Robot committed
593
  {
594
595
596
597
    SM_SCOPED_TRACE(SetScalarColoring)
      .arg("display", this)
      .arg("arrayname", arrayname)
      .arg("attribute_type", attribute_type);
598
599
600
601
    vtkSMPropertyHelper(this, "LookupTable", true).RemoveAllValues();
    vtkSMPropertyHelper(this, "ScalarOpacityFunction", true).RemoveAllValues();
    this->UpdateVTKObjects();
    return true;
Kitware Robot's avatar
Kitware Robot committed
602
  }
603

604
  // Now, setup transfer functions.
Mathieu Westphal's avatar
Mathieu Westphal committed
605
  bool haveComponent = useComponent;
606
  bool separate = (vtkSMPropertyHelper(this, "UseSeparateColorMap", true).GetAsInt() != 0);
607
  bool useTransfer2D = (vtkSMPropertyHelper(this, "UseTransfer2D", true).GetAsInt() != 0);
608
  std::string decoratedArrayName = this->GetDecoratedArrayName(arrayname);
609
  vtkNew<vtkSMTransferFunctionManager> mgr;
610
  vtkSMProxy* lutProxy = nullptr;
611
  if (vtkSMProperty* lutProperty = this->GetProperty("LookupTable"))
Kitware Robot's avatar
Kitware Robot committed
612
  {
613
    lutProxy =
614
      mgr->GetColorTransferFunction(decoratedArrayName.c_str(), this->GetSessionProxyManager());
615
    if (useComponent)
Kitware Robot's avatar
Kitware Robot committed
616
    {
617
      if (component >= 0)
Kitware Robot's avatar
Kitware Robot committed
618
      {
619
620
621
        vtkSMPropertyHelper(lutProxy, "VectorMode").Set("Component");
        vtkSMPropertyHelper(lutProxy, "VectorComponent").Set(component);
        lutProxy->UpdateVTKObjects();
Kitware Robot's avatar
Kitware Robot committed
622
623
624
      }
      else
      {
625
626
627
        vtkSMPropertyHelper(lutProxy, "VectorMode").Set("Magnitude");
        lutProxy->UpdateVTKObjects();
      }
Kitware Robot's avatar
Kitware Robot committed
628
    }
Mathieu Westphal's avatar
Mathieu Westphal committed
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
    else
    {
      // No Component defined for coloring, in order to generate a valid trace
      // a component is needed, recover currently used component
      const char* vectorMode = vtkSMPropertyHelper(lutProxy, "VectorMode").GetAsString();
      haveComponent = true;
      if (strcmp(vectorMode, "Component") == 0)
      {
        component = vtkSMPropertyHelper(lutProxy, "VectorComponent").GetAsInt();
      }
      else // Magnitude
      {
        component = -1;
      }
    }
644

645
    vtkSMPropertyHelper(lutProperty).Set(lutProxy);
646
647
648
649

    // Get the array information for the color array to determine transfer function properties
    vtkPVArrayInformation* colorArrayInfo = this->GetArrayInformationForColorArray();
    if (colorArrayInfo)
Kitware Robot's avatar
Kitware Robot committed
650
    {
651
      if (colorArrayInfo->GetDataType() == VTK_STRING)
Kitware Robot's avatar
Kitware Robot committed
652
      {
653
        vtkSMPropertyHelper(lutProxy, "IndexedLookup", true).Set(1);
654
        lutProxy->UpdateVTKObjects();
655
      }
Mathieu Westphal's avatar
Mathieu Westphal committed
656
657
658
659
660
661
662
663
664
      if (haveComponent)
      {
        const char* componentName = colorArrayInfo->GetComponentName(component);
        if (strcmp(componentName, "") != 0)
        {
          SM_SCOPED_TRACE(SetScalarColoring)
            .arg("display", this)
            .arg("arrayname", arrayname)
            .arg("attribute_type", attribute_type)
665
666
            .arg("component", componentName)
            .arg("separate", separate);
Mathieu Westphal's avatar
Mathieu Westphal committed
667
668
669
670
671
672
        }
        else
        {
          haveComponent = false;
        }
      }
673
    }
Kitware Robot's avatar
Kitware Robot committed
674
  }
675

Mathieu Westphal's avatar
Mathieu Westphal committed
676
677
678
679
680
  if (!haveComponent)
  {
    SM_SCOPED_TRACE(SetScalarColoring)
      .arg("display", this)
      .arg("arrayname", arrayname)
681
682
      .arg("attribute_type", attribute_type)
      .arg("separate", separate);
Mathieu Westphal's avatar
Mathieu Westphal committed
683
684
  }

685
  if (vtkSMProperty* sofProperty = this->GetProperty("ScalarOpacityFunction"))
Kitware Robot's avatar
Kitware Robot committed
686
  {
687
    vtkSMProxy* sofProxy =
688
      mgr->GetOpacityTransferFunction(decoratedArrayName.c_str(), this->GetSessionProxyManager());
689
    vtkSMPropertyHelper(sofProperty).Set(sofProxy);
Kitware Robot's avatar
Kitware Robot committed
690
  }
691

692
693
  if (vtkSMProperty* tf2dProperty = this->GetProperty("TransferFunction2D"))
  {
694
695
    vtkSMProxy* tf2dProxy =
      mgr->GetTransferFunction2D(decoratedArrayName.c_str(), this->GetSessionProxyManager());
696
    vtkSMPropertyHelper(tf2dProperty).Set(tf2dProxy);
697
698
    this->UpdateProperty("TransferFunction2D");
    if (lutProxy && useTransfer2D)
699
700
701
702
    {
      vtkSMPropertyHelper(lutProxy, "Use2DTransferFunction").Set(useTransfer2D);
      lutProxy->UpdateVTKObjects();
    }
703
704
  }

705
706
707
708
  this->UpdateVTKObjects();
  return true;
}

709
710
711
//----------------------------------------------------------------------------
std::string vtkSMPVRepresentationProxy::GetDecoratedArrayName(const std::string& arrayname)
{
712
713
  std::ostringstream ss;
  ss << arrayname;
Timothee Chabat's avatar
Timothee Chabat committed
714
  if (this->GetProperty("TransferFunction2D"))
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
  {
    bool useGradientAsY =
      (vtkSMPropertyHelper(this, "UseGradientForTransfer2D", true).GetAsInt() == 1);
    if (!useGradientAsY)
    {
      std::string array2Name;
      vtkSMProperty* colorArray2Property = this->GetProperty("ColorArray2Name");
      if (colorArray2Property)
      {
        vtkSMPropertyHelper colorArray2Helper(colorArray2Property);
        array2Name = colorArray2Helper.GetInputArrayNameToProcess();
      }
      if (!array2Name.empty())
      {
        ss << "_" << array2Name;
      }
    }
  }
733
734
735
  if (vtkSMPropertyHelper(this, "UseSeparateColorMap", true).GetAsInt())
  {
    // Use global id for separate color map
736
737
738
    std::ostringstream ss1;
    ss1 << "Separate_" << this->GetGlobalIDAsString() << "_" << ss.str();
    return ss1.str();
739
  }
740
  return ss.str();
741
742
}

743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
//----------------------------------------------------------------------------
int vtkSMPVRepresentationProxy::IsScalarBarStickyVisible(vtkSMProxy* view)
{
  if (!view)
  {
    return -1;
  }
  vtkSMProperty* lutProperty = this->GetProperty("LookupTable");
  if (!lutProperty)
  {
    vtkWarningMacro("Missing 'LookupTable' property.");
    return -1;
  }
  vtkSMPropertyHelper lutPropertyHelper(lutProperty);
  if (lutPropertyHelper.GetNumberOfElements() == 0 || lutPropertyHelper.GetAsProxy(0) == nullptr)
  {
    vtkWarningMacro("Failed to determine the LookupTable being used.");
    return -1;
  }
  vtkSMProxy* lutProxy = lutPropertyHelper.GetAsProxy(0);
  vtkSMScalarBarWidgetRepresentationProxy* sbProxy =
    vtkSMScalarBarWidgetRepresentationProxy::SafeDownCast(
      vtkSMTransferFunctionProxy::FindScalarBarRepresentation(lutProxy, view));
  if (sbProxy)
  {
    vtkSMPropertyHelper sbsvPropertyHelper(sbProxy->GetProperty("StickyVisible"));
    return sbsvPropertyHelper.GetNumberOfElements()
      ? vtkSMPropertyHelper(sbProxy, "StickyVisible").GetAsInt()
      : -1;
  }
  return -1;
}

776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::UpdateScalarBarRange(vtkSMProxy* view, bool deleteRange)
{
  bool usingScalarBarColoring = this->GetUsingScalarColoring();

  vtkSMProperty* lutProperty = this->GetProperty("LookupTable");
  if (!lutProperty)
  {
    vtkWarningMacro("Missing 'LookupTable' property");
    return false;
  }

  vtkSMPropertyHelper lutPropertyHelper(lutProperty);
  vtkSMProxy* lutProxy =
    usingScalarBarColoring ? lutPropertyHelper.GetAsProxy(0) : this->LastLUTProxy.GetPointer();

  if (!lutProxy)
  {
    return false;
  }

  vtkSMScalarBarWidgetRepresentationProxy* sbProxy =
    vtkSMScalarBarWidgetRepresentationProxy::SafeDownCast(
      vtkSMTransferFunctionProxy::FindScalarBarRepresentation(lutProxy, view));

  if (!sbProxy)
  {
    return false;
  }

  vtkNew<vtkSMTransferFunctionManager> mgr;
  vtkSMProxy* sbSMProxy = mgr->GetScalarBarRepresentation(lutProxy, view);

  vtkSMProperty* maxRangeProp = sbSMProxy->GetProperty("DataRangeMax");
  vtkSMProperty* minRangeProp = sbSMProxy->GetProperty("DataRangeMin");

  if (minRangeProp && maxRangeProp)
  {
    vtkSMPropertyHelper minRangePropHelper(minRangeProp);
    vtkSMPropertyHelper maxRangePropHelper(maxRangeProp);

    // We remove the range that was potentially previously stored
    sbProxy->RemoveRange(this);

    // If we do not want to delete this range, then we update it with its potential new value.
    if (!deleteRange)
    {
      sbProxy->AddRange(this);
    }

    double updatedRange[2];
    sbProxy->GetRange(updatedRange);
    minRangePropHelper.Set(updatedRange[0]);
    maxRangePropHelper.Set(updatedRange[1]);
  }
  sbSMProxy->UpdateVTKObjects();

  this->LastLUTProxy = usingScalarBarColoring ? lutProxy : nullptr;
  return true;
}

837
//----------------------------------------------------------------------------
838
vtkSMProxy* vtkSMPVRepresentationProxy::GetLUTProxy(vtkSMProxy* view)
839
840
{
  if (!view)
Kitware Robot's avatar
Kitware Robot committed
841
  {
842
    return nullptr;
Kitware Robot's avatar
Kitware Robot committed
843
  }
844
845
846

  vtkSMProperty* lutProperty = this->GetProperty("LookupTable");
  if (!lutProperty)
Kitware Robot's avatar
Kitware Robot committed
847
  {
848
    vtkWarningMacro("Missing 'LookupTable' property.");
849
    return nullptr;
Kitware Robot's avatar
Kitware Robot committed
850
  }
851
852

  vtkSMPropertyHelper lutPropertyHelper(lutProperty);
853
  if (lutPropertyHelper.GetNumberOfElements() == 0 || lutPropertyHelper.GetAsProxy(0) == nullptr)
854
855
856
857
858
859
860
861
862
863
  {
    return nullptr;
  }

  return lutPropertyHelper.GetAsProxy(0);
}

//----------------------------------------------------------------------------
bool vtkSMPVRepresentationProxy::SetScalarBarVisibility(vtkSMProxy* view, bool visible)
{
864
865
866
867
868
  if (!view)
  {
    return false;
  }

869
870
  vtkSMProxy* lutProxy = this->GetLUTProxy(view);
  if (!lutProxy)
Kitware Robot's avatar
Kitware Robot committed
871
  {
872
873
    vtkWarningMacro("Failed to determine the LookupTable being used.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
874
  }
875

876
877
878
879
880
  SM_SCOPED_TRACE(CallMethod)
    .arg(this)
    .arg("SetScalarBarVisibility")
    .arg(view)
    .arg(visible)
Kitware Robot's avatar
Kitware Robot committed
881
    .arg("comment", visible ? "show color bar/color legend" : "hide color bar/color legend");
882

883
884
885
886
887
888
889
890
891
892
893
  // If the lut proxy changed, we need to remove ourself (representation proxy)
  // from the scalar bar widget that we used to be linked to.
  if (this->LastLUTProxy && lutProxy != this->LastLUTProxy)
  {
    if (auto lastSBProxy = vtkSMScalarBarWidgetRepresentationProxy::SafeDownCast(
          vtkSMTransferFunctionProxy::FindScalarBarRepresentation(this->LastLUTProxy, view)))
    {
      lastSBProxy->RemoveRange(this);
    }
  }

894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
  vtkSMScalarBarWidgetRepresentationProxy* sbProxy =
    vtkSMScalarBarWidgetRepresentationProxy::SafeDownCast(
      vtkSMTransferFunctionProxy::FindScalarBarRepresentation(lutProxy, view));

  if (sbProxy)
  {
    int legacyVisible = vtkSMPropertyHelper(sbProxy, "Visibility").GetAsInt();
    // If scalar bar is set to not be visible but was previously visible,
    // then the user has pressed the scalar bar button hiding the scalar bar.
    // We keep this information well preserved in the scalar bar representation.
    // This method is not called when hiding the whole representation, so we are safe
    // on scalar bar disappearance occuring on such event, it won't mess with this engine.
    if (legacyVisible && !visible)
    {
      vtkSMPropertyHelper(sbProxy, "StickyVisible").Set(0);
    }
    // If the scalar bar is set to be visible, we are in the case where we automatically
    // show the scalarbar, whether or not it was previously hidden.
    else if (visible)
    {
      vtkSMPropertyHelper(sbProxy, "StickyVisible").Set(1);
    }
  }
917
918
919
920

  // if hiding the Scalar Bar, just look if there's a LUT and then hide the
  // corresponding scalar bar. We won't worry too much about whether scalar
  // coloring is currently enabled for this.
921
  if (!visible)
Kitware Robot's avatar
Kitware Robot committed
922
  {
923
    if (sbProxy)
Kitware Robot's avatar
Kitware Robot committed
924
    {
925
926
927
928
      vtkSMPropertyHelper(sbProxy, "Visibility").Set(0);
      vtkSMPropertyHelper(sbProxy, "Enabled").Set(0);
      sbProxy->UpdateVTKObjects();
    }
Kitware Robot's avatar
Kitware Robot committed
929
930
    return true;
  }
931
932

  if (!this->GetUsingScalarColoring())
Kitware Robot's avatar
Kitware Robot committed
933
  {
934
    return false;
Kitware Robot's avatar
Kitware Robot committed
935
  }
936
937

  vtkNew<vtkSMTransferFunctionManager> mgr;
938
939
  vtkSMProxy* sbSMProxy = mgr->GetScalarBarRepresentation(lutProxy, view);
  if (!sbSMProxy)
Kitware Robot's avatar
Kitware Robot committed
940
  {
941
942
    vtkWarningMacro("Failed to locate/create ScalarBar representation.");
    return false;
Kitware Robot's avatar
Kitware Robot committed
943
  }
944

945
946
  vtkSMPropertyHelper(sbSMProxy, "Enabled").Set(1);
  vtkSMPropertyHelper(sbSMProxy, "Visibility").Set(1);
947