Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

levelset: surface smoothing #461

Merged
merged 11 commits into from
Jun 6, 2024
Merged

Conversation

ksamouchos
Copy link
Contributor

@ksamouchos ksamouchos commented Apr 12, 2024

This pull request introduces a new tool which smooths out a discretized surface (polygon or polyhedral). The smoothed surface is continuous and is equipped with a continuous normal. Also, it passes form the discretized geometry's vertices and respects the normal vectors corresponding to each vertex. The new level set computes the projection point and normal based on the new continuous surface.

This pull request completes task IMM-770.

@ksamouchos ksamouchos self-assigned this Apr 12, 2024
@ksamouchos ksamouchos force-pushed the levelset.surface.interpolation branch from b3817e5 to d4da8ee Compare April 12, 2024 09:54
@andrea-iob andrea-iob changed the title levelset: Surface Smoothing levelset: surface Smoothing Apr 12, 2024
@andrea-iob andrea-iob changed the title levelset: surface Smoothing levelset: surface smoothing Apr 12, 2024
src/CG/CG.hpp Outdated Show resolved Hide resolved
src/CG/CG_elem.cpp Outdated Show resolved Hide resolved
@andrea-iob
Copy link
Member

Since it's still a draft, I've only made some random comments without actually testing the changes.

@andrea-iob andrea-iob self-requested a review April 15, 2024 07:34
@ksamouchos ksamouchos force-pushed the levelset.surface.interpolation branch from df82ab6 to b3d50c9 Compare May 16, 2024 16:42
@ksamouchos
Copy link
Contributor Author

I changed function

void setSurface(const SurfUnstructured *surface, double featureAngle, LevelSetSurfaceSmoothing surfaceSmoothing, bool force = false);

to allow the user to modify the surface smoothing order of object LevelSetSegmentationObject after its creation.

src/levelset/levelSetSegmentationObject.cpp Outdated Show resolved Hide resolved
src/levelset/levelSetSegmentationObject.cpp Outdated Show resolved Hide resolved
src/levelset/levelSetSegmentationObject.cpp Outdated Show resolved Hide resolved
src/levelset/levelSetSegmentationObject.cpp Show resolved Hide resolved
Copy link
Member

@andrea-iob andrea-iob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've still two main concerns:

  • I don't see any documentation of how the high order smoothing is evaluated. Did I miss it or it's not there yet?
  • I don't understand how the code for updating cell cache could still work if fillCellGeometricNarrowBandLocationCache can return an UNKNOWN location for cells inside the narrow band.

src/patchkernel/surface_kernel.hpp Show resolved Hide resolved
src/patchkernel/line_kernel.cpp Outdated Show resolved Hide resolved
src/patchkernel/surface_kernel.cpp Outdated Show resolved Hide resolved
@ksamouchos ksamouchos force-pushed the levelset.surface.interpolation branch from b3d50c9 to 7c98677 Compare May 29, 2024 14:29
@ksamouchos
Copy link
Contributor Author

Rebased to the current master

@ksamouchos ksamouchos force-pushed the levelset.surface.interpolation branch from 7c98677 to 4040cdd Compare May 30, 2024 17:21
@ksamouchos
Copy link
Contributor Author

I added a detailed documentation for functions "evalHighOrderProjectionOnLine" and "evalHighOrderProjectionOnTriangle".

@ksamouchos
Copy link
Contributor Author

I'm answering to the question of @andrea-iob about why I removed the assert from function

LevelSetCellLocation LevelSetSegmentationObject::fillCellGeometricNarrowBandLocationCache(long id)

Let's have a look at one of the new integration tests I've added which is not working without removing the assert. The test is the following:

In this case the size of the narrow band is zero. Thus, function "fillCellGeometricNarrowBandLocationCache" finds valoid cell support only for intersected cells. For the rest returns an UNKNOWN location:

return LevelSetCellLocation::UNKNOWN;

However, when a smoothed geometry is used, there are cells like the one with id=2824 which are intersected by the discretized geometry but not by the smoothed geometry. These cells have a valid cell support, so the function continues its process by checking if the location is NARROW_BAND_INTERSECTED or NARROW_BAND_DISTANCE in line

