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

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

#include "vtkClientServerStream.h"
#include "vtkCollection.h"
19
#include "vtkCompositeRepresentation.h"
20
#include "vtkDataRepresentation.h"
21
#include "vtkDoubleArray.h"
22 23
#include "vtkIdTypeArray.h"
#include "vtkInformation.h"
24
#include "vtkInformationDoubleKey.h"
25 26 27
#include "vtkInformationIntegerKey.h"
#include "vtkInformationIterator.h"
#include "vtkInformationStringKey.h"
28
#include "vtkObjectFactory.h"
29
#include "vtkPVDataInformation.h"
30
#include "vtkPVSelectionInformation.h"
31
#include "vtkProcessModule.h"
32
#include "vtkSMDoubleVectorProperty.h"
33
#include "vtkSMIdTypeVectorProperty.h"
34
#include "vtkSMInputProperty.h"
35
#include "vtkSMIntVectorProperty.h"
36
#include "vtkSMOutputPort.h"
37
#include "vtkSMPropertyHelper.h"
38
#include "vtkSMProxyManager.h"
39
#include "vtkSMSession.h"
40
#include "vtkSMSessionProxyManager.h"
41
#include "vtkSMSourceProxy.h"
42 43 44 45
#include "vtkSelection.h"
#include "vtkSelectionNode.h"
#include "vtkSelectionSerializer.h"
#include "vtkSmartPointer.h"
46
#include "vtkUnsignedIntArray.h"
47
#include "vtkView.h"
48

49
#include <cassert>
50
#include <map>
51
#include <set>
52
#include <sstream>
53
#include <vector>
54 55 56 57 58 59 60 61 62 63

vtkStandardNewMacro(vtkSMSelectionHelper);

//-----------------------------------------------------------------------------
void vtkSMSelectionHelper::PrintSelf(ostream& os, vtkIndent indent)
{
  this->Superclass::PrintSelf(os, indent);
}

//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
64 65
vtkSMProxy* vtkSMSelectionHelper::NewSelectionSourceFromSelectionInternal(vtkSMSession* session,
  vtkSelectionNode* selection, vtkSMProxy* selSource, bool ignore_composite_keys)
