00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020 #define CHRONODEF
00021 #include "SMDS_UnstructuredGrid.hxx"
00022 #include "SMDS_Mesh.hxx"
00023 #include "SMDS_MeshInfo.hxx"
00024 #include "SMDS_Downward.hxx"
00025 #include "SMDS_MeshVolume.hxx"
00026
00027 #include "utilities.h"
00028
00029 #include <vtkCellArray.h>
00030 #include <vtkCellLinks.h>
00031 #include <vtkIdTypeArray.h>
00032 #include <vtkUnsignedCharArray.h>
00033
00034 #include <list>
00035 #include <climits>
00036
00037 using namespace std;
00038
00039 SMDS_CellLinks* SMDS_CellLinks::New()
00040 {
00041 MESSAGE("SMDS_CellLinks::New");
00042 return new SMDS_CellLinks();
00043 }
00044
00045 vtkCellLinks::Link* SMDS_CellLinks::ResizeL(vtkIdType sz)
00046 {
00047 return vtkCellLinks::Resize(sz);
00048 }
00049
00050 vtkIdType SMDS_CellLinks::GetLinksSize()
00051 {
00052 return this->Size;
00053 }
00054
00055 SMDS_CellLinks::SMDS_CellLinks() :
00056 vtkCellLinks()
00057 {
00058 }
00059
00060 SMDS_CellLinks::~SMDS_CellLinks()
00061 {
00062 }
00063
00064 SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New()
00065 {
00066 MESSAGE("SMDS_UnstructuredGrid::New");
00067 return new SMDS_UnstructuredGrid();
00068 }
00069
00070 SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() :
00071 vtkUnstructuredGrid()
00072 {
00073 _cellIdToDownId.clear();
00074 _downTypes.clear();
00075 _downArray.clear();
00076 _mesh = 0;
00077 }
00078
00079 SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid()
00080 {
00081 }
00082
00083 unsigned long SMDS_UnstructuredGrid::GetMTime()
00084 {
00085 unsigned long mtime = vtkUnstructuredGrid::GetMTime();
00086 MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime);
00087 return mtime;
00088 }
00089
00090 void SMDS_UnstructuredGrid::Update()
00091 {
00092 MESSAGE("SMDS_UnstructuredGrid::Update");
00093 return vtkUnstructuredGrid::Update();
00094 }
00095
00096 void SMDS_UnstructuredGrid::UpdateInformation()
00097 {
00098 MESSAGE("SMDS_UnstructuredGrid::UpdateInformation");
00099 return vtkUnstructuredGrid::UpdateInformation();
00100 }
00101
00102 vtkPoints* SMDS_UnstructuredGrid::GetPoints()
00103 {
00104
00105
00106 return this->Points;
00107 }
00108
00109
00110 int SMDS_UnstructuredGrid::InsertNextLinkedCell(int type, int npts, vtkIdType *pts)
00111 {
00112 if (type != VTK_POLYHEDRON)
00113 return vtkUnstructuredGrid::InsertNextLinkedCell(type, npts, pts);
00114
00115
00116
00117 int cellid = this->InsertNextCell(type, npts, pts);
00118
00119 set<vtkIdType> setOfNodes;
00120 setOfNodes.clear();
00121 int nbfaces = npts;
00122 int i = 0;
00123 for (int nf = 0; nf < nbfaces; nf++)
00124 {
00125 int nbnodes = pts[i];
00126 i++;
00127 for (int k = 0; k < nbnodes; k++)
00128 {
00129
00130 setOfNodes.insert(pts[i]);
00131 i++;
00132 }
00133 }
00134
00135 set<vtkIdType>::iterator it = setOfNodes.begin();
00136 for (; it != setOfNodes.end(); ++it)
00137 {
00138
00139 this->Links->ResizeCellList(*it, 1);
00140 this->Links->AddCellReference(cellid, *it);
00141 }
00142
00143 return cellid;
00144 }
00145
00146
00147 void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh)
00148 {
00149 _mesh = mesh;
00150 }
00151
00152 void SMDS_UnstructuredGrid::compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
00153 std::vector<int>& idCellsOldToNew, int newCellSize)
00154 {
00155 MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1);
00156 int alreadyCopied = 0;
00157
00158
00159
00160 vtkPoints *newPoints = vtkPoints::New();
00161 newPoints->SetDataType(VTK_DOUBLE);
00162 newPoints->SetNumberOfPoints(newNodeSize);
00163 if (newNodeSize)
00164 {
00165 MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize);
00166
00167
00168 int oldNodeSize = idNodesOldToNew.size();
00169
00170 int i = 0;
00171 while ( i < oldNodeSize )
00172 {
00173
00174 while ( i < oldNodeSize && idNodesOldToNew[i] < 0 )
00175 ++i;
00176 int startBloc = i;
00177
00178 while ( i < oldNodeSize && idNodesOldToNew[i] >= 0 )
00179 ++i;
00180 int endBloc = i;
00181 copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc);
00182 }
00183 newPoints->Squeeze();
00184 }
00185
00186
00187
00188 int oldCellSize = this->Types->GetNumberOfTuples();
00189
00190 vtkCellArray *newConnectivity = vtkCellArray::New();
00191 newConnectivity->Initialize();
00192 int oldCellDataSize = this->Connectivity->GetData()->GetSize();
00193 newConnectivity->Allocate(oldCellDataSize);
00194 MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
00195
00196 vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
00197 newTypes->Initialize();
00198 newTypes->SetNumberOfValues(newCellSize);
00199
00200 vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
00201 newLocations->Initialize();
00202 newLocations->SetNumberOfValues(newCellSize);
00203
00204
00205 vtkIdType tmpid[NBMAXNODESINCELL];
00206 vtkIdType *pointsCell = &tmpid[0];
00207
00208 alreadyCopied = 0;
00209 int i = 0;
00210 while ( i < oldCellSize )
00211 {
00212
00213 while ( i < oldCellSize && this->Types->GetValue(i) == VTK_EMPTY_CELL )
00214 ++i;
00215 int startBloc = i;
00216
00217 while ( i < oldCellSize && this->Types->GetValue(i) != VTK_EMPTY_CELL )
00218 ++i;
00219 int endBloc = i;
00220 if ( endBloc > startBloc )
00221 copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell,
00222 alreadyCopied, startBloc, endBloc);
00223 }
00224
00225 newConnectivity->Squeeze();
00226
00227 if (1)
00228 {
00229 MESSAGE("------- newNodeSize, setPoints");
00230 this->SetPoints(newPoints);
00231 MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints());
00232 }
00233
00234 if (this->FaceLocations)
00235 {
00236 vtkIdTypeArray *newFaceLocations = vtkIdTypeArray::New();
00237 newFaceLocations->Initialize();
00238 newFaceLocations->Allocate(newTypes->GetSize());
00239 vtkIdTypeArray *newFaces = vtkIdTypeArray::New();
00240 newFaces->Initialize();
00241 newFaces->Allocate(this->Faces->GetSize());
00242 for (int i = 0; i < oldCellSize; i++)
00243 {
00244 if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
00245 continue;
00246 int newCellId = idCellsOldToNew[i];
00247 if (newTypes->GetValue(newCellId) == VTK_POLYHEDRON)
00248 {
00249 newFaceLocations->InsertNextValue(newFaces->GetMaxId()+1);
00250 int oldFaceLoc = this->FaceLocations->GetValue(i);
00251 int nCellFaces = this->Faces->GetValue(oldFaceLoc++);
00252 newFaces->InsertNextValue(nCellFaces);
00253 for (int n=0; n<nCellFaces; n++)
00254 {
00255 int nptsInFace = this->Faces->GetValue(oldFaceLoc++);
00256 newFaces->InsertNextValue(nptsInFace);
00257 for (int k=0; k<nptsInFace; k++)
00258 {
00259 int oldpt = this->Faces->GetValue(oldFaceLoc++);
00260 newFaces->InsertNextValue(idNodesOldToNew[oldpt]);
00261 }
00262 }
00263 }
00264 else
00265 {
00266 newFaceLocations->InsertNextValue(-1);
00267 }
00268 }
00269 newFaceLocations->Squeeze();
00270 newFaces->Squeeze();
00271 newFaceLocations->Register(this);
00272 newFaces->Register(this);
00273 this->SetCells(newTypes, newLocations, newConnectivity, newFaceLocations, newFaces);
00274 newFaceLocations->Delete();
00275 newFaces->Delete();
00276 }
00277 else
00278 this->SetCells(newTypes, newLocations, newConnectivity, FaceLocations, Faces);
00279
00280 newPoints->Delete();
00281 newTypes->Delete();
00282 newLocations->Delete();
00283 newConnectivity->Delete();
00284 this->BuildLinks();
00285 }
00286
00287 void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied,
00288 int start, int end)
00289 {
00290 MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
00291 void *target = newPoints->GetVoidPointer(3 * alreadyCopied);
00292 void *source = this->Points->GetVoidPointer(3 * start);
00293 int nbPoints = end - start;
00294 if (nbPoints > 0)
00295 {
00296 memcpy(target, source, 3 * sizeof(double) * nbPoints);
00297 for (int j = start; j < end; j++)
00298 idNodesOldToNew[j] = alreadyCopied++;
00299 }
00300 }
00301
00302 void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew,
00303 std::vector<int>& idNodesOldToNew, vtkCellArray* newConnectivity,
00304 vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
00305 int start, int end)
00306 {
00307 MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
00308 for (int j = start; j < end; j++)
00309 {
00310 newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
00311 idCellsOldToNew[j] = alreadyCopied;
00312 vtkIdType oldLoc = this->Locations->GetValue(j);
00313 vtkIdType nbpts;
00314 vtkIdType *oldPtsCell = 0;
00315 this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
00316 assert(nbpts < NBMAXNODESINCELL);
00317
00318 for (int l = 0; l < nbpts; l++)
00319 {
00320 int oldval = oldPtsCell[l];
00321 pointsCell[l] = idNodesOldToNew[oldval];
00322
00323 }
00324 newConnectivity->InsertNextCell(nbpts, pointsCell);
00325 int newLoc = newConnectivity->GetInsertLocation(nbpts);
00326
00327 newLocations->SetValue(alreadyCopied, newLoc);
00328 alreadyCopied++;
00329 }
00330 }
00331
00332 int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId)
00333 {
00334 if((vtkCellId < 0) || (vtkCellId >= _cellIdToDownId.size()))
00335 {
00336
00337
00338 return -1;
00339 }
00340 return _cellIdToDownId[vtkCellId];
00341 }
00342
00343 void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
00344 {
00345
00346 _cellIdToDownId[vtkCellId] = downId;
00347 }
00348
00349 void SMDS_UnstructuredGrid::CleanDownwardConnectivity()
00350 {
00351 for (int i = 0; i < _downArray.size(); i++)
00352 {
00353 if (_downArray[i])
00354 delete _downArray[i];
00355 _downArray[i] = 0;
00356 }
00357 _cellIdToDownId.clear();
00358 }
00359
00364 void SMDS_UnstructuredGrid::BuildDownwardConnectivity(bool withEdges)
00365 {
00366 MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2);
00367
00368
00369
00370
00371 this->CleanDownwardConnectivity();
00372
00373
00374
00375 _downArray.resize(VTK_MAXTYPE + 1, 0);
00376
00377 _downArray[VTK_LINE] = new SMDS_DownEdge(this);
00378 _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this);
00379 _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this);
00380 _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this);
00381 _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this);
00382 _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this);
00383 _downArray[VTK_TETRA] = new SMDS_DownTetra(this);
00384 _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this);
00385 _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this);
00386 _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this);
00387 _downArray[VTK_WEDGE] = new SMDS_DownPenta(this);
00388 _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this);
00389 _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this);
00390 _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this);
00391
00392
00393
00394 const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo();
00395
00396 int nbLinTetra = meshInfo.NbTetras(ORDER_LINEAR);
00397 int nbQuadTetra = meshInfo.NbTetras(ORDER_QUADRATIC);
00398 int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR);
00399 int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC);
00400 int nbLinPrism = meshInfo.NbPrisms(ORDER_LINEAR);
00401 int nbQuadPrism = meshInfo.NbPrisms(ORDER_QUADRATIC);
00402 int nbLinHexa = meshInfo.NbHexas(ORDER_LINEAR);
00403 int nbQuadHexa = meshInfo.NbHexas(ORDER_QUADRATIC);
00404
00405 int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa);
00406 int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa);
00407 int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra;
00408 int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra;
00409 int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa);
00410 int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa);
00411
00412 int GuessSize[VTK_QUADRATIC_TETRA];
00413 GuessSize[VTK_LINE] = nbLineGuess;
00414 GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess;
00415 GuessSize[VTK_TRIANGLE] = nbLinTriaGuess;
00416 GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess;
00417 GuessSize[VTK_QUAD] = nbLinQuadGuess;
00418 GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess;
00419 GuessSize[VTK_TETRA] = nbLinTetra;
00420 GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra;
00421 GuessSize[VTK_PYRAMID] = nbLinPyra;
00422 GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra;
00423 GuessSize[VTK_WEDGE] = nbLinPrism;
00424 GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism;
00425 GuessSize[VTK_HEXAHEDRON] = nbLinHexa;
00426 GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa;
00427
00428 _downArray[VTK_LINE]->allocate(nbLineGuess);
00429 _downArray[VTK_QUADRATIC_EDGE]->allocate(nbQuadEdgeGuess);
00430 _downArray[VTK_TRIANGLE]->allocate(nbLinTriaGuess);
00431 _downArray[VTK_QUADRATIC_TRIANGLE]->allocate(nbQuadTriaGuess);
00432 _downArray[VTK_QUAD]->allocate(nbLinQuadGuess);
00433 _downArray[VTK_QUADRATIC_QUAD]->allocate(nbQuadQuadGuess);
00434 _downArray[VTK_TETRA]->allocate(nbLinTetra);
00435 _downArray[VTK_QUADRATIC_TETRA]->allocate(nbQuadTetra);
00436 _downArray[VTK_PYRAMID]->allocate(nbLinPyra);
00437 _downArray[VTK_QUADRATIC_PYRAMID]->allocate(nbQuadPyra);
00438 _downArray[VTK_WEDGE]->allocate(nbLinPrism);
00439 _downArray[VTK_QUADRATIC_WEDGE]->allocate(nbQuadPrism);
00440 _downArray[VTK_HEXAHEDRON]->allocate(nbLinHexa);
00441 _downArray[VTK_QUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa);
00442
00443
00444
00445
00446
00447
00448
00449
00450 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20);
00451 int cellSize = this->Types->GetNumberOfTuples();
00452 _cellIdToDownId.resize(cellSize, -1);
00453
00454 for (int i = 0; i < cellSize; i++)
00455 {
00456 int vtkFaceType = this->GetCellType(i);
00457 if (SMDS_Downward::getCellDimension(vtkFaceType) == 2)
00458 {
00459 int vtkFaceId = i;
00460
00461 int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId);
00462 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
00463 downFace->setTempNodes(connFaceId, vtkFaceId);
00464 int vols[2] = { -1, -1 };
00465 int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols);
00466
00467 for (int ivol = 0; ivol < nbVolumes; ivol++)
00468 {
00469 int vtkVolId = vols[ivol];
00470 int vtkVolType = this->GetCellType(vtkVolId);
00471
00472 int connVolId = _downArray[vtkVolType]->addCell(vtkVolId);
00473 _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType);
00474 _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType);
00475
00476 }
00477 }
00478 }
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493 CHRONOSTOP(20);
00494 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21);
00495
00496 for (int i = 0; i < cellSize; i++)
00497 {
00498 int vtkType = this->GetCellType(i);
00499 if (SMDS_Downward::getCellDimension(vtkType) == 3)
00500 {
00501
00502 int vtkVolId = i;
00503
00504
00505 _downArray[vtkType]->addCell(vtkVolId);
00506
00507
00508
00509 SMDS_Down3D* downVol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
00510 ListElemByNodesType facesWithNodes;
00511 downVol->computeFacesWithNodes(vtkVolId, facesWithNodes);
00512
00513
00514 for (int iface = 0; iface < facesWithNodes.nbElems; iface++)
00515 {
00516
00517
00518
00519 int vtkFaceType = facesWithNodes.elems[iface].vtkType;
00520 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
00521 int vols[2] = { -1, -1 };
00522 int *nodes = &facesWithNodes.elems[iface].nodeIds[0];
00523 int lg = facesWithNodes.elems[iface].nbNodes;
00524 int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols);
00525
00526
00527
00528
00529
00530
00531 int connFaceId = -1;
00532 for (int ivol = 0; ivol < nbVolumes; ivol++)
00533 {
00534 int vtkVolId2 = vols[ivol];
00535 int vtkVolType = this->GetCellType(vtkVolId2);
00536
00537 int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
00538 SMDS_Down3D* downVol2 = static_cast<SMDS_Down3D*> (_downArray[vtkVolType]);
00539 connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]);
00540 if (connFaceId >= 0)
00541 break;
00542 }
00543
00544
00545
00546
00547 if (connFaceId < 0)
00548 {
00549 connFaceId = _downArray[vtkFaceType]->addCell();
00550 downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]);
00551 }
00552
00553
00554
00555
00556 for (int ivol = 0; ivol < nbVolumes; ivol++)
00557 {
00558 int vtkVolId2 = vols[ivol];
00559 int vtkVolType = this->GetCellType(vtkVolId2);
00560
00561 int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
00562 _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType);
00563 _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType);
00564
00565 }
00566 }
00567 }
00568 }
00569
00570
00571
00572
00573
00574
00575
00576
00577
00578
00579 CHRONOSTOP(21);
00580 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22);
00581
00582 for (int i = 0; i < cellSize; i++)
00583 {
00584 int vtkEdgeType = this->GetCellType(i);
00585 if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1)
00586 {
00587 int vtkEdgeId = i;
00588
00589 int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId);
00590 SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
00591 downEdge->setNodes(connEdgeId, vtkEdgeId);
00592 vector<int> vtkIds;
00593 int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds);
00594 int downFaces[1000];
00595 unsigned char downTypes[1000];
00596 int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes);
00597 for (int n = 0; n < nbDownFaces; n++)
00598 {
00599 _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType);
00600 _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]);
00601 }
00602 }
00603 }
00604
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616 CHRONOSTOP(22);CHRONO(23);
00617
00618 for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++)
00619 {
00620 if (SMDS_Downward::getCellDimension(vtkFaceType) != 2)
00621 continue;
00622
00623
00624
00625 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
00626 int maxId = downFace->getMaxId();
00627 for (int faceId = 0; faceId < maxId; faceId++)
00628 {
00629
00630 ListElemByNodesType edgesWithNodes;
00631 downFace->computeEdgesWithNodes(faceId, edgesWithNodes);
00632
00633
00634
00635 for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++)
00636 {
00637
00638
00639
00640
00641 vector<int> vtkIds;
00642 unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
00643 int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
00644 SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
00645 int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds);
00646
00647 int downFaces[1000];
00648 unsigned char downTypes[1000];
00649 int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes);
00650
00651
00652
00653 int connEdgeId = -1;
00654 for (int idf = 0; idf < nbDownFaces; idf++)
00655 {
00656 int faceId2 = downFaces[idf];
00657 int faceType = downTypes[idf];
00658
00659 SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
00660 connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]);
00661 if (connEdgeId >= 0)
00662 break;
00663 }
00664
00665
00666
00667 if (connEdgeId < 0)
00668 {
00669
00670 connEdgeId = _downArray[vtkEdgeType]->addCell();
00671 downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds);
00672
00673 }
00674
00675
00676
00677
00678 for (int idf = 0; idf < nbDownFaces; idf++)
00679 {
00680 int faceId2 = downFaces[idf];
00681 int faceType = downTypes[idf];
00682
00683
00684 _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType);
00685 _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType);
00686
00687
00688 }
00689 }
00690 }
00691 }
00692
00693 CHRONOSTOP(23);CHRONO(24);
00694
00695
00696
00697
00698 for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--)
00699 {
00700 if (SMDS_Downward *down = _downArray[vtkType])
00701 {
00702 down->compactStorage();
00703 }
00704 }
00705
00706
00707
00708 for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++)
00709 {
00710 if (SMDS_Downward *down = _downArray[vtkType])
00711 {
00712 if (down->getMaxId())
00713 {
00714 MESSAGE("Cells of Type " << vtkType << " : number of entities, est: "
00715 << GuessSize[vtkType] << " real: " << down->getMaxId());
00716 }
00717 }
00718 }CHRONOSTOP(24);CHRONOSTOP(2);
00719 counters::stats();
00720 }
00721
00732 int SMDS_UnstructuredGrid::GetNeighbors(int* neighborsVtkIds, int* downIds, unsigned char* downTypes, int vtkId)
00733 {
00734 int vtkType = this->GetCellType(vtkId);
00735 int cellDim = SMDS_Downward::getCellDimension(vtkType);
00736 if (cellDim <2)
00737 return 0;
00738 int cellId = this->_cellIdToDownId[vtkId];
00739
00740 int nbCells = _downArray[vtkType]->getNumberOfDownCells(cellId);
00741 const int *downCells = _downArray[vtkType]->getDownCells(cellId);
00742 const unsigned char* downTyp = _downArray[vtkType]->getDownTypes(cellId);
00743
00744
00745
00746 int nb = 0;
00747 for (int i = 0; i < nbCells; i++)
00748 {
00749 int downId = downCells[i];
00750 int cellType = downTyp[i];
00751 int nbUp = _downArray[cellType]->getNumberOfUpCells(downId);
00752 const int *upCells = _downArray[cellType]->getUpCells(downId);
00753 const unsigned char* upTypes = _downArray[cellType]->getUpTypes(downId);
00754
00755
00756
00757
00758 for (int j = 0; j < nbUp; j++)
00759 {
00760 if ((upCells[j] == cellId) && (upTypes[j] == vtkType))
00761 continue;
00762 int vtkNeighbor = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
00763 neighborsVtkIds[nb] = vtkNeighbor;
00764 downIds[nb] = downId;
00765 downTypes[nb] = cellType;
00766 nb++;
00767 }
00768 if (nb >= NBMAXNEIGHBORS)
00769 assert(0);
00770 }
00771 return nb;
00772 }
00773
00779 int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int vtkId)
00780 {
00781 int vtkType = this->GetCellType(vtkId);
00782 int dim = SMDS_Downward::getCellDimension(vtkType);
00783 int nbFaces = 0;
00784 unsigned char cellTypes[1000];
00785 int downCellId[1000];
00786 if (dim == 1)
00787 {
00788 int downId = this->CellIdToDownId(vtkId);
00789 if (downId < 0)
00790 {
00791 MESSAGE("Downward structure not up to date: new edge not taken into account");
00792 return 0;
00793 }
00794 nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId);
00795 const int *upCells = _downArray[vtkType]->getUpCells(downId);
00796 const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId);
00797 for (int i=0; i< nbFaces; i++)
00798 {
00799 cellTypes[i] = upTypes[i];
00800 downCellId[i] = upCells[i];
00801 }
00802 }
00803 else if (dim == 2)
00804 {
00805 nbFaces = 1;
00806 cellTypes[0] = this->GetCellType(vtkId);
00807 int downId = this->CellIdToDownId(vtkId);
00808 if (downId < 0)
00809 {
00810 MESSAGE("Downward structure not up to date: new face not taken into account");
00811 return 0;
00812 }
00813 downCellId[0] = downId;
00814 }
00815
00816 int nbvol =0;
00817 for (int i=0; i<nbFaces; i++)
00818 {
00819 int vtkTypeFace = cellTypes[i];
00820 int downId = downCellId[i];
00821 int nv = _downArray[vtkTypeFace]->getNumberOfUpCells(downId);
00822 const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId);
00823 const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId);
00824 for (int j=0; j<nv; j++)
00825 {
00826 int vtkVolId = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
00827 if (vtkVolId >= 0)
00828 volVtkIds[nbvol++] = vtkVolId;
00829 }
00830 }
00831 return nbvol;
00832 }
00833
00840 int SMDS_UnstructuredGrid::GetParentVolumes(int* volVtkIds, int downId, unsigned char downType)
00841 {
00842 int vtkType = downType;
00843 int dim = SMDS_Downward::getCellDimension(vtkType);
00844 int nbFaces = 0;
00845 unsigned char cellTypes[1000];
00846 int downCellId[1000];
00847 if (dim == 1)
00848 {
00849 nbFaces = _downArray[vtkType]->getNumberOfUpCells(downId);
00850 const int *upCells = _downArray[vtkType]->getUpCells(downId);
00851 const unsigned char* upTypes = _downArray[vtkType]->getUpTypes(downId);
00852 for (int i=0; i< nbFaces; i++)
00853 {
00854 cellTypes[i] = upTypes[i];
00855 downCellId[i] = upCells[i];
00856 }
00857 }
00858 else if (dim == 2)
00859 {
00860 nbFaces = 1;
00861 cellTypes[0] = vtkType;
00862 downCellId[0] = downId;
00863 }
00864
00865 int nbvol =0;
00866 for (int i=0; i<nbFaces; i++)
00867 {
00868 int vtkTypeFace = cellTypes[i];
00869 int downId = downCellId[i];
00870 int nv = _downArray[vtkTypeFace]->getNumberOfUpCells(downId);
00871 const int *upCells = _downArray[vtkTypeFace]->getUpCells(downId);
00872 const unsigned char* upTypes = _downArray[vtkTypeFace]->getUpTypes(downId);
00873 for (int j=0; j<nv; j++)
00874 {
00875 int vtkVolId = _downArray[upTypes[j]]->getVtkCellId(upCells[j]);
00876 if (vtkVolId >= 0)
00877 volVtkIds[nbvol++] = vtkVolId;
00878 }
00879 }
00880 return nbvol;
00881 }
00882
00889 void SMDS_UnstructuredGrid::GetNodeIds(std::set<int>& nodeSet, int downId, unsigned char downType)
00890 {
00891 _downArray[downType]->getNodeIds(downId, nodeSet);
00892 }
00893
00899 void SMDS_UnstructuredGrid::ModifyCellNodes(int vtkVolId, std::map<int, int> localClonedNodeIds)
00900 {
00901 vtkIdType npts = 0;
00902 vtkIdType *pts;
00903 this->GetCellPoints(vtkVolId, npts, pts);
00904 for (int i = 0; i < npts; i++)
00905 {
00906 if (localClonedNodeIds.count(pts[i]))
00907 {
00908 vtkIdType oldpt = pts[i];
00909 pts[i] = localClonedNodeIds[oldpt];
00910
00911
00912
00913 }
00914 }
00915 }
00916
00922 int SMDS_UnstructuredGrid::getOrderedNodesOfFace(int vtkVolId, std::vector<vtkIdType>& orderedNodes)
00923 {
00924 int vtkType = this->GetCellType(vtkVolId);
00925 int cellDim = SMDS_Downward::getCellDimension(vtkType);
00926 if (cellDim != 3)
00927 return 0;
00928 SMDS_Down3D *downvol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
00929 int downVolId = this->_cellIdToDownId[vtkVolId];
00930 downvol->getOrderedNodesOfFace(downVolId, orderedNodes);
00931 return orderedNodes.size();
00932 }
00933
00934 void SMDS_UnstructuredGrid::BuildLinks()
00935 {
00936
00937 if (this->Links)
00938 {
00939 this->Links->UnRegister(this);
00940 }
00941
00942 this->Links = SMDS_CellLinks::New();
00943 this->Links->Allocate(this->GetNumberOfPoints());
00944 this->Links->Register(this);
00945 this->Links->BuildLinks(this, this->Connectivity);
00946 this->Links->Delete();
00947 }
00948
00963 SMDS_MeshVolume* SMDS_UnstructuredGrid::extrudeVolumeFromFace(int vtkVolId,
00964 int domain1,
00965 int domain2,
00966 std::set<int>& originalNodes,
00967 std::map<int, std::map<int, int> >& nodeDomains,
00968 std::map<int, std::map<long, int> >& nodeQuadDomains)
00969 {
00970
00971 vector<vtkIdType> orderedOriginals;
00972 orderedOriginals.clear();
00973 set<int>::const_iterator it = originalNodes.begin();
00974 for (; it != originalNodes.end(); ++it)
00975 orderedOriginals.push_back(*it);
00976
00977 int nbNodes = this->getOrderedNodesOfFace(vtkVolId, orderedOriginals);
00978 vector<vtkIdType> orderedNodes;
00979
00980 switch (orderedOriginals.size())
00981 {
00982 case 3:
00983 case 4:
00984 for (int i = 0; i < nbNodes; i++)
00985 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
00986 for (int i = 0; i < nbNodes; i++)
00987 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
00988 break;
00989 case 6:
00990 case 8:
00991 {
00992 long dom1 = domain1;
00993 long dom2 = domain2;
00994 long dom1_2;
00995 if (domain1 < domain2)
00996 dom1_2 = dom1 + INT_MAX * dom2;
00997 else
00998 dom1_2 = dom2 + INT_MAX * dom1;
00999
01000 int ima = orderedOriginals.size();
01001 int mid = orderedOriginals.size() / 2;
01002
01003 for (int i = 0; i < mid; i++)
01004 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
01005 for (int i = 0; i < mid; i++)
01006 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
01007 for (int i = mid; i < ima; i++)
01008 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain1]);
01009 for (int i = mid; i < ima; i++)
01010 orderedNodes.push_back(nodeDomains[orderedOriginals[i]][domain2]);
01011 for (int i = 0; i < mid; i++)
01012 {
01013 int oldId = orderedOriginals[i];
01014 int newId;
01015 if (nodeQuadDomains.count(oldId) && nodeQuadDomains[oldId].count(dom1_2))
01016 newId = nodeQuadDomains[oldId][dom1_2];
01017 else
01018 {
01019 double *coords = this->GetPoint(oldId);
01020 SMDS_MeshNode *newNode = _mesh->AddNode(coords[0], coords[1], coords[2]);
01021 newId = newNode->getVtkId();
01022 std::map<long, int> emptyMap;
01023 nodeQuadDomains[oldId] = emptyMap;
01024 nodeQuadDomains[oldId][dom1_2] = newId;
01025 }
01026 orderedNodes.push_back(newId);
01027 }
01028 }
01029 break;
01030 default:
01031 ASSERT(0);
01032 }
01033
01034 SMDS_MeshVolume *vol = _mesh->AddVolumeFromVtkIds(orderedNodes);
01035
01036
01037 return vol;
01038 }