1 /*=========================================================================
2 
3   Program:   Visualization Toolkit
4   Module:    vtkCPExodusIIElementBlock.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 #include "vtkCPExodusIIElementBlock.h"
17 
18 #include "vtkCellType.h"
19 #include "vtkCellTypes.h"
20 #include "vtkGenericCell.h"
21 #include "vtkIdTypeArray.h"
22 #include "vtkObjectFactory.h"
23 #include "vtkPoints.h"
24 
25 #include <algorithm>
26 
27 //------------------------------------------------------------------------------
28 vtkStandardNewMacro(vtkCPExodusIIElementBlock);
29 vtkStandardNewMacro(vtkCPExodusIIElementBlockImpl);
30 
31 //------------------------------------------------------------------------------
PrintSelf(ostream & os,vtkIndent indent)32 void vtkCPExodusIIElementBlockImpl::PrintSelf(ostream& os, vtkIndent indent)
33 {
34   this->Superclass::PrintSelf(os, indent);
35   os << indent << "Elements: " << this->Elements << endl;
36   os << indent << "CellType: " << vtkCellTypes::GetClassNameFromTypeId(this->CellType) << endl;
37   os << indent << "CellSize: " << this->CellSize << endl;
38   os << indent << "NumberOfCells: " << this->NumberOfCells << endl;
39 }
40 
41 //------------------------------------------------------------------------------
SetExodusConnectivityArray(int * elements,const std::string & type,int numElements,int nodesPerElement)42 bool vtkCPExodusIIElementBlockImpl::SetExodusConnectivityArray(
43   int* elements, const std::string& type, int numElements, int nodesPerElement)
44 {
45   if (!elements)
46   {
47     return false;
48   }
49 
50   // Try to figure out the vtk cell type:
51   if (type.size() < 3)
52   {
53     vtkErrorMacro(<< "Element type too short, expected at least 3 char: " << type);
54     return false;
55   }
56   std::string typekey = type.substr(0, 3);
57   std::transform(typekey.begin(), typekey.end(), typekey.begin(), ::toupper);
58   if (typekey == "CIR" || typekey == "SPH")
59   {
60     this->CellType = VTK_VERTEX;
61   }
62   else if (typekey == "TRU" || typekey == "BEA")
63   {
64     this->CellType = VTK_LINE;
65   }
66   else if (typekey == "TRI")
67   {
68     this->CellType = VTK_TRIANGLE;
69   }
70   else if (typekey == "QUA" || typekey == "SHE")
71   {
72     this->CellType = VTK_QUAD;
73   }
74   else if (typekey == "TET")
75   {
76     this->CellType = VTK_TETRA;
77   }
78   else if (typekey == "WED")
79   {
80     this->CellType = VTK_WEDGE;
81   }
82   else if (typekey == "HEX")
83   {
84     this->CellType = VTK_HEXAHEDRON;
85   }
86   else
87   {
88     vtkErrorMacro(<< "Unknown cell type: " << type);
89     return false;
90   }
91 
92   this->CellSize = static_cast<vtkIdType>(nodesPerElement);
93   this->NumberOfCells = static_cast<vtkIdType>(numElements);
94   this->Elements = elements;
95   this->Modified();
96 
97   return true;
98 }
99 
100 //------------------------------------------------------------------------------
GetNumberOfCells()101 vtkIdType vtkCPExodusIIElementBlockImpl::GetNumberOfCells()
102 {
103   return this->NumberOfCells;
104 }
105 
106 //------------------------------------------------------------------------------
GetCellType(vtkIdType)107 int vtkCPExodusIIElementBlockImpl::GetCellType(vtkIdType)
108 {
109   return this->CellType;
110 }
111 
112 //------------------------------------------------------------------------------
GetCellPoints(vtkIdType cellId,vtkIdList * ptIds)113 void vtkCPExodusIIElementBlockImpl::GetCellPoints(vtkIdType cellId, vtkIdList* ptIds)
114 {
115   ptIds->SetNumberOfIds(this->CellSize);
116 
117   std::transform(
118     this->GetElementStart(cellId), this->GetElementEnd(cellId), ptIds->GetPointer(0), NodeToPoint);
119 }
120 
121 //------------------------------------------------------------------------------
GetPointCells(vtkIdType ptId,vtkIdList * cellIds)122 void vtkCPExodusIIElementBlockImpl::GetPointCells(vtkIdType ptId, vtkIdList* cellIds)
123 {
124   const int targetElement = PointToNode(ptId);
125   int* element = this->GetStart();
126   int* elementEnd = this->GetEnd();
127 
128   cellIds->Reset();
129 
130   element = std::find(element, elementEnd, targetElement);
131   while (element != elementEnd)
132   {
133     cellIds->InsertNextId(static_cast<vtkIdType>((element - this->Elements) / this->CellSize));
134     element = std::find(element, elementEnd, targetElement);
135   }
136 }
137 
138 //------------------------------------------------------------------------------
GetMaxCellSize()139 int vtkCPExodusIIElementBlockImpl::GetMaxCellSize()
140 {
141   return this->CellSize;
142 }
143 
144 //------------------------------------------------------------------------------
GetIdsOfCellsOfType(int type,vtkIdTypeArray * array)145 void vtkCPExodusIIElementBlockImpl::GetIdsOfCellsOfType(int type, vtkIdTypeArray* array)
146 {
147   array->Reset();
148   if (type == this->CellType)
149   {
150     array->SetNumberOfComponents(1);
151     array->Allocate(this->NumberOfCells);
152     for (vtkIdType i = 0; i < this->NumberOfCells; ++i)
153     {
154       array->InsertNextValue(i);
155     }
156   }
157 }
158 
159 //------------------------------------------------------------------------------
IsHomogeneous()160 int vtkCPExodusIIElementBlockImpl::IsHomogeneous()
161 {
162   return 1;
163 }
164 
165 //------------------------------------------------------------------------------
Allocate(vtkIdType,int)166 void vtkCPExodusIIElementBlockImpl::Allocate(vtkIdType, int)
167 {
168   vtkErrorMacro("Read only container.");
169 }
170 
171 //------------------------------------------------------------------------------
InsertNextCell(int,vtkIdList *)172 vtkIdType vtkCPExodusIIElementBlockImpl::InsertNextCell(int, vtkIdList*)
173 {
174   vtkErrorMacro("Read only container.");
175   return -1;
176 }
177 
178 //------------------------------------------------------------------------------
InsertNextCell(int,vtkIdType,const vtkIdType[])179 vtkIdType vtkCPExodusIIElementBlockImpl::InsertNextCell(int, vtkIdType, const vtkIdType[])
180 {
181   vtkErrorMacro("Read only container.");
182   return -1;
183 }
184 
185 //------------------------------------------------------------------------------
InsertNextCell(int,vtkIdType,const vtkIdType[],vtkIdType,const vtkIdType[])186 vtkIdType vtkCPExodusIIElementBlockImpl::InsertNextCell(
187   int, vtkIdType, const vtkIdType[], vtkIdType, const vtkIdType[])
188 {
189   vtkErrorMacro("Read only container.");
190   return -1;
191 }
192 
193 //------------------------------------------------------------------------------
ReplaceCell(vtkIdType,int,const vtkIdType[])194 void vtkCPExodusIIElementBlockImpl::ReplaceCell(vtkIdType, int, const vtkIdType[])
195 {
196   vtkErrorMacro("Read only container.");
197 }
198 
199 //------------------------------------------------------------------------------
vtkCPExodusIIElementBlockImpl()200 vtkCPExodusIIElementBlockImpl::vtkCPExodusIIElementBlockImpl()
201   : Elements(nullptr)
202   , CellType(VTK_EMPTY_CELL)
203   , CellSize(0)
204   , NumberOfCells(0)
205 {
206 }
207 
208 //------------------------------------------------------------------------------
~vtkCPExodusIIElementBlockImpl()209 vtkCPExodusIIElementBlockImpl::~vtkCPExodusIIElementBlockImpl()
210 {
211   delete[] this->Elements;
212 }
213