66
{
67 68
  assert("Session need to be provided and need to be valid" && session);

69
  if (!selection || !selection->GetSelectionList())
Kitware Robot's avatar
Kitware Robot committed
70
  {
Utkarsh Ayachit's avatar
Utkarsh Ayachit committed
71
    return selSource;
Kitware Robot's avatar
Kitware Robot committed
72
  }
73

74
  vtkSMProxy* originalSelSource = selSource;
75

76
  vtkInformation* selProperties = selection->GetProperties();
77
  int contentType = selection->GetContentType();
78

79 80 81 82 83 84 85
  // Determine the type of selection source proxy to create that will
  // generate the a vtkSelection same the "selection" instance passed as an
  // argument.
  const char* proxyname = 0;
  bool use_composite = false;
  bool use_hierarchical = false;
  switch (contentType)
Kitware Robot's avatar
Kitware Robot committed
86 87 88 89 90 91 92 93 94 95 96 97 98 99
  {
    case -1:
      // ContentType is not defined. Empty selection.
      return selSource;

    case vtkSelectionNode::FRUSTUM:
      proxyname = "FrustumSelectionSource";
      break;

    case vtkSelectionNode::INDICES:
      // we need to choose between IDSelectionSource,
      // CompositeDataIDSelectionSource and HierarchicalDataIDSelectionSource.
      proxyname = "IDSelectionSource";
      if (!ignore_composite_keys && selProperties->Has(vtkSelectionNode::COMPOSITE_INDEX()))
100
      {
Kitware Robot's avatar
Kitware Robot committed
101 102
        proxyname = "CompositeDataIDSelectionSource";
        use_composite = true;
103
      }
Kitware Robot's avatar
Kitware Robot committed
104 105 106
      else if (!ignore_composite_keys &&
        selProperties->Has(vtkSelectionNode::HIERARCHICAL_LEVEL()) &&
        selProperties->Has(vtkSelectionNode::HIERARCHICAL_INDEX()))
107
      {
Kitware Robot's avatar
Kitware Robot committed
108 109 110
        proxyname = "HierarchicalDataIDSelectionSource";
        use_hierarchical = true;
        use_composite = false;
111
      }
Kitware Robot's avatar
Kitware Robot committed
112
      break;
113

Kitware Robot's avatar
Kitware Robot committed
114 115 116
    case vtkSelectionNode::GLOBALIDS:
      proxyname = "GlobalIDSelectionSource";
      break;
117

Kitware Robot's avatar
Kitware Robot committed
118 119 120
    case vtkSelectionNode::BLOCKS:
      proxyname = "BlockSelectionSource";
      break;
121

Kitware Robot's avatar
Kitware Robot committed
122 123 124
    case vtkSelectionNode::THRESHOLDS:
      proxyname = "ThresholdSelectionSource";
      break;
125

Kitware Robot's avatar
Kitware Robot committed
126 127 128 129
    default:
      vtkGenericWarningMacro("Unhandled ContentType: " << contentType);
      return selSource;
  }
130

131
  if (selSource && strcmp(selSource->GetXMLName(), proxyname) != 0)
Kitware Robot's avatar
Kitware Robot committed
132
  {
133
    vtkGenericWarningMacro("A composite selection has different types of selections."
Kitware Robot's avatar
Kitware Robot committed
134
                           "This is not supported.");
135
    return selSource;
Kitware Robot's avatar
Kitware Robot committed
136
  }
137

138
  if (!selSource)
Kitware Robot's avatar
Kitware Robot committed
139
  {
140 141
    // If selSource is not present we need to create a new one. The type of
    // proxy we instantiate depends on the type of the vtkSelection.
142
    vtkSMSessionProxyManager* pxm =
Kitware Robot's avatar
Kitware Robot committed
143
      vtkSMProxyManager::GetProxyManager()->GetSessionProxyManager(session);
144
    selSource = pxm->NewProxy("sources", proxyname);
Kitware Robot's avatar
Kitware Robot committed
145
  }
146 147

  // Set some common property values using the state of the vtkSelection.
148
  if (selProperties->Has(vtkSelectionNode::FIELD_TYPE()))
Kitware Robot's avatar
Kitware Robot committed
149 150 151
  {
    vtkSMIntVectorProperty* ivp =
      vtkSMIntVectorProperty::SafeDownCast(selSource->GetProperty("FieldType"));
152
    ivp->SetElement(0, selProperties->Get(vtkSelectionNode::FIELD_TYPE()));
Kitware Robot's avatar
Kitware Robot committed
153
  }
154

155
  if (selProperties->Has(vtkSelectionNode::CONTAINING_CELLS()))
Kitware Robot's avatar
Kitware Robot committed
156 157 158
  {
    vtkSMIntVectorProperty* ivp =
      vtkSMIntVectorProperty::SafeDownCast(selSource->GetProperty("ContainingCells"));
159
    ivp->SetElement(0, selProperties->Get(vtkSelectionNode::CONTAINING_CELLS()));
Kitware Robot's avatar
Kitware Robot committed
160
  }
161

162
  if (selProperties->Has(vtkSelectionNode::INVERSE()))
Kitware Robot's avatar
Kitware Robot committed
163 164 165
  {
    vtkSMIntVectorProperty* ivp =
      vtkSMIntVectorProperty::SafeDownCast(selSource->GetProperty("InsideOut"));
166
    ivp->SetElement(0, selProperties->Get(vtkSelectionNode::INVERSE()));
Kitware Robot's avatar
Kitware Robot committed
167
  }
168

169
  if (contentType == vtkSelectionNode::FRUSTUM)
Kitware Robot's avatar
Kitware Robot committed
170
  {
171
    // Set the selection ids, which is the frustum vertex.
Kitware Robot's avatar
Kitware Robot committed
172 173
    vtkSMDoubleVectorProperty* dvp =
      vtkSMDoubleVectorProperty::SafeDownCast(selSource->GetProperty("Frustum"));
174

Kitware Robot's avatar
Kitware Robot committed
175
    vtkDoubleArray* verts = vtkDoubleArray::SafeDownCast(selection->GetSelectionList());
176
    dvp->SetElements(verts->GetPointer(0));
Kitware Robot's avatar
Kitware Robot committed
177
  }
178
  else if (contentType == vtkSelectionNode::GLOBALIDS)
Kitware Robot's avatar
Kitware Robot committed
179 180 181
  {
    vtkSMIdTypeVectorProperty* ids =
      vtkSMIdTypeVectorProperty::SafeDownCast(selSource->GetProperty("IDs"));
182
    if (!originalSelSource)
Kitware Robot's avatar
Kitware Robot committed
183
    {
184
      ids->SetNumberOfElements(0);
Kitware Robot's avatar
Kitware Robot committed
185
    }
186
    unsigned int curValues = ids->GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
187
    vtkIdTypeArray* idList = vtkIdTypeArray::SafeDownCast(selection->GetSelectionList());
188
    if (idList)
Kitware Robot's avatar
Kitware Robot committed
189
    {
190
      vtkIdType numIDs = idList->GetNumberOfTuples();
Kitware Robot's avatar
Kitware Robot committed
191 192 193 194
      ids->SetNumberOfElements(curValues + numIDs);
      for (vtkIdType cc = 0; cc < numIDs; cc++)
      {
        ids->SetElement(curValues + cc, idList->GetValue(cc));
195
      }
196
    }
Kitware Robot's avatar
Kitware Robot committed
197
  }
198
  else if (contentType == vtkSelectionNode::BLOCKS)
Kitware Robot's avatar
Kitware Robot committed
199
  {
200
    std::set<vtkIdType> block_ids;
Kitware Robot's avatar
Kitware Robot committed
201 202 203
    vtkSMIdTypeVectorProperty* blocks =
      vtkSMIdTypeVectorProperty::SafeDownCast(selSource->GetProperty("Blocks"));
    vtkUnsignedIntArray* idList = vtkUnsignedIntArray::SafeDownCast(selection->GetSelectionList());
204
    if (idList)
Kitware Robot's avatar
Kitware Robot committed
205 206 207
    {
      for (unsigned int cc = 0, max = blocks->GetNumberOfElements();
           (cc < max && originalSelSource != NULL); ++cc)
208
      {
209
        block_ids.insert(blocks->GetElement(cc));
Kitware Robot's avatar
Kitware Robot committed
210
      }
211
      assert(idList->GetNumberOfComponents() == 1 || idList->GetNumberOfTuples() == 0);
Kitware Robot's avatar
Kitware Robot committed
212 213
      for (vtkIdType cc = 0, max = idList->GetNumberOfTuples(); cc < max; ++cc)
      {
214 215
        block_ids.insert(idList->GetValue(cc));
      }
Kitware Robot's avatar
Kitware Robot committed
216
    }
217
    if (block_ids.size() > 0)
Kitware Robot's avatar
Kitware Robot committed
218
    {
219 220 221
      std::vector<vtkIdType> block_ids_vec(block_ids.size());
      std::copy(block_ids.begin(), block_ids.end(), block_ids_vec.begin());
      blocks->SetElements(&block_ids_vec[0], static_cast<unsigned int>(block_ids_vec.size()));
Kitware Robot's avatar
Kitware Robot committed
222
    }
223
    else
Kitware Robot's avatar
Kitware Robot committed
224
    {
225
      blocks->SetNumberOfElements(0);
226
    }
Kitware Robot's avatar
Kitware Robot committed
227
  }
228
  else if (contentType == vtkSelectionNode::INDICES)
Kitware Robot's avatar
Kitware Robot committed
229
  {
230
    vtkIdType procID = -1;
231
    if (selProperties->Has(vtkSelectionNode::PROCESS_ID()))
Kitware Robot's avatar
Kitware Robot committed
232
    {
233
      procID = selProperties->Get(vtkSelectionNode::PROCESS_ID());
Kitware Robot's avatar
Kitware Robot committed
234
    }
235 236

    // Add the selection proc ids and cell ids to the IDs property.
Kitware Robot's avatar
Kitware Robot committed
237 238
    vtkSMIdTypeVectorProperty* ids =
      vtkSMIdTypeVectorProperty::SafeDownCast(selSource->GetProperty("IDs"));
239
    if (!originalSelSource)
Kitware Robot's avatar
Kitware Robot committed
240
    {
241 242
      // remove default values set by the XML if we created a brand new proxy.
      ids->SetNumberOfElements(0);
Kitware Robot's avatar
Kitware Robot committed
243
    }
244
    unsigned int curValues = ids->GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
245
    vtkIdTypeArray* idList = vtkIdTypeArray::SafeDownCast(selection->GetSelectionList());
246
    if (idList)
Kitware Robot's avatar
Kitware Robot committed
247
    {
248 249
      vtkIdType numIDs = idList->GetNumberOfTuples();
      if (!use_composite && !use_hierarchical)
Kitware Robot's avatar
Kitware Robot committed
250 251 252
      {
        ids->SetNumberOfElements(curValues + numIDs * 2);
        for (vtkIdType cc = 0; cc < numIDs; cc++)
253
        {
Kitware Robot's avatar
Kitware Robot committed
254 255
          ids->SetElement(curValues + 2 * cc, procID);
          ids->SetElement(curValues + 2 * cc + 1, idList->GetValue(cc));
256
        }
Kitware Robot's avatar
Kitware Robot committed
257
      }
258
      else if (use_composite)
Kitware Robot's avatar
Kitware Robot committed
259
      {
260
        vtkIdType composite_index = 0;
261
        if (selProperties->Has(vtkSelectionNode::COMPOSITE_INDEX()))
Kitware Robot's avatar
Kitware Robot committed
262
        {
263
          composite_index = selProperties->Get(vtkSelectionNode::COMPOSITE_INDEX());
264
        }
Kitware Robot's avatar
Kitware Robot committed
265 266 267

        ids->SetNumberOfElements(curValues + numIDs * 3);
        for (vtkIdType cc = 0; cc < numIDs; cc++)
268
        {
Kitware Robot's avatar
Kitware Robot committed
269 270 271 272 273 274 275
          ids->SetElement(curValues + 3 * cc, composite_index);
          ids->SetElement(curValues + 3 * cc + 1, procID);
          ids->SetElement(curValues + 3 * cc + 2, idList->GetValue(cc));
        }
      }
      else if (use_hierarchical)
      {
276 277
        vtkIdType level = selProperties->Get(vtkSelectionNode::HIERARCHICAL_LEVEL());
        vtkIdType dsIndex = selProperties->Get(vtkSelectionNode::HIERARCHICAL_INDEX());
Kitware Robot's avatar
Kitware Robot committed
278 279 280 281 282 283
        ids->SetNumberOfElements(curValues + numIDs * 3);
        for (vtkIdType cc = 0; cc < numIDs; cc++)
        {
          ids->SetElement(curValues + 3 * cc, level);
          ids->SetElement(curValues + 3 * cc + 1, dsIndex);
          ids->SetElement(curValues + 3 * cc + 2, idList->GetValue(cc));
284
        }
285 286
      }
    }
Kitware Robot's avatar
Kitware Robot committed
287
  }
288
  else if (contentType == vtkSelectionNode::THRESHOLDS)
Kitware Robot's avatar
Kitware Robot committed
289 290
  {
    vtkDoubleArray* selectionList = vtkDoubleArray::SafeDownCast(selection->GetSelectionList());
291 292 293 294
    assert(selectionList);

    vtkSMPropertyHelper(selSource, "ArrayName").Set(selectionList->GetName());
    vtkSMPropertyHelper tHelper(selSource, "Thresholds");
Kitware Robot's avatar
Kitware Robot committed
295 296
    for (vtkIdType cc = 0, max = selectionList->GetNumberOfTuples(); (cc + 1) < max; cc += 2)
    {
297
      tHelper.Set(cc, selectionList->GetValue(cc));
Kitware Robot's avatar
Kitware Robot committed
298
      tHelper.Set(cc + 1, selectionList->GetValue(cc + 1));
299
    }
Kitware Robot's avatar
Kitware Robot committed
300
  }
301

302 303 304 305 306
  return selSource;
}

