251 if (levelSet ==
nullptr) {
252 Logger::getInstance()
253 .addWarning(
"No level set was passed to FromSurfaceMesh.")
257 if (mesh ==
nullptr) {
258 Logger::getInstance()
259 .addWarning(
"No mesh was passed to FromSurfaceMesh.")
264 const auto &grid = levelSet->getGrid();
268 bool removeBoundaries[
D];
269 for (
unsigned i = 0; i <
D; ++i) {
270 if (!removeBoundaryTriangles[i] && grid.isBoundaryPeriodic(i)) {
271 removeBoundaries[i] =
false;
273 removeBoundaries[i] =
true;
277 std::vector<std::pair<hrleVectorType<hrleIndexType, D>,
T>> points2;
281 typedef typename std::vector<
282 std::pair<hrleVectorType<hrleIndexType, D>, std::pair<T, T>>>
285 T gridDelta = grid.getGridDelta();
287 hrleVectorType<T, D> gridMin, gridMax;
288 for (
unsigned i = 0; i <
D; ++i) {
289 gridMin[i] = grid.getMinIndex(i) * gridDelta;
290 gridMax[i] = grid.getMaxIndex(i) * gridDelta;
294 std::vector<std::array<unsigned, D>> &elements =
295 mesh->template getElements<D>();
297 for (
unsigned currentElement = 0; currentElement < elements.size();
299 hrleVectorType<T, D> nodes[
D];
300 hrleVectorType<T, D> center(
T(0));
302 std::bitset<2 * D> flags;
304 bool removeElement =
false;
306 for (
int dim = 0; dim <
D; dim++) {
307 for (
int q = 0; q <
D; q++) {
308 nodes[q][dim] = mesh->nodes[elements[currentElement][q]][dim];
309 if (std::abs(nodes[q][dim] - gridMin[dim]) <
310 boundaryEps * gridDelta)
311 nodes[q][dim] = gridMin[dim];
312 if (std::abs(nodes[q][dim] - gridMax[dim]) <
313 boundaryEps * gridDelta)
314 nodes[q][dim] = gridMax[dim];
316 if (nodes[q][dim] > gridMin[dim])
318 if (nodes[q][dim] < gridMax[dim])
319 flags.reset(dim +
D);
321 center[dim] += nodes[q][dim];
323 if (removeBoundaries[dim] && (flags[dim] || flags[dim +
D])) {
324 removeElement =
true;
332 center /=
static_cast<T>(
D);
339 hrleVectorType<T, D> minNode = nodes[0];
340 hrleVectorType<T, D> maxNode = nodes[0];
341 for (
int i = 1; i <
D; ++i) {
342 minNode = Min(minNode, nodes[i]);
343 maxNode = Max(maxNode, nodes[i]);
347 hrleVectorType<hrleIndexType, D> minIndex, maxIndex;
348 for (
int q = 0; q <
D; q++) {
350 static_cast<hrleIndexType
>(std::ceil(minNode[q] / gridDelta));
352 static_cast<hrleIndexType
>(std::floor(maxNode[q] / gridDelta));
357 for (
unsigned i = 0; i <
D; ++i) {
358 if (removeBoundaries[i]) {
359 minIndex[i] = std::max(minIndex[i], grid.getMinIndex(i));
361 maxIndex[i] = std::min(maxIndex[i], grid.getMaxGridPoint(i));
366 for (
int z = 0; z <
D; z++) {
367 hrleVectorType<hrleIndexType,
D - 1> min_bb, max_bb;
369 for (
int h = 0; h <
D - 1; ++h) {
370 min_bb[h] = minIndex[(z + h + 1) %
D];
371 max_bb[h] = maxIndex[(z + h + 1) %
D];
374 box bb(min_bb, max_bb);
382 hrleVectorType<hrleIndexType, D> it_b;
383 for (
int h = 0; h <
D - 1; ++h)
384 it_b[(z + h + 1) %
D] = (*it_bb)[h];
386 hrleVectorType<T, D> p;
387 for (
int k = 1; k <
D; k++)
388 p[(k + z) %
D] = grid.gridPositionOfGlobalIndex(
389 (k + z) %
D, it_b[(k + z) %
D]);
392 int intersection_status = calculateGridlineTriangleIntersection(
393 p, nodes, z, intersection);
395 if (intersection_status != 0) {
397 assert(intersection >= minNode[z] &&
398 "Intersection should be inside Domain!");
399 assert(intersection <= maxNode[z] &&
400 "Intersection should be inside Domain!");
404 if (removeBoundaries[z] &&
405 intersection > gridDelta * (grid.getMaxIndex(z)))
407 if (removeBoundaries[z] &&
408 intersection < grid.getMinLocalCoordinate(z))
412 grid.globalCoordinate2LocalIndex(z, intersection);
414 hrleIndexType floor =
static_cast<hrleIndexType
>(
415 std::floor(intersection2 - distanceEps));
416 hrleIndexType ceil =
static_cast<hrleIndexType
>(
417 std::ceil(intersection2 + distanceEps));
419 floor = std::max(floor, minIndex[z] - 1);
420 ceil = std::min(ceil, maxIndex[z] + 1);
421 floor = std::max(floor, grid.getMinIndex(z));
422 ceil = std::min(ceil, grid.getMaxIndex(z));
424 if (!removeBoundaries[z]) {
425 floor = grid.globalIndex2LocalIndex(z, floor);
426 ceil = grid.globalIndex2LocalIndex(z, ceil);
429 hrleVectorType<T, D> t = center;
430 t[z] -= intersection;
431 for (
int k = 1; k <
D; k++)
432 t[(z + k) %
D] -= p[(z + k) %
D];
435 for (it_b[z] = floor; it_b[z] <= ceil; ++(it_b[z])) {
437 T RealDistance = it_b[z] - intersection2;
439 T SignDistance = RealDistance;
441 SignDistance -= signEps * t[z];
443 if (intersection_status < 0) {
444 RealDistance = -RealDistance;
445 SignDistance = -SignDistance;
448 if (RealDistance < 0.)
449 SignDistance = -SignDistance;
451 RealDistance *= (1. - distanceEps * 1e-3);
452 if (RealDistance > 1.)
454 if (RealDistance < -1.)
457 if (RealDistance == 0.)
461 std::make_pair(grid.globalIndices2LocalIndices(it_b),
462 std::make_pair(SignDistance, RealDistance)));
469 std::sort(points.begin(), points.end());
472 typename point_vector::iterator it_points = points.begin();
473 while (it_points != points.end()) {
474 hrleVectorType<hrleIndexType, D> tmp = it_points->first;
476 std::make_pair(it_points->first, it_points->second.second));
480 }
while ((it_points != points.end()) && (it_points->first == tmp));
484 levelSet->insertPoints(points2);
485 levelSet->getDomain().segment();
486 levelSet->finalize(2);