pqModelTransformSupportBehavior.cxx 9.76 KB
Newer Older
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
/*=========================================================================

   Program: ParaView
   Module:  pqModelTransformSupportBehavior.cxx

   Copyright (c) 2005,2006 Sandia Corporation, Kitware Inc.
   All rights reserved.

   ParaView is a free software; you can redistribute it and/or modify it
   under the terms of the ParaView license version 1.2.

   See License_v1.2.txt for the full ParaView license.
   A copy of this license can be obtained by contacting
   Kitware Inc.
   28 Corporate Drive
   Clifton Park, NY 12065
   USA

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHORS OR
CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

========================================================================*/
#include "pqModelTransformSupportBehavior.h"

#include "pqApplicationCore.h"
#include "pqDataRepresentation.h"
#include "pqPipelineSource.h"
#include "pqServerManagerModel.h"
#include "pqView.h"
39
#include "vtkDataObject.h"
40
41
#include "vtkPVArrayInformation.h"
#include "vtkPVDataInformation.h"
42
43
#include "vtkSMProperty.h"
#include "vtkSMPropertyHelper.h"
44
45
46
47
48
#include "vtkSMSourceProxy.h"
#include "vtkTuple.h"

#include <QtDebug>

49
50
#include <cassert>

51
52
namespace
{
Kitware Robot's avatar
Kitware Robot committed
53
54
static vtkSMSourceProxy* FindVisibleProducerWithChangeOfBasisMatrix(pqView* view)
{
Ben Boeckel's avatar
Ben Boeckel committed
55
  Q_FOREACH (pqRepresentation* repr, view->getRepresentations())
Kitware Robot's avatar
Kitware Robot committed
56
57
58
  {
    pqDataRepresentation* drepr = qobject_cast<pqDataRepresentation*>(repr);
    if (!drepr || !drepr->isVisible())
59
    {
Kitware Robot's avatar
Kitware Robot committed
60
      continue;
61
62
    }

Kitware Robot's avatar
Kitware Robot committed
63
64
65
66
67
    vtkPVDataInformation* info = drepr->getInputDataInformation();
    vtkPVArrayInformation* cobm =
      info->GetArrayInformation("ChangeOfBasisMatrix", vtkDataObject::FIELD);
    vtkPVArrayInformation* bbimc = cobm
      ? info->GetArrayInformation("BoundingBoxInModelCoordinates", vtkDataObject::FIELD)
68
      : nullptr;
Kitware Robot's avatar
Kitware Robot committed
69
    if (cobm && bbimc)
70
    {
Kitware Robot's avatar
Kitware Robot committed
71
72
73
      return vtkSMSourceProxy::SafeDownCast(drepr->getInput()->getProxy());
    }
  }
74
  return nullptr;
Kitware Robot's avatar
Kitware Robot committed
75
76
77
}

/// Changes the title property iff its value wasn't explicitly changed by the user.
78
/// If value is nullptr, we restore the property default else the property is set to
Kitware Robot's avatar
Kitware Robot committed
79
80
81
82
/// the specified value.
void SafeSetAxisTitle(vtkSMProxy* gridAxis, const char* pname, const char* value)
{
  vtkSMProperty* prop = gridAxis->GetProperty(pname);
83
  assert(prop);
84

Kitware Robot's avatar
Kitware Robot committed
85
  vtkSMPropertyHelper helper(prop);
86

Kitware Robot's avatar
Kitware Robot committed
87
88
  QString key = QString("MTSBAutoTitle.%1").arg(pname);
  if (prop->IsValueDefault() ||
89
    (gridAxis->HasAnnotation(key.toUtf8().data()) &&
90
      strcmp(gridAxis->GetAnnotation(key.toUtf8().data()), helper.GetAsString()) == 0))
Kitware Robot's avatar
Kitware Robot committed
91
92
93
94
  {
    if (value)
    {
      helper.Set(value);
95
      gridAxis->SetAnnotation(key.toUtf8().data(), value);
96
    }
Kitware Robot's avatar
Kitware Robot committed
97
98
99
    else
    {
      prop->ResetToDefault();
100
      gridAxis->RemoveAnnotation(key.toUtf8().data());
Kitware Robot's avatar
Kitware Robot committed
101
102
103
    }
  }
}
104
105
106
107
108
109
110
111
}

//-----------------------------------------------------------------------------
pqModelTransformSupportBehavior::pqModelTransformSupportBehavior(QObject* parentObject)
  : Superclass(parentObject)
{
  pqServerManagerModel* smmodel = pqApplicationCore::instance()->getServerManagerModel();
  this->connect(smmodel, SIGNAL(viewAdded(pqView*)), SLOT(viewAdded(pqView*)));
Ben Boeckel's avatar
Ben Boeckel committed
112
  Q_FOREACH (pqView* view, smmodel->findItems<pqView*>())
Kitware Robot's avatar
Kitware Robot committed
113
  {
114
    this->viewAdded(view);
Kitware Robot's avatar
Kitware Robot committed
115
  }
116
117
118
}

