LCOV - code coverage report
Current view: top level - src/geometry - fnormals.jl (source / functions) Hit Total Coverage
Test: on branch nothing Lines: 19 26 73.1 %
Date: 2025-07-10 13:12:25 Functions: 0 0 -

          Line data    Source code
       1       48384 : rawtrianglenormal(g::AbstractGeometry, f::FHnd) =
       2             :     cross(rawtrianglebase(g, f)[2:3]...)
       3             : 
       4           0 : rawtrianglenormal(m::Mesh, x, f::FHnd) = rawtrianglenormal(geometry(m, x), f)
       5             : 
       6      161652 : function _safe_normalize(nrm::SVector{3, T}) where {T}
       7      161652 :     len = norm(nrm)
       8      161652 :     (len < eps(T)) && return zeros(SVector{3, T})
       9      161652 :     nrm / len
      10             : end
      11             : 
      12             : """
      13             :     nrm = rawtrianglenormal(mesh, x, f)
      14             : 
      15             :     g = geometry(mesh, x)
      16             :     nrm = rawtrianglenormal(g, x)
      17             : 
      18             : Compute "unnormalized" normal vector to triangle `f`.
      19             : 
      20             : !!! warning "precondition"
      21             :     Face `f` refers to a triangle.
      22             : 
      23             : See also [`geometry`](@ref), [`rawtrianglebase`](@ref), [`trianglenormal`](@ref)
      24             : """ rawtrianglenormal
      25             : 
      26           0 : trianglenormal(g::AbstractGeometry, f::FHnd) =
      27             :     rawtrianglenormal(g, f) |> _safe_normalize
      28             : 
      29           0 : trianglenormal(m::Mesh, x, f::FHnd) = trianglenormal(geometry(m, x), f)
      30             : 
      31             : """
      32             :     nrm = trianglenormal(mesh, x, f)
      33             : 
      34             :     g = geometry(mesh, x)
      35             :     nrm = trianglenormal(g, f)
      36             : 
      37             : Compute unit-length normal vector to triangle `f`.
      38             : 
      39             : !!! warning "precondition"
      40             :     Face `f` refers to a triangle.
      41             : 
      42             : !!! note
      43             :     The `trianglenormal` *always* returns a finite vector:
      44             :     For a degenerated triangle with zero area, its normal vector
      45             :     is  *undefined*, and `trianglenormal` returns `zeros(..)`
      46             :     (*not= `[NaN,...]`).
      47             : 
      48             : See also [`geometry`](@ref), [`rawtrianglenormal`](@ref)
      49             : """ trianglenormal
      50             : 
      51       48384 : function trianglenormalarea(g::AbstractGeometry, f::FHnd)
      52       48384 :     nrm = rawtrianglenormal(g, f)
      53       48384 :     len = norm(nrm)
      54             : 
      55       48384 :     nrm / len, len
      56             : end
      57             : 
      58           0 : trianglenormalarea(m::Mesh, x, f::FHnd) = trianglenormalarea(geometry(m, x), f)
      59             : 
      60             : 
      61             : """
      62             :     nrm, ar = trianglenormalarea(mesh, x, f)
      63             : 
      64             :     g = geometry(mesh, x)
      65             :     nrm, ar = trianglenormalarea(g, f)
      66             : 
      67             : Compute unit-length [`trianglenormal`](@ref) and [`trianglearea`](@ref).
      68             : 
      69             : See also [`geometry`](@ref), [`trianglenormal`](@ref) and [`trianglearea`](@ref)
      70             : """ trianglenormalarea
      71             : 
      72      161652 : function facenormal(g::AbstractGeometry, f::FHnd)
      73             :     # _, u, v = rawfacebase(g, f)
      74             :     # _safe_normalize(u × v)
      75             : 
      76      161652 :     m = _mesh(g)
      77      161652 :     x = _vpos(g)
      78             : 
      79      161652 :     a, b, c, hnext = first3(m, f)
      80             : 
      81      161652 :     (hnext == NoH) && return _safe_normalize((x[b] - x[a]) × (x[c] - x[a]))
      82             : 
      83             :     # c = mean(x[v] for v in vertices(m, f))
      84          78 :     bc = (x[a] + x[b] + x[c]) / 3
      85             : 
      86             :     # NOTE: c cancels out below, but I prefer computing w/ local coordinates,
      87             :     #       thus being independent of the absolute position of the face.
      88             :     #       Any "anchor" is good (or possibly better than (0, 0, 0))
      89             : 
      90          78 :     nrm = sum((x[source(m, h)] - bc) × (x[destination(m, h)] - bc) for h in halfedges(m, f))
      91          78 :     _safe_normalize(nrm)
      92             : end
      93             : 
      94           0 : facenormal(m::Mesh, x, f::FHnd) = facenormal(geometry(m, x), f)
      95             : 
      96             : """
      97             :     nrm = facenormal(mesh, x, f)
      98             : 
      99             :     g = geometry(mesh, x)
     100             :     nrm = facenormal(g, f)
     101             : 
     102             : Compute face normal from [`rawfacebase`](@ref).
     103             : 
     104             : See also [`geometry`](@ref), [`rawfacebase`](@ref), [`trianglenormal`](@ref)
     105             : """ facenormal
     106             : 
     107       48384 : facenormalarea(g::AbstractGeometry, f::FHnd) =
     108             :     facenormalarea(g, f, _istriangulation(g))
     109             : 
     110       48384 : facenormalarea(g::AbstractGeometry, f::FHnd, ::IsTriangulation) =
     111             :     trianglenormalarea(g, f)
     112             : 
     113           0 : facenormalarea(g::AbstractGeometry, f::FHnd, ::NoTriangulation) =
     114             :     (facenormal(g, f), facearea(g, f))
     115             : 
     116           0 : facenormalarea(m::Mesh, x, f::FHnd) = facenormalarea(geometry(m, x), f)

Generated by: LCOV version 1.16