Attributes
Attributes map handles to mesh elements (e.g., to a vertex) to values (e.g., a vertex position). They are realized as a list of vectors of same size: if a new element is pushed, all vectors for this element grow simultaneously. Attributes can be disabled and enabled. Disabled attributes remain unchanged while enabled attributes grow.
Note that an efficient implementation of attribute lists may define a particular type for this list (as a named tuple). This requires that all attributes must be defined during initialization (i.e., there is no way to add attributes later). Disable attributes that are currently not required.
Indexing
Attributes are indexed by handles, tuples of handles, arrays of handles, or generators (that yield handles):
# Let ma be a managed attribute list and x one of its attributes.
# Let ma be index by handles of type H.
h = H(1)
x[h] == 0 # read single
x[h] = 1 # write single
#= read multiple
x[(h,h)] # yields tuples (x[h], x[h])
x[[h,h]] # yields array [x[h], x[h]]
sum(x[used(ma)]) # sums x for all handles generated by used(ma)
x[used(ma)] # yields generator
#= write multiple
i = H(2)
x[(h, i)] = 1
x[(h, i)] = (1,2)
x[[h, i]] = [1,2]
x[used(ma)] = 1
x[used(ma)] = 1:n_used(ma)Base.empty! — Method
empty!(ma::ManagedAttributes)Remove all elements.
Base.similar — Method
Create attribute of same type and state but empty vector.
Base.sizehint! — Method
Apply Base.sizehint! to all enabled attributes.
PMeshAttributes.attrlength — Method
Get number of entries in attributes. This is the length of [vec](@ref)(attr) for any enabled attribute attr in a.
PMeshAttributes.attrspecs — Function
s = attrspecs(a::Attribute)
s = attrspecs(attrs::Attributes)Query specifications for single attribute a or list of Attributes. The returned specifications can be used with constructors createattribute and createattributes.
The second form returns a NamedTuple or Vector{Pair} depending on the type of Attributes.
attrspecs doesn't include the indextype!
See also specifyattr
PMeshAttributes.clone — Function
newattrs = clone(attrs::Attributes)Create identical copy of attrs but don't copy data for disabled attributes.
PMeshAttributes.clone — Method
anew = clone(a::Attribute)Create identical copy (deepcopy of vector) of enabled attribute, don;t copy vector data for disabled attribute.
PMeshAttributes.countunused — Method
n = countunused(ma::ManagedAttributes)Count – i.e., compute in O(n_total(ma)) – the number of unused elements.
See also countused
PMeshAttributes.countused — Method
n = countused(ma::ManagedAttributes)Count – i.e., compute in O(n_total(ma)) – the number of used elements.
See also countunused
PMeshAttributes.createattribute — Function
a = createattribute(T[, h=Int; enabled=true, x0=zero(T))
a = createattribute((t::Type, enabled::Bool, x0)[, h=Int])Create Attribute of type T and index type h with default value x0.
The second form creates an attribute from a specification tuple from specifyattr.
See also Attribute, attrspecs, specifyattr
PMeshAttributes.createattributes — Function
a = createattributes(:name => spec, ... [; htyp=Int])
a = createattributes((:name => spec, ...) [; htyp=Int])
a = createattributes([:name => spec, ...], [; htyp=Int])
a = createattributes(Dict(:name => spec, ...), [; htyp=Int])Create Attributes from list with common index/handle type htyp. The two calls create NamedTuples, the second two calls create Dicts.
The specification is given as a list (Tuple or Vector) or Pairs or 2-Tuples. The preferred notation is Pairs and :name => spec (instead of (:name, spec).
The specification spec for each attribute is either a single type (attribute is enabled with zero default values, see Attribute) or the result from specifyattr.
See also specifyattr, Attribute
PMeshAttributes.defaultvalue — Method
Query default value of Attribute a.
See also setdefaultvalue!
PMeshAttributes.enabled — Method
Query Dict of enabled attributes.
PMeshAttributes.hasattr — Function
Does attrs include an attribute name?
PMeshAttributes.indextype — Method
indextype(a::Attributes)Query index or handle type for a.
PMeshAttributes.indices — Method
is = indices(ma::ManagedAttributes[; i0 = I(1))Integer range of all indices from Int(i0) to n_total
indices returns a UnitRange, whereas handles generates handles (of type I) from integer indices.
See also handles
PMeshAttributes.initattr! — Method
initattr!(ma, n[, use=true)Create n elements with used state.
PMeshAttributes.isconsistent — Method
succcess = isconsistent(ma::ManagedAttributes)Apply consistency checks, print diagnostic messages.
PMeshAttributes.isconsistent — Method
result::Bool = isconsistent(attrs)Apply consistency checks.
PMeshAttributes.iscontiguous — Method
iscontiguous(ma::ManagedAttributes)Does ma represent a sequence of elements that are all used, i.e., there are no "gaps" in the sequence used.
PMeshAttributes.isenabled — Method
PMeshAttributes.isindex — Method
isindex(ma::ManagedAttributes, i)Is i a valid index to ma, i.e., is it within the range from 1 to n_total.
See also isused, isindexused
PMeshAttributes.isindexused — Method
isindexused(ma::ManagedAttributes, i)Does index i refer to a used element? Tests used state for a valid index.
This method requires a valid index, i.e., isindex
PMeshAttributes.isunusedindex — Method
isunusedindex(ma::ManagedAttributes, i)Does index i refer to an unused element? This implies isindex and not isindexused.
See also isindex, isindexused
PMeshAttributes.isused — Method
isused(ma::ManagedAttributes, i)Does index i refer to a used element? This implies isindex and isindexused.
See also isindex, isindexused, setused!
PMeshAttributes.n_total — Method
n = n_total(ma::ManagedAttributes)Get total number of – used and unsued – elements.
PMeshAttributes.nextunused — Method
j = nextunused(predicate, ma::ManagedAttributes[, i0])Get index of next used vertex from i0.
PMeshAttributes.nextused — Method
j = nextused(predicate, ma::ManagedAttributes[, i0])Get index of next used vertex from i0.
See also isused, nextwith, nextunused
PMeshAttributes.nextwith — Method
j = nextwith(predicate, ma::ManagedAttributes[, i0])Get next index from i0 that satisfies predicate(ma, i0). Returns invalid handle I(0) if no such handle exists.
See also nextused
PMeshAttributes.pushattr! — Method
Push default value onto all enabled attributes.
PMeshAttributes.pushattr! — Method
pushattr!(ma::ManagedAttributes[, use=true])Push new elements with use state.
PMeshAttributes.resizeattr! — Method
Resize all enabled attributes, grow with default values.
PMeshAttributes.setallused! — Method
PMeshAttributes.setdefaultvalue! — Method
Set default value of Attribute a used with pushattr! and resizeattr!.
PMeshAttributes.setenabled! — Function
setenabled!(attr[, state::Bool=true])
setenabled!(attrs, (:name, state::Bool); initialize=true)
setenabled!(attrs, dict::Dict{Symbol, Bool); initialize=true)Set enabled state for attribute name or for all attributes name => state in dict. Fill with defaultvalue if initialize==true.
See also Attributes, isenabled, enabled
PMeshAttributes.setunused! — Method
setunused!(ma::ManagedAttributes, i)Unset used state for element at index i.
See also isused, setunused!
PMeshAttributes.setused! — Function
setused!(ma::ManagedAttributes, i)
setused!(ma::ManagedAttributes, i, state::Bool)Set (or unset) used state for element at index i.
See also isused, setunused!
PMeshAttributes.shrinkdisabled! — Function
shrinkdisabled!(a)
shrinkdisabled!(attrs)Replace vec(a) by empty array if !isenabled(a). Apply to all attrs.
PMeshAttributes.shrinkdisabled! — Method
shrinkdisabled!(a::Attribute)"Free" memory for data of any disabled attribute in a: the data vector is replaced by a zero-length vector.
PMeshAttributes.specifyattr — Method
spec = specifyattr(T [; enabled=true, x0=zero(T)])Yields specification of an Attribute for use with createattributes. The returned spec is a 3-Tuple, possibly with with default values for the optional keyword arguments.
See also createattributes, Attribute
PMeshAttributes.unused — Method
for h in unused(ma::ManagedAttributes)
...
endGenerate sequence of all unused elements.
PMeshAttributes.used — Method
for h in used(ma::ManagedAttributes)
...
endGenerate sequence of all used elements.
PMeshAttributes.Attribute — Type
# create an attribute with default value x0
a= createattribute(typ::Type{T}[, index::Type[; enabled=true, x0=zero(typ))
indextype(a) # query index type
eltype(a) # query element type T
isenabled(a)
vec(a) # get raw Vector{T}
length(a) # get length of vec(a)
sizehint!(a, n) # same as sizehint!(vec(a))
a[h] # access by index or handle
defaultvalue(a) # query default value
setdefaultvalue!(a)An attribute of a mesh.
Attributes are stored for vertices, faces, half-edges and edges of a mesh. Whenever the number of elements (vertices or factes or ...) changes, all associated attributes change in size. Attributes can disabled such that they will not resize until they are enabled again.
Typically, one operates on a Dict-like set of named Attributes'.
Each attribute is vector-valued and stores per-element values, which can be accessed by indices or handles: pass Hnd type as index.
See also Attributes
PMeshAttributes.FlagsType — Type
Type for manage attribute flags.
PMeshAttributes.ManagedAttributes — Type
Specify abstract managed attribute with index/handle type I.
Mapping attribute values
Attribute values can be maped by functions, i.e., one can construct "virtual read-only" attributes. Such mapped attributes can be evaluated using the same indexing as for attributes.
# x is an attribute, f and g are functions
fx = map(f, x)
fx[h] # is equivalent to f.(x[h])
fx = f ∘ x # is equivalent to map(f, x)
gfx = g ∘ fx # maps by g ∘ f
gfx[h] # is equivalent to g.(f.(x[h])) == g.(fx(h))
gfx = fx ∘ g # maps by f ∘ g
gfx[h] # is equivalent to f.(g.(x[h])) == f.(gx(h))Note that for any composition with ∘ (from left or from right), the attribute is always evaluated first, i.e., you compose the mapping.
Base.map — Method
fa = map(f, attr) x = fa[idx]
Combine reading attr with a map f. Think of fa as a "read-only, virtual attribute".
Using map as above is equivalent to
x = f.(attr[idx])Composition can be used as a syntactic alternative or for composing maps, e.g.,
fa = f ∘ attr
x = fa[idx]
gfa = g ∘ fa
y = gfa[idx] # y == g.(f.(x)) == (g ∘ f).(x)
fga = fa ∘ g
y = fga[idx] # y == f.(g.(x)) == (f ∘ g).(x)PMeshAttributes.MappedAttribute — Type
Map attribute values