Skip to content

Commit

Permalink
levelset: evaluate normal based on a low or high order smoothed boundary
Browse files Browse the repository at this point in the history
  • Loading branch information
Konstantinos committed May 29, 2024
1 parent 5bc2cb8 commit 579053c
Show file tree
Hide file tree
Showing 2 changed files with 34 additions and 103 deletions.
131 changes: 33 additions & 98 deletions src/levelset/levelSetSegmentationObject.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -290,12 +290,13 @@ std::array<double, 3> LevelSetSegmentationSurfaceInfo::evalNormal(const std::arr
const SegmentConstIterator &segmentItr) const
{
// Project the point on the surface and evaluate the point-projection vector
int nSegmentVertices = segmentItr->getVertexCount();
BITPIT_CREATE_WORKSPACE(lambda, double, nSegmentVertices, ReferenceElementInfo::MAX_ELEM_VERTICES);
evalProjection(point, segmentItr, lambda);
std::array<double, 3> projectionPoint;
std::array<double, 3> projectionNormal;
evalProjection(point, segmentItr, &projectionPoint, &projectionNormal);

// Evaluate normal
return computeSurfaceNormal(segmentItr, lambda);
BITPIT_UNUSED(projectionPoint);

return projectionNormal;
}

/*!
Expand Down Expand Up @@ -1796,7 +1797,26 @@ int LevelSetSegmentationBaseObject::evalPart(const std::array<double,3> &point)
*/
std::array<double,3> LevelSetSegmentationBaseObject::evalNormal(const std::array<double,3> &point, bool signedLevelSet) const
{
return _evalNormal(point, signedLevelSet);
// Project the point on the surface and evaluate the point-projection vector
std::array<double, 3> projectionPoint;
std::array<double, 3> projectionNormal;
evalProjection(point, signedLevelSet, &projectionPoint, &projectionNormal);

BITPIT_UNUSED(projectionPoint);

return projectionNormal;
}

/*!
* Evaluate the normal of the surface at the segment closest to the specified point.
*
* \param point are the coordinates of the point
* \param signedLevelSet controls if signed levelset function will be used
* \result The normal of the surface at the segment closest to the specified point.
*/
std::array<double,3> LevelSetSegmentationBaseObject::_evalNormal(const std::array<double,3> &point, bool signedLevelSet) const
{
return evalNormal(point, signedLevelSet);
}

/*!
Expand Down Expand Up @@ -2686,7 +2706,13 @@ std::array<double,3> LevelSetSegmentationObject::_evalCellNormal(long id, bool s
long support = evalCellSupport(id);
std::array<double,3> centroid = m_kernel->computeCellCentroid(id);

return _evalNormal(centroid, support, signedLevelSet);
std::array<double, 3> projectionPoint;
std::array<double, 3> projectionNormal;
_evalProjection(centroid, support, signedLevelSet, &projectionPoint, &projectionNormal);

BITPIT_UNUSED(projectionPoint);

return projectionNormal;
}

/*!
Expand Down Expand Up @@ -2743,20 +2769,6 @@ std::array<double,3> LevelSetSegmentationObject::_evalGradient(const std::array<
return _evalGradient(point, support, signedLevelSet);
}

/*!
* Evaluate the normal of the surface at the segment closest to the specified point.
*
* \param point are the coordinates of the point
* \param signedLevelSet controls if signed levelset function will be used
* \result The normal of the surface at the segment closest to the specified point.
*/
std::array<double,3> LevelSetSegmentationObject::_evalNormal(const std::array<double,3> &point, bool signedLevelSet) const
{
long support = evalSupport(point);

return _evalNormal(point, support, signedLevelSet);
}

/*!
* Evaluate the projection of the given point on the surface created based on
* the points representing the specified segment. The surface passes from these
Expand Down Expand Up @@ -2913,41 +2925,6 @@ long LevelSetSegmentationObject::_evalSupport(const std::array<double,3> &point,
return closestSegmentId;
}

/*!
* Evaluate the normal of the surface at the segment closest to the specified point.
*
* \param point are the coordinates of the point
* \param support is the the closest segment to the specified point
* \param signedLevelSet controls if signed levelset function will be used
* \result The normal of the surface at the segment closest to the specified point.
*/
std::array<double,3> LevelSetSegmentationObject::_evalNormal(const std::array<double,3> &point, long support,
bool signedLevelSet) const
{
// Early return if the support is not valid
//
// With an invalid support, only the unsigend levelset can be evaluated.
if (support < 0) {
if (!signedLevelSet || empty()) {
return levelSetDefaults::NORMAL;
}

throw std::runtime_error("With an invalid support, only the unsigend levelset can be evaluated.");
}

// Evaluate the normal
//
// If an unsigned evaluation is requested, the orientation of the surface should be discarded
// and in order to have a normal that is agnostic with respect the two sides of the surface.
LevelSetSegmentationSurfaceInfo::SegmentConstIterator supportItr = getSurface().getCellConstIterator(support);
std::array<double,3> normal = m_surfaceInfo->evalNormal(point, supportItr);
if (!signedLevelSet) {
normal *= static_cast<double>(evalSign(point));
}

return normal;
}

