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: miscellaneous fixes #451

Merged
merged 4 commits into from
Mar 4, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 15 additions & 6 deletions src/levelset/levelSetObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -903,6 +903,14 @@ bool LevelSetObject::isCellInNarrowBand(long id)const
*
* The value of the levelset is evaluated and compared with the specified narrow band size.
*
* If a point is inside a cell that belongs to the narrow band because it is a neighbour of a
* cell with a different levelset sign, its function may identify the point as outside the
* narrow band. That's because it will only compare the levelset of the point with the narrow
* band size. The extreme case is when the narrow band size is set to zero and being a neighbour
* of a cell with a different levelset sign is the only criterion to identify cells inside the
* narrow band. In this situation, this function will identify as inside the narrow band only
* the points that lie on the levelset-zero iso surface.
*
* \param point are the coordinates of the point
* \result Return true if the cell is in the narrow band, false otherwise.
*/
Expand All @@ -914,7 +922,7 @@ bool LevelSetObject::isInNarrowBand(const std::array<double,3> &point)const
}

// Early return if no narrow band was set
if (m_narrowBandSize != LEVELSET_NARROW_BAND_UNLIMITED) {
if (m_narrowBandSize == LEVELSET_NARROW_BAND_UNLIMITED) {
return true;
}

Expand Down Expand Up @@ -1111,9 +1119,11 @@ void LevelSetObject::fillCellPropagatedSignCache()
// Set the sign of the cell
//
// If the sign of the cell has already been set, we check if it matches
// the seed sign and then we skip the cell.
//
// If the cell is a seed, we remove it from the seed list.
// the seed sign and then we skip the cell, otherwise we set the sign of
// the cell and we process its neighoburs. Once the sign of a cell is
// set, we can remove it form the seed list (there is no need to start
// again the porpagation from that cell, beause it will not reach any
// new portions of the domain).
if (cellId != seedId) {
CellCacheCollection::ValueCache<char>::Entry cellSignEntry = propagatedSignCache->findEntry(cellId);
if (cellSignEntry.isValid()) {
Expand All @@ -1125,10 +1135,9 @@ void LevelSetObject::fillCellPropagatedSignCache()
} else {
continue;
}

seedIds.erase(cellId);
} else {
propagatedSignCache->insertEntry(cellId, seedSign);
seedIds.erase(cellId);
}
}

Expand Down
24 changes: 12 additions & 12 deletions src/levelset/levelSetSegmentationObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,14 +183,16 @@ double LevelSetSegmentationSurfaceInfo::getFeatureAngle() const {
}

/*!
* Evaluate the signed distance function at the specified point.
* Evaluate the distance function at the specified point.
*
* @param[in] point are the coordinates of point
* @param[in] segmentItr is an iterator pointing to the closest segment
* @return The signed distance function at the specified point.
* @param[in] signedDistance controls if the signed or unsigned distance will be evaluated
* @return The distance function at the specified point.
*/
double LevelSetSegmentationSurfaceInfo::evalDistance(const std::array<double, 3> &point,
const SegmentConstIterator &segmentItr) const
const SegmentConstIterator &segmentItr,
bool signedDistance) const
{
// Project the point on the surface and evaluate the point-projection vector
int nSegmentVertices = segmentItr->getVertexCount();
Expand All @@ -200,6 +202,9 @@ double LevelSetSegmentationSurfaceInfo::evalDistance(const std::array<double, 3>

// Evaluate unsigned distance
double unsignedDistance = norm2(pointProjectionVector);
if (!signedDistance) {
return unsignedDistance;
}

// Signed distance
//
Expand Down Expand Up @@ -1762,7 +1767,7 @@ short LevelSetSegmentationObject::_evalSign(const std::array<double,3> &point, l

LevelSetSegmentationSurfaceInfo::SegmentConstIterator supportItr = getSurface().getCellConstIterator(support);

return evalValueSign(m_surfaceInfo->evalDistance(point, supportItr));
return evalValueSign(m_surfaceInfo->evalDistance(point, supportItr, true));
}

/*!
Expand All @@ -1789,7 +1794,7 @@ double LevelSetSegmentationObject::_evalValue(const std::array<double,3> &point,

// Evaluate the distance of the point from the surface
LevelSetSegmentationSurfaceInfo::SegmentConstIterator supportItr = getSurface().getCellConstIterator(support);
double distance = m_surfaceInfo->evalDistance(point, supportItr);
double distance = m_surfaceInfo->evalDistance(point, supportItr, signedLevelSet);

// Early return if the point lies on the surface
if (evalValueSign(distance) == 0) {
Expand Down Expand Up @@ -1831,7 +1836,7 @@ std::array<double,3> LevelSetSegmentationObject::_evalGradient(const std::array<

// Evaluate the distance of the point from the surface
LevelSetSegmentationSurfaceInfo::SegmentConstIterator supportItr = getSurface().getCellConstIterator(support);
double distance = m_surfaceInfo->evalDistance(point, supportItr);
double distance = m_surfaceInfo->evalDistance(point, supportItr, signedLevelSet);

// Early return if the point lies on the surface
if (evalValueSign(distance) == 0) {
Expand All @@ -1843,12 +1848,7 @@ std::array<double,3> LevelSetSegmentationObject::_evalGradient(const std::array<
}

// Evaluate levelset gradient
std::array<double,3> gradient = m_surfaceInfo->evalDistanceVector(point, supportItr);
if (signedLevelSet) {
gradient /= distance;
} else {
gradient /= std::abs(distance);
}
std::array<double,3> gradient = m_surfaceInfo->evalDistanceVector(point, supportItr) / distance;

return gradient;
}
Expand Down
2 changes: 1 addition & 1 deletion src/levelset/levelSetSegmentationObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ class LevelSetSegmentationSurfaceInfo {

double getFeatureAngle() const;

double evalDistance(const std::array<double, 3> &point, const SegmentConstIterator &segmentItr) const;
double evalDistance(const std::array<double, 3> &point, const SegmentConstIterator &segmentItr, bool signedDistance) const;
std::array<double, 3> evalDistanceVector(const std::array<double, 3> &point, const SegmentConstIterator &segmentItr) const;

std::array<double, 3> evalNormal(const std::array<double, 3> &point, const SegmentConstIterator &segmentItr) const;
Expand Down