forked from kscience/visionforge
Make solid arguments immutable
This commit is contained in:
parent
5af8fe3e99
commit
0d53b6f77d
@ -19,6 +19,8 @@
|
||||
- VisionGroup builder accepts `null` as name for statics instead of `""`
|
||||
- gdml sphere is rendered as a SphereLayer instead of Sphere (#35)
|
||||
- Tube is replaced by more general ConeSurface
|
||||
- position, rotation and size moved to properties
|
||||
- prototypes moved to children
|
||||
|
||||
### Deprecated
|
||||
|
||||
|
@ -27,7 +27,7 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
|
||||
}
|
||||
|
||||
val canvasOptions = Canvas3DOptions {
|
||||
size{
|
||||
size {
|
||||
minSize = 400
|
||||
}
|
||||
axes {
|
||||
@ -57,9 +57,8 @@ fun VisionLayout<Solid>.showcase() {
|
||||
rotationX = PI / 4
|
||||
color("blue")
|
||||
}
|
||||
sphereLayer(50,40){
|
||||
theta = (PI/2).toFloat()
|
||||
rotationX = - PI * 3 / 4
|
||||
sphereLayer(50, 40, theta = PI / 2) {
|
||||
rotationX = -PI * 3 / 4
|
||||
z = 110
|
||||
color(Colors.pink)
|
||||
}
|
||||
|
@ -23,7 +23,7 @@ internal fun SolidGroup.varBox(
|
||||
action: VariableBox.() -> Unit = {},
|
||||
): VariableBox = VariableBox(xSize, ySize).apply(action).also { set(name, it) }
|
||||
|
||||
internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeVision() {
|
||||
internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() {
|
||||
|
||||
override fun render(three: ThreePlugin): Object3D {
|
||||
val geometry = BoxGeometry(xSize, ySize, 1)
|
||||
|
@ -1,12 +1,15 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import space.kscience.dataforge.meta.Config
|
||||
import space.kscience.dataforge.meta.MetaItem
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.set
|
||||
import space.kscience.dataforge.names.Name
|
||||
|
||||
/**
|
||||
* Property containers are used to create a symmetric behaviors for vision properties and style builders
|
||||
*/
|
||||
public interface VisionPropertyContainer<out T> {
|
||||
public interface VisionPropertyContainer<out V: Vision> {
|
||||
public fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean = false,
|
||||
@ -15,4 +18,18 @@ public interface VisionPropertyContainer<out T> {
|
||||
): MetaItem?
|
||||
|
||||
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
|
||||
}
|
||||
|
||||
public open class SimpleVisionPropertyContainer<out V: Vision>(protected val config: Config): VisionPropertyContainer<V>{
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean
|
||||
): MetaItem? = config[name]
|
||||
|
||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||
config[name] = item
|
||||
}
|
||||
|
||||
}
|
@ -232,11 +232,10 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
||||
bottomRadius = solid.rmax1 * lScale,
|
||||
height = solid.z * lScale,
|
||||
upperRadius = solid.rmax2 * lScale,
|
||||
startAngle = solid.startphi * aScale,
|
||||
angle = solid.deltaphi * aScale,
|
||||
name = name
|
||||
) {
|
||||
startAngle = solid.startphi * aScale
|
||||
angle = solid.deltaphi * aScale
|
||||
}
|
||||
)
|
||||
} else {
|
||||
coneSurface(
|
||||
bottomOuterRadius = solid.rmax1 * lScale,
|
||||
@ -244,11 +243,10 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
||||
height = solid.z * lScale,
|
||||
topOuterRadius = solid.rmax2 * lScale,
|
||||
topInnerRadius = solid.rmin2 * lScale,
|
||||
startAngle = solid.startphi * aScale,
|
||||
angle = solid.deltaphi * aScale,
|
||||
name = name
|
||||
) {
|
||||
startAngle = solid.startphi * aScale
|
||||
angle = solid.deltaphi * aScale
|
||||
}
|
||||
)
|
||||
}
|
||||
is GdmlXtru -> extrude(name) {
|
||||
shape {
|
||||
@ -276,12 +274,15 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
||||
scaleZ = solid.scale.z.toFloat()
|
||||
}
|
||||
}
|
||||
is GdmlSphere -> sphereLayer(solid.rmax * lScale, solid.rmin * lScale, name) {
|
||||
phi = solid.deltaphi * aScale
|
||||
theta = solid.deltatheta * aScale
|
||||
phiStart = solid.startphi * aScale
|
||||
thetaStart = solid.starttheta * aScale
|
||||
}
|
||||
is GdmlSphere -> sphereLayer(
|
||||
outerRadius = solid.rmax * lScale,
|
||||
innerRadius = solid.rmin * lScale,
|
||||
phi = solid.deltaphi * aScale,
|
||||
theta = solid.deltatheta * aScale,
|
||||
phiStart = solid.startphi * aScale,
|
||||
thetaStart = solid.starttheta * aScale,
|
||||
name = name,
|
||||
)
|
||||
is GdmlOrb -> sphere(solid.r * lScale, name = name)
|
||||
is GdmlPolyhedra -> extrude(name) {
|
||||
//getting the radius of first
|
||||
|
@ -15,11 +15,11 @@ import kotlin.math.sin
|
||||
@Serializable
|
||||
@SerialName("solid.cone")
|
||||
public class ConeSegment(
|
||||
public var bottomRadius: Float,
|
||||
public var height: Float,
|
||||
public var topRadius: Float,
|
||||
public var startAngle: Float = 0f,
|
||||
public var angle: Float = PI2
|
||||
public val bottomRadius: Float,
|
||||
public val height: Float,
|
||||
public val topRadius: Float,
|
||||
public val startAngle: Float = 0f,
|
||||
public val angle: Float = PI2
|
||||
) : SolidBase(), GeometrySolid {
|
||||
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
@ -83,10 +83,14 @@ public inline fun VisionContainerBuilder<Solid>.cone(
|
||||
bottomRadius: Number,
|
||||
height: Number,
|
||||
upperRadius: Number = 0.0,
|
||||
startAngle: Number = 0f,
|
||||
angle: Number = PI2,
|
||||
name: String? = null,
|
||||
block: ConeSegment.() -> Unit = {}
|
||||
): ConeSegment = ConeSegment(
|
||||
bottomRadius.toFloat(),
|
||||
height.toFloat(),
|
||||
topRadius = upperRadius.toFloat()
|
||||
topRadius = upperRadius.toFloat(),
|
||||
startAngle = startAngle.toFloat(),
|
||||
angle = angle.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
@ -16,13 +16,13 @@ import kotlin.math.sin
|
||||
@Serializable
|
||||
@SerialName("solid.coneSurface")
|
||||
public class ConeSurface(
|
||||
public var bottomRadius: Float,
|
||||
public var bottomInnerRadius: Float,
|
||||
public var height: Float,
|
||||
public var topRadius: Float,
|
||||
public var topInnerRadius: Float,
|
||||
public var startAngle: Float = 0f,
|
||||
public var angle: Float = PI2,
|
||||
public val bottomRadius: Float,
|
||||
public val bottomInnerRadius: Float,
|
||||
public val height: Float,
|
||||
public val topRadius: Float,
|
||||
public val topInnerRadius: Float,
|
||||
public val startAngle: Float = 0f,
|
||||
public val angle: Float = PI2,
|
||||
) : SolidBase(), GeometrySolid {
|
||||
|
||||
init {
|
||||
@ -148,6 +148,8 @@ public inline fun VisionContainerBuilder<Solid>.coneSurface(
|
||||
height: Number,
|
||||
topOuterRadius: Number,
|
||||
topInnerRadius: Number,
|
||||
startAngle: Number = 0f,
|
||||
angle: Number = PI2,
|
||||
name: String? = null,
|
||||
block: ConeSurface.() -> Unit = {},
|
||||
): ConeSurface = ConeSurface(
|
||||
@ -156,4 +158,6 @@ public inline fun VisionContainerBuilder<Solid>.coneSurface(
|
||||
height = height.toFloat(),
|
||||
topRadius = topOuterRadius.toFloat(),
|
||||
topInnerRadius = topInnerRadius.toFloat(),
|
||||
startAngle = startAngle.toFloat(),
|
||||
angle = angle.toFloat()
|
||||
).apply(block).also { set(name, it) }
|
@ -2,9 +2,8 @@ package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.VisionContainerBuilder
|
||||
import space.kscience.visionforge.set
|
||||
import space.kscience.dataforge.meta.Config
|
||||
import space.kscience.visionforge.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
@ -13,7 +12,7 @@ import kotlin.math.sin
|
||||
public typealias Shape2D = List<Point2D>
|
||||
|
||||
@Serializable
|
||||
public class Shape2DBuilder(private val points: MutableList<Point2D> = ArrayList()) {
|
||||
public class Shape2DBuilder(private val points: ArrayList<Point2D> = ArrayList()) {
|
||||
|
||||
public fun point(x: Number, y: Number) {
|
||||
points.add(Point2D(x, y))
|
||||
@ -38,19 +37,9 @@ public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Flo
|
||||
@Serializable
|
||||
@SerialName("solid.extrude")
|
||||
public class Extruded(
|
||||
public var shape: List<Point2D> = ArrayList(),
|
||||
public var layers: MutableList<Layer> = ArrayList()
|
||||
) : SolidBase(), GeometrySolid {
|
||||
|
||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
this.shape = Shape2DBuilder().apply(block).build()
|
||||
//TODO send invalidation signal
|
||||
}
|
||||
|
||||
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()))
|
||||
//TODO send invalidation signal
|
||||
}
|
||||
public val shape: List<Point2D>,
|
||||
public val layers: List<Layer>
|
||||
) : SolidBase(), GeometrySolid, VisionPropertyContainer<Extruded> {
|
||||
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
val shape: Shape2D = shape
|
||||
@ -103,6 +92,24 @@ public class Extruded(
|
||||
}
|
||||
}
|
||||
|
||||
public class ExtrudeBuilder(
|
||||
public var shape: List<Point2D> = emptyList(),
|
||||
public var layers: ArrayList<Layer> = ArrayList(),
|
||||
config: Config = Config()
|
||||
) : SimpleVisionPropertyContainer<Extruded>(config) {
|
||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
this.shape = Shape2DBuilder().apply(block).build()
|
||||
}
|
||||
|
||||
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()))
|
||||
}
|
||||
|
||||
internal fun build(): Extruded = Extruded(shape, layers).apply { configure(config) }
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun VisionContainerBuilder<Solid>.extrude(name: String? = null, action: Extruded.() -> Unit = {}): Extruded =
|
||||
Extruded().apply(action).also { set(name, it) }
|
||||
public fun VisionContainerBuilder<Solid>.extrude(
|
||||
name: String? = null,
|
||||
action: ExtrudeBuilder.() -> Unit = {}
|
||||
): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) }
|
@ -13,7 +13,7 @@ import space.kscience.visionforge.set
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.line")
|
||||
public class PolyLine(public var points: List<Point3D>) : SolidBase(), Solid {
|
||||
public class PolyLine(public val points: List<Point3D>) : SolidBase(), Solid {
|
||||
|
||||
//var lineType by string()
|
||||
public var thickness: Number by allProperties(inherit = false).number(1.0,
|
||||
|
@ -37,6 +37,8 @@ public interface Solid : Vision {
|
||||
|
||||
override val descriptor: NodeDescriptor get() = Companion.descriptor
|
||||
|
||||
|
||||
|
||||
public companion object {
|
||||
// val SELECTED_KEY = "selected".asName()
|
||||
public val DETAIL_KEY: Name = "detail".asName()
|
||||
|
@ -2,11 +2,7 @@ package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.float
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.node
|
||||
import space.kscience.visionforge.VisionBase
|
||||
import space.kscience.visionforge.VisionChange
|
||||
|
||||
@ -20,15 +16,3 @@ public open class SolidBase : VisionBase(), Solid {
|
||||
super.update(change)
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Meta.toVector(default: Float = 0f) = Point3D(
|
||||
this[Solid.X_KEY].float ?: default,
|
||||
this[Solid.Y_KEY].float ?: default,
|
||||
this[Solid.Z_KEY].float ?: default
|
||||
)
|
||||
|
||||
internal fun Solid.updatePosition(meta: Meta?) {
|
||||
meta[Solid.POSITION_KEY].node?.toVector()?.let { position = it }
|
||||
meta[Solid.ROTATION_KEY].node?.toVector()?.let { rotation = it }
|
||||
meta[Solid.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
|
||||
}
|
@ -9,9 +9,9 @@ import space.kscience.visionforge.set
|
||||
@Serializable
|
||||
@SerialName("solid.label")
|
||||
public class SolidLabel(
|
||||
public var text: String,
|
||||
public var fontSize: Double,
|
||||
public var fontFamily: String,
|
||||
public val text: String,
|
||||
public val fontSize: Double,
|
||||
public val fontFamily: String,
|
||||
) : SolidBase(), Solid
|
||||
|
||||
@VisionBuilder
|
||||
|
@ -4,6 +4,7 @@ import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.visionforge.VisionBuilder
|
||||
import space.kscience.visionforge.VisionContainerBuilder
|
||||
import space.kscience.visionforge.VisionPropertyContainer
|
||||
import space.kscience.visionforge.set
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
@ -12,12 +13,12 @@ import kotlin.math.sin
|
||||
@Serializable
|
||||
@SerialName("solid.sphere")
|
||||
public class Sphere(
|
||||
public var radius: Float,
|
||||
public var phiStart: Float = 0f,
|
||||
public var phi: Float = PI2,
|
||||
public var thetaStart: Float = 0f,
|
||||
public var theta: Float = PI.toFloat(),
|
||||
) : SolidBase(), GeometrySolid {
|
||||
public val radius: Float,
|
||||
public val phiStart: Float = 0f,
|
||||
public val phi: Float = PI2,
|
||||
public val thetaStart: Float = 0f,
|
||||
public val theta: Float = PI.toFloat(),
|
||||
) : SolidBase(), GeometrySolid, VisionPropertyContainer<Sphere> {
|
||||
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
fun point3DfromSphCoord(r: Float, theta: Float, phi: Float): Point3D {
|
||||
|
@ -15,12 +15,12 @@ import kotlin.math.sin
|
||||
@Serializable
|
||||
@SerialName("solid.sphereLayer")
|
||||
public class SphereLayer(
|
||||
public var outerRadius: Float,
|
||||
public var innerRadius: Float,
|
||||
public var phiStart: Float = 0f,
|
||||
public var phi: Float = PI2,
|
||||
public var thetaStart: Float = 0f,
|
||||
public var theta: Float = PI.toFloat(),
|
||||
public val outerRadius: Float,
|
||||
public val innerRadius: Float,
|
||||
public val phiStart: Float = 0f,
|
||||
public val phi: Float = PI2,
|
||||
public val thetaStart: Float = 0f,
|
||||
public val theta: Float = PI.toFloat(),
|
||||
) : SolidBase(), GeometrySolid {
|
||||
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>): Unit = geometryBuilder.run {
|
||||
@ -72,9 +72,17 @@ public class SphereLayer(
|
||||
public inline fun VisionContainerBuilder<Solid>.sphereLayer(
|
||||
outerRadius: Number,
|
||||
innerRadius: Number,
|
||||
phiStart: Number = 0f,
|
||||
phi: Number = PI2,
|
||||
thetaStart: Number = 0f,
|
||||
theta: Number = PI.toFloat(),
|
||||
name: String? = null,
|
||||
action: SphereLayer.() -> Unit = {},
|
||||
): SphereLayer = SphereLayer(
|
||||
outerRadius.toFloat(),
|
||||
innerRadius.toFloat(),
|
||||
phiStart.toFloat(),
|
||||
phi.toFloat(),
|
||||
thetaStart.toFloat(),
|
||||
theta.toFloat()
|
||||
).apply(action).also { set(name, it) }
|
@ -105,4 +105,17 @@ public fun Point3D.toMeta(): MetaBuilder = Meta {
|
||||
X_KEY put x
|
||||
Y_KEY put y
|
||||
Z_KEY put z
|
||||
}
|
||||
|
||||
|
||||
internal fun Meta.toVector(default: Float = 0f) = Point3D(
|
||||
this[Solid.X_KEY].float ?: default,
|
||||
this[Solid.Y_KEY].float ?: default,
|
||||
this[Solid.Z_KEY].float ?: default
|
||||
)
|
||||
|
||||
internal fun Solid.updatePosition(meta: Meta?) {
|
||||
meta[Solid.POSITION_KEY].node?.toVector()?.let { position = it }
|
||||
meta[Solid.ROTATION_KEY].node?.toVector()?.let { rotation = it }
|
||||
meta[Solid.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
|
||||
}
|
@ -6,6 +6,6 @@ import space.kscience.visionforge.solid.SolidBase
|
||||
/**
|
||||
* A custom visual object that has its own Three.js renderer
|
||||
*/
|
||||
public abstract class ThreeVision : SolidBase() {
|
||||
public abstract class ThreeJsVision : SolidBase() {
|
||||
public abstract fun render(three: ThreePlugin): Object3D
|
||||
}
|
@ -49,7 +49,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
|
||||
public fun buildObject3D(obj: Solid): Object3D = when (obj) {
|
||||
is ThreeVision -> obj.render(this)
|
||||
is ThreeJsVision -> obj.render(this)
|
||||
is SolidReferenceGroup -> ThreeReferenceFactory(this, obj)
|
||||
is SolidGroup -> {
|
||||
val group = ThreeGroup()
|
||||
|
Loading…
Reference in New Issue
Block a user