From 579053c25cdbf678280b50cdee35c19e38572ba7 Mon Sep 17 00:00:00 2001 From: Konstantinos Date: Mon, 8 Apr 2024 15:27:03 +0200 Subject: [PATCH] levelset: evaluate normal based on a low or high order smoothed boundary --- src/levelset/levelSetSegmentationObject.cpp | 131 +++++--------------- src/levelset/levelSetSegmentationObject.hpp | 6 +- 2 files changed, 34 insertions(+), 103 deletions(-) diff --git a/src/levelset/levelSetSegmentationObject.cpp b/src/levelset/levelSetSegmentationObject.cpp index 21f118aa0c..70f18a3001 100644 --- a/src/levelset/levelSetSegmentationObject.cpp +++ b/src/levelset/levelSetSegmentationObject.cpp @@ -290,12 +290,13 @@ std::array 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 projectionPoint; + std::array projectionNormal; + evalProjection(point, segmentItr, &projectionPoint, &projectionNormal); - // Evaluate normal - return computeSurfaceNormal(segmentItr, lambda); + BITPIT_UNUSED(projectionPoint); + + return projectionNormal; } /*! @@ -1796,7 +1797,26 @@ int LevelSetSegmentationBaseObject::evalPart(const std::array &point) */ std::array LevelSetSegmentationBaseObject::evalNormal(const std::array &point, bool signedLevelSet) const { - return _evalNormal(point, signedLevelSet); + // Project the point on the surface and evaluate the point-projection vector + std::array projectionPoint; + std::array 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 LevelSetSegmentationBaseObject::_evalNormal(const std::array &point, bool signedLevelSet) const +{ + return evalNormal(point, signedLevelSet); } /*! @@ -2686,7 +2706,13 @@ std::array LevelSetSegmentationObject::_evalCellNormal(long id, bool s long support = evalCellSupport(id); std::array centroid = m_kernel->computeCellCentroid(id); - return _evalNormal(centroid, support, signedLevelSet); + std::array projectionPoint; + std::array projectionNormal; + _evalProjection(centroid, support, signedLevelSet, &projectionPoint, &projectionNormal); + + BITPIT_UNUSED(projectionPoint); + + return projectionNormal; } /*! @@ -2743,20 +2769,6 @@ std::array 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 LevelSetSegmentationObject::_evalNormal(const std::array &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 @@ -2913,41 +2925,6 @@ long LevelSetSegmentationObject::_evalSupport(const std::array &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 LevelSetSegmentationObject::_evalNormal(const std::array &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 normal = m_surfaceInfo->evalNormal(point, supportItr); - if (!signedLevelSet) { - normal *= static_cast(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 @@ -3162,31 +3139,6 @@ long LevelSetBooleanObject::_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 LevelSetBooleanObject::_evalNormal(const std::array &point, bool signedLevelSet) const -{ - return _evalFunction>(point, signedLevelSet, [&point, signedLevelSet] (const LevelSetBooleanResult &result) - { - const LevelSetSegmentationBaseObject *resultObject = result.getObject(); - if ( !resultObject ) { - return levelSetDefaults::NORMAL; - } - - std::array normal = resultObject->evalNormal(point, signedLevelSet); - if (signedLevelSet) { - normal *= static_cast(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 @@ -3350,23 +3302,6 @@ int LevelSetComplementObject::_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 LevelSetComplementObject::_evalNormal(const std::array &point, bool signedLevelSet) const -{ - std::array 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 diff --git a/src/levelset/levelSetSegmentationObject.hpp b/src/levelset/levelSetSegmentationObject.hpp index 52d0b17655..91e83f102c 100644 --- a/src/levelset/levelSetSegmentationObject.hpp +++ b/src/levelset/levelSetSegmentationObject.hpp @@ -172,7 +172,7 @@ class LevelSetSegmentationBaseObject : public LevelSetObject { virtual const SurfUnstructured & _evalSurface(const std::array &point) const = 0; virtual int _evalPart(const std::array &point) const; - virtual std::array _evalNormal(const std::array &point, bool signedLevelSet) const = 0; + std::array _evalNormal(const std::array &point, bool signedLevelSet) const; virtual long _evalSupport(const std::array &point) const = 0; virtual long _evalSupport(const std::array &point, double searchRadius) const = 0; virtual void _evalProjection(const std::array &point, bool signedLevelSet, std::array *projectionPoint, std::array *projectionNormal) const = 0; @@ -230,7 +230,6 @@ class LevelSetSegmentationObject : public LevelSetSegmentationBaseObject { const SurfUnstructured & _evalSurface(const std::array &point) const override; long _evalSupport(const std::array &point) const override; long _evalSupport(const std::array &point, double searchRadius) const override; - std::array _evalNormal(const std::array &point, bool signedLevelSet) const override; void _evalProjection(const std::array &point, bool signedLevelSet, std::array *projectionPoint, std::array *projectionNormal) const override; private: @@ -241,7 +240,6 @@ class LevelSetSegmentationObject : public LevelSetSegmentationBaseObject { short _evalSign(const std::array &point, long support) const; double _evalValue(const std::array &point, long support, bool signedLevelSet) const; std::array _evalGradient(const std::array &point, long support, bool signedLevelSet) const; - std::array _evalNormal(const std::array &point, long support, bool signedLevelSet) const; void _evalProjection(const std::array &point, long support, bool signedLevelSet, std::array *projectionPoint, std::array *projectionNormal) const; }; @@ -265,7 +263,6 @@ class LevelSetBooleanObject: public LevelSetBool long _evalSupport(const std::array &point) const override; long _evalSupport(const std::array &point, double searchRadius) const override; int _evalPart(const std::array &point) const override; - std::array _evalNormal(const std::array &point, bool signedLevelSet) const override; void _evalProjection(const std::array &point, bool signedLevelSet, std::array *projectionPoint, std::array *projectionNormal) const override; }; @@ -288,7 +285,6 @@ class LevelSetComplementObject: public LevelSetC long _evalSupport(const std::array &point) const override; long _evalSupport(const std::array &point, double searchRadius) const override; int _evalPart(const std::array &point) const override; - std::array _evalNormal(const std::array &point, bool signedLevelSet) const override; void _evalProjection(const std::array &point, bool signedLevelSet, std::array *projectionPoint, std::array *projectionNormal) const override; };