forked from kscience/visionforge
Add surface geometry
This commit is contained in:
parent
00213c089d
commit
c7640a686a
@ -1,6 +1,9 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
|
import space.kscience.visionforge.solid.extruded
|
||||||
|
import space.kscience.visionforge.solid.polygon
|
||||||
|
import space.kscience.visionforge.solid.solid
|
||||||
|
|
||||||
fun main() = makeVisionFile {
|
fun main() = makeVisionFile {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
@ -12,8 +15,6 @@ fun main() = makeVisionFile {
|
|||||||
}
|
}
|
||||||
layer(-30)
|
layer(-30)
|
||||||
layer(30)
|
layer(30)
|
||||||
}.apply {
|
|
||||||
edges(false)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,19 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
//fun main() = makeVisionFile {
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
// vision("canvas") {
|
import space.kscience.visionforge.solid.polygon
|
||||||
// solid {
|
import space.kscience.visionforge.solid.solid
|
||||||
// ambientLight()
|
import space.kscience.visionforge.solid.surface
|
||||||
// surface("surface") {
|
|
||||||
// shape{
|
fun main() = makeVisionFile {
|
||||||
// polygon(8, 100)
|
vision("canvas") {
|
||||||
// layer(-30)
|
solid {
|
||||||
// layer(30)
|
ambientLight()
|
||||||
// }
|
surface("surface") {
|
||||||
// }
|
layer(0, {polygon(8,10)}, {polygon(8,20)})
|
||||||
// }
|
layer(10, {polygon(8,10)}, {polygon(8,30)})
|
||||||
// }
|
|
||||||
//}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,37 +9,8 @@ import space.kscience.kmath.geometry.component2
|
|||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.setChild
|
import space.kscience.visionforge.setChild
|
||||||
import kotlin.math.PI
|
|
||||||
import kotlin.math.cos
|
|
||||||
import kotlin.math.sin
|
|
||||||
|
|
||||||
|
|
||||||
public typealias Shape2D = List<Float32Vector2D>
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
public class Shape2DBuilder(private val points: ArrayList<Float32Vector2D> = ArrayList()) {
|
|
||||||
|
|
||||||
public fun point(x: Number, y: Number) {
|
|
||||||
points.add(Float32Vector2D(x, y))
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun build(): Shape2D = points
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
|
||||||
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
|
||||||
val angle = 2 * PI / vertices
|
|
||||||
for (i in 0 until vertices) {
|
|
||||||
point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* A layer for extruded shape
|
|
||||||
*/
|
|
||||||
@Serializable
|
|
||||||
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An extruded shape with the same number of points on each layer.
|
* An extruded shape with the same number of points on each layer.
|
||||||
*/
|
*/
|
||||||
@ -50,6 +21,12 @@ public class Extruded(
|
|||||||
public val layers: List<Layer>,
|
public val layers: List<Layer>,
|
||||||
) : SolidBase<Extruded>(), GeometrySolid {
|
) : SolidBase<Extruded>(), GeometrySolid {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A layer for extruded shape
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" }
|
require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" }
|
||||||
}
|
}
|
||||||
@ -72,6 +49,8 @@ public class Extruded(
|
|||||||
var lowerLayer = layers.first()
|
var lowerLayer = layers.first()
|
||||||
var upperLayer: List<Float32Vector3D>
|
var upperLayer: List<Float32Vector3D>
|
||||||
|
|
||||||
|
geometryBuilder.cap(layers.first().reversed())
|
||||||
|
|
||||||
for (i in (1 until layers.size)) {
|
for (i in (1 until layers.size)) {
|
||||||
upperLayer = layers[i]
|
upperLayer = layers[i]
|
||||||
for (j in (0 until shape.size - 1)) {
|
for (j in (0 until shape.size - 1)) {
|
||||||
@ -93,7 +72,7 @@ public class Extruded(
|
|||||||
)
|
)
|
||||||
lowerLayer = upperLayer
|
lowerLayer = upperLayer
|
||||||
}
|
}
|
||||||
geometryBuilder.cap(layers.first().reversed())
|
|
||||||
geometryBuilder.cap(layers.last())
|
geometryBuilder.cap(layers.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -102,10 +81,12 @@ public class Extruded(
|
|||||||
public var layers: MutableList<Layer> = ArrayList(),
|
public var layers: MutableList<Layer> = ArrayList(),
|
||||||
public val properties: MutableMeta = MutableMeta(),
|
public val properties: MutableMeta = MutableMeta(),
|
||||||
) {
|
) {
|
||||||
|
@VisionBuilder
|
||||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||||
this.shape = Shape2DBuilder().apply(block).build()
|
this.shape = Shape2DBuilder().apply(block).build()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@VisionBuilder
|
||||||
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
|
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
|
||||||
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
|
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,26 @@
|
|||||||
|
package space.kscience.visionforge.solid
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlin.math.PI
|
||||||
|
import kotlin.math.cos
|
||||||
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
public typealias Shape2D = List<Float32Vector2D>
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class Shape2DBuilder(private val points: ArrayList<Float32Vector2D> = ArrayList()) {
|
||||||
|
|
||||||
|
public fun point(x: Number, y: Number) {
|
||||||
|
points.add(Float32Vector2D(x, y))
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun build(): Shape2D = points
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||||
|
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
||||||
|
val angle = 2 * PI / vertices
|
||||||
|
for (i in 0 until vertices) {
|
||||||
|
point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i))
|
||||||
|
}
|
||||||
|
}
|
@ -41,6 +41,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
|
|||||||
subclass(ConeSurface.serializer())
|
subclass(ConeSurface.serializer())
|
||||||
subclass(Convex.serializer())
|
subclass(Convex.serializer())
|
||||||
subclass(Extruded.serializer())
|
subclass(Extruded.serializer())
|
||||||
|
subclass(Surface.serializer())
|
||||||
subclass(PolyLine.serializer())
|
subclass(PolyLine.serializer())
|
||||||
subclass(SolidLabel.serializer())
|
subclass(SolidLabel.serializer())
|
||||||
subclass(Sphere.serializer())
|
subclass(Sphere.serializer())
|
||||||
|
@ -2,9 +2,14 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.kmath.geometry.component1
|
import space.kscience.kmath.geometry.component1
|
||||||
import space.kscience.kmath.geometry.component2
|
import space.kscience.kmath.geometry.component2
|
||||||
import space.kscience.kmath.structures.Float32
|
import space.kscience.kmath.structures.Float32
|
||||||
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
|
import space.kscience.visionforge.VisionBuilder
|
||||||
|
import space.kscience.visionforge.setChild
|
||||||
|
|
||||||
|
|
||||||
private inline fun <T> Iterable<T>.sumOf(selector: (T) -> Float32): Float32 {
|
private inline fun <T> Iterable<T>.sumOf(selector: (T) -> Float32): Float32 {
|
||||||
@ -130,7 +135,39 @@ public class Surface(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class Builder(
|
||||||
|
public var layers: MutableList<Layer> = ArrayList(),
|
||||||
|
public val properties: MutableMeta = MutableMeta(),
|
||||||
|
) {
|
||||||
|
|
||||||
|
public fun layer(
|
||||||
|
z: Number,
|
||||||
|
innerBuilder: (Shape2DBuilder.() -> Unit)? = null,
|
||||||
|
outerBuilder: Shape2DBuilder.() -> Unit,
|
||||||
|
) {
|
||||||
|
layers.add(
|
||||||
|
Layer(
|
||||||
|
z.toFloat(),
|
||||||
|
outer = Shape2DBuilder().apply(outerBuilder).build(),
|
||||||
|
inner = innerBuilder?.let { Shape2DBuilder().apply(innerBuilder).build() }
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
internal fun build(): Surface = Surface(layers).apply {
|
||||||
|
properties.setMeta(Name.EMPTY, this@Builder.properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public const val TYPE: String = "solid.surface"
|
public const val TYPE: String = "solid.surface"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@VisionBuilder
|
||||||
|
public fun MutableVisionContainer<Solid>.surface(
|
||||||
|
name: String? = null,
|
||||||
|
action: Surface.Builder.() -> Unit = {},
|
||||||
|
): Surface = Surface.Builder().apply(action).build().also { setChild(name, it) }
|
||||||
|
Loading…
Reference in New Issue
Block a user