42 #include <vtkCellArray.h> 43 #include <vtkCellData.h> 44 #include <vtkCharArray.h> 45 #include <vtkDataArray.h> 46 #include <vtkIdTypeArray.h> 47 #include <vtkIntArray.h> 48 #include <vtkKdTree.h> 49 #include <vtkMergePoints.h> 50 #include <vtkObjectFactory.h> 51 #include <vtkPointData.h> 52 #include <vtkPoints.h> 53 #include <vtkUnsignedCharArray.h> 54 #include <vtkUnstructuredGrid.h> 61 class mergeCellsSTLCloak {
63 std::map<vtkIdType, vtkIdType> IdTypeMap;
67 this->TotalNumberOfDataSets = 0;
68 this->TotalNumberOfCells = 0;
69 this->TotalNumberOfPoints = 0;
71 this->NumberOfCells = 0;
72 this->NumberOfPoints = 0;
74 this->PointMergeTolerance = 10e-4f;
75 this->MergeDuplicatePoints = 1;
77 this->InputIsUGrid = 0;
78 this->InputIsPointSet = 0;
81 this->cellList = NULL;
83 this->UnstructuredGrid = NULL;
85 this->GlobalIdMap =
new mergeCellsSTLCloak;
86 this->GlobalCellIdMap =
new mergeCellsSTLCloak;
88 this->UseGlobalIds = 0;
89 this->UseGlobalCellIds = 0;
97 delete this->GlobalIdMap;
98 delete this->GlobalCellIdMap;
100 this->SetUnstructuredGrid(0);
107 delete this->cellList;
108 this->cellList = NULL;
112 vtkIdType newPtId, oldPtId, newCellId;
113 vtkSmartPointer<vtkIdTypeArray> idMap;
115 vtkUnstructuredGrid *ugrid = this->UnstructuredGrid;
118 vtkErrorMacro(<<
"SetUnstructuredGrid first");
122 if (this->TotalNumberOfDataSets <= 0) {
126 vtkErrorMacro(<<
"Must SetTotalNumberOfCells, SetTotalNumberOfPoints and " 127 "SetTotalNumberOfDataSets (upper bounds at least)" 128 " before starting to MergeDataSets");
133 vtkPointData *pointArrays =
set->GetPointData();
134 vtkCellData *cellArrays =
set->GetCellData();
143 if (ugrid->GetNumberOfCells() == 0) {
144 vtkPointSet *check1 = vtkPointSet::SafeDownCast(
set);
147 this->InputIsPointSet = 1;
148 vtkUnstructuredGrid *check2 = vtkUnstructuredGrid::SafeDownCast(
set);
149 this->InputIsUGrid = (check2 !=
nullptr);
152 this->StartUGrid(
set);
154 this->ptList->IntersectFieldList(pointArrays);
155 this->cellList->IntersectFieldList(cellArrays);
158 vtkIdType numPoints =
set->GetNumberOfPoints();
159 vtkIdType numCells =
set->GetNumberOfCells();
165 if (this->MergeDuplicatePoints) {
166 if (this->UseGlobalIds)
174 idMap = vtkSmartPointer<vtkIdTypeArray>::Take(
175 this->MapPointsToIdsUsingGlobalIds(
set));
177 idMap = vtkSmartPointer<vtkIdTypeArray>::Take(
178 this->MapPointsToIdsUsingLocator(
set));
184 vtkIdType nextPt = (vtkIdType)this->NumberOfPoints;
186 vtkPoints *pts = ugrid->GetPoints();
188 for (oldPtId = 0; oldPtId < numPoints; oldPtId++) {
190 newPtId = idMap->GetValue(oldPtId);
195 if (newPtId == nextPt) {
196 pts->SetPoint(nextPt, set->GetPoint(oldPtId));
198 ugrid->GetPointData()->CopyData(*this->ptList, pointArrays,
199 this->nextGrid, oldPtId, nextPt);
207 if (this->InputIsUGrid) {
208 newCellId = this->AddNewCellsUnstructuredGrid(
set, idMap);
210 newCellId = this->AddNewCellsDataSet(
set, idMap);
213 this->NumberOfPoints = nextPt;
214 this->NumberOfCells = newCellId;
222 vtkIdTypeArray *idMap) {
223 vtkIdType oldCellId,
id, newPtId, newCellId = 0, oldPtId;
225 vtkUnstructuredGrid *ugrid = this->UnstructuredGrid;
226 vtkCellData *cellArrays =
set->GetCellData();
227 vtkIdType numCells =
set->GetNumberOfCells();
230 cellPoints->Allocate(VTK_CELL_SIZE);
232 vtkIdType nextCellId = 0;
234 int duplicateCellTest = 0;
236 if (this->UseGlobalCellIds) {
237 int success = this->GlobalCellIdAccessStart(
set);
240 nextCellId = this->GlobalCellIdMap->IdTypeMap.size();
241 duplicateCellTest = 1;
245 for (oldCellId = 0; oldCellId < numCells; oldCellId++) {
246 if (duplicateCellTest) {
247 vtkIdType globalId = this->GlobalCellIdAccessGetId(oldCellId);
249 std::pair<std::map<vtkIdType, vtkIdType>::iterator,
bool> inserted =
251 this->GlobalCellIdMap->IdTypeMap.insert(
252 std::map<vtkIdType, vtkIdType>::value_type(globalId, nextCellId));
254 if (inserted.second) {
261 set->GetCellPoints(oldCellId, cellPoints);
263 for (
id = 0;
id < cellPoints->GetNumberOfIds();
id++) {
264 oldPtId = cellPoints->GetId(
id);
267 newPtId = idMap->GetValue(oldPtId);
269 newPtId = this->NumberOfPoints + oldPtId;
271 cellPoints->SetId(
id, newPtId);
274 newCellId = (vtkIdType)ugrid->InsertNextCell(set->GetCellType(oldCellId),
277 ugrid->GetCellData()->CopyData(*(this->cellList), cellArrays,
278 this->nextGrid, oldCellId, newCellId);
281 cellPoints->Delete();
286 vtkIdTypeArray *idMap) {
291 if (this->nextGrid == 0) firstSet = 1;
293 vtkUnstructuredGrid *newUgrid = vtkUnstructuredGrid::SafeDownCast(
set);
294 vtkUnstructuredGrid *Ugrid = this->UnstructuredGrid;
298 vtkCellArray *newCellArray = newUgrid->GetCells();
299 vtkIdType *newCells = newCellArray->GetPointer();
300 vtkIdType *newLocs = newUgrid->GetCellLocationsArray()->GetPointer(0);
301 unsigned char *newTypes = newUgrid->GetCellTypesArray()->GetPointer(0);
303 int newNumCells = newUgrid->GetNumberOfCells();
304 int newNumConnections = newCellArray->GetData()->GetNumberOfTuples();
309 vtkIdList *duplicateCellIds = NULL;
310 int numDuplicateCells = 0;
311 int numDuplicateConnections = 0;
313 if (this->UseGlobalCellIds) {
314 int success = this->GlobalCellIdAccessStart(
set);
317 vtkIdType nextLocalId = this->GlobalCellIdMap->IdTypeMap.size();
321 for (
id = 0;
id < newNumCells;
id++) {
322 vtkIdType globalId = this->GlobalCellIdAccessGetId(
id);
324 std::pair<std::map<vtkIdType, vtkIdType>::iterator,
bool> inserted =
326 this->GlobalCellIdMap->IdTypeMap.insert(
327 std::map<vtkIdType, vtkIdType>::value_type(globalId,
330 if (inserted.second) {
333 duplicateCellIds->InsertNextId(
id);
336 int npoints = newCells[newLocs[
id]];
338 numDuplicateConnections += (npoints + 1);
342 if (numDuplicateCells == 0) {
343 duplicateCellIds->Delete();
344 duplicateCellIds = NULL;
351 vtkCellArray *cellArray = NULL;
352 vtkIdType *cells = NULL;
353 vtkIdType *locs = NULL;
354 unsigned char *types = NULL;
357 int numConnections = 0;
360 cellArray = Ugrid->GetCells();
361 cells = cellArray->GetPointer();
362 locs = Ugrid->GetCellLocationsArray()->GetPointer(0);
363 types = Ugrid->GetCellTypesArray()->GetPointer(0);
366 numCells = Ugrid->GetNumberOfCells();
367 numConnections = cellArray->GetData()->GetNumberOfTuples();
374 int totalNumCells = numCells + newNumCells - numDuplicateCells;
375 int totalNumConnections =
376 numConnections + newNumConnections - numDuplicateConnections;
379 mergedcells->SetNumberOfValues(totalNumConnections);
382 vtkIdType *idptr = mergedcells->GetPointer(0);
383 memcpy(idptr, cells,
sizeof(vtkIdType) * numConnections);
387 finalCellArray->SetCells(totalNumCells, mergedcells);
392 locationArray->SetNumberOfValues(totalNumCells);
394 vtkIdType *iptr = locationArray->GetPointer(0);
397 memcpy(iptr, locs, numCells *
sizeof(vtkIdType));
403 typeArray->SetNumberOfValues(totalNumCells);
405 unsigned char *cptr = typeArray->GetPointer(0);
408 memcpy(cptr, types, numCells *
sizeof(
unsigned char));
413 vtkIdType finalCellId = numCells;
414 vtkIdType nextCellArrayIndex =
static_cast<vtkIdType
>(numConnections);
415 vtkCellData *cellArrays =
set->GetCellData();
417 vtkIdType oldPtId, finalPtId;
419 int nextDuplicateCellId = 0;
421 for (vtkIdType oldCellId = 0; oldCellId < newNumCells; oldCellId++) {
422 vtkIdType size = *newCells++;
424 if (duplicateCellIds) {
425 vtkIdType skipId = duplicateCellIds->GetId(nextDuplicateCellId);
427 if (skipId == oldCellId) {
429 nextDuplicateCellId++;
434 locationArray->SetValue(finalCellId, nextCellArrayIndex);
436 typeArray->SetValue(finalCellId, newTypes[oldCellId]);
438 mergedcells->SetValue(nextCellArrayIndex++, size);
440 for (
id = 0;
id < size;
id++) {
441 oldPtId = *newCells++;
444 finalPtId = idMap->GetValue(oldPtId);
446 finalPtId = this->NumberOfPoints + oldPtId;
449 mergedcells->SetValue(nextCellArrayIndex++, finalPtId);
452 Ugrid->GetCellData()->CopyData(*(this->cellList), cellArrays,
453 this->nextGrid, oldCellId, finalCellId);
458 Ugrid->SetCells(typeArray, locationArray, finalCellArray);
460 mergedcells->Delete();
462 locationArray->Delete();
463 finalCellArray->Delete();
465 if (duplicateCellIds) {
466 duplicateCellIds->Delete();
473 vtkPointData *PD =
set->GetPointData();
474 vtkCellData *CD =
set->GetCellData();
476 vtkUnstructuredGrid *ugrid = this->UnstructuredGrid;
478 if (!this->InputIsUGrid) {
479 ugrid->Allocate(this->TotalNumberOfCells);
488 if (this->InputIsPointSet) {
489 vtkPointSet *ps = vtkPointSet::SafeDownCast(
set);
490 pts->SetDataType(ps->GetPoints()->GetDataType());
493 pts->SetNumberOfPoints(
494 this->TotalNumberOfPoints);
496 ugrid->SetPoints(pts);
505 new vtkDataSetAttributes::FieldList(this->TotalNumberOfDataSets);
507 new vtkDataSetAttributes::FieldList(this->TotalNumberOfDataSets);
509 this->ptList->InitializeFieldList(PD);
510 this->cellList->InitializeFieldList(CD);
512 if (this->UseGlobalIds) {
513 ugrid->GetPointData()->CopyGlobalIdsOn();
515 ugrid->GetPointData()->CopyAllocate(*ptList, this->TotalNumberOfPoints);
516 if (this->UseGlobalCellIds) {
517 ugrid->GetCellData()->CopyGlobalIdsOn();
519 ugrid->GetCellData()->CopyAllocate(*cellList, this->TotalNumberOfCells);
527 vtkUnstructuredGrid *ugrid = this->UnstructuredGrid;
529 if (this->NumberOfPoints < this->TotalNumberOfPoints) {
533 ugrid->GetPoints()->GetData()->Resize(this->NumberOfPoints);
545 int success = this->GlobalNodeIdAccessStart(
set);
548 vtkErrorMacro(
"global id array is not available");
552 vtkIdType npoints =
set->GetNumberOfPoints();
555 idMap->SetNumberOfValues(npoints);
557 vtkIdType nextNewLocalId = this->GlobalIdMap->IdTypeMap.size();
561 for (vtkIdType oldId = 0; oldId < npoints; oldId++) {
562 vtkIdType globalId = this->GlobalNodeIdAccessGetId(oldId);
564 std::pair<std::map<vtkIdType, vtkIdType>::iterator,
bool> inserted =
566 this->GlobalIdMap->IdTypeMap.insert(
567 std::map<vtkIdType, vtkIdType>::value_type(globalId,
570 if (inserted.second) {
573 idMap->SetValue(oldId, nextNewLocalId);
579 idMap->SetValue(oldId, inserted.first->second);
592 vtkUnstructuredGrid *grid = this->UnstructuredGrid;
593 vtkPoints *points0 = grid->GetPoints();
594 vtkIdType npoints0 = (vtkIdType)this->NumberOfPoints;
596 vtkPointSet *ps = vtkPointSet::SafeDownCast(
set);
598 vtkIdType npoints1 =
set->GetNumberOfPoints();
601 points1 = ps->GetPoints();
604 points1->SetNumberOfPoints(npoints1);
606 for (ptId = 0; ptId < npoints1; ptId++) {
607 points1->SetPoint(ptId, set->GetPoint(ptId));
612 idMap->SetNumberOfValues(npoints1);
614 vtkIdType nextNewLocalId = npoints0;
616 if (this->PointMergeTolerance == 0.0) {
625 set->GetBounds(bounds);
638 points0->GetData()->SetNumberOfTuples(npoints0);
639 grid->GetBounds(tmpbounds);
640 points0->GetData()->SetNumberOfTuples(this->TotalNumberOfPoints);
642 bounds[0] = ((tmpbounds[0] < bounds[0]) ? tmpbounds[0] : bounds[0]);
643 bounds[2] = ((tmpbounds[2] < bounds[2]) ? tmpbounds[2] : bounds[2]);
644 bounds[4] = ((tmpbounds[4] < bounds[4]) ? tmpbounds[4] : bounds[4]);
646 bounds[1] = ((tmpbounds[1] > bounds[1]) ? tmpbounds[1] : bounds[1]);
647 bounds[3] = ((tmpbounds[3] > bounds[3]) ? tmpbounds[3] : bounds[3]);
648 bounds[5] = ((tmpbounds[5] > bounds[5]) ? tmpbounds[5] : bounds[5]);
651 locator->InitPointInsertion(ptarray, bounds);
656 for (ptId = 0; ptId < npoints0; ptId++) {
660 points0->GetPoint(ptId, x);
661 locator->InsertUniquePoint(x, newId);
663 for (ptId = 0; ptId < npoints1; ptId++) {
664 points1->GetPoint(ptId, x);
665 locator->InsertUniquePoint(x, newId);
667 idMap->SetValue(ptId, newId);
677 vtkPoints *ptArrays[2];
685 points0->GetData()->SetNumberOfTuples(npoints0);
687 ptArrays[0] = points0;
688 ptArrays[1] = points1;
691 ptArrays[0] = points1;
695 kd->BuildLocatorFromPoints(ptArrays, numArrays);
697 vtkIdTypeArray *pointToEquivClassMap =
698 kd->BuildMapForDuplicatePoints(this->PointMergeTolerance);
703 points0->GetData()->SetNumberOfTuples(this->TotalNumberOfPoints);
717 std::map<vtkIdType, vtkIdType> newIdMap;
721 for (ptId = 0; ptId < npoints0; ptId++) {
722 vtkIdType EqClassRep = pointToEquivClassMap->GetValue(ptId);
724 if (EqClassRep != ptId) {
726 std::map<vtkIdType, vtkIdType>::value_type(EqClassRep, ptId));
730 for (ptId = 0; ptId < npoints1; ptId++) {
731 vtkIdType EqClassRep = pointToEquivClassMap->GetValue(ptId + npoints0);
733 if (EqClassRep < npoints0) {
734 idMap->SetValue(ptId,
739 std::pair<std::map<vtkIdType, vtkIdType>::iterator,
bool> inserted =
741 newIdMap.insert(std::map<vtkIdType, vtkIdType>::value_type(
742 EqClassRep, nextNewLocalId));
744 bool newEqClassRep = inserted.second;
745 vtkIdType existingMappedId = inserted.first->second;
748 idMap->SetValue(ptId, nextNewLocalId);
753 ptId, existingMappedId);
757 pointToEquivClassMap->Delete();
774 if (this->GlobalCellIdArray) {
775 switch (this->GlobalCellIdArrayType) {
776 vtkTemplateMacro(VTK_TT *ids =
777 static_cast<VTK_TT *>(this->GlobalCellIdArray);
778 return static_cast<vtkIdType
>(ids[idx]));
784 if (this->UseGlobalCellIds) {
785 vtkDataArray *da =
set->GetCellData()->GetGlobalIds();
787 this->GlobalCellIdArray = da->GetVoidPointer(0);
788 this->GlobalCellIdArrayType = da->GetDataType();
793 this->GlobalCellIdArray = 0;
798 if (this->GlobalIdArray) {
799 switch (this->GlobalIdArrayType) {
800 vtkTemplateMacro(VTK_TT *ids = static_cast<VTK_TT *>(this->GlobalIdArray);
801 return static_cast<vtkIdType
>(ids[idx]));
808 if (this->UseGlobalIds) {
809 vtkDataArray *da =
set->GetPointData()->GetGlobalIds();
811 this->GlobalIdArray = da->GetVoidPointer(0);
812 this->GlobalIdArrayType = da->GetDataType();
817 this->GlobalIdArray = 0;
821 void mergeCells::PrintSelf(ostream &os, vtkIndent indent) {
822 this->Superclass::PrintSelf(os, indent);
824 os << indent <<
"TotalNumberOfDataSets: " << this->TotalNumberOfDataSets
826 os << indent <<
"TotalNumberOfCells: " << this->TotalNumberOfCells << endl;
827 os << indent <<
"TotalNumberOfPoints: " << this->TotalNumberOfPoints << endl;
829 os << indent <<
"NumberOfCells: " << this->NumberOfCells << endl;
830 os << indent <<
"NumberOfPoints: " << this->NumberOfPoints << endl;
832 os << indent <<
"GlobalIdMap: " << this->GlobalIdMap->IdTypeMap.size()
834 os << indent <<
"GlobalCellIdMap: " << this->GlobalCellIdMap->IdTypeMap.size()
837 os << indent <<
"PointMergeTolerance: " << this->PointMergeTolerance << endl;
838 os << indent <<
"MergeDuplicatePoints: " << this->MergeDuplicatePoints
840 os << indent <<
"InputIsUGrid: " << this->InputIsUGrid << endl;
841 os << indent <<
"InputIsPointSet: " << this->InputIsPointSet << endl;
842 os << indent <<
"UnstructuredGrid: " << this->UnstructuredGrid << endl;
843 os << indent <<
"ptList: " << this->ptList << endl;
844 os << indent <<
"cellList: " << this->cellList << endl;
845 os << indent <<
"UseGlobalIds: " << this->UseGlobalIds << endl;
846 os << indent <<
"UseGlobalCellIds: " << this->UseGlobalCellIds << endl;
vtkIdType AddNewCellsDataSet(vtkDataSet *set, vtkIdTypeArray *idMap)
vtkIdType GlobalCellIdAccessGetId(vtkIdType idx)
vtkIdTypeArray * MapPointsToIdsUsingGlobalIds(vtkDataSet *set)
int GlobalCellIdAccessStart(vtkDataSet *set)
geoMeshBase * New(MeshType meshType)
Create a new mesh object.
~mergeCells() VTK_OVERRIDE
vtkIdTypeArray * MapPointsToIdsUsingLocator(vtkDataSet *set)
vtkIdType id
id in .inp file
vtkIdType GlobalNodeIdAccessGetId(vtkIdType idx)
vtkIdType AddNewCellsUnstructuredGrid(vtkDataSet *set, vtkIdTypeArray *idMap)
vtkSmartPointer< vtkIdTypeArray > MergeDataSet(vtkDataSet *set)
Provide a DataSet to be merged in to the final UnstructuredGrid.
void StartUGrid(vtkDataSet *set)
vtkStandardNewMacro(exoGeoMesh)
int GlobalNodeIdAccessStart(vtkDataSet *set)