//-----------------------------------------------------------------------------
vtkSMProxy* vtkSMSelectionHelper::NewSelectionSourceFromSelection(
307
  vtkSMSession* session, vtkSelection* selection, bool ignore_composite_keys)
308
{
Kitware Robot's avatar
Kitware Robot committed
309
  vtkSMProxy* selSource = 0;
310
  unsigned int numNodes = selection->GetNumberOfNodes();
Kitware Robot's avatar
Kitware Robot committed
311 312
  for (unsigned int cc = 0; cc < numNodes; cc++)
  {
313
    vtkSelectionNode* node = selection->GetNode(cc);
314
    selSource = vtkSMSelectionHelper::NewSelectionSourceFromSelectionInternal(
315
      session, node, selSource, ignore_composite_keys);
Kitware Robot's avatar
Kitware Robot committed
316
  }
317
  if (selSource)
Kitware Robot's avatar
Kitware Robot committed
318
  {
319
    selSource->UpdateVTKObjects();
Kitware Robot's avatar
Kitware Robot committed
320
  }
321 322
  return selSource;
}
323

324
//-----------------------------------------------------------------------------
Kitware Robot's avatar
Kitware Robot committed
325 326
vtkSMProxy* vtkSMSelectionHelper::ConvertSelection(
  int outputType, vtkSMProxy* selectionSourceProxy, vtkSMSourceProxy* dataSource, int dataPort)