if (_intersectSurface(id, cellUnsigendValue, CELL_LOCATION_INTERSECTION_MODE) == LevelSetIntersectionStatus::TRUE) {

Cells like the one mentioned above don't belong to any of these two categories meaning that the assert that follows will throw an error. By removing the assert, the code still functions normally, because the location of these cells is declared later in function "fillCartesianCellZoneCache". Either these cells are neighboring the narrow band and detected in line

locationCache->insertEntry(neighId, static_cast<char>(LevelSetCellLocation::NARROW_BAND_NEIGHBOUR));

or belong to the bulk and are detected in line
locationCache->insertEntry(cellId, static_cast<char>(LevelSetCellLocation::BULK));

More specifically, cell 2824 belongs to the second category.

Consequently, the removal of the assert is necessary and does not harm the code.

@andrea-iob
Copy link
Member

Consequently, the removal of the assert is necessary and does not harm the code.

Ok.

Let's avoid caching unknown cell locations (like we already do in LevelSetObject::fillCellGeometricNarrowBandLocationCache) and add a comment explaining that, in the high order case, it's fine to have cells whose cell location will be unknown:

    // Update the cell location cache
    //
    // First we need to check if the cell intersects the surface, and only if it doesn't we
    // should check if its distance is lower than the narrow band size.
    //
    // When high order smoothing is active, there may be cells whose support is within the search
    // radius, but they are not intersected and their distance is less than the narrow band size.
    // These cells are not geometrically inside the narrow band, they are neighbours of cells
    // geometrically inside the narrow band and as such it's up to the caller of this function to
    // identify their cell location.
    LevelSetCellLocation cellLocation = LevelSetCellLocation::UNKNOWN;
    if (_intersectSurface(id, cellUnsigendValue, CELL_LOCATION_INTERSECTION_MODE) == LevelSetIntersectionStatus::TRUE) {
        cellLocation = LevelSetCellLocation::NARROW_BAND_INTERSECTED;
    } else if (cellUnsigendValue <= m_narrowBandSize) {
        cellLocation = LevelSetCellLocation::NARROW_BAND_DISTANCE;
    }
    assert((getSurfaceSmoothing() == LevelSetSurfaceSmoothing::HIGH_ORDER) || (cellLocation != LevelSetCellLocation::UNKNOWN));

    if (cellLocation != LevelSetCellLocation::UNKNOWN) {
        CellCacheCollection::ValueCache<char> *locationCache = getCellCache<char>(m_cellLocationCacheId);
        locationCache->insertEntry(id, static_cast<char>(cellLocation));
    }

@andrea-iob
Copy link
Member

If you address the last two comments the pull request can be merged.

@ksamouchos ksamouchos force-pushed the levelset.surface.interpolation branch from 4040cdd to db57bd5 Compare June 5, 2024 16:59
@ksamouchos
Copy link
Contributor Author

Consequently, the removal of the assert is necessary and does not harm the code.

Ok.

Let's avoid caching unknown cell locations (like we already do in LevelSetObject::fillCellGeometricNarrowBandLocationCache) and add a comment explaining that, in the high order case, it's fine to have cells whose cell location will be unknown:

    // Update the cell location cache
    //
    // First we need to check if the cell intersects the surface, and only if it doesn't we
    // should check if its distance is lower than the narrow band size.
    //
    // When high order smoothing is active, there may be cells whose support is within the search
    // radius, but they are not intersected and their distance is less than the narrow band size.
    // These cells are not geometrically inside the narrow band, they are neighbours of cells
    // geometrically inside the narrow band and as such it's up to the caller of this function to
    // identify their cell location.
    LevelSetCellLocation cellLocation = LevelSetCellLocation::UNKNOWN;
    if (_intersectSurface(id, cellUnsigendValue, CELL_LOCATION_INTERSECTION_MODE) == LevelSetIntersectionStatus::TRUE) {
        cellLocation = LevelSetCellLocation::NARROW_BAND_INTERSECTED;
    } else if (cellUnsigendValue <= m_narrowBandSize) {
        cellLocation = LevelSetCellLocation::NARROW_BAND_DISTANCE;
    }
    assert((getSurfaceSmoothing() == LevelSetSurfaceSmoothing::HIGH_ORDER) || (cellLocation != LevelSetCellLocation::UNKNOWN));

    if (cellLocation != LevelSetCellLocation::UNKNOWN) {
        CellCacheCollection::ValueCache<char> *locationCache = getCellCache<char>(m_cellLocationCacheId);
        locationCache->insertEntry(id, static_cast<char>(cellLocation));
    }

Done

@ksamouchos
Copy link
Contributor Author

Should I squash the commits before merging?

@andrea-iob
Copy link
Member

Should I squash the commits before merging?

Keep the commits separate.

@ksamouchos ksamouchos merged commit c6e9186 into master Jun 6, 2024
10 checks passed
@ksamouchos ksamouchos deleted the levelset.surface.interpolation branch June 6, 2024 12:00
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants