PartitionedMesh


class PartitionedMesh


An immutable** complex shape expressed as a set of triangles. This is used to represent the shape of a stroke or other complex objects. The mesh may be divided into multiple partitions, which enables certain brush effects (e.g. "multi-coat"), and allows ink to create strokes using greater than 2^16 triangles (which must be rendered in multiple passes).

A PartitionedMesh may optionally have one or more "outlines", which are polylines that traverse some or all of the vertices in the mesh; these are used for path-based rendering of strokes. This supports disjoint meshes such as dashed lines.

PartitionedMesh provides fast intersection and coverage testing by use of an internal spatial index.

** PartitionedMesh is technically not immutable, as the spatial index is lazily instantiated; however, from the perspective of a caller, its properties do not change over the course of its lifetime. The entire object is thread-safe.

Summary

Public functions

Box?

Returns the minimum bounding box of the PartitionedMesh.

@FloatRange(from = 0.0, to = 1.0) Float
computeCoverage(box: Box, boxToThis: AffineTransform)

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with box.

@FloatRange(from = 0.0, to = 1.0) Float
computeCoverage(
    other: PartitionedMesh,
    otherShapeToThis: AffineTransform
)

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with the other.

@FloatRange(from = 0.0, to = 1.0) Float
computeCoverage(
    parallelogram: Parallelogram,
    parallelogramToThis: AffineTransform
)

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with parallelogram.

@FloatRange(from = 0.0, to = 1.0) Float
computeCoverage(triangle: Triangle, triangleToThis: AffineTransform)

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with triangle.

Boolean
computeCoverageIsGreaterThan(
    box: Box,
    coverageThreshold: Float,
    boxToThis: AffineTransform
)

Returns true if the approximate portion of the PartitionedMesh covered by box is greater than coverageThreshold.

Boolean
computeCoverageIsGreaterThan(
    other: PartitionedMesh,
    coverageThreshold: Float,
    otherShapeToThis: AffineTransform
)

Returns true if the approximate portion of this PartitionedMesh covered by the other is greater than coverageThreshold.

Boolean
computeCoverageIsGreaterThan(
    parallelogram: Parallelogram,
    coverageThreshold: Float,
    parallelogramToThis: AffineTransform
)

Returns true if the approximate portion of the PartitionedMesh covered by parallelogram is greater than coverageThreshold.

Boolean
computeCoverageIsGreaterThan(
    triangle: Triangle,
    coverageThreshold: Float,
    triangleToThis: AffineTransform
)

Returns true if the approximate portion of the PartitionedMesh covered by triangle is greater than coverageThreshold.

@IntRange(from = 0) Int
getOutlineCount(groupIndex: @IntRange(from = 0) Int)

Returns the number of outlines that comprise the render group at groupIndex.

@IntRange(from = 0) Int
getOutlineVertexCount(
    groupIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int
)

Returns the number of vertices that are in the outline at outlineIndex in the render group at groupIndex.

@IntRange(from = 0) Int

Returns the number of render groups in this mesh.

Unit

Initializes this MutableEnvelope's spatial index for geometry queries.

MutableVec
populateOutlinePosition(
    groupIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int,
    outlineVertexIndex: @IntRange(from = 0) Int,
    outPosition: MutableVec
)

Populates outPosition with the position of the outline vertex at outlineVertexIndex in the outline at outlineIndex in the render group at groupIndex, and returns outPosition.

open String

Protected functions

Unit

Public functions

computeBoundingBox

Added in 1.0.0-alpha01
fun computeBoundingBox(): Box?

Returns the minimum bounding box of the PartitionedMesh. This will be null if the PartitionedMesh is empty.

computeCoverage

Added in 1.0.0-alpha01
fun computeCoverage(
    box: Box,
    boxToThis: AffineTransform = AffineTransform.IDENTITY
): @FloatRange(from = 0.0, to = 1.0) Float

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with box. This is calculated by finding the sum of areas of the triangles that intersect the given box, and dividing that by the sum of the areas of all triangles in the PartitionedMesh, all in the PartitionedMesh's coordinate space. Triangles in the PartitionedMesh that overlap each other (e.g. in the case of a stroke that loops back over itself) are counted individually. Note that, if any triangles have negative area (due to winding, see Triangle.computeSignedArea), the absolute value of their area will be used instead.

On an empty PartitionedMesh, this will always return 0.

Optional argument boxToThis contains the transform that maps from box's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverage

Added in 1.0.0-alpha01
fun computeCoverage(
    other: PartitionedMesh,
    otherShapeToThis: AffineTransform = AffineTransform.IDENTITY
): @FloatRange(from = 0.0, to = 1.0) Float

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with the other. This is calculated by finding the sum of areas of the triangles that intersect other, and dividing that by the sum of the areas of all triangles in the PartitionedMesh, all in the PartitionedMesh's coordinate space. Triangles in the PartitionedMesh that overlap each other (e.g. in the case of a stroke that loops back over itself) are counted individually. Note that, if any triangles have negative area (due to winding, see Triangle.computeSignedArea), the absolute value of their area will be used instead.

On an empty PartitionedMesh, this will always return 0.

Optional argument otherShapeToThis contains the transform that maps from other's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverage

Added in 1.0.0-alpha01
fun computeCoverage(
    parallelogram: Parallelogram,
    parallelogramToThis: AffineTransform = AffineTransform.IDENTITY
): @FloatRange(from = 0.0, to = 1.0) Float

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with parallelogram. This is calculated by finding the sum of areas of the triangles that intersect the given parallelogram, and dividing that by the sum of the areas of all triangles in the PartitionedMesh, all in the PartitionedMesh's coordinate space. Triangles in the PartitionedMesh that overlap each other (e.g. in the case of a stroke that loops back over itself) are counted individually. Note that, if any triangles have negative area (due to winding, see Triangle.computeSignedArea), the absolute value of their area will be used instead.