327
{
Kitware Robot's avatar
Kitware Robot committed
328
  const char* inproxyname = selectionSourceProxy ? selectionSourceProxy->GetXMLName() : 0;
329 330
  const char* outproxyname = 0;
  switch (outputType)
Kitware Robot's avatar
Kitware Robot committed
331 332 333 334
  {
    case vtkSelectionNode::GLOBALIDS:
      outproxyname = "GlobalIDSelectionSource";
      break;
335

Kitware Robot's avatar
Kitware Robot committed
336 337 338
    case vtkSelectionNode::FRUSTUM:
      outproxyname = "FrustumSelectionSource";
      break;
339

Kitware Robot's avatar
Kitware Robot committed
340 341 342
    case vtkSelectionNode::LOCATIONS:
      outproxyname = "LocationSelectionSource";
      break;
343

Kitware Robot's avatar
Kitware Robot committed
344 345 346
    case vtkSelectionNode::THRESHOLDS:
      outproxyname = "ThresholdSelectionSource";
      break;
347

Kitware Robot's avatar
Kitware Robot committed
348 349 350
    case vtkSelectionNode::BLOCKS:
      outproxyname = "BlockSelectionSource";
      break;
351

Kitware Robot's avatar
Kitware Robot committed
352 353 354
    case vtkSelectionNode::INDICES:
    {
      const char* dataName = dataSource->GetOutputPort(dataPort)->GetDataClassName();
355
      outproxyname = "IDSelectionSource";
356
      if (dataName)
Kitware Robot's avatar
Kitware Robot committed
357
      {
358
        if (strcmp(dataName, "vtkHierarchicalBoxDataSet") == 0)
Kitware Robot's avatar
Kitware Robot committed
359
        {
360
          outproxyname = "HierarchicalDataIDSelectionSource";
Kitware Robot's avatar
Kitware Robot committed
361
        }
362
        else if (strcmp(dataName, "vtkMultiBlockDataSet") == 0)
Kitware Robot's avatar
Kitware Robot committed
363
        {
364 365 366
          outproxyname = "CompositeDataIDSelectionSource";
        }
      }
Kitware Robot's avatar
Kitware Robot committed
367
    }
368 369
    break;

Kitware Robot's avatar
Kitware Robot committed
370 371 372 373
    default:
      vtkGenericWarningMacro("Cannot convert to type : " << outputType);
      return 0;
  }
374

375
  if (selectionSourceProxy && strcmp(inproxyname, outproxyname) == 0)
Kitware Robot's avatar
Kitware Robot committed
376
  {
377 378 379
    // No conversion needed.
    selectionSourceProxy->Register(0);
    return selectionSourceProxy;
Kitware Robot's avatar
Kitware Robot committed
380
  }
381

382
  if (outputType == vtkSelectionNode::INDICES && selectionSourceProxy)
Kitware Robot's avatar
Kitware Robot committed
383
  {
384
    vtkSMVectorProperty* ids = 0;
Kitware Robot's avatar
Kitware Robot committed
385
    ids = vtkSMVectorProperty::SafeDownCast(selectionSourceProxy->GetProperty("IDs"));
386 387
    // this "if" condition does not do any conversion in input is GLOBALIDS
    // selection with no ids.
388

389
    if (!ids || ids->GetNumberOfElements() > 0)
Kitware Robot's avatar
Kitware Robot committed
390
    {
391
      // convert from *anything* to indices.
392
      return vtkSMSelectionHelper::ConvertInternal(
Kitware Robot's avatar
Kitware Robot committed
393 394
        vtkSMSourceProxy::SafeDownCast(selectionSourceProxy), dataSource, dataPort,
        vtkSelectionNode::INDICES);
395
    }
Kitware Robot's avatar
Kitware Robot committed
396
  }
397
  else if (outputType == vtkSelectionNode::GLOBALIDS && selectionSourceProxy)
Kitware Robot's avatar
Kitware Robot committed
398 399 400
  {
    vtkSMVectorProperty* ids =
      vtkSMVectorProperty::SafeDownCast(selectionSourceProxy->GetProperty("IDs"));
401 402 403
    // This "if" condition avoid doing any conversion if input is a ID based
    // selection and has no ids.
    if (!ids || ids->GetNumberOfElements() > 0)
Kitware Robot's avatar
Kitware Robot committed
404
    {
405
      // convert from *anything* to global IDs.
406
      return vtkSMSelectionHelper::ConvertInternal(
Kitware Robot's avatar
Kitware Robot committed
407 408
        vtkSMSourceProxy::SafeDownCast(selectionSourceProxy), dataSource, dataPort,
        vtkSelectionNode::GLOBALIDS);
409
    }
Kitware Robot's avatar
Kitware Robot committed
410
  }
411
  else if (outputType == vtkSelectionNode::BLOCKS && selectionSourceProxy &&
412
    (strcmp(inproxyname, "GlobalIDSelectionSource") == 0 ||
Kitware Robot's avatar
Kitware Robot committed
413 414 415
             strcmp(inproxyname, "HierarchicalDataIDSelectionSource") == 0 ||
             strcmp(inproxyname, "CompositeDataIDSelectionSource") == 0))
  {
416
    return vtkSMSelectionHelper::ConvertInternal(
Kitware Robot's avatar
Kitware Robot committed
417 418 419
      vtkSMSourceProxy::SafeDownCast(selectionSourceProxy), dataSource, dataPort,
      vtkSelectionNode::BLOCKS);
  }
420 421 422

  // Conversion not possible, so simply create a new proxy of the requested
  // output type with some empty defaults.
423
  vtkSMSessionProxyManager* pxm = dataSource->GetSessionProxyManager();
424 425
  vtkSMProxy* outSource = pxm->NewProxy("sources", outproxyname);
  if (!outSource)
Kitware Robot's avatar
Kitware Robot committed
426
  {
427
    return outSource;
Kitware Robot's avatar
Kitware Robot committed
428
  }
429 430

  // Note that outSource->ConnectionID and outSource->Servers are not yet set.
Kitware Robot's avatar
Kitware Robot committed
431 432
  if (vtkSMVectorProperty* vp = vtkSMVectorProperty::SafeDownCast(outSource->GetProperty("IDs")))
  {
433 434
    // remove default ID values.
    vp->SetNumberOfElements(0);
Kitware Robot's avatar
Kitware Robot committed
435
  }
436 437

  if (selectionSourceProxy)
Kitware Robot's avatar
Kitware Robot committed
438
  {
439
    // try to copy as many properties from the old-source to the new one.
Kitware Robot's avatar
Kitware Robot committed
440 441 442 443
    outSource->GetProperty("ContainingCells")
      ->Copy(selectionSourceProxy->GetProperty("ContainingCells"));
    outSource->GetProperty("FieldType")->Copy(selectionSourceProxy->GetProperty("FieldType"));
    outSource->GetProperty("InsideOut")->Copy(selectionSourceProxy->GetProperty("InsideOut"));
444
    outSource->UpdateVTKObjects();
Kitware Robot's avatar
Kitware Robot committed
445
  }
446 447 448 449
  return outSource;
}

