1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkAddMembershipArray.cxx
5 
6   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7   All rights reserved.
8   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10      This software is distributed WITHOUT ANY WARRANTY; without even
11      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12      PURPOSE.  See the above copyright notice for more information.
13 
14 =========================================================================*/
15 /*-------------------------------------------------------------------------
16   Copyright 2008 Sandia Corporation.
17   Under the terms of Contract DE-AC04-94AL85000 with Sandia Corporation,
18   the U.S. Government retains certain rights in this software.
19 -------------------------------------------------------------------------*/
20 
21 #include "vtkAddMembershipArray.h"
22 
23 #include "vtkAbstractArray.h"
24 #include "vtkAnnotation.h"
25 #include "vtkAnnotationLayers.h"
26 #include "vtkBitArray.h"
27 #include "vtkCellData.h"
28 #include "vtkConvertSelection.h"
29 #include "vtkDataObject.h"
30 #include "vtkDataSet.h"
31 #include "vtkDataSetAttributes.h"
32 #include "vtkDoubleArray.h"
33 #include "vtkGraph.h"
34 #include "vtkIdTypeArray.h"
35 #include "vtkInformation.h"
36 #include "vtkInformationVector.h"
37 #include "vtkIntArray.h"
38 #include "vtkObjectFactory.h"
39 #include "vtkPointData.h"
40 #include "vtkSelection.h"
41 #include "vtkSelectionNode.h"
42 #include "vtkSmartPointer.h"
43 #include "vtkTable.h"
44 #include "vtkVariant.h"
45 #include "vtkVariantArray.h"
46 
47 vtkStandardNewMacro(vtkAddMembershipArray);
48 vtkCxxSetObjectMacro(vtkAddMembershipArray, InputValues, vtkAbstractArray);
49 
50 //------------------------------------------------------------------------------
vtkAddMembershipArray()51 vtkAddMembershipArray::vtkAddMembershipArray()
52 {
53   this->FieldType = -1;
54   this->OutputArrayName = nullptr;
55   this->SetOutputArrayName("membership");
56   this->InputArrayName = nullptr;
57   this->InputValues = nullptr;
58   this->SetNumberOfInputPorts(3);
59 }
60 
61 //------------------------------------------------------------------------------
~vtkAddMembershipArray()62 vtkAddMembershipArray::~vtkAddMembershipArray()
63 {
64   this->SetOutputArrayName(nullptr);
65   this->SetInputArrayName(nullptr);
66 }
67 
68 //------------------------------------------------------------------------------
FillInputPortInformation(int port,vtkInformation * info)69 int vtkAddMembershipArray::FillInputPortInformation(int port, vtkInformation* info)
70 {
71   if (port == 0)
72   {
73     info->Remove(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE());
74     info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkGraph");
75     info->Append(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkTable");
76   }
77   else if (port == 1)
78   {
79     info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkSelection");
80     info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
81   }
82   else if (port == 2)
83   {
84     info->Set(vtkAlgorithm::INPUT_IS_OPTIONAL(), 1);
85     info->Set(vtkAlgorithm::INPUT_REQUIRED_DATA_TYPE(), "vtkAnnotationLayers");
86     return 1;
87   }
88 
89   return 1;
90 }
91 
92 //------------------------------------------------------------------------------
RequestData(vtkInformation *,vtkInformationVector ** inputVector,vtkInformationVector * outputVector)93 int vtkAddMembershipArray::RequestData(
94   vtkInformation*, vtkInformationVector** inputVector, vtkInformationVector* outputVector)
95 {
96   vtkInformation* inInfo = inputVector[0]->GetInformationObject(0);
97   vtkDataObject* input = inInfo->Get(vtkDataObject::DATA_OBJECT());
98   vtkSelection* inputSelection = vtkSelection::GetData(inputVector[1]);
99   vtkAnnotationLayers* inputAnnotations = vtkAnnotationLayers::GetData(inputVector[2]);
100   vtkInformation* outputInfo = outputVector->GetInformationObject(0);
101   vtkDataObject* output = outputInfo->Get(vtkDataObject::DATA_OBJECT());
102   vtkGraph* graph = vtkGraph::SafeDownCast(output);
103   vtkTable* table = vtkTable::SafeDownCast(output);
104 
105   output->ShallowCopy(input);
106 
107   if (!inputSelection)
108   {
109     if (!this->InputArrayName || !this->InputValues)
110       return 1;
111 
112     vtkDataSetAttributes* ds = nullptr;
113     switch (this->FieldType)
114     {
115       case vtkAddMembershipArray::VERTEX_DATA:
116         if (graph)
117         {
118           ds = graph->GetVertexData();
119         }
120         break;
121       case vtkAddMembershipArray::EDGE_DATA:
122         if (graph)
123         {
124           ds = graph->GetEdgeData();
125         }
126         break;
127       case vtkAddMembershipArray::ROW_DATA:
128         if (table)
129         {
130           ds = table->GetRowData();
131         }
132         break;
133     }
134 
135     if (!ds)
136     {
137       vtkErrorMacro("Unsupported input field type.");
138       return 0;
139     }
140 
141     vtkIntArray* vals = vtkIntArray::New();
142     vals->SetNumberOfTuples(ds->GetNumberOfTuples());
143     vals->SetNumberOfComponents(1);
144     vals->SetName(this->OutputArrayName);
145     vals->FillComponent(0, 0);
146 
147     vtkAbstractArray* inputArray = ds->GetAbstractArray(this->InputArrayName);
148     if (inputArray && this->InputValues)
149     {
150       for (vtkIdType i = 0; i < inputArray->GetNumberOfTuples(); ++i)
151       {
152         vtkVariant v(0);
153         switch (inputArray->GetDataType())
154         {
155           vtkExtraExtendedTemplateMacro(v = *static_cast<VTK_TT*>(inputArray->GetVoidPointer(i)));
156         }
157         if (this->InputValues->LookupValue(v) >= 0)
158         {
159           vals->SetValue(i, 1);
160         }
161         else
162         {
163           vals->SetValue(i, 0);
164         }
165       }
166     }
167 
168     ds->AddArray(vals);
169 
170     vals->Delete();
171 
172     return 1;
173   }
174 
175   vtkSmartPointer<vtkSelection> selection = vtkSmartPointer<vtkSelection>::New();
176   selection->DeepCopy(inputSelection);
177 
178   if (inputAnnotations)
179   {
180     for (unsigned int i = 0; i < inputAnnotations->GetNumberOfAnnotations(); ++i)
181     {
182       vtkAnnotation* a = inputAnnotations->GetAnnotation(i);
183       if (a->GetInformation()->Has(vtkAnnotation::ENABLE()) &&
184         a->GetInformation()->Get(vtkAnnotation::ENABLE()) == 0)
185       {
186         continue;
187       }
188       selection->Union(a->GetSelection());
189     }
190   }
191 
192   vtkSmartPointer<vtkIdTypeArray> rowList = vtkSmartPointer<vtkIdTypeArray>::New();
193   vtkSmartPointer<vtkIdTypeArray> edgeList = vtkSmartPointer<vtkIdTypeArray>::New();
194   vtkSmartPointer<vtkIdTypeArray> vertexList = vtkSmartPointer<vtkIdTypeArray>::New();
195 
196   if (graph)
197   {
198     vtkConvertSelection::GetSelectedVertices(selection, graph, vertexList);
199     vtkConvertSelection::GetSelectedEdges(selection, graph, edgeList);
200   }
201   else if (table)
202   {
203     vtkConvertSelection::GetSelectedRows(selection, table, rowList);
204   }
205 
206   if (vertexList->GetNumberOfTuples() != 0)
207   {
208     vtkSmartPointer<vtkIntArray> vals = vtkSmartPointer<vtkIntArray>::New();
209     vals->SetNumberOfTuples(graph->GetVertexData()->GetNumberOfTuples());
210     vals->SetNumberOfComponents(1);
211     vals->SetName(this->OutputArrayName);
212     vals->FillComponent(0, 0);
213     vtkIdType numSelectedVerts = vertexList->GetNumberOfTuples();
214     for (vtkIdType i = 0; i < numSelectedVerts; ++i)
215     {
216       vals->SetValue(vertexList->GetValue(i), 1);
217     }
218     graph->GetVertexData()->AddArray(vals);
219   }
220 
221   if (edgeList->GetNumberOfTuples() != 0)
222   {
223     vtkSmartPointer<vtkIntArray> vals = vtkSmartPointer<vtkIntArray>::New();
224     vals->SetNumberOfTuples(graph->GetEdgeData()->GetNumberOfTuples());
225     vals->SetNumberOfComponents(1);
226     vals->SetName(this->OutputArrayName);
227     vals->FillComponent(0, 0);
228     vtkIdType numSelectedEdges = edgeList->GetNumberOfTuples();
229     for (vtkIdType i = 0; i < numSelectedEdges; ++i)
230     {
231       vals->SetValue(edgeList->GetValue(i), 1);
232     }
233     graph->GetEdgeData()->AddArray(vals);
234   }
235 
236   if (rowList->GetNumberOfTuples() != 0)
237   {
238     vtkSmartPointer<vtkIntArray> vals = vtkSmartPointer<vtkIntArray>::New();
239     vals->SetNumberOfTuples(table->GetRowData()->GetNumberOfTuples());
240     vals->SetNumberOfComponents(1);
241     vals->SetName(this->OutputArrayName);
242     vals->FillComponent(0, 0);
243     vtkIdType numSelectedRows = rowList->GetNumberOfTuples();
244     for (vtkIdType i = 0; i < numSelectedRows; ++i)
245     {
246       vals->SetValue(rowList->GetValue(i), 1);
247     }
248     table->GetRowData()->AddArray(vals);
249   }
250 
251   return 1;
252 }
253 
254 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)255 void vtkAddMembershipArray::PrintSelf(ostream& os, vtkIndent indent)
256 {
257   this->Superclass::PrintSelf(os, indent);
258   os << indent << "FieldType: " << this->FieldType << endl;
259   os << indent << "OutputArrayName: " << (this->OutputArrayName ? this->OutputArrayName : "(none)")
260      << endl;
261   os << indent << "InputArrayName: " << (this->InputArrayName ? this->InputArrayName : "(none)")
262      << endl;
263   if (this->InputValues)
264   {
265     os << indent << "Input Values :" << endl;
266     int num = this->InputValues->GetNumberOfTuples();
267     for (int idx = 0; idx < num; ++idx)
268     {
269       vtkVariant v(0);
270       switch (this->InputValues->GetDataType())
271       {
272         vtkExtraExtendedTemplateMacro(
273           v = *static_cast<VTK_TT*>(this->InputValues->GetVoidPointer(idx)));
274       }
275       os << v.ToString() << endl;
276     }
277   }
278 }
279