/*!
* Evaluate the projection of the given point on the surface created based on
* the points representing the specified segment. The surface passes from these
Expand Down Expand Up @@ -3162,31 +3139,6 @@ long LevelSetBooleanObject<LevelSetSegmentationBaseObject>::_evalSupport(const s
return getReferenceObject(point)->evalSupport(point, searchRadius);
}

/*!
* Evaluate the normal of the surface at the segment closest to the specified point.
*
* \param point are the coordinates of the point
* \param signedLevelSet controls if signed levelset function will be used
* \result The normal of the surface at the segment closest to the specified point.
*/
std::array<double,3> LevelSetBooleanObject<LevelSetSegmentationBaseObject>::_evalNormal(const std::array<double,3> &point, bool signedLevelSet) const
{
return _evalFunction<std::array<double,3>>(point, signedLevelSet, [&point, signedLevelSet] (const LevelSetBooleanResult<LevelSetSegmentationBaseObject> &result)
{
const LevelSetSegmentationBaseObject *resultObject = result.getObject();
if ( !resultObject ) {
return levelSetDefaults::NORMAL;
}

std::array<double,3> normal = resultObject->evalNormal(point, signedLevelSet);
if (signedLevelSet) {
normal *= static_cast<double>(result.getObjectSign());
}

return normal;
});
}

/*!
* Evaluate the projection of the given point on the surface created based on
* the points representing the specified segment. The surface passes from these
Expand Down Expand Up @@ -3350,23 +3302,6 @@ int LevelSetComplementObject<LevelSetSegmentationBaseObject>::_evalPart(const st
return getSourceObject()->evalPart(point);
}

/*!
* Evaluate the normal of the surface at the segment closest to the specified point.
*
* \param point are the coordinates of the point
* \param signedLevelSet controls if signed levelset function will be used
* \result The normal of the surface at the segment closest to the specified point.
*/
std::array<double,3> LevelSetComplementObject<LevelSetSegmentationBaseObject>::_evalNormal(const std::array<double,3> &point, bool signedLevelSet) const
{
std::array<double,3> normal = getSourceObject()->evalNormal(point, signedLevelSet);
if (signedLevelSet) {
normal *= -1.;
}

return normal;
}

/*!
* Evaluate the projection of the given point on the surface created based on
* the points representing the specified segment. The surface passes from these
Expand Down
6 changes: 1 addition & 5 deletions src/levelset/levelSetSegmentationObject.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ class LevelSetSegmentationBaseObject : public LevelSetObject {

virtual const SurfUnstructured & _evalSurface(const std::array<double,3> &point) const = 0;
virtual int _evalPart(const std::array<double,3> &point) const;
virtual std::array<double,3> _evalNormal(const std::array<double,3> &point, bool signedLevelSet) const = 0;
std::array<double,3> _evalNormal(const std::array<double,3> &point, bool signedLevelSet) const;
virtual long _evalSupport(const std::array<double,3> &point) const = 0;
virtual long _evalSupport(const std::array<double,3> &point, double searchRadius) const = 0;
virtual void _evalProjection(const std::array<double,3> &point, bool signedLevelSet, std::array<double, 3> *projectionPoint, std::array<double, 3> *projectionNormal) const = 0;
Expand Down Expand Up @@ -230,7 +230,6 @@ class LevelSetSegmentationObject : public LevelSetSegmentationBaseObject {
const SurfUnstructured & _evalSurface(const std::array<double,3> &point) const override;
long _evalSupport(const std::array<double,3> &point) const override;
long _evalSupport(const std::array<double,3> &point, double searchRadius) const override;
std::array<double,3> _evalNormal(const std::array<double,3> &point, bool signedLevelSet) const override;
void _evalProjection(const std::array<double,3> &point, bool signedLevelSet, std::array<double, 3> *projectionPoint, std::array<double, 3> *projectionNormal) const override;

private:
Expand All @@ -241,7 +240,6 @@ class LevelSetSegmentationObject : public LevelSetSegmentationBaseObject {
short _evalSign(const std::array<double,3> &point, long support) const;
double _evalValue(const std::array<double,3> &point, long support, bool signedLevelSet) const;
std::array<double,3> _evalGradient(const std::array<double,3> &point, long support, bool signedLevelSet) const;
std::array<double,3> _evalNormal(const std::array<double,3> &point, long support, bool signedLevelSet) const;
void _evalProjection(const std::array<double,3> &point, long support, bool signedLevelSet, std::array<double, 3> *projectionPoint, std::array<double, 3> *projectionNormal) const;

};
Expand All @@ -265,7 +263,6 @@ class LevelSetBooleanObject<LevelSetSegmentationBaseObject>: public LevelSetBool
long _evalSupport(const std::array<double,3> &point) const override;
long _evalSupport(const std::array<double,3> &point, double searchRadius) const override;
int _evalPart(const std::array<double,3> &point) const override;
std::array<double,3> _evalNormal(const std::array<double,3> &point, bool signedLevelSet) const override;
void _evalProjection(const std::array<double,3> &point, bool signedLevelSet, std::array<double, 3> *projectionPoint, std::array<double, 3> *projectionNormal) const override;

};
Expand All @@ -288,7 +285,6 @@ class LevelSetComplementObject<LevelSetSegmentationBaseObject>: public LevelSetC
long _evalSupport(const std::array<double,3> &point) const override;
long _evalSupport(const std::array<double,3> &point, double searchRadius) const override;
int _evalPart(const std::array<double,3> &point) const override;
std::array<double,3> _evalNormal(const std::array<double,3> &point, bool signedLevelSet) const override;
void _evalProjection(const std::array<double,3> &point, bool signedLevelSet, std::array<double, 3> *projectionPoint, std::array<double, 3> *projectionNormal) const override;

};
Expand Down

0 comments on commit 579053c

Please sign in to comment.