{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Terrestrial Laser Scanning of a Small Apple Tree with Leaf Flutter\n",
"\n",
"Notebook: Hannah Weiser, 2023\n",
"\n",
"This is a demonstration of scanning a [dynamic scene](https://github.com/3dgeo-heidelberg/helios/wiki/Dynamic-scenes), consisting of a tree with moving leaves.\n",
"\n",
"We will use the command-line access of HELIOS++ to run the simulation, and use Python just for displaying the input XMLs and the resulting point clouds."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {
"ExecuteTime": {
"end_time": "2023-08-24T14:57:47.799832Z",
"start_time": "2023-08-24T14:57:47.400770Z"
}
},
"outputs": [],
"source": [
"from pathlib import Path\n",
"from IPython.display import Code\n",
"from pyhelios.util.xmldisplayer import display_xml, find_playback_dir"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [],
"source": [
"import os\n",
"os.chdir(\"..\")"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Scene\n",
"\n",
"The scene was generated in [Blender](https://www.blender.org/) using three add-ons:\n",
"- [Sapling Tree Gen](https://docs.blender.org/manual/en/latest/addons/add_curve/sapling.html): This add-on allows to create trees using a set of parameters, using the algorithm by [Weber & Penn (1995)](https://doi.org/10.1145/218380.218427). For the resulting tree, the stem curve was converted to a mesh, and the leaves were [separated \"By Loose Parts\"](https://docs.blender.org/manual/en/latest/modeling/meshes/editing/mesh/separate.html). This way, each leaf can be moved individually.\n",
"- [Move Leaves](https://github.com/han16nah/movingtree_b2h/blob/main/addons/moveleaves.py): This add-on creates a leaf animation for a given tree (created by e.g., Sapling Tree Gen) by rotating the leaves around their leaf base. The user can provide an initial leaf angle distribution, the (random) fraction of leaves moving, the oscillation frequency and the normal distributions $N$($\\mu$, $\\sigma$), from which the three Euler rotation angles $X$, $Y$ and $Z$ will be sampled at each time step. In this case, half of the leaves are moving with an oscillation frequency of 6 and a rotation angle normal distribution $N(0°, 16°)$ for $X$ and $N(0°, 4°)$ for $Y$ and $Z$.\n",
"- [DynScene2HELIOS](https://github.com/3dgeo-heidelberg/dyn_b2h): This add-on allows exporting dynamic Blender scenes (i.e., scenes with rigid motions) to HELIOS++ sceneparts and scenes. It considers translations and rotations.\n",
"\n",
"This is what the Blender animation looks like:\n",
"![moving_tree](https://github.com/3dgeo-heidelberg/helios/blob/dev/img/example15.gif?raw=true \"moving_tree\")\n",
"\n",
"Finally, further modifications were made:\n",
"- A wavefront material template library (MTL) was assigned (`leafwood.mtl`), which contains `helios_spectra` and `helios_classification` for the different materials (`Leaves` and `TrunksAndBranches`) to assign realistic reflectance values and to create an automatic classification of the output point cloud.\n",
"\n",
"The exported dynamic scene is very large, but you can have a look [here](https://github.com/3dgeo-heidelberg/helios/blob/dev/data/scenes/movingtrees/tree10_a.xml). Let's have a look at how the sceneparts are configured."
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Static Scene Parts\n",
"\n",
"For the static sceneparts, we simply load the 3D models from the corresponding OBJ files. For completeness, we also set the \"up axis\" to \"z\", which is also the HELIOS++ default.\n",
"\n",
"```XML\n",
"
<platform id="tripod" name="TLS Tripod" type="static" drag="0">\n",
"\t\t<scannerMount x="0" y="0" z="1.5">\n",
"\t\t</scannerMount>\n",
"\t</platform>\n",
"\t\n",
"
<scanner id="riegl_vz400" name="RIEGL VZ-400" accuracy_m="0.005" beamDivergence_rad="0.0003" headRotatePerSecMax_deg="60" optics="rotating" pulseFreqs_Hz="100000,300000" pulseLength_ns="5" rangeMin_m="1.5" scanAngleMax_deg="120" scanAngleEffectiveMax_deg="50" scanFreqMin_Hz="3" scanFreqMax_Hz="120">\n",
"\t\t\n",
"\t\t<FWFSettings beamSampleQuality="3" />\t\n",
"\t\t<beamOrigin x="0" y="0" z="0.2">\n",
"\t\t\t<rot axis="y" angle_deg="0" />\n",
"\t\t\t<rot axis="z" angle_deg="0" />\n",
"\t\t\t<rot axis="x" angle_deg="0" />\n",
"\t\t</beamOrigin>\n",
"\t\t<headRotateAxis x="0" y="0" z="1" />\n",
"\t\t\n",
"\t</scanner>\n",
"\t\n",
"
<document>\n",
" <scannerSettings id="tls" active="true" pulseFreq_hz="600000" verticalResolution_deg="0.04" horizontalResolution_deg="0.04" />\n",
" <survey name="tls_tree1_dyn" platform="data/platforms.xml#tripod" scanner="data/scanners_tls.xml#riegl_vz400" scene="data/scenes/dyn/tree1_dyn.xml#tree1">\n",
" <leg>\n",
" <platformSettings x="3.0000" y="0.0000" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="45.0000" headRotateStop_deg="135.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" <leg>\n",
" <platformSettings x="1.5000" y="2.5981" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="105.0000" headRotateStop_deg="195.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" <leg>\n",
" <platformSettings x="-1.5000" y="2.5981" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="-195.0000" headRotateStop_deg="-105.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" <leg>\n",
" <platformSettings x="-3.0000" y="0.0000" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="-135.0000" headRotateStop_deg="-45.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" <leg>\n",
" <platformSettings x="-1.5000" y="-2.5981" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="-75.0000" headRotateStop_deg="15.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" <leg>\n",
" <platformSettings x="1.5000" y="-2.5981" z="0" onGround="false" />\n",
" <scannerSettings template="tls" headRotateStart_deg="-15.0000" headRotateStop_deg="75.0000" trajectoryTimeInterval_s="0.05" />\n",
" </leg>\n",
" \n",
" </survey>\n",
" </document>\n",
"