244 if (levelSet ==
nullptr) {
245 Logger::getInstance()
246 .addError(
"No level set was passed to FromSurfaceMesh.")
250 if (mesh ==
nullptr) {
251 Logger::getInstance()
252 .addError(
"No mesh was passed to FromSurfaceMesh.")
257 const auto &grid = levelSet->getGrid();
261 bool removeBoundaries[
D];
262 for (
unsigned i = 0; i <
D; ++i) {
263 if (!removeBoundaryTriangles[i] && grid.isBoundaryPeriodic(i)) {
264 removeBoundaries[i] =
false;
266 removeBoundaries[i] =
true;
270 std::vector<std::pair<viennahrle::Index<D>,
T>> points2;
274 typedef std::vector<std::pair<viennahrle::Index<D>, std::pair<T, T>>>
279 VectorType<T, D> gridMin, gridMax;
280 for (
unsigned i = 0; i <
D; ++i) {
281 gridMin[i] = grid.getMinIndex(i) *
gridDelta;
282 gridMax[i] = grid.getMaxIndex(i) *
gridDelta;
286 std::vector<std::array<unsigned, D>> &elements =
287 mesh->template getElements<D>();
289 for (
unsigned currentElement = 0; currentElement < elements.size();
291 VectorType<T, D> nodes[
D];
292 VectorType<T, D> center;
293 std::fill(center.begin(), center.end(), 0);
295 std::bitset<2 * D> flags;
297 bool removeElement =
false;
299 for (
int dim = 0; dim <
D; dim++) {
300 for (
int q = 0; q <
D; q++) {
301 nodes[q][dim] = mesh->nodes[elements[currentElement][q]][dim];
302 if (std::abs(nodes[q][dim] - gridMin[dim]) <
304 nodes[q][dim] = gridMin[dim];
305 if (std::abs(nodes[q][dim] - gridMax[dim]) <
307 nodes[q][dim] = gridMax[dim];
309 if (nodes[q][dim] > gridMin[dim])
311 if (nodes[q][dim] < gridMax[dim])
312 flags.reset(dim +
D);
314 center[dim] += nodes[q][dim];
316 if (removeBoundaries[dim] && (flags[dim] || flags[dim +
D])) {
317 removeElement =
true;
325 for (
int q = 0; q <
D; q++)
326 center[q] /=
static_cast<T>(
D);
333 VectorType<T, D> minNode = nodes[0];
334 VectorType<T, D> maxNode = nodes[0];
335 for (
int i = 1; i <
D; ++i) {
336 minNode = Min(minNode, nodes[i]);
337 maxNode = Max(maxNode, nodes[i]);
348 viennahrle::Index<D> minIndex, maxIndex;
349 for (
int q = 0; q <
D; q++) {
350 minIndex[q] =
static_cast<hrleIndexType
>(
351 std::ceil(minNode[q] /
gridDelta - distanceEps));
352 maxIndex[q] =
static_cast<hrleIndexType
>(
353 std::floor(maxNode[q] /
gridDelta + distanceEps));
358 for (
unsigned i = 0; i <
D; ++i) {
359 if (removeBoundaries[i]) {
360 minIndex[i] = std::max(minIndex[i], grid.getMinIndex(i));
362 maxIndex[i] = std::min(maxIndex[i], grid.getMaxGridPoint(i));
367 for (
int z = 0; z <
D; z++) {
368 VectorType<hrleIndexType,
D - 1> min_bb, max_bb;
370 for (
int h = 0; h <
D - 1; ++h) {
371 min_bb[h] = minIndex[(z + h + 1) %
D];
372 max_bb[h] = maxIndex[(z + h + 1) %
D];
375 box bb(min_bb, max_bb);
383 viennahrle::Index<D> it_b;
384 for (
int h = 0; h <
D - 1; ++h)
385 it_b[(z + h + 1) %
D] = (*it_bb)[h];
388 for (
int k = 1; k <
D; k++)
389 p[(k + z) %
D] = grid.gridPositionOfGlobalIndex(
390 (k + z) %
D, it_b[(k + z) %
D]);
393 int intersection_status = calculateGridlineTriangleIntersection(
394 p, nodes, z, intersection);
396 if (intersection_status != 0) {
398 assert(intersection >= minNode[z] &&
399 "Intersection should be inside Domain!");
400 assert(intersection <= maxNode[z] &&
401 "Intersection should be inside Domain!");
405 if (removeBoundaries[z] &&
406 intersection >
gridDelta * (grid.getMaxIndex(z)))
408 if (removeBoundaries[z] &&
409 intersection < grid.getMinLocalCoordinate(z))
413 grid.globalCoordinate2LocalIndex(z, intersection);
415 auto floor =
static_cast<hrleIndexType
>(
416 std::floor(intersection2 - distanceEps));
417 auto ceil =
static_cast<hrleIndexType
>(
418 std::ceil(intersection2 + distanceEps));
420 floor = std::max(floor, minIndex[z] - 1);
421 ceil = std::min(ceil, maxIndex[z] + 1);
422 floor = std::max(floor, grid.getMinIndex(z));
423 ceil = std::min(ceil, grid.getMaxIndex(z));
425 if (!removeBoundaries[z]) {
426 floor = grid.globalIndex2LocalIndex(z, floor);
427 ceil = grid.globalIndex2LocalIndex(z, ceil);
430 VectorType<T, D> t = center;
431 t[z] -= intersection;
432 for (
int k = 1; k <
D; k++)
433 t[(z + k) %
D] -= p[(z + k) %
D];
436 for (it_b[z] = floor; it_b[z] <= ceil; ++(it_b[z])) {
438 T RealDistance = it_b[z] - intersection2;
440 T SignDistance = RealDistance;
442 SignDistance -= signEps * t[z];
444 if (intersection_status < 0) {
445 RealDistance = -RealDistance;
446 SignDistance = -SignDistance;
449 if (RealDistance < 0.)
450 SignDistance = -SignDistance;
452 RealDistance *= (1. - distanceEps * 1e-3);
453 if (RealDistance > 1.)
455 if (RealDistance < -1.)
458 if (RealDistance == 0.)
462 std::make_pair(grid.globalIndices2LocalIndices(it_b),
463 std::make_pair(SignDistance, RealDistance)));
470 std::sort(points.begin(), points.end());
473 auto it_points = points.begin();
474 while (it_points != points.end()) {
475 viennahrle::Index<D> tmp = it_points->first;
477 std::make_pair(it_points->first, it_points->second.second));
481 }
while ((it_points != points.end()) && (it_points->first == tmp));
485 levelSet->insertPoints(points2);
486 levelSet->getDomain().segment();
487 levelSet->finalize(2);