Scenes and 3D meshes
Public API
PlantGeomPrimitives.Mesh — Type
MeshA struct representing a 3D mesh. Every three vertices represents a triangle. Properties per triangle are stored in a dictionary of arrays.
Fields
vertices: A vector containing the vertices of the mesh.properties: A dictionary containing additional properties of the mesh (arrays of properties per triangle).
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> p = Dict{Symbol, AbstractVector}(:normals => [Vec(0.0, 0.0, 1.0)]);
julia> m = Mesh(v, p);PlantGeomPrimitives.Mesh — Method
Mesh(m::GB.Mesh)Convert a GeometryBasics.Mesh object to a Mesh object. This is useful for interoperability with the PlantGeomPrimitives.jl package.
Arguments
m: TheGeometryBasics.Meshobject to convert.
Returns
A Mesh object containing the vertices of the mesh.
Example
julia> import GeometryBasics as GB;
julia> m = GB.Mesh([GB.Point(0.0, 0.0, 0.0), GB.Point(1.0, 0.0, 0.0), GB.Point(0.0, 1.0, 0.0)], [GB.TriangleFace(1, 2, 3)]);
julia> mesh = Mesh(m);
julia> typeof(mesh);PlantGeomPrimitives.Mesh — Method
Mesh(meshes)Merge multiple meshes into a single one
Arguments
meshes: Vector of meshes to merge.
Returns
A new Mesh object that is the result of merging all the input meshes.
Example
julia> e = Ellipse(length = 2.0, width = 2.0, n = 10);
julia> r = Rectangle(length = 10.0, width = 0.2);
julia> m = Mesh([e,r]);PlantGeomPrimitives.Mesh — Method
Mesh(vertices)Generate a triangular mesh from a vector of vertices.
Arguments
vertices: List of vertices (each vertex implement asVec).
Returns
A Mesh object.
Example
julia> verts = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> Mesh(verts);PlantGeomPrimitives.Mesh — Method
Mesh(nt, type)Generate a triangular dense mesh with enough memory allocated to store nt triangles. The behaviour is equivalent to generating an empty mesh but may be computationally more efficient when appending a large number of primitives. If a lower floating precision is required, this may be specified as an optional third argument as in Mesh(10, Float32).
Arguments
nt: The number of triangles to allocate memory for.type: The floating-point precision type for the mesh data (default isFloat64).
Returns
A Mesh object with no vertices or normals.
Example
julia> m = Mesh(1_000);
julia> nvertices(m);
julia> ntriangles(m);
julia> Mesh(1_000, Float32);PlantGeomPrimitives.Mesh — Method
Mesh(type = Float64)Generate an empty triangular dense mesh that represents a primitive or 3D scene. By default a Mesh object will only accept coordinates in double floating precision (Float64) but a lower precision can be generated by specifying the corresponding data type as in Mesh(Float32).
Arguments
type: The floating-point precision type for the mesh data (default isFloat64).
Returns
A Mesh object with no vertices or normals.
Example
julia> m = Mesh();
julia> nvertices(m);
julia> ntriangles(m);
julia> Mesh(Float32);PlantGeomPrimitives.Vec — Type
Vec(x, y, z)3D vector or point with coordinates x, y and z.
julia> v = Vec(0.0, 0.0, 0.0);
julia> v = Vec(0f0, 0f0, 0f0);PlantGeomPrimitives.BBox — Method
BBox(pmin::Vec, pmax::Vec)Build an axis-aligned bounding box given the vector of minimum (pmin) and maximum (pmax) coordinates.
Arguments
pmin: The minimum coordinates of the bounding box.pmax: The maximum coordinates of the bounding box.
Examples
julia> p0 = Vec(0.0, 0.0, 0.0);
julia> p1 = Vec(1.0, 1.0, 1.0);
julia> box = BBox(p0, p1);PlantGeomPrimitives.BBox — Method
BBox(m::Mesh)Build a tight axis-aligned bounding box around a Mesh object.
Arguments
m: The mesh to build the bounding box around.
Examples
julia> m = Rectangle();
julia> box = BBox(m);PlantGeomPrimitives.Ellipse — Method
Ellipse(;length = 1.0, width = 1.0, n = 20)Create a triangular mesh approximating an ellipse with dimensions given by length and width, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the ellipse.width = 1.0: The width of the ellipse.n = 20: The number of triangles to be used in the mesh.
Examples
julia> Ellipse(;length = 1.0, width = 1.0, n = 20);PlantGeomPrimitives.HollowCone — Method
HollowCone(;length = 1.0, width = 1.0, height = 1.0, n = 20)Create a hollow cone with dimensions given by length, width and height, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the cone (distance between base and apex).width = 1.0: The width of the base of the cone.height = 1.0: The height of the base of the cone.n = 20: The number of triangles to be used in the mesh.
Examples
julia> HollowCone(;length = 1.0, width = 1.0, height = 1.0, n = 20);PlantGeomPrimitives.HollowCube — Method
HollowCube(;length = 1.0, width = 1.0, height = 1.0)Create a hollow cube (a prism) with dimensions given by length, width and height, standard location and orientation.
Arguments
length = 1.0: The length of the cube.width = 1.0: The width of the base of the cube.height = 1.0: The height of the base of the cube.
Examples
julia> HollowCube(;length = 1.0, width = 1.0, height = 1.0);PlantGeomPrimitives.HollowCylinder — Method
HollowCylinder(;length = 1.0, width = 1.0, height = 1.0, n = 40)Create a hollow cylinder with dimensions given by length, width and height, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the cylinder (distance between bases).width = 1.0: The width of the base of the cylinder.height = 1.0: The height of the base of the cylinder.n = 40: The number of triangles to discretize the cylinder into.
Examples
julia> HollowCylinder(;length = 1.0, width = 1.0, height = 1.0, n = 40);PlantGeomPrimitives.HollowFrustum — Method
HollowFrustum(;length = 1.0, width = 1.0, height = 1.0, ratio = 1.0, n = 40)Create a hollow frustum with dimensions given by length, width and height, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the frustum (distance between bases).width = 1.0: The width of the base of the frustum.height = 1.0: The height of the base of the frustum.ratio = 1.0: The ratio between the top and bottom base radii.n = 40: The number of triangles to discretize the frustum into.
Examples
julia> HollowFrustum(;length = 1.0, width = 1.0, height = 1.0, n = 40, ratio = 0.5);PlantGeomPrimitives.O — Method
O()Returns the origin of the 3D coordinate system as a Vec object. By default, the coordinates will be in double floating precision (Float64) but it is possible to generate a version with lower floating precision as in O(Float32).
julia> O();
julia> O(Float32);PlantGeomPrimitives.Rectangle — Method
Rectangle(;length = 1.0, width = 1.0)Create a rectangle with dimensions given by length and width, standard location and orientation.
Arguments
length = 1.0: The length of the rectangle.width = 1.0: The width of the rectangle.
Examples
julia> Rectangle(;length = 1.0, width = 1.0);PlantGeomPrimitives.SolidCone — Method
SolidCone(;length = 1.0, width = 1.0, height = 1.0, n = 40)Create a solid cone with dimensions given by length, width and height, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the cone (distance between base and apex).width = 1.0: The width of the base of the cone.height = 1.0: The height of the base of the cone.n = 40: The number of triangles to be used in the mesh.
Examples
julia> SolidCone(;length = 1.0, width = 1.0, height = 1.0, n = 40);PlantGeomPrimitives.SolidCube — Method
SolidCube(;length = 1.0, width = 1.0, height = 1.0)Create a solid cube with dimensions given by length, width and height, standard location and orientation.
Arguments
length = 1.0: The length of the cube.width = 1.0: The width of the base of the cube.height = 1.0: The height of the base of the cube.
Examples
julia> SolidCube(;length = 1.0, width = 1.0, height = 1.0);PlantGeomPrimitives.SolidCylinder — Method
SolidCylinder(;length = 1.0, width = 1.0, height = 1.0, n = 80)Create a solid cylinder with dimensions given by length, width and height, discretized into n triangles (must be even) and standard location and orientation.
Arguments
length = 1.0: The length of the cylinder (distance between bases).width = 1.0: The width of the base of the cylinder.height = 1.0: The height of the base of the cylinder.n = 80: The number of triangles to discretize the cylinder into.
Examples
julia> SolidCylinder(;length = 1.0, width = 1.0, height = 1.0, n = 80);PlantGeomPrimitives.SolidFrustum — Method
SolidFrustum(;length = 1.0, width = 1.0, height = 1.0, ratio = 1.0, n = 40)Create a solid frustum with dimensions given by length, width and height, discretized into n triangles and standard location and orientation.
Arguments
length = 1.0: The length of the frustum (distance between bases).width = 1.0: The width of the base of the frustum.height = 1.0: The height of the base of the frustum.ratio = 1.0: The ratio between the top and bottom base radii.n = 40: The number of triangles to discretize the frustum into.
Examples
julia> SolidFrustum(;length = 1.0, width = 1.0, height = 1.0, n = 40, ratio = 0.5);PlantGeomPrimitives.Trapezoid — Method
Trapezoid(;length = 1.0, width = 1.0, ratio = 1.0)Create a trapezoid with dimensions given by length and the larger width and the ratio between the smaller and larger widths. The trapezoid is generted at the standard location and orientation.
Arguments
length = 1.0: The length of the trapezoid.width = 1.0: The larger width of the trapezoid (the lower base of the trapezoid).ratio = 1.0: The ratio between the smaller and larger widths.
Examples
julia> Trapezoid(;length = 1.0, width = 1.0, ratio = 1.0);PlantGeomPrimitives.Triangle — Method
Triangle(;length = 1.0, width = 1.0)Create a triangle with dimensions given by length and width, standard location and orientation.
Arguments
length = 1.0: The length of the triangle.width = 1.0: The width of the triangle.
Examples
julia> Triangle(;length = 1.0, width = 1.0);PlantGeomPrimitives.X — Method
X(s)Returns scaled vector in the direction of the X axis with length s as a Vec object using the same floating point precision as s.
julia> X(1.0);
julia> X(1f0) ;PlantGeomPrimitives.X — Method
X()Returns an unit vector in the direction of the X axis as a Vec object. By default, the coordinates will be in double floating precision (Float64) but it is possible to generate a version with lower floating precision as in X(Float32).
julia> X();
julia> X(Float32);PlantGeomPrimitives.Y — Method
Y(s)Returns scaled vector in the direction of the Y axis with length s as a Vec object using the same floating point precision as s.
julia> Y(1.0);
julia> Y(1f0);PlantGeomPrimitives.Y — Method
Y()Returns an unit vector in the direction of the Y axis as a Vec object. By default, the coordinates will be in double floating precision (Float64) but it is possible to generate a version with lower floating precision as in Y(Float32).
julia> Y();
julia> Y(Float32);PlantGeomPrimitives.Z — Method
Z(s)Returns scaled vector in the direction of the Z axis with length s as a Vec object using the same floating point precision as s.
julia> Z(1.0);
julia> Z(1f0);PlantGeomPrimitives.Z — Method
Z()Returns an unit vector in the direction of the Z axis as a Vec object. By default, the coordinates will be in double floating precision (Float64) but it is possible to generate a version with lower floating precision as in Z(Float32).
julia> Z();
julia> Z(Float32);PlantGeomPrimitives.add! — Method
add!(mesh1, mesh2; kwargs...)Manually add a mesh to an existing mesh with optional properties captured as keywords. Make sure to be consistent with the properties (both meshes should end up with the same lsit of properties). For example, if the scene was created with :colors, then you should provide:colors`` for the new mesh as well.
Arguments
mesh1: The current mesh we want to extend.mesh1: A new mesh we want to add.kwargs: Properties to be set per triangle in the new mesh.
Example
julia> t1 = Triangle(length = 1.0, width = 1.0);
julia> using ColorTypes: RGB
julia> add_property!(t1, :colors, rand(RGB));
julia> t2 = Rectangle(length = 5.0, width = 0.5);
julia> add!(t1, t2, colors = rand(RGB));PlantGeomPrimitives.add_property! — Function
add_property!(m::Mesh, prop::Symbol, data, nt = ntriangles(m))Add a property to a mesh. The property is identified by a name (prop) and is stored as an array of values (data), one per triangle. If the property already exists, the new data is appended to the existing property, otherwise a new property is created. It is possible to pass a single object for data, in which case the property will be set to the same value for all triangles.
Arguments
mesh: The mesh to which the property is to be added.prop: The name of the property to be added as aSymbol.data: The data to be added to the property (an array or a single value).nt: The number of triangles to be assumed ifdatais not an array. By default this is the number of triangles in the mesh.
Returns
The mesh with updated properties.
Example
julia> r = Rectangle();
julia> add_property!(r, :absorbed_PAR, [0.0, 0.0]);
julia> properties(r);PlantGeomPrimitives.add_property! — Method
add_property!(p::Dict{Symbol, AbstractVector}, prop::Symbol, data::AbstractVector)Add data to an existing property in a dictionary of properties. If the property already exists, the new data is appended to the existing property. If the property does not exist, please use add_properties! instead.
Arguments
p: The dictionary of properties to which the property will be added.prop: The name of the property to be added as aSymbol, given thatpropis inp.data: The data to be added to the property (an array or a single value).
Returns
The modified dictionary of properties with the new property added.
Example
julia> p = Dict{Symbol, AbstractVector}(:prop1 => [1.0, 2.0]);
julia> prop = :prop1;
julia> data = [3.0, 4.0];
julia> add_property!(p, prop, data);
julia> p;PlantGeomPrimitives.area — Method
area(mesh::Mesh)Total surface area of a mesh (as the sum of areas of individual triangles).
Arguments
mesh: Mesh which area is to be calculated.
Returns
The total surface area of the mesh as a number.
Example
julia> r = Rectangle(length = 10.0, width = 0.2);
julia> area(r);
julia> r = Rectangle(length = 10f0, width = 0.2f0);
julia> area(r);PlantGeomPrimitives.areas — Method
areas(m::Mesh)A vector with the areas of the different triangles that form a mesh.
Arguments
mesh: Mesh which areas are to be calculated.
Returns
A vector with the areas of the different triangles that form the mesh.
Example
julia> r = Rectangle(length = 10.0, width = 0.2);
julia> areas(r);
julia> r = Rectangle(length = 10f0, width = 0.2f0);
julia> areas(r);PlantGeomPrimitives.edges — Method
edges(mesh::Mesh)Retrieve the edges of a mesh (three edges per triangle).
Arguments
mesh: The mesh from which to retrieve the edges.
Returns
A vector containing the edges of the mesh.
PlantGeomPrimitives.get_triangle — Method
get_triangle(m::Mesh, i)Retrieve the vertices for the i-th triangle in a mesh.
Arguments
mesh: The mesh from which to retrieve the triangle.i: The index of the triangle to retrieve.
Returns
A vector containing the three vertices defining the i-th triangle.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0),
Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(0.0, 0.0, 1.0)];
julia> m = Mesh(v);
julia> get_triangle(m, 2);PlantGeomPrimitives.load_mesh — Method
load_mesh(filename, type = Float64)Import a mesh from a file given by filename. Supported formats include stl, ply, obj and msh. By default, this will generate a Mesh object that uses double floating-point precision. However, a lower precision can be specified by passing the relevant data type as in load_mesh(filename, Float32).
Arguments
filename: The path to the file containing the mesh.type: The floating-point precision type for the mesh data (default isFloat64).
Example
julia> mesh = load_mesh("path/to/mesh.obj");
julia> mesh = load_mesh("path/to/mesh.obj", Float32);PlantGeomPrimitives.normals — Method
normals(mesh::Mesh)Retrieve the normals of a mesh.
Arguments
mesh: The mesh from which to retrieve the normals.
Returns
A vector containing the normals of the mesh.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> m = Mesh(v);
julia> normals(m);PlantGeomPrimitives.ntriangles — Method
ntriangles(mesh)Extract the number of triangles in a mesh.
Arguments
mesh: The mesh from which to extract the number of triangles.
Returns
The number of triangles in the mesh as an integer.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> m = Mesh(v);
julia> ntriangles(m);PlantGeomPrimitives.nvertices — Method
nvertices(mesh)The number of vertices in a mesh.
Arguments
mesh: The mesh from which to retrieve the number of vertices.
Returns
The number of vertices in the mesh as an integer.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> m = Mesh(v);
julia> nvertices(m);PlantGeomPrimitives.properties — Method
properties(mesh::Mesh)Retrieve the properties of a mesh. Properties are stored as a dictionary with one entry per type of property. Each property is an array of objects, one per triangle. Each property is identified by a symbol (e.g.).
Arguments
mesh: The mesh from which to retrieve the normals.
Returns
A vector containing the normals of the mesh.
Example
julia> r = Rectangle();
julia> add_property!(r, :absorbed_PAR, [0.0, 0.0]);
julia> properties(r);PlantGeomPrimitives.rotate! — Method
rotate!(m::Mesh; x::Vec, y::Vec, z::Vec)Rotate a mesh m to a new coordinate system given by x, y and z.
Arguments
m: The mesh to be rotated.x: The new x-axis as aVec.y: The new y-axis as aVec.z: The new z-axis as aVec.
Examples
julia> m = Rectangle();
julia> x = Vec(1.0, 0.0, 0.0);
julia> y = Vec(0.0, 1.0, 0.0);
julia> z = Vec(0.0, 0.0, 1.0);
julia> rotate!(m, x = x, y = y, z = z);PlantGeomPrimitives.rotatex! — Method
rotatex!(m::Mesh, θ)Rotate a mesh m around the x axis by angle θ.
Arguments
m: The mesh to be scaled.θ: Angle of rotation in radians.
Examples
julia> m = Rectangle();
julia> θ = pi/2;
julia> rotatex!(m, θ)PlantGeomPrimitives.rotatey! — Method
rotatey!(m::Mesh, θ)Rotate a mesh m around the y axis by angle θ.
Arguments
m: The mesh to be scaled.θ: Angle of rotation in radians.
Examples
julia> m = Rectangle();
julia> θ = pi/2;
julia> rotatey!(m, θ);PlantGeomPrimitives.rotatez! — Method
rotatez!(m::Mesh, θ)Rotate a mesh m around the z axis by angle θ.
Arguments
m: The mesh to be scaled.θ: Angle of rotation in radians.
Examples
julia> m = Rectangle();
julia> θ = pi/2;
julia> rotatez!(m, θ);PlantGeomPrimitives.save_mesh — Method
save_mesh(mesh; fileformat = :STL_BINARY, filename)Save a mesh into an external file using a variety of formats.
Arguments
mesh: Object of typeMesh.fileformat: Format to store the mesh as symbol.filename: Name of the file in which to store the mesh as string.
Details
The fileformat should take one of the following arguments: :STL_BINARY, :STL_ASCII, :PLY_BINARY, :PLY_ASCII or :OBJ. Note that these names should be passed as symnols.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> mesh = Mesh(v);
julia> save_mesh(mesh, fileformat = :STL_BINARY, filename = "path/to/mesh.bstl");PlantGeomPrimitives.scale! — Method
scale!(m::Mesh, vec::Vec)Scale a mesh m along the three axes provided by vec.
Arguments
m: The mesh to be scaled.vec: A vector containing the scaling factors for the x, y, and z axes.
Examples
julia> m = Rectangle();
julia> scaling_vector = Vec(2.0, 1.5, 3.0);
julia> scale!(m, scaling_vector);PlantGeomPrimitives.slice! — Method
slice!(mesh::Mesh; X = (), Y = (), Z = ())Slice a mesh along specified planes in the X, Y, and Z directions. This function modifies the input mesh in place. The resulting mesh will contain a higher number of triangles which all constrained to the planes specified. The function will also add a property :slices to the mesh that contains the indices of the planes where each triangle lies.
Arguments
mesh::Mesh: The mesh to be sliced.X: A tuple or array of X-coordinates where the mesh should be sliced.Y: A tuple or array of Y-coordinates where the mesh should be sliced.Z: A tuple or array of Z-coordinates where the mesh should be sliced.
Example
julia> import ColorTypes: RGB;
julia> mesh = Rectangle(length = 1.0, width = 1.0);
julia> slice!(mesh, Y = collect(-0.25:0.25:0.5), Z = collect(0.25:0.25:1));
julia> add_property!(mesh, :colors, rand(RGB));
julia> using PlantViz;
julia> render(mesh, wireframe = true);PlantGeomPrimitives.slices — Method
slices(mesh::Mesh)Retrieve the indices indicating the slices to which each triangle in the mesh belongs to.
Arguments
mesh: The mesh from which to retrieve the slices.
Returns
A vector containing the slice indices of the triangles in the mesh.
Example
julia> mesh = Rectangle(length = 1.0, width = 1.0);
julia> slice!(mesh, Y = collect(-0.25:0.25:0.5), Z = collect(0.25:0.25:1));
julia> slices(mesh);PlantGeomPrimitives.translate! — Method
translate!(m::Mesh, v::Vec)Translate the mesh m by vector v.
Arguments
m: The mesh to be translated.v: The vector by which the mesh is to be translated.
Examples
julia> m = Rectangle();
julia> v = Vec(2.0, 1.5, 3.0);
julia> translate!(m, v);PlantGeomPrimitives.vertices — Method
vertices(mesh::Mesh)Retrieve the vertices of a mesh.
Arguments
mesh: The mesh from which to retrieve the vertices.
Returns
A vector containing the vertices of the mesh.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> m = Mesh(v);
julia> vertices(m);Private
Private functions, types or constants from PlantGeomPrimitives. These are not exported, so you need to prefix the function name with PlantGeomPrimitives. to access them. Also bear in mind that these are not part of the public API, so they may change without notice.
Base.eltype — Method
eltype(mesh::Mesh)Extract the the type used to represent coordinates in a mesh (e.g., Float64).
Fields
mesh: The mesh from which to extract the element type.
Example
julia> v = [Vec(0.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0), Vec(1.0, 0.0, 0.0)];
julia> m = Mesh(v);
julia> eltype(m);PlantGeomPrimitives.GLMesh — Method
GLMesh(m::Mesh{FT}) where {FT<:AbstractFloat}Convert a Mesh object to a GeometryBasics.Mesh object. This is useful for interoperability with the GeometryBasics.jl package.
Arguments
m: The mesh to convert, which should be of typeMesh{FT}whereFTis a floating-point type.
Returns
A GeometryBasics.Mesh object containing the vertices and faces of the mesh.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> m = Mesh(vs);
julia> gl_mesh = PG.GLMesh(m);PlantGeomPrimitives.add_properties! — Method
function add_properties!(p1::Dict{Symbol, AbstractVector}, p2::Dict{Symbol, AbstractVector})Merge properties from p2 into p1. Both dictionaries must have the same keys. If a key exists in p2 but not in p1, it will be added to p1. If a key exists in both, the values from p2 will be appended to the existing values in p1.
Arguments
p1: The first dictionary of properties to which the second will be added.p2: The second dictionary of properties to be merged into the first.
Returns
The modified p1 dictionary with properties from p2 added.
Example
julia> import PlantGeomPrimitives as PG;
julia> p1 = Dict{Symbol, AbstractVector}(:prop1 => [1.0, 2.0], :prop2 => [3.0, 4.0]);
julia> p2 = Dict{Symbol, AbstractVector}(:prop1 => [5.0, 6.0], :prop2 => [7.0, 8.0]);
julia> merged_properties = PG.add_properties!(p1, p2);
julia> merged_properties;PlantGeomPrimitives.area_triangle — Method
area_triangle(v1::Vec, v2::Vec, v3::Vec)Calculates the area of a triangle given its vertices.
Arguments
v1,v2,v3: Vertices of the triangle as vectors.
Returns
The area of the triangle.
Example
julia> import PlantGeomPrimitives as PG;
julia> v1 = Vec(0.0, 0.0, 0.0);
julia> v2 = Vec(1.0, 0.0, 0.0);
julia> v3 = Vec(0.0, 1.0, 0.0);
julia> PG.area_triangle(v1, v2, v3);PlantGeomPrimitives.check_intersection — Method
check_intersection(m::Mesh, t::Integer, i::Integer, h::Real, j::Integer)Calculate how many intersection points there are between the plane and the triangle and return the vertex index that is relevant to compute the intersection (depends on how many intersection points there are). When a triangle is not intersected we return the index of the voxel or layer where the triangle lies. When there is an intersection we return -1 as the voxel indexing will be determined in the intersection function.
Arguments
m: The mesh containing the triangle to be checked.t: The index of the triangle in the mesh.i: The index of the axis (1 for X, 2 for Y, 3 for Z).h: The height of the plane along the specified axis.j: The index of the plane in the specified axis.
Returns
A tuple containing:
- The number of intersection points (0, 1, or 2).
- The index of the vertex that is relevant for the intersection (1, 2, or 3).
- The slice index (0 if not applicable).
- The signs of the distances to the plane for each vertex.
Example
julia> import PlantGeomPrimitives as PG;
julia> m = Rectangle(length = 1.0, width = 1.0);
julia> PG.check_intersection(m, 1, 2, 0.5, 1);PlantGeomPrimitives.next — Method
next(i::Integer)Auxilliary function to help move across all vertices (implements modulo arithmetic 1). Note that mod(i, 3) returns 0, 1, 2 hence the +1 at the end, but since i is just a normal integer it will always represent the next value.
Arguments:
i: The current vertex index (1, 2, or 3).
Returns
The next vertex index in the sequence (1, 2, or 3).
Example
julia> import PlantGeomPrimitives as PG;
julia> PG.next(1);
julia> PG.next(2);
julia> PG.next(3);
PlantGeomPrimitives.one_intersection_point — Method
one_intersection_point(i, h, vi, es, vs)Compute the intersection point between a plane and the edge opposite to the vertex vi of a triangle defined by its vertices vs and edges es.
Arguments
i: The index of the coordinate axis (1 for X, 2 for Y, 3 for Z).h: The height of the plane along the specified axis.vi: The index of the vertex that is relevant for the intersection (1, 2, or 3).es: The edges of the triangle.vs: The vertices of the triangle.
Returns
The 3D coordinates of the intersection point.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> es = [vs[2] - vs[1], vs[3] - vs[2], vs[3] - vs[1]]; # Examples: intersect the triangle with the plane x = 0.5, using vertex 1 as the reference
julia> PG.one_intersection_point(1, 0.5, 3, es, vs); # Intersection point between the plane and the edge opposite to vertex 1
julia> PG.one_intersection_point(1, 0.5, 2, es, vs); # Intersection point between the plane and the edge opposite to vertex 2PlantGeomPrimitives.one_triangle_intersection! — Method
one_triangle_intersection!(mesh, t, i, h, vi, slindex, j, s)Intersect a triangle with a plane, create new triangles, and add them to the mesh.
Arguments
mesh: The mesh containing the triangle to be intersected.t: The index of the triangle in the mesh.i: The index of the axis (1 for X, 2 for Y, 3 for Z).h: The height of the plane along the specified axis.vi: The index of the vertex that is relevant for the intersection (1, 2, or 3).slindex: The slice index for the triangle.j: The index of the plane in the specified axis.s: The signs of the distances to the plane for each vertex.
Returns
A tuple containing the updated slice indices for the two new triangles created from the intersection.
Example
julia> import PlantGeomPrimitives as PG;
julia> mesh = Rectangle(length = 1.0, width = 1.0);
julia> PG.update_edges!(mesh);
julia> nverts_before = length(vertices(mesh));
julia> PG.one_triangle_intersection!(mesh, 1, 2, 0.5, 1, [1,1,1], 2, [1, -1, -1]);
julia> nverts_after = length(vertices(mesh));PlantGeomPrimitives.push_edges! — Method
push_edges!(vs, m, i0)Create the three edges stored as a vector of vectors from the vertices vs starting at index i0 and add them to the mesh's property.
Arguments
vs: The vertices of the mesh.m: The mesh to which the edges will be added.i0: The starting index in the vertices vector from which to create the edges.
Returns
Nothing. It modifies the mesh in place by adding the edges.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> m = Mesh(vs);
julia> PG.update_edges!(m);
julia> PG.push_edges!(vs, m, 1);
julia> edges(m);PlantGeomPrimitives.transform! — Method
transform!(m::Mesh, trans::CT.AbstractAffineMap)In-place affine transfrmation of a mesh m using a transformation map trans.
Arguments
m: The mesh to be transformed.trans: The transformation map that defines the affine transformation to be
applied to the mesh.
Returns
The transformed mesh m with updated vertices and normals.
Example
julia> import CoordinateTransformations as CT;
julia> import PlantGeomPrimitives as PG;
julia> m = Rectangle();
julia> vec = Vec(1.0, 2.0, 3.0);
julia> trans = CT.LinearMap(CT.SDiagonal(vec...));
julia> PG.transform!(m, trans);PlantGeomPrimitives.two_intersection_points — Method
two_intersection_points(i, h, vi, es, vs)Compute the intersection points between a plane and the two edges that share the vertex vi of a triangle defined by its vertices vs and edges es.
Arguments
i: The index of the coordinate axis (1 for X, 2 for Y, 3 for Z).h: The height of the plane along the specified axis.vi: The index of the vertex that is relevant for the intersection (1, 2, or 3).es: The edges of the triangle.vs: The vertices of the triangle.
Returns
A tuple containing the 3D coordinates of the two intersection points.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> es = [vs[2] - vs[1], vs[3] - vs[2], vs[1] - vs[3]]; # Examples: intersect the triangle with the plane x = 0.5, using vertex 1 as the reference
julia> PG.two_intersection_points(1, 0.5, 3, es, vs); # Intersection points between the plane and the edges opposite to vertex 1
julia> PG.two_intersection_points(1, 0.5, 2, es, vs); # Intersection points between the plane and the edges opposite to vertex 2PlantGeomPrimitives.two_triangle_intersections! — Method
two_triangle_intersections!(mesh, t, i, h, vi, slindex, j, s)Intersect a triangle with a plane, create two new triangles, and add them to the mesh.
Arguments
mesh: The mesh containing the triangle to be intersected.t: The index of the triangle in the mesh.i: The index of the axis (1 for X, 2 for Y, 3 for Z).h: The height of the plane along the specified axis.vi: The index of the vertex that is relevant for the intersection (1, 2, or 3).slindex: The slice index for the triangle.j: The index of the plane in the specified axis.s: The signs of the distances to the plane for each vertex.
Returns
A tuple containing the updated slice indices for the three new triangles created from the intersection.
Example
julia> import PlantGeomPrimitives as PG;
julia> mesh = Rectangle(length = 1.0, width = 1.0);
julia> PG.update_edges!(mesh);
julia> nverts_before = length(vertices(mesh));
julia> PG.two_triangle_intersections!(mesh, 1, 2, 0.5, 1, [1,1,1], 2, [1, -1, -1]);
julia> nverts_after = length(vertices(mesh));
PlantGeomPrimitives.update_edges! — Method
update_edges!(m::Mesh{FT}) where {FT<:AbstractFloat}Calculate the edges of a mesh and add them as properties. This function checks if the edges property exists, and if not, it creates it. It then computes the edges for all vertices in the mesh.
Arguments
m: The mesh for which to update the edges.
Returns
Nothing. It modifies the mesh in place by adding the edges as a property.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> m = Mesh(vs);
julia> PG.update_edges!(m);
julia> edges(m);PlantGeomPrimitives.update_normals! — Method
update_normals!(m::Mesh{FT}) where {FT<:AbstractFloat}Calculate the normals of a mesh and add them as properties. This function checks if the normals property exists, and if not, it creates it. It then computes the normals for all vertices in the mesh.
Arguments
m: The mesh for which to update the normals.
Returns
Nothing. It modifies the mesh in place by adding the normals as a property.
Example
julia> import PlantGeomPrimitives as PG;
julia> vs = [Vec(0.0, 0.0, 0.0), Vec(1.0, 0.0, 0.0), Vec(0.0, 1.0, 0.0)];
julia> m = Mesh(vs);
julia> PG.update_normals!(m);
julia> normals(m);