API
PlantGeom.Material
PlantGeom.Phong
PlantGeom.RefMesh
PlantGeom.RefMeshes
PlantGeom.geometry
Base.:==
Base.:==
Base.:==
Meshes.nelements
Meshes.nelements
Meshes.nvertices
Meshes.nvertices
PlantGeom.align_ref_meshes
PlantGeom.attributes_to_xml
PlantGeom.color_type
PlantGeom.colorant_to_string
PlantGeom.coordinates!
PlantGeom.diagram
PlantGeom.diagram!
PlantGeom.extend_pos
PlantGeom.get_attr_type
PlantGeom.get_color
PlantGeom.get_colormap
PlantGeom.get_mtg_color
PlantGeom.get_ref_mesh_index
PlantGeom.get_ref_mesh_index!
PlantGeom.get_ref_meshes
PlantGeom.get_ref_meshes_color
PlantGeom.map_coord
PlantGeom.materialBDD_to_material
PlantGeom.material_to_opf_string
PlantGeom.meshBDD_to_meshes
PlantGeom.mtg_coordinates_df
PlantGeom.mtg_to_opf_link
PlantGeom.mtg_topology_to_xml!
PlantGeom.normals_vertex
PlantGeom.parse_geometry
PlantGeom.parse_materialBDD!
PlantGeom.parse_meshBDD!
PlantGeom.parse_opf_array
PlantGeom.parse_opf_attributeBDD!
PlantGeom.parse_opf_elements!
PlantGeom.parse_opf_topology!
PlantGeom.parse_ref_meshes
PlantGeom.read_opf
PlantGeom.read_ops
PlantGeom.read_ops_file
PlantGeom.refmesh_to_mesh
PlantGeom.refmesh_to_mesh!
PlantGeom.rotate_point
PlantGeom.taper
PlantGeom.transform_mesh!
PlantGeom.write_opf
PlantGeom.write_ops
PlantGeom.xmax
PlantGeom.xmin
PlantGeom.ymax
PlantGeom.ymin
PlantGeom.zmax
PlantGeom.zmin
RecipesBase.plot
RecipesBase.plot!
PlantGeom.Material
— TypeA material for the illumination model (e.g. Phong illumination).
PlantGeom.Phong
— TypeData structure for a mesh material that is used to describe the light components of a Phong reflection type model. All data is stored as RGBα for Red, Green, Blue and transparency.
PlantGeom.RefMesh
— TypeRefMesh(
name::S
mesh::SimpleMesh
normals::N
texture_coords::T
material::M
taper::Bool
)
RefMesh(name, mesh, material = RGB(220 / 255, 220 / 255, 220 / 255))
RefMesh type. Stores all information about a Mesh:
name::S
: the mesh namemesh::SimpleMesh
: the actual mesh information -> points and topologynormals::Vector{Float64}
: the normals, given as a vector of x1,y1,z1,x2,y2,z2...texture_coords::Vector{Float64}
: the texture coordinates (not used yet), idem, a vectormaterial::M
: the material, used to set the shadingtaper::Bool
:true
if tapering is enabled
The reference meshes are then transformed on each node of the MTG using a transformation matrix to match the actual mesh.
PlantGeom.RefMeshes
— TypeRefMeshes type. Data base that stores all RefMesh
in an MTG. Usually stored in the :ref_meshes
attribute of the root node.
PlantGeom.geometry
— Typegeometry(; ref_mesh<:RefMesh, ref_mesh_index=nothing, transformation=Identity(), dUp=1.0, dDwn=1.0, mesh::Union{SimpleMesh,Nothing}=nothing)
A Node geometry with the reference mesh, its transformation (as a function) and optionnally the index of the reference mesh in the reference meshes data base (see notes) and the resulting mesh (optional to save memory).
Note
The refmesh usually points to a RefMesh
stored in the `:refmeshes` attribute of the root node of the MTG.
Although optional, storing the index of the reference mesh (ref_mesh_index
) in the database allows a faster writing of the MTG as an OPF to disk.
The transformation
field should be a TransformsBase.Transform
, such as TransformsBase.Identity
, or the ones implemented in Meshes.jl
, e.g. Translate
, Scale
... If you already have the transformation matrix, you can pass it to Meshes.Affine()
.
Base.:==
— Method==(a::geometry, b::geometry)
Test RefMeshes equality.
Base.:==
— Method==(a::RefMesh, b::RefMesh)
Test RefMesh equality.
Base.:==
— Method==(a::RefMeshes, b::RefMeshes)
Test RefMeshes equality.
Meshes.nelements
— Methodnelements(meshes::RefMeshes)
Return the number of elements for each reference mesh as a vector of nelements
Meshes.nelements
— Methodnelements(meshes::RefMeshes)
Return the number of elements of a reference mesh
Meshes.nvertices
— Methodnvertices(meshes::RefMeshes)
Return the number of vertices for each reference mesh as a vector of nvertices
Meshes.nvertices
— Methodnvertices(meshes::RefMesh)
Return the number of vertices of a reference mesh
PlantGeom.align_ref_meshes
— Methodalign_ref_meshes(meshes::RefMeshes)
Align all reference meshes along the X axis. Used for visualisation only.
PlantGeom.attributes_to_xml
— Methodattributes_to_xml(node, xml_parent)
Write an MTG node into an XML node.
PlantGeom.color_type
— Methodcolor_type(color, opf)
Return the type of the color, whether it is an attribute, a colorant, or a RefMeshColorant.
Arguments
color
: The color to be checked.opf
: The MTG to be plotted.
Returns
RefMeshColorant
: If the color is :slategray3, then it is the default color given by Meshes,
so we assume nothing was passed by the user and color by reference mesh instead.
AttributeColorant
: If the color is an attribute of the MTG, then we color by that attribute.T
: If the color is a colorant, then we color everything by that color.
Examples
using MultiScaleTreeGraph, PlantGeom, Colors
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
# Colors:
color_type(:red, opf)
color_type(RGB(0.1,0.5,0.1), opf)
# Attributes:
color_type(:Length, opf)
# Default color:
color_type(:slategray3, opf)
# Dict of colors:
color_type(Dict(1=>RGB(0.1,0.5,0.1), 2=>RGB(0.5,0.1,0.1)), opf)
PlantGeom.colorant_to_string
— Methodcolorant_to_string(x)
Parse a geometry material for OPF writing.
PlantGeom.coordinates!
— Methodcoordinates!(mtg; angle = 45; force = false)
Compute dummy 3d coordinates for the mtg nodes using an alterning phyllotaxy. Used when coordinates are missing. Coordinates are just node attributes with reserved names: :XX, :YY and :ZZ.
Returns
Nothing, mutates the mtg in-place (adds :XX, :YY and :ZZ to nodes).
Examples
file = joinpath(dirname(dirname(pathof(MultiScaleTreeGraph))),"test","files","simple_plant.mtg")
mtg = read_mtg(file)
coordinates!(mtg)
DataFrame(mtg, [:XX, :YY, :ZZ])
PlantGeom.diagram
— Functiondiagram(opf::MultiScaleTreeGraph.Node; kwargs...)
diagram!(opf::MultiScaleTreeGraph.Node; kwargs...)
Make a diagram of the MTG tree using a Makie.jl
backend.
This function is an extension to the package. It is only available if you imported a Makie backend (e.g. using GLMakie
) prior to using PlantGeom
.
The main attributes are:
- color: the color of the nodes
- colormap: the colormap used if the color uses an attribute. By default it uses viridis.
Must be a ColorScheme from ColorSchemes or a Symbol with its name.
Examples
using GLMakie, PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
# file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","coffee.opf")
opf = read_opf(file)
diagram(opf)
# We can also color the 3d plot with several options:
# With one shared color:
diagram(opf, color = :red)
# Or colouring by opf attribute, *e.g.* using the nodes Z coordinates:
diagram(opf, color = :ZZ)
PlantGeom.diagram!
— Functiondiagram(opf::MultiScaleTreeGraph.Node; kwargs...)
diagram!(opf::MultiScaleTreeGraph.Node; kwargs...)
Make a diagram of the MTG tree using a Makie.jl
backend.
This function is an extension to the package. It is only available if you imported a Makie backend (e.g. using GLMakie
) prior to using PlantGeom
.
The main attributes are:
- color: the color of the nodes
- colormap: the colormap used if the color uses an attribute. By default it uses viridis.
Must be a ColorScheme from ColorSchemes or a Symbol with its name.
Examples
using GLMakie, PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
# file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","coffee.opf")
opf = read_opf(file)
diagram(opf)
# We can also color the 3d plot with several options:
# With one shared color:
diagram(opf, color = :red)
# Or colouring by opf attribute, *e.g.* using the nodes Z coordinates:
diagram(opf, color = :ZZ)
PlantGeom.extend_pos
— MethodAdd a new point after (x1,y1) using same direction and length relative to it
PlantGeom.get_attr_type
— MethodGet the attributes types in Julia DataType
.
PlantGeom.get_color
— Methodget_color(var <: AbstractArray, range_var, colormap=colorschemes[:viridis])
get_color(var, range_var, colormap=colorschemes[:viridis])
Map value(s) to colors from a colormap based on a range of values
Arguments
var
: value(s) to map to colorsrange_var
: range of values to map to colorscolormap
: colormap to use
Returns
color
: color(s) corresponding tovar
Examples
```julia using Colors
getcolor(1, 1:2, colormap = colorschemes[:viridis]) # returns RGB{N0f8}(0.267004,0.00487433,0.329415) getcolor(1:2, 1:10, colormap = colorschemes[:viridis]) # returns RGB{N0f8}(0.267004,0.00487433,0.329415) get_color(1:2, 1:10, 1, colormap = colorschemes[:viridis]) # returns RGB{N0f8}(0.267004,0.00487433,0.329415)
PlantGeom.get_colormap
— Methodget_colormap(colormap)
Get the colormap as a ColorScheme if it is a named color or ColorScheme
PlantGeom.get_mtg_color
— Methodget_mtg_color(color, opf)
Return the color to be used for the plot.
Arguments
color
: The color to be checked.opf
: The MTG to be plotted.
Returns
The color to be used for the plot.
Examples
using MultiScaleTreeGraph, PlantGeom, Colors
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
get_mtg_color(:red, opf)
get_mtg_color(RGB(0.1,0.5,0.1), opf)
get_mtg_color(:Length, opf)
get_mtg_color(:slategray3, opf)
get_mtg_color(Dict(1=>RGB(0.1,0.5,0.1), 2=>RGB(0.1,0.1,0.5)), opf)
get_mtg_color(Dict(1 => :burlywood4, 2 => :springgreen4), opf)
PlantGeom.get_ref_mesh_index
— Functionget_ref_mesh_index!(node, ref_meshes = get_ref_meshes(node))
get_ref_mesh_index(node, ref_meshes = get_ref_meshes(node))
Get the index of the reference mesh used in the current node.
Notes
Please use the ref_meshes
argument preferably as not giving it make the function visit the root node each time otherwise, and it can become a limitation when traversing a big MTG.
PlantGeom.get_ref_mesh_index!
— Functionget_ref_mesh_index!(node, ref_meshes = get_ref_meshes(node))
get_ref_mesh_index(node, ref_meshes = get_ref_meshes(node))
Get the index of the reference mesh used in the current node.
Notes
Please use the ref_meshes
argument preferably as not giving it make the function visit the root node each time otherwise, and it can become a limitation when traversing a big MTG.
PlantGeom.get_ref_meshes
— Methodget_ref_meshes(mtg)
Get all reference meshes from an mtg, usually from an OPF.
Examples
using PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
meshes = get_ref_meshes(opf)
using GLMakie
viz(meshes)
PlantGeom.get_ref_meshes_color
— Methodget_ref_meshes_color(meshes::RefMeshes)
Get the reference meshes colors (only the diffuse part for now).
Examples
using MultiScaleTreeGraph, PlantGeom
file = joinpath(dirname(dirname(pathof(MultiScaleTreeGraph))),"test","files","simple_plant.opf")
opf = read_opf(file)
meshes = get_ref_meshes(opf)
PlantGeom.get_ref_meshes_color(meshes)
PlantGeom.map_coord
— Methodmap_coord(f, mesh, coord)
Apply function f
over the mesh coordinates coord
. Values for coord
can be 1 for x, 2 for y and 3 for z.
PlantGeom.materialBDD_to_material
— MethodParse a material in opf format to a Phong
material.
PlantGeom.material_to_opf_string
— Methodmaterial_to_opf_string(material::Phong)
material_to_opf_string(material::Colorant)
Format a material into a Dict for OPF writting.
PlantGeom.meshBDD_to_meshes
— MethodmeshBDD_to_meshes(x)
Examples
using MultiScaleTreeGraph
file = joinpath(dirname(dirname(pathof(MultiScaleTreeGraph))),"test","files","simple_plant.opf")
opf = read_opf(file)
meshBDD_to_meshes(opf[:meshBDD])
PlantGeom.mtg_coordinates_df
— Functionmtg_coordinates_df(mtg, attr; force = false)
mtg_coordinates_df!(mtg, attr; force = false)
Extract the coordinates of the nodes of the mtg and the coordinates of their parents (:XXfrom, :YYfrom, :ZZ_from) and output a DataFrame. Optionally you can also provide an attribute to add to the output DataFrame too by passing its name as a symbol to attr
.
The coordinates are computed using coordinates!
if missing, or if force = true
.
PlantGeom.mtg_to_opf_link
— Methodmtg_to_opf_link(link)
Takes an MTG link as input ("/", "<" or "+") and outputs its corresponding link as declared in the OPF format ("decomp", "follow" or "branch")
PlantGeom.mtg_topology_to_xml!
— Functionmtg_topology_to_xml!(node, xml_parent)
Write the MTG topology, attributes and geometry into XML format. This function is used to write the "topology" section of the OPF.
PlantGeom.normals_vertex
— Methodnormals_vertex(mesh::Meshes.SimpleMesh)
Compute per vertex normals and return them as a StaticArrays.SVector
.
#! This is a naive approach because I have no time right know. #! We just put the face mesh as a vertex mesh (and ovewritting values for common points)
TODO: Use a real computation instead. See e.g.:
https://stackoverflow.com/questions/45477806/general-method-for-calculating-smooth-vertex-normals-with-100-smoothness?noredirect=1&lq=1
PlantGeom.parse_geometry
— MethodParse the geometry element of the OPF.
Note
The transformation matrix is 3*4. elem = elem.content
PlantGeom.parse_materialBDD!
— MethodParse the materialBDD using parse_opf_elements!
PlantGeom.parse_meshBDD!
— MethodParse the meshBDD using parse_opf_array
PlantGeom.parse_opf_array
— FunctionParse an array of values from the OPF into a Julia array (Arrays in OPFs are not following XML recommendations)
PlantGeom.parse_opf_attributeBDD!
— MethodParse the opf attributes as a Dict.
PlantGeom.parse_opf_elements!
— MethodGeneric parser for OPF elements.
Arguments
opf::OrderedDict
: the opf Dict (using [XMLDict.xml_dict])elem_types::Array
: the target types of the element (e.g. "[String, Int64]")
Details
elem_types
should be of the same length as the number of elements found in each item of the subchild. elem_types = [Float64, Float64, Float64, Float64, Float64, Float64]
PlantGeom.parse_opf_topology!
— Functionparse_opf_topology!(node, mtg, features, attr_type, mtg_type, ref_meshes, id_set=Set{Int}())
Parser of the OPF topology.
Arguments
node::ElementNode
: the XML node to parse.mtg::Union{Nothing,Node}
: the parent MTG node.features::Dict
: the features of the OPF.attr_type::DataType
: the type of the attributes to use.mtg_type::DataType
: the type of the MTG to use.ref_meshes::Dict
: the reference meshes.read_id::Bool
: whether to read the ID from the OPF or recompute it on the fly.max_id::RefValue{Int64}=Ref(1)
: the ID of the first node, ifread_id==false
.
Note
The transformation matrices in geometry
are 3*4.
PlantGeom.parse_ref_meshes
— Methodparse_ref_meshes(mtg)
Parse the reference meshes of an OPF into RefMeshes.
PlantGeom.read_opf
— Methodread_opf(file; attr_type = Dict, mtg_type = MutableNodeMTG)
Read an OPF file, and returns an MTG.
Arguments
file::String
: The path to the opf file.attr_type::DataType = Dict
: the type used to hold the attribute values for each node.mtg_type = MutableNodeMTG
: the type used to hold the mtg encoding for each node (i.e.
link, symbol, index, scale). See details section below.
read_id::Bool = true
: whether to read the ID from the OPF or recompute it on the fly.max_id::RefValue{Int64}=Ref(1)
: the ID of the first node, ifread_id==false
.
Details
attr_type
should be:
NamedTuple
if you don't plan to modify the attributes of the mtg, e.g. to use them for
plotting or computing statistics...
MutableNamedTuple
if you plan to modify the attributes values but not adding new attributes
very often, e.g. recompute an attribute value...
Dict
or similar (e.g.OrderedDict
) if you plan to heavily modify the attributes, e.g.
adding/removing attributes a lot
The MultiScaleTreeGraph
package provides two types for mtg_type
, one immutable (NodeMTG
), and one mutable (MutableNodeMTG
). If you're planning on modifying the mtg encoding of some of your nodes, you should use MutableNodeMTG
, and if you don't want to modify anything, use NodeMTG
instead as it should be faster.
Note
See the documentation of the MTG format from the MTG package documentation for further details, e.g. The MTG concept.
Returns
The MTG root node.
Examples
using PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
# file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","coffee.opf")
opf = read_opf(file)
PlantGeom.read_ops
— Methodread_ops(file; attr_type=Dict{String,Any}, mtg_type=MutableNodeMTG)
Reads an OPS file and returns the content as a MultiScaleTreeGraph
.
Arguments
file::String
: Path of the.ops
file to read.attr_type::Type=Dict{Symbol,Any}
: Type of the attributes to use.mtg_type::Type
: Type of the MTG to use, e.g.NodeMTG
orMutableNodeMTG
.
Returns
A MultiScaleTreeGraph
of the scene, with the OPFs as children of the scene node. The dimension of the scene is available in the scene_dimensions
attribute of the scene node. Each root node of the OPFs has a scene_transformation
attribute that stores the transformation applied to the OPF by the scene. It allows updating the scene transformations and write the scene back to disk. The OPF root node also has the following attributes:
sceneID::Int
: Scene ID.plantID::Int
: Plant ID.filePath::String
: Path to the original.opf
file.pos::Meshes.Point
: Position of the object.scale::Float64
: Scale of the object.inclinationAzimut::Float64
: Inclination azimut of the object.inclinationAngle::Float64
: Inclination angle of the object.rotation::Float64
: Rotation of the object.functional_group::String
: Functional group of the object.
Details
Node IDs of the OPFs are recomputed at import to ensure their uniqueness in the larger scene MTG.
Example
using CairoMakie, PlantGeom
joinpath(pathof(PlantGeom) |> dirname |> dirname, "test", "files", "scene.ops") |> read_ops |> viz
PlantGeom.read_ops_file
— Methodread_ops_file(file)
Read the content of an .ops
file and return a tuple with the scene dimensions and the object table.
Arguments
file::String
: Path of the.ops
file to read.
Returns
The scene dimensions and the object table as a tuple. The scene dimensions are a tuple of two Meshes.Point
with the origin point and opposite point of the scene. The object table is an array of NamedTuple
with the following fields:
sceneID::Int
: Scene ID.plantID::Int
: Plant ID.filePath::String
: Path to the.opf
file.pos::Meshes.Point
: Position of the object.scale::Float64
: Scale of the object.inclinationAzimut::Float64
: Inclination azimut of the object.inclinationAngle::Float64
: Inclination angle of the object.rotation::Float64
: Rotation of the object.functional_group::String
: Functional group of the object.
PlantGeom.refmesh_to_mesh
— Functionrefmesh_to_mesh!(node)
refmesh_to_mesh(node)
Compute a node mesh based on the reference mesh, the transformation matrix and the tapering. The mutating version adds the new mesh to the mesh
field of the geometry attribute of the node.
Examples
using PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
node = opf[1][1][1]
new_mesh = refmesh_to_mesh(node)
using GLMakie
viz(new_mesh)
PlantGeom.refmesh_to_mesh!
— Functionrefmesh_to_mesh!(node)
refmesh_to_mesh(node)
Compute a node mesh based on the reference mesh, the transformation matrix and the tapering. The mutating version adds the new mesh to the mesh
field of the geometry attribute of the node.
Examples
using PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
node = opf[1][1][1]
new_mesh = refmesh_to_mesh(node)
using GLMakie
viz(new_mesh)
PlantGeom.rotate_point
— MethodRotate a point (x1,y1) around (x0, y0) with angle
.
PlantGeom.taper
— MethodReturns a tapered mesh using dDwn and dUp based on the geometry of an input mesh. Tapering a mesh transforms it into a tapered version (i.e. pointy) or enlarged object, e.g. make a cone from a cylinder.
PlantGeom.transform_mesh!
— Methodtransform_mesh!(node::Node, transformation)
Add a new transformation to the node geometry transformation
field. The transformation is composed with the previous transformation if any.
transformation
must be a function.
It is also possible to invert a transformation using revert
from Meshes.jl
.
Examples
using PlantGeom, MultiScaleTreeGraph, GLMakie, Rotations, Meshes
file = joinpath(dirname(dirname(pathof(PlantGeom))), "test", "files", "simple_plant.opf")
opf = read_opf(file)
# Visualize the mesh as is:
viz(opf)
# Copy the OPF, and translate the whole plant by 15 in the y direction (this is in cm, the mesh comes from XPlo):
opf2 = deepcopy(opf)
transform!(opf2, x -> transform_mesh!(x, Translate(0, 15, 0)))
viz!(opf2) # Visualize it again in the same figure
# Same but rotate the whole plant around the X axis:
opf3 = deepcopy(opf)
transform!(opf3, x -> transform_mesh!(x, Rotate(RotX(0.3))))
# NB: we use Rotations.jl's RotX here. Input in radian, use rad2deg and deg2rad if needed.
viz!(opf3)
# Same but rotate only the second leaf around the Z axis:
opf4 = deepcopy(opf)
# Build the meshes from the reference meshes (need it because we want the coordinates of the parent):
transform!(opf4, refmesh_to_mesh!)
# Get the second leaf in the OPF:
leaf_node = get_node(opf4, 8)
# Get the parent node (internode) Z coordinates:
parent_zmax = zmax(leaf_node.parent)
# Define a rotation of the mesh around the Z axis defined by the parent node max Z:
transformation = recenter(Rotate(RotZ(1.0)), Point(0.0, 0.0, parent_zmax))
# Update the transformation matrix of the leaf and its mesh:
transform_mesh!(leaf_node, transformation)
# Plot the result:
viz(opf)
viz!(opf4)
PlantGeom.write_opf
— Methodwrite_opf(file, opf)
Write an MTG with explicit geometry to disk as an OPF file.
Notes
Node attributes :ref_meshes
and :geometry
are treated as reserved keywords and should not be used without knowing their meaning:
:ref_meshes
: aRefMeshes
structure that holds the MTG reference meshes.:geometry
: ageometry
instance
Examples
using PlantGeom
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
opf = read_opf(file)
write_opf("test.opf", opf)
opf2 = read_opf("test.opf")
viz(opf2)
PlantGeom.write_ops
— Methodwrite_ops(file, scene_dimensions, object_table)
Write a scene file (.ops
), with the given dimensions and object table.
Arguments
file::String
: Path of the.ops
file to write.scene_dimensions::Tuple{Meshes.Point{3,T},Meshes.Point{3,T}}
: Dimensions of the scene.object_table
: Table with the objects to write in the.ops
file. The table may have the following columns:sceneID::Int
: Scene ID (mandatory).plantID::Int
: Plant ID (mandatory).filePath::String
: Path to the.opf
file (mandatory).pos::Meshes.Point{3,T}
: Position of the object (mandatory).functional_group::String
: Functional group of the object, used to map the object to the models (mandatory).scale::T
: Scale of the object (optional, 0.0 as default).inclinationAzimut::T
: Inclination azimut of the object (optional, 0.0 as default).inclinationAngle::T
: Inclination angle of the object (optional, 0.0 as default).rotation::T
: Rotation of the object (optional, 0.0 as default).
Details
object_table
can be of any format that implement the Tables.jl
interface, e.g. an array of NamedTuple
s, a DataFrame
...
Example
```julia using Meshes using Tables using PlantGeom
scenedimensions = (Meshes.Point(0.0, 0.0, 0.0), Meshes.Point(100.0, 100.0, 100.0)) positions = [Meshes.Point(50.0, 50.0, 50.0), Meshes.Point(60.0, 60.0, 60.0), Meshes.Point(70.0, 70.0, 70.0)] objecttable = [ (sceneID=1, plantID=p, filePath="opf/plantp.opf", pos=positions[p], functionalgroup="plant", rotation=0.1) for p in 1:3 ]
writeops("scene.ops", scenedimensions, object_table)
PlantGeom.xmax
— Functionxmax(x)
ymax(x)
zmax(x)
Get the maximum x, y or z coordinates of a mesh or a Node.
PlantGeom.xmin
— Functionxmin(x)
ymin(x)
zmin(x)
Get the minimum x, y or z coordinates of a mesh or a Node.
PlantGeom.ymax
— Functionxmax(x)
ymax(x)
zmax(x)
Get the maximum x, y or z coordinates of a mesh or a Node.
PlantGeom.ymin
— Functionxmin(x)
ymin(x)
zmin(x)
Get the minimum x, y or z coordinates of a mesh or a Node.
PlantGeom.zmax
— Functionxmax(x)
ymax(x)
zmax(x)
Get the maximum x, y or z coordinates of a mesh or a Node.
PlantGeom.zmin
— Functionxmin(x)
ymin(x)
zmin(x)
Get the minimum x, y or z coordinates of a mesh or a Node.
RecipesBase.plot
— Functionplot(opf::MultiScaleTreeGraph.Node; kwargs...)
plot!(opf::MultiScaleTreeGraph.Node; kwargs...)
Make a diagram of the MTG tree, paired with a Plots.jl
backend.
See also diagram
for the same plot with a Makie.jl
backend.
Attributes
mode = "2d"
: The mode for plotting, either "2d" or "3d"node_color = :black
: the node color, can be a color or any MTG attributeedge_color = node_color
: same asnode_color
, but for the edgescolormap = :viridis
: the colormap used for coloringcolor_missing = RGBA(0, 0, 0, 0.3)
: The color used for missing values
Examples
# import Pkg; Pkg.add("PlotlyJS")
using Plots, PlantGeom
plotlyjs()
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
# file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","coffee.opf")
opf = read_opf(file)
plot(opf, node_color = :Length)
RecipesBase.plot!
— Functionplot(opf::MultiScaleTreeGraph.Node; kwargs...)
plot!(opf::MultiScaleTreeGraph.Node; kwargs...)
Make a diagram of the MTG tree, paired with a Plots.jl
backend.
See also diagram
for the same plot with a Makie.jl
backend.
Attributes
mode = "2d"
: The mode for plotting, either "2d" or "3d"node_color = :black
: the node color, can be a color or any MTG attributeedge_color = node_color
: same asnode_color
, but for the edgescolormap = :viridis
: the colormap used for coloringcolor_missing = RGBA(0, 0, 0, 0.3)
: The color used for missing values
Examples
# import Pkg; Pkg.add("PlotlyJS")
using Plots, PlantGeom
plotlyjs()
file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","simple_plant.opf")
# file = joinpath(dirname(dirname(pathof(PlantGeom))),"test","files","coffee.opf")
opf = read_opf(file)
plot(opf, node_color = :Length)