File: vtkSMRepresentedArrayListDomain.cxx

package info (click to toggle)
paraview 5.1.2%2Bdfsg1-2
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 221,108 kB
  • ctags: 236,092
  • sloc: cpp: 2,416,026; ansic: 190,891; python: 99,856; xml: 81,001; tcl: 46,915; yacc: 5,039; java: 4,413; perl: 3,108; sh: 1,974; lex: 1,926; f90: 748; asm: 471; pascal: 228; makefile: 198; objc: 83; fortran: 31
file content (262 lines) | stat: -rw-r--r-- 9,996 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
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
251
252
253
254
255
256
257
258
259
260
261
262
/*=========================================================================

  Program:   ParaView
  Module:    vtkSMRepresentedArrayListDomain.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 "vtkSMRepresentedArrayListDomain.h"

#include "vtkCommand.h"
#include "vtkDataObject.h"
#include "vtkObjectFactory.h"
#include "vtkPVArrayInformation.h"
#include "vtkPVCompositeDataInformation.h"
#include "vtkPVDataInformation.h"
#include "vtkPVRepresentedArrayListSettings.h"
#include "vtkPVXMLElement.h"
#include "vtkSMProperty.h"
#include "vtkSMRepresentationProxy.h"

#include <vtksys/RegularExpression.hxx>
#include <cassert>

namespace
{
  // Given composite data set information, check whether the arrays
  // associated with the field data in the leaf blocks have a single
  // tuple. We do this to limit which field arrays are available to
  // the domain.
  bool vtkFieldArrayHasOneTuplePerCompositeDataSetLeaf(vtkPVCompositeDataInformation* info, const char* arrayName)
    {
    for (unsigned int i = 0; i < info->GetNumberOfChildren(); ++i)
      {
      vtkPVDataInformation* childInfo = info->GetDataInformation(i);
      if (childInfo)
        {
        vtkPVCompositeDataInformation* compositeChildInfo = childInfo->GetCompositeDataInformation();
        if (compositeChildInfo->GetNumberOfChildren() == 0)
          {
          // We have found a leaf in the dataset. Check whether the field
          // array with the given name has just one tuple.
          vtkPVArrayInformation* childArrayInfo = childInfo->GetArrayInformation(
            arrayName, vtkDataObject::FIELD_ASSOCIATION_NONE);
          if (childArrayInfo && childArrayInfo->GetNumberOfTuples() != 1)
            {
            return false;
            }
          }
        else
          {
          // Recurse on the composite data information in the child
          if (!vtkFieldArrayHasOneTuplePerCompositeDataSetLeaf(compositeChildInfo, arrayName))
            {
            return false;
            }
          }
        }
      }

    // If we got here, everything checks out
    return true;
    }
}

// Callback to update the RepresentedArrayListDomain
class vtkSMRepresentedArrayListDomainUpdateCommand : public vtkCommand
{
public:
  vtkWeakPointer<vtkSMRepresentedArrayListDomain> Domain;
  typedef vtkCommand Superclass;
  vtkSMRepresentedArrayListDomainUpdateCommand()
    {
      this->Domain = NULL;
    }
  virtual const char* GetClassNameInternal() const
    { return "vtkSMRepresentedArrayListDomainUpdateCommand"; }
  static vtkSMRepresentedArrayListDomainUpdateCommand* New()
    {
      return new vtkSMRepresentedArrayListDomainUpdateCommand();
    }
  virtual void Execute(vtkObject*, unsigned long, void*)
  {
    if (this->Domain)
      {
      this->Domain->Update(NULL);
      }
  }
};


vtkStandardNewMacro(vtkSMRepresentedArrayListDomain);
//----------------------------------------------------------------------------
vtkSMRepresentedArrayListDomain::vtkSMRepresentedArrayListDomain()
{
  this->ObserverId = 0;

  // See description in vtkSMRepresentedArrayListDomain::Update().
  this->UseTrueParentForRepresentatedDataInformation = true;

  // The question is whether to just pick the first available array when the
  // "chosen" attribute is not available or not. Opting for not. This keeps us
  // from ending up scalar coloring random data arrays by default. This logic
  // may need to be reconsidered.
  this->PickFirstAvailableArrayByDefault = false;

  // Set up observer on vtkPVRepresentedArrayListSettings so that the domain
  // updates whenever the settings are changed.
  vtkSMRepresentedArrayListDomainUpdateCommand* observer =
    vtkSMRepresentedArrayListDomainUpdateCommand::New();
  observer->Domain = this;

  vtkPVRepresentedArrayListSettings* arrayListSettings = vtkPVRepresentedArrayListSettings::GetInstance();
  arrayListSettings->AddObserver(vtkCommand::ModifiedEvent, observer);
  observer->FastDelete();
}

//----------------------------------------------------------------------------
vtkSMRepresentedArrayListDomain::~vtkSMRepresentedArrayListDomain()
{
  this->SetRepresentationProxy(NULL);
}

//----------------------------------------------------------------------------
void vtkSMRepresentedArrayListDomain::Update(vtkSMProperty* property)
{
  if (this->RepresentationProxy == NULL)
    {
    // When the update happens the first time, save a reference to the
    // representation proxy and add observers so that we can monitor the
    // representation updates.
    vtkSMRepresentationProxy* selfProxy = (this->GetProperty()?
      vtkSMRepresentationProxy::SafeDownCast(this->GetProperty()->GetParent()) : NULL);

    // BUG #15586. This is a tricky issue. The problem is that the
    // PVRepresentationBase (which is a composite representation comprising of
    // other representations) exposes the "ColorArrayName" property from one of
    // its subproxies. That ensures proper grouping and placement of this
    // property's widget in the UI. However, the problem is that the domain for
    // this property needs to be updated based on the representated-data
    // information of the composite-representation rather than the internal
    // representation (which is what was causing the reported bug, since we always
    // ended up getting represented-data information from the "Surface
    // Representation". Adding a mechanism to tell the domain to the use teh
    // represented-data information from the outer most representation overcomes
    // this issue with less XML tricks and better backwards compatibility.
    vtkSMRepresentationProxy* outerMostRepresentation =
      (selfProxy && this->UseTrueParentForRepresentatedDataInformation)?
      vtkSMRepresentationProxy::SafeDownCast(selfProxy->GetTrueParentProxy()) : NULL;

    this->SetRepresentationProxy(outerMostRepresentation? outerMostRepresentation : selfProxy);
    }
  this->Superclass::Update(property);
}

//----------------------------------------------------------------------------
void vtkSMRepresentedArrayListDomain::SetRepresentationProxy(
  vtkSMRepresentationProxy* repr)
{
  if (this->RepresentationProxy != repr)
    {
    if (this->RepresentationProxy && this->ObserverId)
      {
      this->RepresentationProxy->RemoveObserver(this->ObserverId);
      }
    this->RepresentationProxy = repr;
    if (repr)
      {
      this->ObserverId = this->RepresentationProxy->AddObserver(
        vtkCommand::UpdateDataEvent,
        this,
        &vtkSMRepresentedArrayListDomain::OnRepresentationDataUpdated);
      }
    }
}

//----------------------------------------------------------------------------
void vtkSMRepresentedArrayListDomain::OnRepresentationDataUpdated()
{
  this->Update(NULL);
}

//----------------------------------------------------------------------------
bool vtkSMRepresentedArrayListDomain::IsFilteredArray(
  vtkPVDataInformation* info, int association, const char* name)
{
  // NOTE: Return `true` to reject.
  vtkPVRepresentedArrayListSettings* colorArraySettings = vtkPVRepresentedArrayListSettings::GetInstance();
  for (int idx = 0; idx < colorArraySettings->GetNumberOfFilterExpressions(); ++idx)
    {
    std::string filterExpression = colorArraySettings->GetFilterExpression(idx);
    vtksys::RegularExpression re(filterExpression);
    bool matches = re.find(name);
    if (matches)
      {
      // filter i.e. remove the array.
      return true;
      }
    }

  // If the array is a field data array and the data is a composite datasets,
  // we need to ensure it has exactly as many tuples as the blocks in dataset
  // for coloring.
  if (association == vtkDataObject::FIELD_ASSOCIATION_NONE &&
      info->GetCompositeDataSetType() >= 0)
    {
    vtkPVCompositeDataInformation* cdi = info->GetCompositeDataInformation();
    assert(cdi);
    return !vtkFieldArrayHasOneTuplePerCompositeDataSetLeaf(cdi, name);
    }

  // don't filter.
  return false;
}

//----------------------------------------------------------------------------
vtkPVDataInformation* vtkSMRepresentedArrayListDomain::GetExtraDataInformation()
{
  // This extra care is needed for vtkSMRepresentedArrayListDomain since
  // this->RepresentationProxy can be a parent proxy in which case, when loading
  // state or undoing/redoing, the Update() on the domain can get called
  // prematurely -- before the outer proxy's state has been updated.
  // GatheringInformation in that case can force the proxy to be created
  // messing up the state of other subproxies yet to be deserialized!
  return this->RepresentationProxy && this->RepresentationProxy->GetObjectsCreated()?
    this->RepresentationProxy->GetRepresentedDataInformation() : NULL;
}

//----------------------------------------------------------------------------
int vtkSMRepresentedArrayListDomain::ReadXMLAttributes(vtkSMProperty* prop, vtkPVXMLElement* elem)
{
  if (!this->Superclass::ReadXMLAttributes(prop, elem))
    {
    return 0;
    }

  int use_true_parent = 1;
  if (elem->GetScalarAttribute("use_true_parent", &use_true_parent) != 0 &&
    use_true_parent == 0)
    {
    this->SetUseTrueParentForRepresentatedDataInformation(false);
    }
  else
    {
    this->SetUseTrueParentForRepresentatedDataInformation(true);
    }
  return 1;
}

//----------------------------------------------------------------------------
void vtkSMRepresentedArrayListDomain::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
  os << indent << "UseTrueParentForRepresentatedDataInformation: "
    << this->UseTrueParentForRepresentatedDataInformation << endl;
}