AMAP Quickstart
PlantGeom now uses the AMAP core reconstruction profile by default in set_geometry_from_attributes! and reconstruct_geometry_from_attributes!.
If you need help choosing explicit-coordinate behavior (explicit_coordinate_mode), start with the AMAP Reconstruction Decision Guide.
1. Load MTG + Reconstruct
Content of `reconstruction_standard.mtg`
CODE: FORM-A
CLASSES:
SYMBOL SCALE DECOMPOSITION INDEXATION DEFINITION
Plant 1 FREE FREE IMPLICIT
Internode 2 FREE FREE IMPLICIT
Leaf 2 FREE FREE IMPLICIT
DESCRIPTION:
LEFT RIGHT RELTYPE MAX
FEATURES:
NAME TYPE
Thickness REAL
Length REAL
Width REAL
YEuler REAL
XEuler REAL
XInsertionAngle REAL
YInsertionAngle REAL
Offset REAL
BorderInsertionOffset REAL
MTG:
ENTITY-CODE Thickness Length Width YEuler XEuler XInsertionAngle YInsertionAngle Offset BorderInsertionOffset
/Plant1
^/Internode1 0.035 0.28 0.035 1.438276615812609
+Leaf1 0.002 0.235 0.116 -18.0 45.0 53.68294196961579 0.2296 0.0175
^<Internode2 0.03325 0.2632 0.03325 2.5244129544236893
+Leaf2 0.002 0.25 0.122 -18.0 135.0 53.81859485365136 0.215824 0.016625
^<Internode3 0.031587500000000004 0.24740800000000002 0.031587500000000004 2.9924849598121632
+Leaf3 0.002 0.265 0.128 -18.0 225.0 52.28224001611974 0.20287456 0.015793750000000002
^<Internode4 0.030008125 0.23256352 0.030008125 2.727892280477045
^+Leaf4 0.002 0.28 0.134 -18.0 315.0 50.48639500938415 0.1907020864 0.0150040625mtg_file = joinpath(pkgdir(PlantGeom), "test", "files", "reconstruction_standard.mtg")
mtg = read_mtg(mtg_file)
set_geometry_from_attributes!(
mtg,
ref_meshes;
convention=default_amap_geometry_convention(),
)
length(descendants(mtg, :geometry; ignore_nothing=true, self=true))8plantviz(mtg, color=Dict("Stem" => :tan4, "Leaf" => :forestgreen))2. Customize AMAP Options
mtg_default = read_mtg(mtg_file)
mtg_custom = read_mtg(mtg_file)
set_geometry_from_attributes!(
mtg_default,
ref_meshes;
convention=default_amap_geometry_convention(),
)
amap_custom = AmapReconstructionOptions(
order_override_mode=:override,
insertion_y_by_order=Dict(2 => 25.0),
)
set_geometry_from_attributes!(
mtg_custom,
ref_meshes;
convention=default_amap_geometry_convention(),
amap_options=amap_custom,
)
(
default=length(descendants(mtg_default, :geometry; ignore_nothing=true, self=true)),
custom=length(descendants(mtg_custom, :geometry; ignore_nothing=true, self=true)),
)(default = 8, custom = 8)Both calls use AMAP stages. The second one customizes option values and visibly changes leaf insertion.
reconstruction_standard.mtg already defines XInsertionAngle on leaves, so phyllotaxy_by_order would not change this specific fixture unless XInsertionAngle is missing.
plantviz(mtg_custom, color=Dict("Stem" => :tan4, "Leaf" => :darkgreen))Code to reproduce this page figures
using PlantGeom
using MultiScaleTreeGraph
using GeometryBasics
using Colors
using CairoMakie
CairoMakie.activate!()
const Tri = GeometryBasics.TriangleFace{Int}
function cylinder_mesh_x(radius=0.5, length=1.0)
GeometryBasics.mesh(
GeometryBasics.Cylinder(
Point(0.0, 0.0, 0.0),
Point(length, 0.0, 0.0),
radius,
),
)
end
function leaf_mesh_x()
GeometryBasics.Mesh(
[
Point(0.0, -0.05, 0.0),
Point(0.0, 0.05, 0.0),
Point(0.2, 0.0, 0.0),
Point(1.2, 0.0, 0.0),
Point(0.7, -0.45, 0.0),
Point(0.7, 0.45, 0.0),
],
Tri[
Tri(1, 2, 3),
Tri(3, 5, 4),
Tri(3, 6, 4),
],
)
end
ref_meshes = Dict(
"Internode" => RefMesh("Stem", cylinder_mesh_x(0.5, 1.0), RGB(0.55, 0.45, 0.35)),
"Leaf" => RefMesh("Leaf", leaf_mesh_x(), RGB(0.1, 0.5, 0.2)),
)
mtg_file = joinpath(pkgdir(PlantGeom), "test", "files", "reconstruction_standard.mtg")
mtg = read_mtg(mtg_file)
set_geometry_from_attributes!(
mtg,
ref_meshes;
convention=default_amap_geometry_convention(),
)
plantviz(mtg, color=Dict("Stem" => :tan4, "Leaf" => :forestgreen))
mtg_custom = read_mtg(mtg_file)
amap_custom = AmapReconstructionOptions(
order_override_mode=:override,
insertion_y_by_order=Dict(2 => 25.0),
)
set_geometry_from_attributes!(
mtg_custom,
ref_meshes;
convention=default_amap_geometry_convention(),
amap_options=amap_custom,
)
plantviz(mtg_custom, color=Dict("Stem" => :tan4, "Leaf" => :darkgreen))