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

          Line data    Source code
       1             : """
       2             : Polygonal surface mesh based on a half-edge data structure.
       3             : 
       4             : The type of the mesh is defined by its vertex/ face/ half-edge/ edge
       5             : attributes `VA`, `FA`, `HA`, `EA` which are [`AbstractVAttr`](@ref),
       6             : [`AbstractFAttr`](@ref), [`AbstractHAttr`](@ref),
       7             : [`AbstractEAttr`](@ref), respectively.
       8             : 
       9             : The state of the half-edge data structure is defined as part of the
      10             : attributes ([`link`](@ref)).
      11             : 
      12             : !!! tip
      13             :     Use [`createmesh`](@ref), [`similar(::Mesh)`](@ref) and [`clone`](@ref)
      14             :     to construct a new mesh.
      15             : 
      16             : See also [`createmesh`](@ref), [`similar`](@ref), [`clone`](@ref),
      17             : [`vattr`](@ref), [`fattr`](@ref), [`hattr`](@ref), [`eattr`](@ref)
      18             : """
      19             : struct Mesh{VA <: AbstractVAttr,
      20             :             FA <: AbstractFAttr,
      21             :             HA <: AbstractHAttr,
      22             :             EA <: AbstractEAttr}
      23             :     v::VA
      24             :     f::FA
      25             :     h::HA
      26             :     e::EA
      27             : 
      28          64 :     Mesh{V, F, H, E}(v::V, f::F, h::H, e::E) where {V, F, H, E} =
      29             :         new(v, f, h, e)
      30             : end
      31             : 
      32             : """
      33             :     mesh = createmesh(v, g, h, e)
      34             : 
      35             : Create mesh with attributes `v` (vertices), `f` (faces), `h`
      36             : (half-edges), `e` (edges).
      37             : 
      38             : !!! note
      39             :     The attributes determine the **type** of `mesh`
      40             : 
      41             : !!! tip
      42             :     Use [`similar(::Mesh)`](@ref) for constructing an empty mesh f
      43             :     identical type (i.e., identical attribute lists including
      44             :     enabled state of attributes).
      45             : 
      46             : # Example
      47             : 
      48             : Create `mesh` with vertex attributes for position `:x` and normals
      49             : `:n`, face normals `:n` and color `:c`, no attributes for half-edges,
      50             : and an edge attribute `:feature`. A default value `:red` is specified
      51             : for face color `:c`, and this attribute is disabled after construction.
      52             : 
      53             :     mesh = createmesh((:x => SVector{3, Float64}, :n => SVector{3, Float64}),
      54             :                       (:n => SVector{3, Float64},
      55             :                        :c => specifyattr(Symbol, enabled=false, x0=:red)),
      56             :                       (),
      57             :                       (:feature => Bool))
      58             : 
      59             : See also [`similar`](@ref), [`Mesh`](@ref)
      60             : """
      61           4 : function createmesh(v, f, h, e)
      62           4 :     va = createvattr(v)
      63           4 :     fa = createfattr(f)
      64           4 :     ha = createhattr(h)
      65           4 :     ea = createeattr(e)
      66             : 
      67           4 :     Mesh{typeof(va), typeof(fa), typeof(ha), typeof(ea)}(va, fa, ha, ea)
      68             : end
      69             : 
      70             : """
      71             :    mc = clone(mesh)
      72             : 
      73             : Create deep copy of mesh but don't copy any disabled attributes.
      74             : In contrast to [`compact`](@ref) this method preserves handles and their
      75             : [`isused`](@ref) state.
      76             : 
      77             : See also [`compact`](@ref)
      78             : """
      79           4 : function clone(mesh::Mesh{V, F, H, E}) where {V, F, H, E}
      80           4 :     Mesh{V, F, H, E}(clone(vattr(mesh)), clone(fattr(mesh)),
      81             :                      clone(hattr(mesh)), clone(eattr(mesh)))
      82             : end
      83             : 
      84             : """
      85             :     mesh2 = similar(mesh)
      86             : 
      87             : Create `mesh2` with identical same lists and identical type as `mesh`.
      88             : The enabled state of attributes and the default values are copied
      89             : from `mesh`.
      90             : 
      91             : See also [`createmesh`](@ref)
      92             : """
      93          54 : function Base.similar(mesh::Mesh{V, F, H, E}) where {V, F, H, E}
      94          54 :     Mesh{V, F, H, E}(similar(vattr(mesh)), similar(fattr(mesh)),
      95             :                      similar(hattr(mesh)), similar(eattr(mesh)))
      96             : end
      97             : 
      98             : """
      99             :     empty!(mesh)
     100             : 
     101             : Remove all vertices, i.e., all mesh elements.
     102             : """
     103           0 : function Base.empty!(mesh::Mesh)
     104           0 :     empty!(vattr(mesh))
     105           0 :     empty!(fattr(mesh))
     106           0 :     resizeattr!(attrs(hattr(mesh)), 0)
     107           0 :     empty!(eattr(mesh))
     108             : 
     109           0 :     mesh
     110             : end
     111             : 
     112             : """
     113             :     link(vattr(mesh))
     114             :     link(fattr(mesh))
     115             :     link(hattr(mesh))
     116             :     link(eattr(mesh))
     117             : 
     118             : Access attribute that stores the state of the half-edge data
     119             : structure, which "links" mesh elements.
     120             : 
     121             : !!! note
     122             :     For internal use only!
     123             : 
     124             : See also [`vattr`](@ref), [`fattr`](@ref), [`hattr`](@ref), [`eattr`](@ref)
     125             : """
     126     3630293 : link(ma::ManagedAttributes) = attrs(ma)._link # attrs(ma, :_link)
     127             : 
     128      428797 : vattr(mesh::Mesh) = mesh.v
     129      434080 : fattr(mesh::Mesh) = mesh.f
     130     3229576 : hattr(mesh::Mesh) = mesh.h
     131     3629949 : eattr(mesh::Mesh) = mesh.e
     132             : 
     133          27 : vattr(mesh::Mesh, name::Symbol) = attrs(vattr(mesh), name)
     134           3 : fattr(mesh::Mesh, name::Symbol) = attrs(fattr(mesh), name)
     135           1 : hattr(mesh::Mesh, name::Symbol) = attrs(hattr(mesh), name)
     136           1 : eattr(mesh::Mesh, name::Symbol) = attrs(eattr(mesh), name)
     137             : 
     138          72 : vattr(mesh::Mesh, name::Val{S}) where {S} = attrs(vattr(mesh), S)
     139           4 : fattr(mesh::Mesh, name::Val{S}) where {S} = attrs(fattr(mesh), S)
     140           1 : hattr(mesh::Mesh, name::Val{S}) where {S} = attrs(hattr(mesh), S)
     141           1 : eattr(mesh::Mesh, name::Val{S}) where {S} = attrs(eattr(mesh), S)
     142             : 
     143          39 : vattr(::Mesh, a::Attribute{T, VHnd}) where {T} = a
     144           1 : fattr(::Mesh, a::Attribute{T, FHnd}) where {T} = a
     145           1 : hattr(::Mesh, a::Attribute{T, HHnd}) where {T} = a
     146           1 : eattr(::Mesh, a::Attribute{T, EHnd}) where {T} = a
     147             : 
     148           2 : function vattr(mesh::Mesh, name, default)
     149           2 :     hasvattr(mesh, name) && return vattr(mesh, name)
     150           1 :     default
     151             : end
     152             : 
     153           2 : function fattr(mesh::Mesh, name, default)
     154           2 :     hasfattr(mesh, name) && return fattr(mesh, name)
     155           1 :     default
     156             : end
     157             : 
     158           2 : function hattr(mesh::Mesh, name, default)
     159           2 :     hashattr(mesh, name) && return hattr(mesh, name)
     160           1 :     default
     161             : end
     162             : 
     163           2 : function eattr(mesh::Mesh, name, default)
     164           2 :     haseattr(mesh, name) && return eattr(mesh, name)
     165           1 :     default
     166             : end
     167             : 
     168             : """
     169             :     list = vattr(mesh)
     170             :     attr = vattr(mesh, name)
     171             :     attr = vattr(mesh, Val(name))     # fast & type-safe if name is a literal
     172             :     attr = vattr(mesh, attr)          # identity
     173             : 
     174             :     attr = vattr(mesh, name, default) # checks hasvattr
     175             : 
     176             : Get vertex attribute list from `mesh` or particular vertex attribute
     177             : `name`. The optional `default` argument is returned if
     178             : [`hasvattr`](@ref) yields `false` similar to `Base.get`.
     179             : 
     180             : Example:
     181             : 
     182             :     x = vattr(mesh, :x)
     183             : 
     184             : See also [`fattr`](@ref), [`hattr`](@ref), [`eattr`](@ref)
     185             : """ vattr
     186             : 
     187             : """
     188             :     list = fattr(mesh)
     189             :     attr = fattr(mesh, name)
     190             :     attr = fattr(mesh, Val(name))     # fast & type-safe if name is a literal
     191             :     attr = fattr(mesh, attr)          # identity
     192             : 
     193             :     attr = fattr(mesh, name, default) # checks hasfattr
     194             : 
     195             : Get face attribute list from `mesh` or particular vertex attribute
     196             : `name`. The optional `default` argument is returned if
     197             : [`hasfattr`](@ref) yields `false` similar to `Base.get`.
     198             : 
     199             : See also [`vattr`](@ref), [`hattr`](@ref), [`eattr`](@ref)
     200             : """ fattr
     201             : 
     202             : """
     203             :     list = hattr(mesh)
     204             :     attr = hattr(mesh, name)
     205             :     attr = hattr(mesh, Val(name))     # fast & type-safe if name is a literal
     206             :     attr = hattr(mesh, attr)          # identity
     207             : 
     208             :     attr = hattr(mesh, name, default) # checks hashattr
     209             : 
     210             : Get half-edge attribute list from `mesh` or particular vertex
     211             : attribute `name`. The optional `default` argument is returned if
     212             : [`hashattr`](@ref) yields `false` similar to `Base.get`.
     213             : 
     214             : 
     215             : See also [`vattr`](@ref), [`fattr`](@ref), [`eattr`](@ref)
     216             : """ hattr
     217             : 
     218             : """
     219             :     list = eattr(mesh)
     220             :     attr = eattr(mesh, name)
     221             :     attr = eattr(mesh, Val(name))     # fast & type-safe if name is a literal
     222             :     attr = eattr(mesh, attr)          # identity
     223             :     attr = eattr(mesh, name, default) # checks haseattr
     224             : 
     225             : Get edge attribute list from `mesh` or particular vertex attribute
     226             : `name`. The optional `default` argument is returned if
     227             : [`haseattr`](@ref) yields `false` similar to `Base.get`.
     228             : 
     229             : 
     230             : See also [`vattr`](@ref), [`fattr`](@ref), [`hattr`](@ref)
     231             : """ eattr
     232             : 
     233           4 : hasvattr(mesh::Mesh, name::Symbol) = hasattr(attrs(vattr(mesh)), name)
     234             : 
     235           2 : hasvattr(mesh::Mesh, ::Val{S}) where {S} = hasvattr(mesh, S)
     236             : 
     237           0 : hasvattr(::Mesh, ::Nothing) = false
     238             : 
     239           0 : hasvattr(::Mesh, a::Attribute{T, VHnd}) where {T} = true
     240             : 
     241             : """
     242             :     hasvattr(mesh, name)
     243             : 
     244             :     hasvattr(mesh, :name)
     245             :     hasvattr(mesh, Val(:name))
     246             : 
     247             :     hasvattr(mesh, nothing)               # always false
     248             :     hasvattr(mesh, ::Attribute{T, FHnd})  # always true
     249             : 
     250             : Does `mesh` provide vertex attribute `name`?
     251             : 
     252             : !!! note
     253             :     Calling `hasvattr` with a vertex attribute yields always `true`
     254             :     for consistency with passing attributes.
     255             :     There is no name we could check!
     256             : 
     257             : See also [`vattr`](@ref)
     258             : """
     259             : hasvattr
     260             : 
     261             : 
     262           3 : hasfattr(mesh::Mesh, name::Symbol) = hasattr(attrs(fattr(mesh)), name)
     263             : 
     264           1 : hasfattr(mesh::Mesh, _name::Val{S}) where {S} = hasfattr(mesh, S)
     265             : 
     266           0 : hasfattr(::Mesh, ::Nothing) = false
     267             : 
     268           0 : hasfattr(::Mesh, a::Attribute{T, FHnd}) where {T} = true
     269             : 
     270             : """
     271             :     hasfattr(mesh, name)
     272             : 
     273             :     hasfattr(mesh, :name)
     274             :     hasfattr(mesh, Val(:name))
     275             :     hasfattr(mesh, nothing)               # always false
     276             :     hasfattr(mesh, ::Attribute{T, FHnd})  # always true
     277             : 
     278             : Does `mesh` provide face attribute `name`?
     279             : 
     280             : !!! note
     281             :     Calling `hasfattr` with a face attribute yields always `true`
     282             :     for consistency with passing attributes.
     283             :     There is no name we could check!
     284             : 
     285             : See also [`fattr`](@ref)
     286             : """
     287             : hasfattr
     288             : 
     289             : 
     290           3 : hashattr(mesh::Mesh, name::Symbol) = hasattr(attrs(hattr(mesh)), name)
     291             : 
     292           1 : hashattr(mesh::Mesh, _name::Val{S}) where {S} = hashattr(mesh, S)
     293             : 
     294           0 : hashattr(::Mesh, ::Nothing) = false
     295             : 
     296           0 : hashattr(::Mesh, a::Attribute{T, HHnd}) where {T} = true
     297             : 
     298             : """
     299             :     hashattr(mesh, name)
     300             : 
     301             :     hashattr(mesh, :name)
     302             :     hashattr(mesh, Val(:name))
     303             :     hashattr(mesh, nothing)               # always false
     304             :     hashattr(mesh, ::Attribute{T, HHnd})  # always true
     305             : 
     306             : 
     307             : Does `mesh` provide half-edge attribute `name`?
     308             : 
     309             : !!! note
     310             :     Calling `hashattr` with an half-edge attribute yields always `true`
     311             :     for consistency with passing attributes.
     312             :     There is no name we could check!
     313             : 
     314             : See also [`hattr`](@ref)
     315             : """ hashattr
     316             : 
     317           3 : haseattr(mesh::Mesh, name::Symbol) = hasattr(attrs(eattr(mesh)), name)
     318             : 
     319           1 : haseattr(mesh::Mesh, _name::Val{S}) where {S} = haseattr(mesh, S)
     320             : 
     321           0 : haseattr(::Mesh, ::Nothing) = false
     322             : 
     323           0 : haseattr(::Mesh, a::Attribute{T, EHnd}) where {T} = true
     324             : 
     325             : """
     326             :     haseattr(mesh, name)
     327             : 
     328             :     haseattr(mesh, :name)
     329             :     haseattr(mesh, Val(:name))
     330             :     haseattr(mesh, nothing)               # always false
     331             :     haseattr(mesh, ::Attribute{T, EHnd})  # always true
     332             : 
     333             : 
     334             : Does `mesh` provide edge attribute `name`?
     335             : 
     336             : !!! note
     337             :     Calling `haseattr` with an edge attribute yields always `true`
     338             :     for consistency with passing attributes.
     339             :     There is no name we could check!
     340             : 
     341             : See also [`eattr`](@ref)
     342             : """ haseattr
     343             : 
     344             : 
     345             : """
     346             :     values = collect(mesh, vattr(...))
     347             : 
     348             : Collect all used values.
     349             : 
     350             : !!! note
     351             :     `vec(vattr(...))` provides a view that includes unused values.
     352             : """
     353           0 : Base.collect(mesh::Mesh, va::Attribute{T, VHnd}) where {T} =
     354             :     T[va[v] for v in vertices(mesh)]
     355             : 
     356             : """
     357             :     values = collect(mesh, fattr(...))
     358             : 
     359             : Collect all used values.
     360             : 
     361             : !!! note
     362             :     `vec(fattr(...))` provides a view that includes unused values.
     363             : """
     364             : 
     365           0 : Base.collect(mesh::Mesh, fa::Attribute{T, FHnd}) where {T} =
     366             :     T[fa[f] for f in faces(mesh)]
     367             : 
     368             : """
     369             :     values = collect(mesh, hattr(...))
     370             : 
     371             : Collect all used values.
     372             : 
     373             : !!! note
     374             :     `vec(hattr(...))` provides a view that includes unused values.
     375             : """
     376           0 : Base.collect(mesh::Mesh, ha::Attribute{T, HHnd}) where {T} =
     377             :     T[ha[h] for h in halfedges(mesh)]
     378             : 
     379             : """
     380             :     values = collect(mesh, ettr(...))
     381             : 
     382             : Collect all used values.
     383             : 
     384             : !!! note
     385             :     `vec(eattr(...))` provides a view that includes unused values.
     386             : """
     387           0 : Base.collect(mesh::Mesh, ea::Attribute{T, EHnd}) where {T} =
     388             :     T[ea[e] for e in edges(mesh)]
     389             : 
     390             : """
     391             : Map handles to elements in attribute
     392             : 
     393             : See also [`maphandles`](@ref)
     394             : """
     395             : struct MapHandles{T, H}
     396       80876 :     attr::PMeshAttributes.Attribute{T, H}
     397             : end
     398             : 
     399       81325 : (ma::MapHandles{T, H})(h::H) where {T, H} = ma.attr[h] :: T
     400             : 
     401             : """
     402             :     a = vattr(mesh, x)
     403             :     f = maphandles(a)
     404             : 
     405             :     elt = f(v::VHnd)
     406             : 
     407             : Create a functor that maps handles to attribute `a` (e.g., `VHnd` to
     408             : vertex attributes) to values.
     409             : """
     410       80876 : maphandles(attr::PMeshAttributes.Attribute{T, Hnd{S}}) where {T, S} =
     411             :     MapHandles{T, Hnd{S}}(attr)

Generated by: LCOV version 1.16