On an empty PartitionedMesh, this will always return 0.

Optional argument parallelogramToThis contains the transform that maps from parallelogram's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverage

Added in 1.0.0-alpha01
fun computeCoverage(
    triangle: Triangle,
    triangleToThis: AffineTransform = AffineTransform.IDENTITY
): @FloatRange(from = 0.0, to = 1.0) Float

Computes an approximate measure of what portion of this PartitionedMesh is covered by or overlaps with triangle. This is calculated by finding the sum of areas of the triangles that intersect the given triangle, and dividing that by the sum of the areas of all triangles in the PartitionedMesh, all in the PartitionedMesh's coordinate space. Triangles in the PartitionedMesh that overlap each other (e.g. in the case of a stroke that loops back over itself) are counted individually. Note that, if any triangles have negative area (due to winding, see Triangle.computeSignedArea), the absolute value of their area will be used instead.

On an empty PartitionedMesh, this will always return 0.

Optional argument triangleToThis contains the transform that maps from triangle's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverageIsGreaterThan

Added in 1.0.0-alpha01
fun computeCoverageIsGreaterThan(
    box: Box,
    coverageThreshold: Float,
    boxToThis: AffineTransform = AffineTransform.IDENTITY
): Boolean

Returns true if the approximate portion of the PartitionedMesh covered by box is greater than coverageThreshold.

This is equivalent to:

computeCoverage(box, boxToThis) coverageThreshold

but may be faster.

On an empty PartitionedMesh, this will always return 0.

Optional argument boxToThis contains the transform that maps from box's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverageIsGreaterThan

Added in 1.0.0-alpha01
fun computeCoverageIsGreaterThan(
    other: PartitionedMesh,
    coverageThreshold: Float,
    otherShapeToThis: AffineTransform = AffineTransform.IDENTITY
): Boolean

Returns true if the approximate portion of this PartitionedMesh covered by the other is greater than coverageThreshold.

This is equivalent to:

computeCoverage(other, otherShapeToThis) coverageThreshold

but may be faster.

On an empty PartitionedMesh, this will always return 0.

Optional argument otherShapeToThis contains the transform that maps from other's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverageIsGreaterThan

Added in 1.0.0-alpha01
fun computeCoverageIsGreaterThan(
    parallelogram: Parallelogram,
    coverageThreshold: Float,
    parallelogramToThis: AffineTransform = AffineTransform.IDENTITY
): Boolean

Returns true if the approximate portion of the PartitionedMesh covered by parallelogram is greater than coverageThreshold.

This is equivalent to:

computeCoverage(parallelogram, parallelogramToThis) coverageThreshold

but may be faster.

On an empty PartitionedMesh, this will always return 0.

Optional argument parallelogramToThis contains the transform that maps from parallelogram's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

computeCoverageIsGreaterThan

Added in 1.0.0-alpha01
fun computeCoverageIsGreaterThan(
    triangle: Triangle,
    coverageThreshold: Float,
    triangleToThis: AffineTransform = AffineTransform.IDENTITY
): Boolean

Returns true if the approximate portion of the PartitionedMesh covered by triangle is greater than coverageThreshold.

This is equivalent to:

computeCoverage(triangle, triangleToThis) coverageThreshold

but may be faster.

On an empty PartitionedMesh, this will always return 0.

Optional argument triangleToThis contains the transform that maps from triangle's coordinate space to this PartitionedMesh's coordinate space, which defaults to AffineTransform.IDENTITY.

getOutlineCount

Added in 1.0.0-alpha01
fun getOutlineCount(groupIndex: @IntRange(from = 0) Int): @IntRange(from = 0) Int

Returns the number of outlines that comprise the render group at groupIndex.

getOutlineVertexCount

Added in 1.0.0-alpha01
fun getOutlineVertexCount(
    groupIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int
): @IntRange(from = 0) Int

Returns the number of vertices that are in the outline at outlineIndex in the render group at groupIndex.

getRenderGroupCount

Added in 1.0.0-alpha01
fun getRenderGroupCount(): @IntRange(from = 0) Int

Returns the number of render groups in this mesh. Each outline in the PartitionedMesh belongs to exactly one render group, which are numbered in z-order: the group with index zero should be rendered on bottom; the group with the highest index should be rendered on top.

initializeSpatialIndex

Added in 1.0.0-alpha01
fun initializeSpatialIndex(): Unit

Initializes this MutableEnvelope's spatial index for geometry queries. If a geometry query is made with this shape and the spatial index is not currently initialized, it will be initialized in real time to satisfy that query.

populateOutlinePosition

Added in 1.0.0-alpha01
fun populateOutlinePosition(
    groupIndex: @IntRange(from = 0) Int,
    outlineIndex: @IntRange(from = 0) Int,
    outlineVertexIndex: @IntRange(from = 0) Int,
    outPosition: MutableVec
): MutableVec

Populates outPosition with the position of the outline vertex at outlineVertexIndex in the outline at outlineIndex in the render group at groupIndex, and returns outPosition. groupIndex must be less than getRenderGroupCount, outlineIndex must be less getOutlineVertexCount for groupIndex, and outlineVertexIndex must be less than getOutlineVertexCount for groupIndex and outlineIndex.

toString

open fun toString(): String

Protected functions

finalize

Added in 1.0.0-alpha01
protected fun finalize(): Unit