//-----------------------------------------------------------------------------
450
vtkSMProxy* vtkSMSelectionHelper::ConvertInternal(
Kitware Robot's avatar
Kitware Robot committed
451
  vtkSMSourceProxy* inSource, vtkSMSourceProxy* dataSource, int dataPort, int outputType)
452
{
453
  vtkSMSessionProxyManager* pxm = dataSource->GetSessionProxyManager();
454 455 456 457 458 459

  // * Update all inputs.
  inSource->UpdatePipeline();
  dataSource->UpdatePipeline();

  // * Filter that converts selections.
Kitware Robot's avatar
Kitware Robot committed
460 461 462
  vtkSMSourceProxy* convertor =
    vtkSMSourceProxy::SafeDownCast(pxm->NewProxy("filters", "ConvertSelection"));
  // convertor->SetServers(inSource->GetServers());
463

Kitware Robot's avatar
Kitware Robot committed
464
  vtkSMInputProperty* ip = vtkSMInputProperty::SafeDownCast(convertor->GetProperty("Input"));
465 466 467 468 469
  ip->AddInputConnection(inSource, 0);

  ip = vtkSMInputProperty::SafeDownCast(convertor->GetProperty("DataInput"));
  ip->AddInputConnection(dataSource, dataPort);

Kitware Robot's avatar
Kitware Robot committed
470 471
  vtkSMIntVectorProperty* ivp =
    vtkSMIntVectorProperty::SafeDownCast(convertor->GetProperty("OutputType"));
472
  ivp->SetElement(0, outputType);
473 474 475 476 477

  vtkSMIntVectorProperty* ivp2 =
    vtkSMIntVectorProperty::SafeDownCast(convertor->GetProperty("AllowMissingArray"));
  ivp2->SetElement(0, true);

478 479 480 481 482 483 484
  convertor->UpdateVTKObjects();

  // * Request conversion.
  convertor->UpdatePipeline();

  // * And finally gathering the information back
  vtkPVSelectionInformation* selInfo = vtkPVSelectionInformation::New();
485
  convertor->GatherInformation(selInfo);
486 487

  vtkSMProxy* outSource = vtkSMSelectionHelper::NewSelectionSourceFromSelection(
488
    inSource->GetSession(), selInfo->GetSelection());
489 490 491 492 493

  // cleanup.
  convertor->Delete();
  selInfo->Delete();
  return outSource;
494
}
495 496

