Salome HOME
PR: debug gui display
[modules/smesh.git] / src / SMDS / SMDS_UnstructuredGrid.cxx
1
2
3 #include "SMDS_UnstructuredGrid.hxx"
4 #include "utilities.h"
5
6 #include <vtkCellArray.h>
7 #include <vtkCellLinks.h>
8 #include <vtkIdTypeArray.h>
9 #include <vtkUnsignedCharArray.h>
10
11 #include <list>
12
13 using namespace std;
14
15 SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New()
16 {
17         MESSAGE("SMDS_UnstructuredGrid::New");
18         return new SMDS_UnstructuredGrid();
19 }
20
21 SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() : vtkUnstructuredGrid()
22 {
23 }
24
25 SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid()
26 {
27 }
28
29
30 unsigned long SMDS_UnstructuredGrid::GetMTime()
31 {
32         unsigned long mtime = vtkUnstructuredGrid::GetMTime();
33         MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime);
34         return mtime;
35 }
36
37 void SMDS_UnstructuredGrid::Update()
38 {
39         MESSAGE("SMDS_UnstructuredGrid::Update");
40         return vtkUnstructuredGrid::Update();
41 }
42
43 void SMDS_UnstructuredGrid::UpdateInformation()
44 {
45         MESSAGE("SMDS_UnstructuredGrid::UpdateInformation");
46         return vtkUnstructuredGrid::UpdateInformation();
47 }
48
49 void SMDS_UnstructuredGrid::compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
50                                                                                 std::vector<int>& idCellsOldToNew, int newCellSize)
51 {
52         MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);
53
54         int startHole = 0;
55         int endHole = 0;
56         int startBloc = 0;
57         int endBloc = 0;
58         int alreadyCopied = 0;
59         int holes = 0;
60
61         typedef enum {lookHoleStart, lookHoleEnd, lookBlocEnd} enumState;
62         enumState compactState = lookHoleStart;
63
64 //      if (this->Links)
65 //      {
66 //              this->Links->UnRegister(this);
67 //              this->Links = 0;
68 //      }
69
70         // --- if newNodeSize, create a new compacted vtkPoints
71
72         vtkPoints *newPoints = 0;
73         if (newNodeSize)
74         {
75                 MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize);
76                 newPoints = vtkPoints::New();
77                 newPoints->Initialize();
78                 newPoints->Allocate(newNodeSize);
79                 newPoints->SetNumberOfPoints(newNodeSize);
80                 int oldNodeSize = idNodesOldToNew.size();
81
82                 for (int i=0; i< oldNodeSize; i++)
83                 {
84                         switch(compactState)
85                         {
86                         case lookHoleStart:
87                                 if (idNodesOldToNew[i] < 0)
88                                 {
89                                         MESSAGE("-------------- newNodeSize, startHole " << i <<  " " << oldNodeSize);
90                                         startHole = i;
91                                         if (!alreadyCopied) // copy the first bloc
92                                         {
93                                                 MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize);
94                                                 copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole);
95                                         }
96                                         compactState = lookHoleEnd;
97                                 }
98                                 break;
99                         case lookHoleEnd:
100                                 if (idNodesOldToNew[i] >= 0)
101                                 {
102                                         MESSAGE("-------------- newNodeSize, endHole " << i <<  " " << oldNodeSize);
103                                         endHole = i;
104                                         startBloc = i;
105                                         compactState = lookBlocEnd;
106                                 }
107                                 break;
108                         case lookBlocEnd:
109                                 if (idNodesOldToNew[i] < 0) endBloc = i; // see nbPoints below
110                                 else if (i == (oldNodeSize-1)) endBloc = i+1;
111                                 if (endBloc)
112                                 {
113                                         MESSAGE("-------------- newNodeSize, endbloc " << endBloc <<  " " << oldNodeSize);
114                                         copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc);
115                                         compactState = lookHoleStart;
116                                         startHole = i;
117                                         endHole = 0;
118                                         startBloc = 0;
119                                         endBloc = 0;
120                                 }
121                                 break;
122                         }
123                 }
124                 if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew
125                 {
126                         MESSAGE("------------- newNodeSize, shorter " << oldNodeSize);
127                         copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize);
128                 }
129                 newPoints->Squeeze();
130         }
131
132         // --- create new compacted Connectivity, Locations and Types
133
134     int oldCellSize = this->Types->GetNumberOfTuples();
135
136         vtkCellArray *newConnectivity = vtkCellArray::New();
137         newConnectivity->Initialize();
138         int oldCellDataSize = this->Connectivity->GetData()->GetSize();
139         newConnectivity->Allocate(oldCellDataSize);
140         MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
141
142         vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
143         newTypes->Initialize();
144         //newTypes->Allocate(oldCellSize);
145         newTypes->SetNumberOfValues(newCellSize);
146
147         vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
148         newLocations->Initialize();
149         //newLocations->Allocate(oldCellSize);
150         newLocations->SetNumberOfValues(newCellSize);
151
152         startHole = 0;
153         endHole = 0;
154         startBloc = 0;
155         endBloc = 0;
156         alreadyCopied = 0;
157         holes = 0;
158         compactState = lookHoleStart;
159
160         vtkIdType tmpid[50];
161         vtkIdType *pointsCell =&tmpid[0]; // --- points id to fill a new cell
162
163     for (int i=0; i<oldCellSize; i++)
164     {
165                 switch(compactState)
166                 {
167                 case lookHoleStart:
168                         if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
169                         {
170                     MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize);
171                                 startHole = i;
172                                 compactState = lookHoleEnd;
173                                 if (!alreadyCopied) // copy the first bloc
174                                 {
175                                         MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize);
176                                         copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, startHole);
177                                 }
178                         }
179                         break;
180                 case lookHoleEnd:
181                         if (this->Types->GetValue(i) != VTK_EMPTY_CELL)
182                         {
183                     MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize);
184                                 endHole = i;
185                                 startBloc = i;
186                                 compactState = lookBlocEnd;
187                                 holes += endHole - startHole;
188                                 //alreadyCopied = startBloc -holes;
189                         }
190                         break;
191                 case lookBlocEnd:
192                         endBloc =0;
193                         if (this->Types->GetValue(i) == VTK_EMPTY_CELL) endBloc =i;
194                         else if (i == (oldCellSize-1)) endBloc = i+1;
195                         if (endBloc)
196                         {
197                         MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize);
198                         copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, startBloc, endBloc);
199                         compactState = lookHoleStart;
200                         }
201                         break;
202                 }
203     }
204     if (!alreadyCopied) // no hole, but shorter
205     {
206         MESSAGE(" -------- newCellSize, shorter " << oldCellSize);
207         copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0, oldCellSize);
208     }
209
210     newConnectivity->Squeeze();
211     //newTypes->Squeeze();
212     //newLocations->Squeeze();
213
214     if (newNodeSize)
215     {
216         MESSAGE("------- newNodeSize, setPoints");
217         this->SetPoints(newPoints);
218         MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints());
219     }
220     this->SetCells(newTypes, newLocations, newConnectivity);
221     this->BuildLinks();
222 }
223
224 void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints,
225                 std::vector<int>& idNodesOldToNew,
226                 int& alreadyCopied,
227                 int start,
228                 int end)
229 {
230         MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
231         void *target = newPoints->GetVoidPointer(3*alreadyCopied);
232         void *source = this->Points->GetVoidPointer(3*start);
233         int nbPoints = end - start;
234         if (nbPoints >0)
235         {
236                 memcpy(target, source, 3*sizeof(float)*nbPoints);
237                 for (int j=start; j<end; j++)
238                         idNodesOldToNew[j] = alreadyCopied++;
239         }
240 }
241
242 void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes,
243                 std::vector<int>& idCellsOldToNew,
244                 std::vector<int>& idNodesOldToNew,
245                 vtkCellArray* newConnectivity,
246                 vtkIdTypeArray* newLocations,
247                 vtkIdType* pointsCell,
248                 int& alreadyCopied,
249                 int start,
250                 int end)
251 {
252         MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
253         for (int j=start; j<end; j++)
254         {
255                 newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
256                 idCellsOldToNew[j] = alreadyCopied;
257                 vtkIdType oldLoc = this->Locations->GetValue(j);
258                 vtkIdType nbpts;
259                 vtkIdType *oldPtsCell = 0;
260                 this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
261                 //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
262                 for (int l=0; l<nbpts; l++)
263                 {
264                         int oldval = oldPtsCell[l];
265                         pointsCell[l] = idNodesOldToNew[oldval];
266                         //MESSAGE("   " << oldval << " " << pointsCell[l]);
267                 }
268                 int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell);
269                 int newLoc = newConnectivity->GetInsertLocation(nbpts);
270                 //MESSAGE(newcnt << " " << newLoc);
271                 newLocations->SetValue(alreadyCopied, newLoc);
272                 alreadyCopied++;
273         }
274 }