//-----------------------------------------------------------------------------
119
pqModelTransformSupportBehavior::~pqModelTransformSupportBehavior() = default;
120
121
122
123
124

//-----------------------------------------------------------------------------
void pqModelTransformSupportBehavior::viewAdded(pqView* view)
{
  if (view)
Kitware Robot's avatar
Kitware Robot committed
125
  {
126
    this->connect(view, SIGNAL(updateDataEvent()), SLOT(viewUpdated()));
Kitware Robot's avatar
Kitware Robot committed
127
  }
128
129
130
131
132
133
}

//-----------------------------------------------------------------------------
void pqModelTransformSupportBehavior::viewUpdated()
{
  pqView* view = qobject_cast<pqView*>(this->sender());
134
  assert(view);
135
136
137
138

  // Check if there is any data source visible in the view that has a
  // ChangeOfBasisMatrix and BoundingBoxInModelCoordinates specified.
  if (vtkSMSourceProxy* producer = FindVisibleProducerWithChangeOfBasisMatrix(view))
Kitware Robot's avatar
Kitware Robot committed
139
  {
140
    this->enableModelTransform(view, producer);
Kitware Robot's avatar
Kitware Robot committed
141
  }
142
  else
Kitware Robot's avatar
Kitware Robot committed
143
  {
144
    this->disableModelTransform(view);
Kitware Robot's avatar
Kitware Robot committed
145
  }
146
147
148
}

//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
149
void pqModelTransformSupportBehavior::enableModelTransform(pqView* view, vtkSMSourceProxy* producer)
150
151
{
  bool are_titles_valid;
152
  vtkTuple<std::string, 3> titles = this->getAxisTitles(producer, 0, &are_titles_valid);
153

Kitware Robot's avatar
Kitware Robot committed
154
155
156
  if (vtkSMProxy* gridAxes3DActor =
        vtkSMPropertyHelper(view->getProxy(), "AxesGrid", /*quiet*/ true).GetAsProxy())
  {
157
158
159
160
161
162
163
    vtkSMPropertyHelper(gridAxes3DActor, "UseModelTransform").Set(1);
    vtkTuple<double, 16> cobm = this->getChangeOfBasisMatrix(producer);
    vtkTuple<double, 6> bounds = this->getBoundingBoxInModelCoordinates(producer);
    vtkSMPropertyHelper(gridAxes3DActor, "ModelTransformMatrix").Set(cobm.GetData(), 16);
    vtkSMPropertyHelper(gridAxes3DActor, "ModelBounds").Set(bounds.GetData(), 6);

    if (are_titles_valid)
Kitware Robot's avatar
Kitware Robot committed
164
    {
165
166
167
      SafeSetAxisTitle(gridAxes3DActor, "XTitle", titles[0].c_str());
      SafeSetAxisTitle(gridAxes3DActor, "YTitle", titles[1].c_str());
      SafeSetAxisTitle(gridAxes3DActor, "ZTitle", titles[2].c_str());
Kitware Robot's avatar
Kitware Robot committed
168
    }
169
    else
Kitware Robot's avatar
Kitware Robot committed
170
    {
171
      // clear data-dependent axis titles.
172
173
174
      SafeSetAxisTitle(gridAxes3DActor, "XTitle", nullptr);
      SafeSetAxisTitle(gridAxes3DActor, "YTitle", nullptr);
      SafeSetAxisTitle(gridAxes3DActor, "ZTitle", nullptr);
175
    }
Kitware Robot's avatar
Kitware Robot committed
176
177
    gridAxes3DActor->UpdateVTKObjects();
  }
178
179

  if (are_titles_valid)
Kitware Robot's avatar
Kitware Robot committed
180
  {
181
    vtkSMProxy* viewProxy = view->getProxy();
Kitware Robot's avatar
Kitware Robot committed
182
183
184
    vtkSMPropertyHelper(viewProxy, "XTitle", /*quiet*/ true).Set(titles[0].c_str());
    vtkSMPropertyHelper(viewProxy, "YTitle", /*quiet*/ true).Set(titles[1].c_str());
    vtkSMPropertyHelper(viewProxy, "ZTitle", /*quiet*/ true).Set(titles[2].c_str());
185
    viewProxy->UpdateVTKObjects();
Kitware Robot's avatar
Kitware Robot committed
186
  }
187
188
189
190
191
}

//-----------------------------------------------------------------------------
void pqModelTransformSupportBehavior::disableModelTransform(pqView* view)
{
Kitware Robot's avatar
Kitware Robot committed
192
193
194
  if (vtkSMProxy* gridAxes3DActor =
        vtkSMPropertyHelper(view->getProxy(), "AxesGrid", /*quiet*/ true).GetAsProxy())
  {
195
196
    vtkSMPropertyHelper helper(gridAxes3DActor, "UseModelTransform");
    if (helper.GetAsInt() != 0)
Kitware Robot's avatar
Kitware Robot committed
197
    {
198
      helper.Set(0);
Kitware Robot's avatar
Kitware Robot committed
199
    }
200
201
202
    SafeSetAxisTitle(gridAxes3DActor, "XTitle", nullptr);
    SafeSetAxisTitle(gridAxes3DActor, "YTitle", nullptr);
    SafeSetAxisTitle(gridAxes3DActor, "ZTitle", nullptr);
203
    gridAxes3DActor->UpdateVTKObjects();
Kitware Robot's avatar
Kitware Robot committed
204
  }
205
206
207
}