//-----------------------------------------------------------------------------
497
bool vtkSMSelectionHelper::MergeSelection(
Kitware Robot's avatar
Kitware Robot committed
498
  vtkSMSourceProxy* output, vtkSMSourceProxy* input, vtkSMSourceProxy* dataSource, int dataPort)
499
{
500
  if (!output || !input)
Kitware Robot's avatar
Kitware Robot committed
501
  {
502
    return false;
Kitware Robot's avatar
Kitware Robot committed
503
  }
504

505 506 507
  // Currently only index based selections i.e. ids, global ids based selections
  // are mergeable and that too only is input and output are identical in all
  // respects (except the indices ofcourse).
508
  if (vtkSMPropertyHelper(output, "FieldType").GetAsInt() !=
509
    vtkSMPropertyHelper(input, "FieldType").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
510
  {
511
    return false;
Kitware Robot's avatar
Kitware Robot committed
512
  }
513

514 515
  if (vtkSMPropertyHelper(output, "ContainingCells", true).GetAsInt() !=
    vtkSMPropertyHelper(input, "ContainingCells", true).GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
516
  {
517
    return false;
Kitware Robot's avatar
Kitware Robot committed
518
  }
519

520
  if (vtkSMPropertyHelper(output, "InsideOut").GetAsInt() !=
521
    vtkSMPropertyHelper(input, "InsideOut").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
522
  {
523
    return false;
Kitware Robot's avatar
Kitware Robot committed
524
  }
525

526 527
  vtkSmartPointer<vtkSMSourceProxy> tempInput;
  if (strcmp(output->GetXMLName(), input->GetXMLName()) != 0)
Kitware Robot's avatar
Kitware Robot committed
528
  {
529 530
    // before totally giving up, check to see if the input selection can be
    // converted to the same type as the output.
531 532
    std::string inputType = input->GetXMLName();
    std::string outputType = output->GetXMLName();
533

Kitware Robot's avatar
Kitware Robot committed
534 535 536 537 538
    if ((inputType == "GlobalIDSelectionSource" && outputType == "IDSelectionSource") ||
      (inputType == "GlobalIDSelectionSource" && outputType == "CompositeDataIDSelectionSource") ||
      (inputType == "IDSelectionSource" && outputType == "GlobalIDSelectionSource") ||
      (inputType == "CompositeDataIDSelectionSource" && outputType == "GlobalIDSelectionSource"))
    {
539 540
      int type = vtkSelectionNode::INDICES;
      if (outputType == "GlobalIDSelectionSource")
Kitware Robot's avatar
Kitware Robot committed
541
      {
542
        type = vtkSelectionNode::GLOBALIDS;
Kitware Robot's avatar
Kitware Robot committed
543
      }
544 545 546

      // Conversion is possible!.
      tempInput.TakeReference(vtkSMSourceProxy::SafeDownCast(
Kitware Robot's avatar
Kitware Robot committed
547
        vtkSMSelectionHelper::ConvertSelection(type, input, dataSource, dataPort)));
548
      input = tempInput;
Kitware Robot's avatar
Kitware Robot committed
549
    }
550
    else
Kitware Robot's avatar
Kitware Robot committed
551
    {
552 553
      return false;
    }
Kitware Robot's avatar
Kitware Robot committed
554
  }
555

556 557
  // mergs IDs or Blocks properties.
  if (output->GetProperty("IDs") && input->GetProperty("IDs"))
Kitware Robot's avatar
Kitware Robot committed
558
  {
559 560 561
    vtkSMPropertyHelper outputIDs(output, "IDs");
    vtkSMPropertyHelper inputIDs(input, "IDs");

562
    std::vector<vtkIdType> ids;
563 564
    unsigned int cc;
    unsigned int count = inputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
565 566
    for (cc = 0; cc < count; cc++)
    {
567
      ids.push_back(inputIDs.GetAsIdType(cc));
Kitware Robot's avatar
Kitware Robot committed
568
    }
569
    count = outputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
570 571
    for (cc = 0; cc < count; cc++)
    {
572
      ids.push_back(outputIDs.GetAsIdType(cc));
Kitware Robot's avatar
Kitware Robot committed
573
    }
574
    outputIDs.Set(&ids[0], static_cast<unsigned int>(ids.size()));
575
    output->UpdateVTKObjects();
576
    return true;
Kitware Robot's avatar
Kitware Robot committed
577
  }
578 579

  if (output->GetProperty("Blocks") && input->GetProperty("Blocks"))
Kitware Robot's avatar
Kitware Robot committed
580
  {
581 582 583
    vtkSMPropertyHelper outputIDs(output, "Blocks");
    vtkSMPropertyHelper inputIDs(input, "Blocks");

584
    std::vector<vtkIdType> ids;
585 586
    unsigned int cc;
    unsigned int count = inputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
587 588
    for (cc = 0; cc < count; cc++)
    {
589
      ids.push_back(inputIDs.GetAsIdType(cc));
Kitware Robot's avatar
Kitware Robot committed
590
    }
591
    count = outputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
592 593
    for (cc = 0; cc < count; cc++)
    {
594
      ids.push_back(outputIDs.GetAsIdType(cc));
Kitware Robot's avatar
Kitware Robot committed
595
    }
596
    outputIDs.Set(&ids[0], static_cast<unsigned int>(ids.size()));
597
    output->UpdateVTKObjects();
598
    return true;
Kitware Robot's avatar
Kitware Robot committed
599
  }
600 601 602

  return false;
}
603

604 605
//-----------------------------------------------------------------------------
bool vtkSMSelectionHelper::SubtractSelection(
Kitware Robot's avatar
Kitware Robot committed
606
  vtkSMSourceProxy* output, vtkSMSourceProxy* input, vtkSMSourceProxy* dataSource, int dataPort)
607 608
{
  if (!output || !input)
Kitware Robot's avatar
Kitware Robot committed
609
  {
610
    return false;
Kitware Robot's avatar
Kitware Robot committed
611
  }
612 613 614 615 616 617

  // Currently only index based selections i.e. ids, global ids based selections
  // are subtractable and that too only is input and output are identical in all
  // respects (except the indices ofcourse).
  if (vtkSMPropertyHelper(output, "FieldType").GetAsInt() !=
    vtkSMPropertyHelper(input, "FieldType").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
618
  {
619
    return false;
Kitware Robot's avatar
Kitware Robot committed
620
  }
621

622 623
  if (vtkSMPropertyHelper(output, "ContainingCells", true).GetAsInt() !=
    vtkSMPropertyHelper(input, "ContainingCells", true).GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
624
  {
625
    return false;
Kitware Robot's avatar
Kitware Robot committed
626
  }
627 628 629

  if (vtkSMPropertyHelper(output, "InsideOut").GetAsInt() !=
    vtkSMPropertyHelper(input, "InsideOut").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
630
  {
631
    return false;
Kitware Robot's avatar
Kitware Robot committed
632
  }
633 634 635

  vtkSmartPointer<vtkSMSourceProxy> tempInput;
  if (strcmp(output->GetXMLName(), input->GetXMLName()) != 0)
Kitware Robot's avatar
Kitware Robot committed
636
  {
637 638 639 640 641
    // before totally giving up, check to see if the input selection can be
    // converted to the same type as the output.
    std::string inputType = input->GetXMLName();
    std::string outputType = output->GetXMLName();

Kitware Robot's avatar
Kitware Robot committed
642 643 644 645 646
    if ((inputType == "GlobalIDSelectionSource" && outputType == "IDSelectionSource") ||
      (inputType == "GlobalIDSelectionSource" && outputType == "CompositeDataIDSelectionSource") ||
      (inputType == "IDSelectionSource" && outputType == "GlobalIDSelectionSource") ||
      (inputType == "CompositeDataIDSelectionSource" && outputType == "GlobalIDSelectionSource"))
    {
647 648
      int type = vtkSelectionNode::INDICES;
      if (outputType == "GlobalIDSelectionSource")
Kitware Robot's avatar
Kitware Robot committed
649
      {
650
        type = vtkSelectionNode::GLOBALIDS;
Kitware Robot's avatar
Kitware Robot committed
651
      }
652 653 654

      // Conversion is possible!.
      tempInput.TakeReference(vtkSMSourceProxy::SafeDownCast(
Kitware Robot's avatar
Kitware Robot committed
655
        vtkSMSelectionHelper::ConvertSelection(type, input, dataSource, dataPort)));
656
      input = tempInput;
Kitware Robot's avatar
Kitware Robot committed
657
    }
658
    else
Kitware Robot's avatar
Kitware Robot committed
659
    {
660 661
      return false;
    }
Kitware Robot's avatar
Kitware Robot committed
662
  }
663 664 665 666 667

  // Recover type of selection, so we know what is contained in selection source
  std::string inputType = input->GetXMLName();
  int selectionTupleSize = 1;
  if (inputType == "ThresholdSelectionSource" || inputType == "IDSelectionSource")
Kitware Robot's avatar
Kitware Robot committed
668
  {
669
    selectionTupleSize = 2;
Kitware Robot's avatar
Kitware Robot committed
670 671 672 673
  }
  else if (inputType == "CompositeDataIDSelectionSource" ||
    inputType == "HierarchicalDataIDSelectionSource")
  {
674
    selectionTupleSize = 3;
Kitware Robot's avatar
Kitware Robot committed
675
  }
676 677 678

  // subtract IDs or Blocks properties.
  if (output->GetProperty("IDs") && input->GetProperty("IDs"))
Kitware Robot's avatar
Kitware Robot committed
679
  {
680 681 682 683 684
    vtkSMPropertyHelper outputIDs(output, "IDs");
    vtkSMPropertyHelper inputIDs(input, "IDs");

    // Stor ids to remove as vector , so set is ordered correctly.
    std::vector<vtkIdType> ids;
Kitware Robot's avatar
Kitware Robot committed
685
    std::set<std::vector<vtkIdType> > idsToRemove;
686 687
    unsigned int cc;
    unsigned int count = outputIDs.GetNumberOfElements() / selectionTupleSize;
Kitware Robot's avatar
Kitware Robot committed
688 689
    for (cc = 0; cc < count; cc++)
    {
690 691
      std::vector<vtkIdType> id;
      for (int i = 0; i < selectionTupleSize; i++)
Kitware Robot's avatar
Kitware Robot committed
692
      {
693 694
        id.push_back(outputIDs.GetAsIdType(cc * selectionTupleSize + i));
      }
Kitware Robot's avatar
Kitware Robot committed
695 696
      idsToRemove.insert(id);
    }
697 698 699

    // Insert ids only if non present in set.
    count = inputIDs.GetNumberOfElements() / selectionTupleSize;
Kitware Robot's avatar
Kitware Robot committed
700 701
    for (cc = 0; cc < count; cc++)
    {
702 703
      std::vector<vtkIdType> id;
      for (int i = 0; i < selectionTupleSize; i++)
Kitware Robot's avatar
Kitware Robot committed
704
      {
705
        id.push_back(inputIDs.GetAsIdType(cc * selectionTupleSize + i));
Kitware Robot's avatar
Kitware Robot committed
706
      }
707
      if (idsToRemove.find(id) == idsToRemove.end())
Kitware Robot's avatar
Kitware Robot committed
708
      {
709
        for (int i = 0; i < selectionTupleSize; i++)
Kitware Robot's avatar
Kitware Robot committed
710
        {
711 712 713
          ids.push_back(id[i]);
        }
      }
Kitware Robot's avatar
Kitware Robot committed
714
    }
715 716 717
    outputIDs.Set(&ids[0], static_cast<unsigned int>(ids.size()));
    output->UpdateVTKObjects();
    return true;
Kitware Robot's avatar
Kitware Robot committed
718
  }
719

720
  if (output->GetProperty("Blocks") && input->GetProperty("Blocks"))
Kitware Robot's avatar
Kitware Robot committed
721
  {
722 723 724 725 726 727 728
    vtkSMPropertyHelper outputIDs(output, "Blocks");
    vtkSMPropertyHelper inputIDs(input, "Blocks");

    std::vector<vtkIdType> ids;
    std::set<vtkIdType> idsToRemove;
    unsigned int cc;
    unsigned int count = outputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
729 730
    for (cc = 0; cc < count; cc++)
    {
731
      idsToRemove.insert(outputIDs.GetAsIdType(cc));
Kitware Robot's avatar
Kitware Robot committed
732
    }
733 734

    count = inputIDs.GetNumberOfElements();
Kitware Robot's avatar
Kitware Robot committed
735 736
    for (cc = 0; cc < count; cc++)
    {
737 738
      vtkIdType id = inputIDs.GetAsIdType(cc);
      if (idsToRemove.find(id) == idsToRemove.end())
Kitware Robot's avatar
Kitware Robot committed
739
      {
740 741
        ids.push_back(inputIDs.GetAsIdType(cc));
      }
Kitware Robot's avatar
Kitware Robot committed
742
    }
743 744 745
    outputIDs.Set(&ids[0], static_cast<unsigned int>(ids.size()));
    output->UpdateVTKObjects();
    return true;
Kitware Robot's avatar
Kitware Robot committed
746
  }
747 748 749 750 751 752

  return false;
}

//-----------------------------------------------------------------------------
bool vtkSMSelectionHelper::ToggleSelection(
Kitware Robot's avatar
Kitware Robot committed
753
  vtkSMSourceProxy* output, vtkSMSourceProxy* input, vtkSMSourceProxy* dataSource, int dataPort)
754 755
{
  if (!output || !input)
Kitware Robot's avatar
Kitware Robot committed
756
  {
757
    return false;
Kitware Robot's avatar
Kitware Robot committed
758
  }
759 760 761 762 763 764

  // Currently only index based selections i.e. ids, global ids based selections
  // are subtractable and that too only is input and output are identical in all
  // respects (except the indices ofcourse).
  if (vtkSMPropertyHelper(output, "FieldType").GetAsInt() !=
    vtkSMPropertyHelper(input, "FieldType").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
765
  {
766
    return false;
Kitware Robot's avatar
Kitware Robot committed
767
  }
768

769 770
  if (vtkSMPropertyHelper(output, "ContainingCells", true).GetAsInt() !=
    vtkSMPropertyHelper(input, "ContainingCells", true).GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
771
  {
772
    return false;
Kitware Robot's avatar
Kitware Robot committed
773
  }
774 775 776

  if (vtkSMPropertyHelper(output, "InsideOut").GetAsInt() !=
    vtkSMPropertyHelper(input, "InsideOut").GetAsInt())
Kitware Robot's avatar
Kitware Robot committed
777
  {
778
    return false;
Kitware Robot's avatar
Kitware Robot committed
779
  }
780 781 782

  vtkSmartPointer<vtkSMSourceProxy> tempInput;
  if (strcmp(output->GetXMLName(), input->GetXMLName()) != 0)
Kitware Robot's avatar
Kitware Robot committed
783
  {
784 785 786 787 788
    // before totally giving up, check to see if the input selection can be
    // converted to the same type as the output.
    std::string inputType = input->GetXMLName();
    std::string outputType = output->GetXMLName();

Kitware Robot's avatar
Kitware Robot committed
789 790 791 792 793
    if ((inputType == "GlobalIDSelectionSource" && outputType == "IDSelectionSource") ||
      (inputType == "GlobalIDSelectionSource" && outputType == "CompositeDataIDSelectionSource") ||
      (inputType == "IDSelectionSource" && outputType == "GlobalIDSelectionSource") ||
      (inputType == "CompositeDataIDSelectionSource" && outputType == "GlobalIDSelectionSource"))
    {
794 795
      int type = vtkSelectionNode::INDICES;
      if (outputType == "GlobalIDSelectionSource")
Kitware Robot's avatar
Kitware Robot committed
796
      {
797
        type = vtkSelectionNode::GLOBALIDS;
Kitware Robot's avatar
Kitware Robot committed
798
      }
799 800 801

      // Conversion is possible!.
      tempInput.TakeReference(vtkSMSourceProxy::SafeDownCast(
Kitware Robot's avatar
Kitware Robot committed
802
        vtkSMSelectionHelper::ConvertSelection(type, input, dataSource, dataPort)));
803
      input = tempInput;
Kitware Robot's avatar
Kitware Robot committed
804
    }
805
    else
Kitware Robot's avatar
Kitware Robot committed
806
    {