* Fill the partition information from the cuts information */
| 132 | * Fill the partition information from the cuts information |
| 133 | */ |
| 134 | vtkPartitioningStrategy::PartitionInformation CutsToPartition(vtkDataSet* dataset, |
| 135 | const std::vector<vtkBoundingBox>& cuts, bool assignBoundaryCellsToSmallestRegionId) |
| 136 | { |
| 137 | if (!dataset || cuts.empty() || dataset->GetNumberOfCells() == 0) |
| 138 | { |
| 139 | vtkWarningWithObjectMacro(nullptr, "Either dataset or cuts are empty"); |
| 140 | return vtkPartitioningStrategy::PartitionInformation(); |
| 141 | } |
| 142 | |
| 143 | auto ghostCells = vtkUnsignedCharArray::SafeDownCast( |
| 144 | dataset->GetCellData()->GetArray(vtkDataSetAttributes::GhostArrayName())); |
| 145 | |
| 146 | const auto numCells = dataset->GetNumberOfCells(); |
| 147 | std::vector<std::vector<int>> cellRegions(numCells, std::vector<int>()); |
| 148 | |
| 149 | // call GetCell/GetCellBounds once to make it thread safe (see vtkDataSet::GetCell). |
| 150 | vtkNew<vtkGenericCell> dummyCell; |
| 151 | dataset->GetCell(0, dummyCell); |
| 152 | double bds[6]; |
| 153 | dataset->GetCellBounds(0, bds); |
| 154 | |
| 155 | // vtkKdNode helps us do fast cell/cut intersections. So convert each cut to a |
| 156 | // vtkKdNode. |
| 157 | std::vector<vtkSmartPointer<vtkKdNode>> kdnodes; |
| 158 | for (const auto& bbox : cuts) |
| 159 | { |
| 160 | auto kdnode = vtkSmartPointer<vtkKdNode>::New(); |
| 161 | kdnode->SetDim(-1); // leaf. |
| 162 | |
| 163 | double cut_bounds[6]; |
| 164 | bbox.GetBounds(cut_bounds); |
| 165 | kdnode->SetBounds(cut_bounds); |
| 166 | kdnodes.emplace_back(std::move(kdnode)); |
| 167 | } |
| 168 | vtkSMPThreadLocalObject<vtkGenericCell> gcellLO; |
| 169 | vtkSMPThreadLocal<std::vector<double>> weightsLO; |
| 170 | const int maxCellSize = dataset->GetMaxCellSize(); |
| 171 | vtkSMPTools::For(0, numCells, |
| 172 | [&](vtkIdType first, vtkIdType last) |
| 173 | { |
| 174 | auto gcell = gcellLO.Local(); |
| 175 | auto weights = weightsLO.Local(); |
| 176 | weights.resize(static_cast<size_t>(maxCellSize)); |
| 177 | for (vtkIdType cellId = first; cellId < last; ++cellId) |
| 178 | { |
| 179 | if (ghostCells != nullptr && |
| 180 | ((ghostCells->GetTypedComponent(cellId, 0) & vtkDataSetAttributes::DUPLICATECELL) != 0)) |
| 181 | { |
| 182 | // skip ghost cells, they will not be extracted since they will be |
| 183 | // extracted on ranks where they are not marked as ghosts. |
| 184 | continue; |
| 185 | } |
| 186 | dataset->GetCell(cellId, gcell); |
| 187 | double cellBounds[6]; |
| 188 | dataset->GetCellBounds(cellId, cellBounds); |
| 189 | for (int cutId = 0; cutId < static_cast<int>(kdnodes.size()); ++cutId) |
| 190 | { |
| 191 | if (kdnodes[cutId]->IntersectsCell( |
no test coverage detected