Add new extrusion types, refactor code. (#323)

This commit is contained in:
Abe Pazos
2023-08-25 21:02:23 +02:00
committed by GitHub
parent 4b42cfc1fc
commit be07a8fc4c
7 changed files with 674 additions and 92 deletions

View File

@@ -0,0 +1,111 @@
package org.openrndr.extra.meshgenerators
import org.openrndr.math.Matrix44
import org.openrndr.math.Vector3
import org.openrndr.shape.Path3D
import org.openrndr.shape.ShapeContour
/**
* Extrude a [contour] along a [path] specifying the number of steps.
*
* @param contour the cross-section of the mesh
* @param path the 3D path
* @param stepCount the number of steps along the [path]
* @param up0 the initial up-vector
* @param contourDistanceTolerance precision for calculating steps along
* [contour]. Lower tolerance results in higher precision.
* @param pathDistanceTolerance precision for calculating steps along
* [path]. Lower tolerance results in higher precision.
* @param steps the resulting positions in the path
* @param frames a list of matrices holding the transformation matrices along
* the path
* @param startCap adds a start cap if set to true
* @param endCap adds an end cap if set to true
* @param writer the vertex writer function
*/
fun extrudeContourStepsMorphed(
contour: (Double) -> ShapeContour,
path: Path3D,
stepCount: Int,
up0: Vector3,
contourDistanceTolerance: Double = 0.5,
pathDistanceTolerance: Double = 0.5,
steps: List<Vector3> = path.equidistantPositions(
stepCount,
pathDistanceTolerance
),
frames: List<Matrix44> = steps.frames(up0),
startCap: Boolean = true,
endCap: Boolean = true,
writer: VertexWriter
) {
val finalFrames = if (path.closed) frames + frames.first() else frames
val crossSections = List(finalFrames.size) {
val t = it / (finalFrames.size - 1.0)
val linearContour = contour(t).sampleLinear(contourDistanceTolerance)
linearContour.adaptivePositions()
}
// Add caps
if (!path.closed) {
if (startCap) {
triangulationWithFrame(
ShapeContour.fromPoints(crossSections.first(), true).shape.triangulation,
finalFrames.first(), false, writer
)
}
if (endCap) {
triangulationWithFrame(
ShapeContour.fromPoints(crossSections.last(), true).shape.triangulation,
finalFrames.last(), false, writer
)
}
}
// Add sides
var i = 0
(finalFrames zip crossSections).windowed(2, 1).forEach {
contourSegment(
it[0].second, it[1].second,
it[0].first, it[1].first,
i.toDouble() / crossSections.size,
(++i).toDouble() / crossSections.size,
writer)
}
}
/**
* Extrude a [contour] along a [path] specifying the number of steps.
*
* @param contour the cross-section of the mesh
* @param path the 3D path
* @param stepCount the number of steps along the [path]
* @param up0 the initial up-vector
* @param contourDistanceTolerance precision for calculating steps along
* [contour]. Lower tolerance results in higher precision.
* @param pathDistanceTolerance precision for calculating steps along
* [path]. Lower tolerance results in higher precision.
*/
fun TriangleMeshBuilder.extrudeContourStepsMorphed(
contour: (Double) -> ShapeContour,
path: Path3D,
stepCount: Int,
up0: Vector3,
startCap: Boolean = true,
endCap: Boolean = true,
contourDistanceTolerance: Double = 0.5,
pathDistanceTolerance: Double = 0.5
) = extrudeContourStepsMorphed(
contour,
path,
stepCount,
up0,
startCap = startCap,
endCap = endCap,
contourDistanceTolerance = contourDistanceTolerance,
pathDistanceTolerance = pathDistanceTolerance,
writer = this::write
)