182 if (!checkAndCalculateBounds()) {
183 differentCellsCount =
184 std::numeric_limits<unsigned long int>::max();
185 customDifferentCellCount =
186 std::numeric_limits<unsigned long int>::max();
191 viennahrle::ConstDenseCellIterator<hrleDomainType> itTarget(
192 levelSetTarget->getDomain(), minIndex);
193 viennahrle::ConstDenseCellIterator<hrleDomainType> itSample(
194 levelSetSample->getDomain(), minIndex);
196 differentCellsCount = 0;
197 customDifferentCellCount = 0;
200 const bool generateMesh = outputMesh !=
nullptr;
204 for (
unsigned i = 0; i <
D; ++i) {
205 outputMesh->minimumExtent[i] = std::numeric_limits<T>::max();
206 outputMesh->maximumExtent[i] = std::numeric_limits<T>::lowest();
212 std::vector<T> cellDifference;
213 std::vector<T> incrementValues;
214 size_t currentPointId = 0;
215 std::unordered_map<viennahrle::Index<D>, size_t,
216 typename viennahrle::Index<D>::hash>
220 for (; itTarget.getIndices() < maxIndex; itTarget.next()) {
221 itSample.goToIndicesSequential(itTarget.getIndices());
224 T centerValueTarget = 0.;
225 T centerValueSample = 0.;
228 for (
int i = 0; i < (1 <<
D); ++i) {
229 centerValueTarget += itTarget.getCorner(i).getValue();
230 centerValueSample += itSample.getCorner(i).getValue();
232 centerValueTarget /= (1 <<
D);
233 centerValueSample /= (1 <<
D);
236 bool insideTarget = (centerValueTarget <= 0.);
237 bool insideSample = (centerValueSample <= 0.);
238 bool isDifferent = insideTarget != insideSample;
241 bool inXRange = useCustomXIncrement &&
242 (itTarget.getIndices()[0] * gridDelta >= xRangeMin &&
243 itTarget.getIndices()[0] * gridDelta <= xRangeMax);
244 bool inYRange = useCustomYIncrement &&
245 (itTarget.getIndices()[1] * gridDelta >= yRangeMin &&
246 itTarget.getIndices()[1] * gridDelta <= yRangeMax);
249 unsigned short int incrementToAdd = defaultIncrement;
250 if (inXRange && inYRange) {
252 incrementToAdd = customXIncrement + customYIncrement;
253 }
else if (inXRange) {
254 incrementToAdd = customXIncrement;
255 }
else if (inYRange) {
256 incrementToAdd = customYIncrement;
262 differentCellsCount += 1;
265 customDifferentCellCount += incrementToAdd;
270 if (generateMesh && (insideTarget || insideSample)) {
272 int difference = isDifferent ? 1 : 0;
274 std::array<unsigned, 1 << D> voxel;
275 bool addVoxel =
true;
279 for (
unsigned i = 0; i < (1 <<
D); ++i) {
280 viennahrle::Index<D> index;
281 for (
unsigned j = 0; j <
D; ++j) {
283 itTarget.getIndices(j) + itTarget.getCorner(i).getOffset()[j];
284 if (index[j] > maxIndex[j]) {
290 auto pointIdValue = std::make_pair(index, currentPointId);
291 auto pointIdPair = pointIdMapping.insert(pointIdValue);
292 voxel[i] = pointIdPair.first->second;
293 if (pointIdPair.second) {
302 if constexpr (
D == 3) {
303 std::array<unsigned, 8> hexa{voxel[0], voxel[1], voxel[3],
304 voxel[2], voxel[4], voxel[5],
306 outputMesh->hexas.push_back(hexa);
307 }
else if constexpr (
D == 2) {
308 std::array<unsigned, 4> quad{voxel[0], voxel[1], voxel[3],
310 outputMesh->tetras.push_back(quad);
313 cellDifference.push_back(difference);
316 incrementValues.push_back(isDifferent ?
static_cast<T>(incrementToAdd)
323 if (generateMesh && !pointIdMapping.empty()) {
325 outputMesh->nodes.resize(pointIdMapping.size());
326 for (
auto it = pointIdMapping.begin(); it != pointIdMapping.end(); ++it) {
328 for (
unsigned i = 0; i <
D; ++i) {
329 coords[i] = gridDelta * it->first[i];
331 if (coords[i] < outputMesh->minimumExtent[i]) {
332 outputMesh->minimumExtent[i] = coords[i];
333 }
else if (coords[i] > outputMesh->maximumExtent[i]) {
334 outputMesh->maximumExtent[i] = coords[i];
337 outputMesh->nodes[it->second] = coords;
341 assert(cellDifference.size() == incrementValues.size());
342 assert(incrementValues.size() ==
343 outputMesh->template getElements<1 <<
D>().size());
344 outputMesh->cellData.insertNextScalarData(cellDifference,
"Difference");
345 outputMesh->cellData.insertNextScalarData(incrementValues,