2 #include "SMDS_UnstructuredGrid.hxx"
3 #include "SMDS_Mesh.hxx"
4 #include "SMDS_MeshInfo.hxx"
5 #include "SMDS_Downward.hxx"
9 #include <vtkCellArray.h>
10 #include <vtkCellLinks.h>
11 #include <vtkIdTypeArray.h>
12 #include <vtkUnsignedCharArray.h>
18 SMDS_UnstructuredGrid* SMDS_UnstructuredGrid::New()
20 MESSAGE("SMDS_UnstructuredGrid::New");
21 return new SMDS_UnstructuredGrid();
24 SMDS_UnstructuredGrid::SMDS_UnstructuredGrid() :
27 _cellIdToDownId.clear();
31 _counters = new counters(100);
34 SMDS_UnstructuredGrid::~SMDS_UnstructuredGrid()
38 unsigned long SMDS_UnstructuredGrid::GetMTime()
40 unsigned long mtime = vtkUnstructuredGrid::GetMTime();
41 MESSAGE("vtkUnstructuredGrid::GetMTime: " << mtime);
45 void SMDS_UnstructuredGrid::Update()
47 MESSAGE("SMDS_UnstructuredGrid::Update");
48 return vtkUnstructuredGrid::Update();
51 void SMDS_UnstructuredGrid::UpdateInformation()
53 MESSAGE("SMDS_UnstructuredGrid::UpdateInformation");
54 return vtkUnstructuredGrid::UpdateInformation();
57 void SMDS_UnstructuredGrid::setSMDS_mesh(SMDS_Mesh *mesh)
62 void SMDS_UnstructuredGrid::compactGrid(std::vector<int>& idNodesOldToNew, int newNodeSize,
63 std::vector<int>& idCellsOldToNew, int newCellSize)
65 MESSAGE("------------------------- SMDS_UnstructuredGrid::compactGrid " << newNodeSize << " " << newCellSize);CHRONO(1);
70 int alreadyCopied = 0;
75 lookHoleStart, lookHoleEnd, lookBlocEnd
77 enumState compactState = lookHoleStart;
81 // this->Links->UnRegister(this);
85 // --- if newNodeSize, create a new compacted vtkPoints
87 vtkPoints *newPoints = 0;
90 MESSAGE("-------------- compactGrid, newNodeSize " << newNodeSize);
91 newPoints = vtkPoints::New();
92 newPoints->Initialize();
93 newPoints->Allocate(newNodeSize);
94 newPoints->SetNumberOfPoints(newNodeSize);
95 int oldNodeSize = idNodesOldToNew.size();
97 for (int i = 0; i < oldNodeSize; i++)
102 if (idNodesOldToNew[i] < 0)
104 MESSAGE("-------------- newNodeSize, startHole " << i << " " << oldNodeSize);
106 if (!alreadyCopied) // copy the first bloc
108 MESSAGE("--------- copy first nodes before hole " << i << " " << oldNodeSize);
109 copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, startHole);
111 compactState = lookHoleEnd;
115 if (idNodesOldToNew[i] >= 0)
117 MESSAGE("-------------- newNodeSize, endHole " << i << " " << oldNodeSize);
120 compactState = lookBlocEnd;
124 if (idNodesOldToNew[i] < 0)
125 endBloc = i; // see nbPoints below
126 else if (i == (oldNodeSize - 1))
130 MESSAGE("-------------- newNodeSize, endbloc " << endBloc << " " << oldNodeSize);
131 copyNodes(newPoints, idNodesOldToNew, alreadyCopied, startBloc, endBloc);
132 compactState = lookHoleStart;
141 if (!alreadyCopied) // no hole, but shorter, no need to modify idNodesOldToNew
143 MESSAGE("------------- newNodeSize, shorter " << oldNodeSize);
144 copyNodes(newPoints, idNodesOldToNew, alreadyCopied, 0, newNodeSize);
146 newPoints->Squeeze();
149 // --- create new compacted Connectivity, Locations and Types
151 int oldCellSize = this->Types->GetNumberOfTuples();
153 vtkCellArray *newConnectivity = vtkCellArray::New();
154 newConnectivity->Initialize();
155 int oldCellDataSize = this->Connectivity->GetData()->GetSize();
156 newConnectivity->Allocate(oldCellDataSize);
157 MESSAGE("oldCellSize="<< oldCellSize << " oldCellDataSize=" << oldCellDataSize);
159 vtkUnsignedCharArray *newTypes = vtkUnsignedCharArray::New();
160 newTypes->Initialize();
161 //newTypes->Allocate(oldCellSize);
162 newTypes->SetNumberOfValues(newCellSize);
164 vtkIdTypeArray *newLocations = vtkIdTypeArray::New();
165 newLocations->Initialize();
166 //newLocations->Allocate(oldCellSize);
167 newLocations->SetNumberOfValues(newCellSize);
175 compactState = lookHoleStart;
178 vtkIdType *pointsCell = &tmpid[0]; // --- points id to fill a new cell
180 for (int i = 0; i < oldCellSize; i++)
182 switch (compactState)
185 if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
187 MESSAGE(" -------- newCellSize, startHole " << i << " " << oldCellSize);
189 compactState = lookHoleEnd;
190 if (!alreadyCopied) // copy the first bloc
192 MESSAGE("--------- copy first bloc before hole " << i << " " << oldCellSize);
193 copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell,
194 alreadyCopied, 0, startHole);
199 if (this->Types->GetValue(i) != VTK_EMPTY_CELL)
201 MESSAGE(" -------- newCellSize, EndHole " << i << " " << oldCellSize);
204 compactState = lookBlocEnd;
205 holes += endHole - startHole;
206 //alreadyCopied = startBloc -holes;
211 if (this->Types->GetValue(i) == VTK_EMPTY_CELL)
213 else if (i == (oldCellSize - 1))
217 MESSAGE(" -------- newCellSize, endBloc " << endBloc << " " << oldCellSize);
218 copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell,
219 alreadyCopied, startBloc, endBloc);
220 compactState = lookHoleStart;
225 if (!alreadyCopied) // no hole, but shorter
227 MESSAGE(" -------- newCellSize, shorter " << oldCellSize);
228 copyBloc(newTypes, idCellsOldToNew, idNodesOldToNew, newConnectivity, newLocations, pointsCell, alreadyCopied, 0,
232 newConnectivity->Squeeze();
233 //newTypes->Squeeze();
234 //newLocations->Squeeze();
238 MESSAGE("------- newNodeSize, setPoints");
239 this->SetPoints(newPoints);
240 MESSAGE("NumberOfPoints: " << this->GetNumberOfPoints());
242 this->SetCells(newTypes, newLocations, newConnectivity);
246 void SMDS_UnstructuredGrid::copyNodes(vtkPoints *newPoints, std::vector<int>& idNodesOldToNew, int& alreadyCopied,
249 MESSAGE("copyNodes " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
250 void *target = newPoints->GetVoidPointer(3 * alreadyCopied);
251 void *source = this->Points->GetVoidPointer(3 * start);
252 int nbPoints = end - start;
255 memcpy(target, source, 3 * sizeof(float) * nbPoints);
256 for (int j = start; j < end; j++)
257 idNodesOldToNew[j] = alreadyCopied++;
261 void SMDS_UnstructuredGrid::copyBloc(vtkUnsignedCharArray *newTypes, std::vector<int>& idCellsOldToNew,
262 std::vector<int>& idNodesOldToNew, vtkCellArray* newConnectivity,
263 vtkIdTypeArray* newLocations, vtkIdType* pointsCell, int& alreadyCopied,
266 MESSAGE("copyBloc " << alreadyCopied << " " << start << " " << end << " size: " << end - start << " total: " << alreadyCopied + end - start);
267 for (int j = start; j < end; j++)
269 newTypes->SetValue(alreadyCopied, this->Types->GetValue(j));
270 idCellsOldToNew[j] = alreadyCopied;
271 vtkIdType oldLoc = this->Locations->GetValue(j);
273 vtkIdType *oldPtsCell = 0;
274 this->Connectivity->GetCell(oldLoc, nbpts, oldPtsCell);
275 //MESSAGE(j << " " << alreadyCopied << " " << (int)this->Types->GetValue(j) << " " << oldLoc << " " << nbpts );
276 for (int l = 0; l < nbpts; l++)
278 int oldval = oldPtsCell[l];
279 pointsCell[l] = idNodesOldToNew[oldval];
280 //MESSAGE(" " << oldval << " " << pointsCell[l]);
282 int newcnt = newConnectivity->InsertNextCell(nbpts, pointsCell);
283 int newLoc = newConnectivity->GetInsertLocation(nbpts);
284 //MESSAGE(newcnt << " " << newLoc);
285 newLocations->SetValue(alreadyCopied, newLoc);
290 int SMDS_UnstructuredGrid::CellIdToDownId(int vtkCellId)
292 // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
293 return _cellIdToDownId[vtkCellId];
296 void SMDS_UnstructuredGrid::setCellIdToDownId(int vtkCellId, int downId)
298 // ASSERT((vtkCellId >= 0) && (vtkCellId < _cellIdToDownId.size()));
299 _cellIdToDownId[vtkCellId] = downId;
302 /*! Build downward connectivity: to do only when needed because heavy memory load.
303 * Downward connectivity is no more valid if vtkUnstructuredGrid is modified.
306 void SMDS_UnstructuredGrid::BuildDownwardConnectivity()
308 MESSAGE("SMDS_UnstructuredGrid::BuildDownwardConnectivity");CHRONO(2);
310 // --- erase previous data if any
312 for (int i = 0; i < _downArray.size(); i++)
315 delete _downArray[i];
318 _cellIdToDownId.clear();
320 // --- create SMDS_Downward structures (in _downArray vector[vtkCellType])
322 _downArray.resize(VTK_QUADRATIC_PYRAMID + 1, 0); // --- max. type value = VTK_QUADRATIC_PYRAMID
324 _downArray[VTK_LINE] = new SMDS_DownEdge(this);
325 _downArray[VTK_QUADRATIC_EDGE] = new SMDS_DownQuadEdge(this);
326 _downArray[VTK_TRIANGLE] = new SMDS_DownTriangle(this);
327 _downArray[VTK_QUADRATIC_TRIANGLE] = new SMDS_DownQuadTriangle(this);
328 _downArray[VTK_QUAD] = new SMDS_DownQuadrangle(this);
329 _downArray[VTK_QUADRATIC_QUAD] = new SMDS_DownQuadQuadrangle(this);
330 _downArray[VTK_TETRA] = new SMDS_DownTetra(this);
331 _downArray[VTK_QUADRATIC_TETRA] = new SMDS_DownQuadTetra(this);
332 _downArray[VTK_PYRAMID] = new SMDS_DownPyramid(this);
333 _downArray[VTK_QUADRATIC_PYRAMID] = new SMDS_DownQuadPyramid(this);
334 _downArray[VTK_WEDGE] = new SMDS_DownPenta(this);
335 _downArray[VTK_QUADRATIC_WEDGE] = new SMDS_DownQuadPenta(this);
336 _downArray[VTK_HEXAHEDRON] = new SMDS_DownHexa(this);
337 _downArray[VTK_QUADRATIC_HEXAHEDRON] = new SMDS_DownQuadHexa(this);
339 // --- get detailed info of number of cells of each type, allocate SMDS_downward structures
341 const SMDS_MeshInfo &meshInfo = _mesh->GetMeshInfo();
343 int nbLinTetra = meshInfo.NbTetras(ORDER_LINEAR);
344 int nbQuadTetra = meshInfo.NbTetras(ORDER_QUADRATIC);
345 int nbLinPyra = meshInfo.NbPyramids(ORDER_LINEAR);
346 int nbQuadPyra = meshInfo.NbPyramids(ORDER_QUADRATIC);
347 int nbLinPrism = meshInfo.NbPrisms(ORDER_LINEAR);
348 int nbQuadPrism = meshInfo.NbPrisms(ORDER_QUADRATIC);
349 int nbLinHexa = meshInfo.NbHexas(ORDER_LINEAR);
350 int nbQuadHexa = meshInfo.NbHexas(ORDER_QUADRATIC);
352 int nbLineGuess = int((4.0 / 3.0) * nbLinTetra + 2 * nbLinPrism + 2.5 * nbLinPyra + 3 * nbLinHexa);
353 int nbQuadEdgeGuess = int((4.0 / 3.0) * nbQuadTetra + 2 * nbQuadPrism + 2.5 * nbQuadPyra + 3 * nbQuadHexa);
354 int nbLinTriaGuess = 2 * nbLinTetra + nbLinPrism + 2 * nbLinPyra;
355 int nbQuadTriaGuess = 2 * nbQuadTetra + nbQuadPrism + 2 * nbQuadPyra;
356 int nbLinQuadGuess = int((2.0 / 3.0) * nbLinPrism + (1.0 / 2.0) * nbLinPyra + 3 * nbLinHexa);
357 int nbQuadQuadGuess = int((2.0 / 3.0) * nbQuadPrism + (1.0 / 2.0) * nbQuadPyra + 3 * nbQuadHexa);
359 int GuessSize[VTK_QUADRATIC_TETRA];
360 GuessSize[VTK_LINE] = nbLineGuess;
361 GuessSize[VTK_QUADRATIC_EDGE] = nbQuadEdgeGuess;
362 GuessSize[VTK_TRIANGLE] = nbLinTriaGuess;
363 GuessSize[VTK_QUADRATIC_TRIANGLE] = nbQuadTriaGuess;
364 GuessSize[VTK_QUAD] = nbLinQuadGuess;
365 GuessSize[VTK_QUADRATIC_QUAD] = nbQuadQuadGuess;
366 GuessSize[VTK_TETRA] = nbLinTetra;
367 GuessSize[VTK_QUADRATIC_TETRA] = nbQuadTetra;
368 GuessSize[VTK_PYRAMID] = nbLinPyra;
369 GuessSize[VTK_QUADRATIC_PYRAMID] = nbQuadPyra;
370 GuessSize[VTK_WEDGE] = nbLinPrism;
371 GuessSize[VTK_QUADRATIC_WEDGE] = nbQuadPrism;
372 GuessSize[VTK_HEXAHEDRON] = nbLinHexa;
373 GuessSize[VTK_QUADRATIC_HEXAHEDRON] = nbQuadHexa;
375 _downArray[VTK_LINE]->allocate(nbLineGuess);
376 _downArray[VTK_QUADRATIC_EDGE]->allocate(nbQuadEdgeGuess);
377 _downArray[VTK_TRIANGLE]->allocate(nbLinTriaGuess);
378 _downArray[VTK_QUADRATIC_TRIANGLE]->allocate(nbQuadTriaGuess);
379 _downArray[VTK_QUAD]->allocate(nbLinQuadGuess);
380 _downArray[VTK_QUADRATIC_QUAD]->allocate(nbQuadQuadGuess);
381 _downArray[VTK_TETRA]->allocate(nbLinTetra);
382 _downArray[VTK_QUADRATIC_TETRA]->allocate(nbQuadTetra);
383 _downArray[VTK_PYRAMID]->allocate(nbLinPyra);
384 _downArray[VTK_QUADRATIC_PYRAMID]->allocate(nbQuadPyra);
385 _downArray[VTK_WEDGE]->allocate(nbLinPrism);
386 _downArray[VTK_QUADRATIC_WEDGE]->allocate(nbQuadPrism);
387 _downArray[VTK_HEXAHEDRON]->allocate(nbLinHexa);
388 _downArray[VTK_QUADRATIC_HEXAHEDRON]->allocate(nbQuadHexa);
390 // --- iteration on vtkUnstructuredGrid cells, only faces
391 // for each vtk face:
392 // create a downward face entry with its downward id.
393 // compute vtk volumes, create downward volumes entry.
394 // mark face in downward volumes
395 // mark volumes in downward face
397 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only faces");CHRONO(20);
398 int cellSize = this->Types->GetNumberOfTuples();
399 _cellIdToDownId.resize(cellSize, -1);
401 for (int i = 0; i < cellSize; i++)
403 int vtkFaceType = this->GetCellType(i);
404 if (SMDS_Downward::getCellDimension(vtkFaceType) == 2)
407 //ASSERT(_downArray[vtkFaceType]);
408 int connFaceId = _downArray[vtkFaceType]->addCell(vtkFaceId);
409 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
410 downFace->setTempNodes(connFaceId, vtkFaceId);
411 int vols[2] = { -1, -1 };
412 int nbVolumes = downFace->computeVolumeIds(vtkFaceId, vols);
413 //MESSAGE("nbVolumes="<< nbVolumes);
414 for (int ivol = 0; ivol < nbVolumes; ivol++)
416 int vtkVolId = vols[ivol];
417 int vtkVolType = this->GetCellType(vtkVolId);
418 //ASSERT(_downArray[vtkVolType]);
419 int connVolId = _downArray[vtkVolType]->addCell(vtkVolId);
420 _downArray[vtkVolType]->addDownCell(connVolId, connFaceId, vtkFaceType);
421 _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId, vtkVolType);
422 // MESSAGE("Face " << vtkFaceId << " belongs to volume " << vtkVolId);
427 // --- iteration on vtkUnstructuredGrid cells, only volumes
428 // for each vtk volume:
429 // create downward volumes entry if not already done
430 // build a temporary list of faces described with their nodes
432 // compute the vtk volumes containing this face
433 // check if the face is already listed in the volumes (comparison of ordered list of nodes)
434 // if not, create a downward face entry (resizing of structure required)
435 // (the downward faces store a temporary list of nodes to ease the comparison)
436 // create downward volumes entry if not already done
437 // mark volumes in downward face
438 // mark face in downward volumes
441 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only volumes");CHRONO(21);
443 for (int i = 0; i < cellSize; i++)
445 int vtkType = this->GetCellType(i);
446 if (SMDS_Downward::getCellDimension(vtkType) == 3)
450 // MESSAGE("vtk volume " << vtkVolId);
451 //ASSERT(_downArray[vtkType]);
452 int connVolId = _downArray[vtkType]->addCell(vtkVolId);
454 // --- find all the faces of the volume, describe the faces by their nodes
456 SMDS_Down3D* downVol = static_cast<SMDS_Down3D*> (_downArray[vtkType]);
457 ListElemByNodesType facesWithNodes;
458 downVol->computeFacesWithNodes(vtkVolId, facesWithNodes);
459 // MESSAGE("vtk volume " << vtkVolId << " contains " << facesWithNodes.nbElems << " faces");
461 for (int iface = 0; iface < facesWithNodes.nbElems; iface++)
463 // --- find the volumes containing the face
466 int vtkFaceType = facesWithNodes.elems[iface].vtkType;
467 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
468 int vols[2] = { -1, -1 };
469 int *nodes = &facesWithNodes.elems[iface].nodeIds[0];
470 int lg = facesWithNodes.elems[iface].nbNodes;
471 int nbVolumes = downFace->computeVolumeIdsFromNodesFace(nodes, lg, vols);
472 // MESSAGE("vtk volume " << vtkVolId << " face " << iface << " belongs to " << nbVolumes << " volumes");
474 // --- check if face is registered in the volumes
479 for (int ivol = 0; ivol < nbVolumes; ivol++)
481 int vtkVolId2 = vols[ivol];
482 int vtkVolType = this->GetCellType(vtkVolId2);
483 //ASSERT(_downArray[vtkVolType]);
484 int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
485 SMDS_Down3D* downVol2 = static_cast<SMDS_Down3D*> (_downArray[vtkVolType]);
486 connFaceId = downVol2->FindFaceByNodes(connVolId2, facesWithNodes.elems[iface]);
488 break; // --- face already created
491 // --- if face is not registered in the volumes, create face
496 connFaceId = _downArray[vtkFaceType]->addCell();
497 downFace->setTempNodes(connFaceId, facesWithNodes.elems[iface]);
500 // --- mark volumes in downward face and mark face in downward volumes
503 for (int ivol = 0; ivol < nbVolumes; ivol++)
505 int vtkVolId2 = vols[ivol];
506 int vtkVolType = this->GetCellType(vtkVolId2);
507 //ASSERT(_downArray[vtkVolType]);
508 int connVolId2 = _downArray[vtkVolType]->addCell(vtkVolId2);
509 _downArray[vtkVolType]->addDownCell(connVolId2, connFaceId, vtkFaceType);
510 _downArray[vtkFaceType]->addUpCell(connFaceId, connVolId2, vtkVolType);
511 // MESSAGE(" From volume " << vtkVolId << " face " << connFaceId << " belongs to volume " << vtkVolId2);
517 // --- iteration on vtkUnstructuredGrid cells, only edges
518 // for each vtk edge:
519 // create downward edge entry
520 // store the nodes id's in downward edge (redundant with vtkUnstructuredGrid)
521 // find downward faces
522 // (from vtk faces or volumes, get downward faces, they have a temporary list of nodes)
523 // mark edge in downward faces
524 // mark faces in downward edge
527 MESSAGE("--- iteration on vtkUnstructuredGrid cells, only edges");CHRONO(22);
529 for (int i = 0; i < cellSize; i++)
531 int vtkEdgeType = this->GetCellType(i);
532 if (SMDS_Downward::getCellDimension(vtkEdgeType) == 1)
535 //ASSERT(_downArray[vtkEdgeType]);
536 int connEdgeId = _downArray[vtkEdgeType]->addCell(vtkEdgeId);
537 SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
538 downEdge->setNodes(connEdgeId, vtkEdgeId);
540 int nbVtkCells = downEdge->computeVtkCells(connEdgeId, vtkIds);
542 unsigned char downTypes[1000];
543 int nbDownFaces = downEdge->computeFaces(connEdgeId, &vtkIds[0], nbVtkCells, downFaces, downTypes);
544 for (int n = 0; n < nbDownFaces; n++)
546 _downArray[downTypes[n]]->addDownCell(downFaces[n], connEdgeId, vtkEdgeType);
547 _downArray[vtkEdgeType]->addUpCell(connEdgeId, downFaces[n], downTypes[n]);
552 // --- iteration on downward faces (they are all listed now)
553 // for each downward face:
554 // build a temporary list of edges with their ordered list of nodes
556 // find all the vtk cells containing this edge
557 // then identify all the downward faces containing the edge, from the vtk cells
558 // check if the edge is already listed in the faces (comparison of ordered list of nodes)
559 // if not, create a downward edge entry with the node id's
560 // mark edge in downward faces
561 // mark downward faces in edge (size of list unknown, to be allocated)
563 CHRONOSTOP(22);CHRONO(23);
565 for (int vtkFaceType = 0; vtkFaceType < VTK_QUADRATIC_PYRAMID; vtkFaceType++)
567 if (SMDS_Downward::getCellDimension(vtkFaceType) != 2)
570 // --- find all the edges of the face, describe the edges by their nodes
572 SMDS_Down2D* downFace = static_cast<SMDS_Down2D*> (_downArray[vtkFaceType]);
573 int maxId = downFace->getMaxId();
574 for (int faceId = 0; faceId < maxId; faceId++)
577 ListElemByNodesType edgesWithNodes;
578 downFace->computeEdgesWithNodes(faceId, edgesWithNodes);
579 // MESSAGE("downward face type " << vtkFaceType << " num " << faceId << " contains " << edgesWithNodes.nbElems << " edges");
582 for (int iedge = 0; iedge < edgesWithNodes.nbElems; iedge++)
585 // --- check if the edge is already registered by exploration of the faces
589 unsigned char vtkEdgeType = edgesWithNodes.elems[iedge].vtkType;
590 int *pts = &edgesWithNodes.elems[iedge].nodeIds[0];
591 SMDS_Down1D* downEdge = static_cast<SMDS_Down1D*> (_downArray[vtkEdgeType]);
592 int nbVtkCells = downEdge->computeVtkCells(pts, vtkIds);
593 //CHRONOSTOP(41);CHRONO(42);
595 unsigned char downTypes[1000];
596 int nbDownFaces = downEdge->computeFaces(pts, &vtkIds[0], nbVtkCells, downFaces, downTypes);
601 for (int idf = 0; idf < nbDownFaces; idf++)
603 int faceId2 = downFaces[idf];
604 int faceType = downTypes[idf];
605 //ASSERT(_downArray[faceType]);
606 SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
607 connEdgeId = downFace2->FindEdgeByNodes(faceId2, edgesWithNodes.elems[iedge]);
609 break; // --- edge already created
612 // --- if edge is not registered in the faces, create edge
617 connEdgeId = _downArray[vtkEdgeType]->addCell();
618 downEdge->setNodes(connEdgeId, edgesWithNodes.elems[iedge].nodeIds);
622 // --- mark faces in downward edge and mark edge in downward faces
625 for (int idf = 0; idf < nbDownFaces; idf++)
627 int faceId2 = downFaces[idf];
628 int faceType = downTypes[idf];
629 //ASSERT(_downArray[faceType]);
630 SMDS_Down2D* downFace2 = static_cast<SMDS_Down2D*> (_downArray[faceType]);
631 _downArray[vtkEdgeType]->addUpCell(connEdgeId, faceId2, faceType);
632 _downArray[faceType]->addDownCell(faceId2, connEdgeId, vtkEdgeType);
633 // MESSAGE(" From face t:" << vtkFaceType << " " << faceId <<
634 // " edge " << connEdgeId << " belongs to face t:" << faceType << " " << faceId2);
640 CHRONOSTOP(23);CHRONO(24);
642 // compact downward connectivity structure: adjust downward arrays size, replace vector<vector int>> by a single vector<int>
643 // 3D first then 2D and last 1D to release memory before edge upCells reorganization, (temporary memory use)
645 for (int vtkType = VTK_QUADRATIC_PYRAMID; vtkType >= 0; vtkType--)
647 if (SMDS_Downward *down = _downArray[vtkType])
649 down->compactStorage();
655 for (int vtkType = 0; vtkType <= VTK_QUADRATIC_PYRAMID; vtkType++)
657 if (SMDS_Downward *down = _downArray[vtkType])
659 if (down->getMaxId())
661 MESSAGE("Cells of Type " << vtkType << " : number of entities, est: "
662 << GuessSize[vtkType] << " real: " << down->getMaxId());
665 }CHRONOSTOP(24);CHRONOSTOP(2);