TreeSkeleton

from acron.proctree import TreeSkeleton
class TreeSkeleton

Bases:

Bases: TypedReferenceCount

A grown tree before it is a mesh: every random choice has been made, and everything below it (the mesh, the LODs, the impostor) is a pure function of it.

Three tables of struct-of-arrays, each array a read-only CPTA that Python reads without a copy (`memoryview(s.node_positions).cast(“f”)`); a skeleton never changes once grown (edit a copy through the growth ops):

  • nodes – the points along each stem: position, a rotation-minimising frame (tangent, normal), radius, arc length from the stem’s start, distance from the root along the wood, the wind weight (continuous across forks: a child starts at its parent’s weight where it grows from) and the branch the node belongs to;

  • branches – the stems in depth-first order (a branch’s whole subtree is `[i, subtree_end)`): first node and node count, parent and the fractional node index on the parent it grows from (`parent_t`), level, kind (0 trunk, 1 branch, 2 root), length and a phase;

  • leaves – the leaf cards: centre, normal, up, size (w, h), the anchor on the stem’s centreline, the wind weight there, a random number, the sprite and the layout (0 single, 1 crossed, 2 cluster).

The crown is the leaves’ bounding ellipsoid (the mesher points leaf normals out of it). Lengths are metres, z up, the root at the origin.

Inheritance diagram

digraph inheritance179810c20f { bgcolor=transparent; rankdir=BT; size="8.0, 12.0"; "DTOOL_SUPER_BASE" [fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style=""]; "ReferenceCount" [URL="acron.core.ReferenceCount.html#acron.core.ReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "ReferenceCount" [arrowsize=0.75,style=""]; "TreeSkeleton" [URL="acron.proctree.TreeSkeleton.html#acron.proctree.TreeSkeleton",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "TypedReferenceCount" -> "TreeSkeleton" [arrowsize=0.75,style=""]; "TypedObject" [URL="acron.core.TypedObject.html#acron.core.TypedObject",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "DTOOL_SUPER_BASE" -> "TypedObject" [arrowsize=0.75,style=""]; "TypedReferenceCount" [URL="acron.core.TypedReferenceCount.html#acron.core.TypedReferenceCount",fillcolor=white,fontname="Vera Sans, DejaVu Sans, Liberation Sans, Arial, Helvetica, sans",fontsize=11,height=0.25,shape=box,style="",target="_top",tooltip="/**"]; "TypedObject" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; "ReferenceCount" -> "TypedReferenceCount" [arrowsize=0.75,style=""]; }
enum Kind
enumerator K_trunk = 0
enumerator K_branch = 1
enumerator K_root = 2
__init__()

A deep copy: the arrays are not shared.

property bounds_max → LPoint3f
property bounds_min → LPoint3f
property branch_first_node → CPTA_int
property branch_kind → CPTA_int
property branch_length → CPTA_float
property branch_level → CPTA_int
property branch_num_nodes → CPTA_int
property branch_parent → CPTA_int
property branch_parent_t → CPTA_float
property branch_phase → CPTA_float
property branch_subtree_end → CPTA_int
property crown_center → LPoint3f
property crown_radii → LVecBase3f
get_bounds_max()
get_bounds_min()
get_branch_first_node()
get_branch_kind()
get_branch_length()
get_branch_level()
get_branch_num_nodes()
get_branch_parent()
get_branch_parent_t()
get_branch_phase()
get_branch_subtree_end()
static get_class_type()
get_crown_center()
get_crown_radii()
get_hash()

A 64-bit FNV-1a digest of every table: equal for byte-identical trees.

get_height()
get_leaf_anchors()
get_leaf_area()

The summed area of the leaf cards (m^2; a crossed card counts once).

get_leaf_branch()
get_leaf_kind()
get_leaf_normals()
get_leaf_positions()
get_leaf_random()
get_leaf_sizes()
get_leaf_sprite()
get_leaf_t()

where each leaf sits on its branch: a fractional node index, like parent_t

where each leaf sits on its branch: a fractional node index, like parent_t

get_leaf_ups()
get_leaf_wind()
get_max_level()
get_node_arc()
get_node_branch()
get_node_dist_root()
get_node_normals()
get_node_positions()
get_node_radii()
get_node_tangents()
get_node_wind()
get_num_branches()
get_num_leaves()
get_num_nodes()
get_trunk_radius()

The radius of the first trunk at its base (before the flare’s peak: the second node).

property height → float
is_valid()

Whether the tables are consistent: every array the length its table says, each branch’s nodes inside the node table, parents before their children, each subtree `[b, subtree_end)` nested inside its parent’s, and every leaf on a real branch. The mesher and the LOD builder check this before they index anything.

property leaf_anchors → CPTA_float
property leaf_branch → CPTA_int
property leaf_kind → CPTA_int
property leaf_normals → CPTA_float
property leaf_positions → CPTA_float
property leaf_random → CPTA_float
property leaf_sizes → CPTA_float
property leaf_sprite → CPTA_int
property leaf_t → CPTA_float

where each leaf sits on its branch: a fractional node index, like parent_t

where each leaf sits on its branch: a fractional node index, like parent_t

where each leaf sits on its branch: a fractional node index, like parent_t

property leaf_ups → CPTA_float
property leaf_wind → CPTA_float
make_copy()
property max_level → int
property node_arc → CPTA_float
property node_branch → CPTA_int
property node_dist_root → CPTA_float
property node_normals → CPTA_float
property node_positions → CPTA_float
property node_radii → CPTA_float
property node_tangents → CPTA_float
property node_wind → CPTA_float
property num_branches → int
property num_leaves → int
property num_nodes → int
output()