//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
208
209
template <class T, int size>
vtkTuple<T, size> GetValues(const char* aname, vtkSMSourceProxy* producer, int port, bool* pisvalid)
210
211
{
  bool dummy;
Kitware Robot's avatar
Kitware Robot committed
212
  pisvalid = pisvalid ? pisvalid : &dummy;
213
214
215
216
217
  *pisvalid = false;

  vtkTuple<T, size> value;
  vtkPVDataInformation* dinfo = producer->GetDataInformation(port);
  if (vtkPVArrayInformation* ainfo =
218
        (dinfo ? dinfo->GetArrayInformation(aname, vtkDataObject::FIELD) : nullptr))
Kitware Robot's avatar
Kitware Robot committed
219
  {
220
    if (ainfo->GetNumberOfComponents() == size)
Kitware Robot's avatar
Kitware Robot committed
221
    {
222
      *pisvalid = true;
Kitware Robot's avatar
Kitware Robot committed
223
224
      for (int cc = 0; cc < size; cc++)
      {
225
226
227
        value[cc] = ainfo->GetComponentRange(cc)[0];
      }
    }
Kitware Robot's avatar
Kitware Robot committed
228
  }
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
  return value;
}

//-----------------------------------------------------------------------------
vtkTuple<double, 16> pqModelTransformSupportBehavior::getChangeOfBasisMatrix(
  vtkSMSourceProxy* producer, int port, bool* pisvalid)
{
  return GetValues<double, 16>("ChangeOfBasisMatrix", producer, port, pisvalid);
}

//-----------------------------------------------------------------------------
vtkTuple<double, 6> pqModelTransformSupportBehavior::getBoundingBoxInModelCoordinates(
  vtkSMSourceProxy* producer, int port, bool* pisvalid)
{
  return GetValues<double, 6>("BoundingBoxInModelCoordinates", producer, port, pisvalid);
}

//-----------------------------------------------------------------------------
247
vtkTuple<std::string, 3> pqModelTransformSupportBehavior::getAxisTitles(
248
249
250
  vtkSMSourceProxy* producer, int port, bool* pisvalid)
{
  bool dummy;
Kitware Robot's avatar
Kitware Robot committed
251
  pisvalid = pisvalid ? pisvalid : &dummy;
252
253
  *pisvalid = false;

254
  vtkTuple<std::string, 3> value;
255
  vtkPVDataInformation* dinfo = producer->GetDataInformation(port);
Kitware Robot's avatar
Kitware Robot committed
256
257
258
259
  if (!dinfo)
  {
    return value;
  }
260
261
262
263

  vtkPVArrayInformation* xtitle = dinfo->GetArrayInformation("AxisTitleForX", vtkDataObject::FIELD);
  vtkPVArrayInformation* ytitle = dinfo->GetArrayInformation("AxisTitleForY", vtkDataObject::FIELD);
  vtkPVArrayInformation* ztitle = dinfo->GetArrayInformation("AxisTitleForZ", vtkDataObject::FIELD);
264
265
266
  if ((xtitle && xtitle->GetComponentName(0) == nullptr) ||
    (ytitle && ytitle->GetComponentName(0) == nullptr) ||
    (ztitle && ztitle->GetComponentName(0) == nullptr))
Kitware Robot's avatar
Kitware Robot committed
267
  {
268
    qCritical() << "Mechanisms for specifying axis titles have changed. "
Kitware Robot's avatar
Kitware Robot committed
269
                   "Please contact the ParaView developers for more info.";
270
    return value;
Kitware Robot's avatar
Kitware Robot committed
271
  }
272
273
274

  *pisvalid = xtitle || ytitle || ztitle;
  if (xtitle && xtitle->GetComponentName(0))
Kitware Robot's avatar
Kitware Robot committed
275
  {
276
    value[0] = xtitle->GetComponentName(0);
Kitware Robot's avatar
Kitware Robot committed
277
  }
278
  if (ytitle && ytitle->GetComponentName(0))
Kitware Robot's avatar
Kitware Robot committed
279
  {
280
    value[1] = ytitle->GetComponentName(0);
Kitware Robot's avatar
Kitware Robot committed
281
  }
282
  if (ztitle && ztitle->GetComponentName(0))
Kitware Robot's avatar
Kitware Robot committed
283
  {
284
    value[2] = ztitle->GetComponentName(0);
Kitware Robot's avatar
Kitware Robot committed
285
  }
286
287
  return value;
}