Salome HOME
PR: debug SMDS memimp
[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
60         typedef enum {lookHoleStart, lookHoleEnd, lookBlocEnd} enumState;
61         enumState compactState = lookHoleStart;
62
63 //      if (this->Links)
64 //      {
65 //              this->Links->UnRegister(this);
66 //              this->Links = 0;
67 //      }
68
69         // --- if newNodeSize, create a new compacted vtkPoints
70
71         vtkPoints *newPoints = 0;
72         if (newNodeSize)
73         {
74                 MESSAGE("-------------- compactGrid, newNodeSize");
75                 newPoints = vtkPoints::New();
76                 newPoints->Initialize();
77                 newPoints->Allocate(newNodeSize);
78                 newPoints->SetNumberOfPoints(newNodeSize);
79                 int oldNodeSize = idNodesOldToNew.size();
80
81                 for (int i=0; i< oldNodeSize; i++)
82                 {
83                         switch(compactState)
84                         {
85                         case lookHoleStart:
86                                 if (idNodesOldToNew[i] < 0)
87                                 {
88                                         MESSAGE("-------------- newNodeSize, startHole " << i <<  " " << oldNodeSize);
89                                         startHole = i;
90                                         compactState = lookHoleEnd;
91                                 }
92                                 break;
93                         case lookHoleEnd:
94                                 if (idNodesOldToNew[i] >= 0)
95                                 {
96                                         MESSAGE("-------------- newNodeSize, endHole " << i <<  " " << oldNodeSize);
97                                         endHole = i;
98                                         startBloc = i;
99                                         compactState = lookBlocEnd;
100                                 }
101                                 break;
102                         case lookBlocEnd:
103                                 if (idNodesOldToNew[i] < 0) endBloc = i; // see nbPoints below
104                                 else if (i == (oldNodeSize-1)) endBloc = i+1;
105                                 if (endBloc)
106                                 {
107                                         MESSAGE("-------------- newNodeSize, endbloc " << endBloc <<  " " << oldNodeSize);
108                                         void *target = newPoints->GetVoidPointer(3*alreadyCopied);
109                                         void *source = this->Points->GetVoidPointer(3*startBloc);
110                                         int nbPoints = endBloc - startBloc;
111                                         memcpy(target, source, 3*sizeof(float)*nbPoints);
112                                         for (int j=startBloc; j<endBloc; j++)
113                                                 idNodesOldToNew[j] = alreadyCopied++;
114                                         compactState = lookHoleStart;
115                                         startHole = i;
116                                         endHole = 0;
117                                         startBloc = 0;
118                                         endBloc = 0;
119                                 }
120                                 break;
121                         }
122                 }
123                 if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew
124                 {
125                         MESSAGE("------------- newNodeSize, shorter " << oldNodeSize)
126                         void *target = newPoints->GetVoidPointer(0);
127                         void *source = this->Points->GetVoidPointer(0);
128                         int nbPoints = newNodeSize;
129                         memcpy(target, source, 3*sizeof(float)*nbPoints);
130                 }
131         }
132
133         // --- create new compacted Connectivity, Locations and Types
134
135     int oldCellSize = this->Types->GetNumberOfTuples();
136
137         vtkCellArray *newConnectivity = vtkCellArray::New();
138         newConnectivity->Initialize();
139         int oldCellDataSize = this->Connectivity->GetData()->GetSize();
140         newConnectivity->Allocate(oldCellDataSize);
141         MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
142
143         vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
144         newTypes->Initialize();
145         //newTypes->Allocate(oldCellSize);
146         newTypes->SetNumberOfValues(newCellSize);
147
148         vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
149         newLocations->Initialize();
150         //newLocations->Allocate(oldCellSize);
151         newLocations->SetNumberOfValues(newCellSize);
152
153         startHole = 0;
154         endHole = 0;
155         startBloc = 0;
156         endBloc = 0;
157         alreadyCopied = 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                         }
174                         break;
175                 case lookHoleEnd:
176                         if (this->Types->GetValue(i) != VTK_EMPTY_CELL)
177                         {
178                         MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize);
179                                 endHole = i;
180                                 startBloc = i;
181                                 compactState = lookBlocEnd;
182                         }
183                         break;
184                 case lookBlocEnd:
185                         if (this->Types->GetValue(i) == VTK_EMPTY_CELL) endBloc =i;
186                         else if (i == (oldCellSize-1)) endBloc = i+1;
187                         if (endBloc)
188                         {
189                         MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize);
190                                 for (int j=startBloc; j<endBloc; j++)
191                                 {
192                                         newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
193                                         idCellsOldToNew[j] = alreadyCopied;
194                                         vtkIdType oldLoc = this->Locations->GetValue(j);
195                                         vtkIdType nbpts;
196                                         vtkIdType *oldPtsCell = 0;
197                                         this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
198                                         for (int l=0; l<nbpts; l++)
199                                         {
200                                                 int oldval = oldPtsCell[l];
201                                                 pointsCell[l] = idNodesOldToNew[oldval];
202                                         }
203                                         int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell);
204                                         int newLoc = newConnectivity->GetInsertLocation(nbpts);
205                                         newLocations->SetValue(alreadyCopied, newLoc);
206                                         alreadyCopied++;
207                                 }
208                         compactState = lookHoleStart;
209                         }
210                         break;
211                 }
212     }
213     if (!alreadyCopied) // no hole, but shorter
214     {
215         MESSAGE(" -------- newCellSize, shorter " << oldCellSize);
216                 for (int j=0; j<oldCellSize; j++)
217                 {
218                         newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
219                         idCellsOldToNew[j] = alreadyCopied;
220                         vtkIdType oldLoc = this->Locations->GetValue(j);
221                         vtkIdType nbpts;
222                         vtkIdType *oldPtsCell = 0;
223                         this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
224                         //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
225                         for (int l=0; l<nbpts; l++)
226                         {
227                                 int oldval = oldPtsCell[l];
228                                 pointsCell[l] = idNodesOldToNew[oldval];
229                                 //MESSAGE("   " << oldval << " " << pointsCell[l]);
230                         }
231                         int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell);
232                         int newLoc = newConnectivity->GetInsertLocation(nbpts);
233                         //MESSAGE(newcnt << " " << newLoc);
234                         newLocations->SetValue(alreadyCopied, newLoc);
235                         alreadyCopied++;
236                 }
237     }
238
239     newConnectivity->Squeeze();
240     //newTypes->Squeeze();
241     //newLocations->Squeeze();
242
243     if (newNodeSize)
244     {
245         MESSAGE("------- newNodeSize, setPoints");
246         this->SetPoints(newPoints);
247     }
248     this->SetCells(newTypes, newLocations, newConnectivity);
249     this->BuildLinks();
250 }