diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt index f92a27af..70bd2276 100644 --- a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/visualGDML.kt @@ -16,24 +16,26 @@ private fun VisualObject3D.withPosition( scale: GDMLScale? = null ): VisualObject3D = apply { pos?.let { - this@withPosition.position.x = pos.x(lUnit) - this@withPosition.position.y = pos.y(lUnit) - this@withPosition.position.z = pos.z(lUnit) + this@withPosition.x = pos.x(lUnit) + this@withPosition.y = pos.y(lUnit) + this@withPosition.z = pos.z(lUnit) } rotation?.let { - this@withPosition.rotation.x = rotation.x() - this@withPosition.rotation.y = rotation.y() - this@withPosition.rotation.z = rotation.z() + this@withPosition.rotationX = rotation.x() + this@withPosition.rotationY = rotation.y() + this@withPosition.rotationZ = rotation.z() } scale?.let { - this@withPosition.scale.x = scale.x.toFloat() - this@withPosition.scale.y = scale.y.toFloat() - this@withPosition.scale.z = scale.z.toFloat() + this@withPosition.scaleX = scale.x.toFloat() + this@withPosition.scaleY = scale.y.toFloat() + this@withPosition.scaleZ = scale.z.toFloat() } //TODO convert units if needed } +@Suppress("NOTHING_TO_INLINE") private inline operator fun Number.times(d: Double) = toDouble() * d +@Suppress("NOTHING_TO_INLINE") private inline operator fun Number.times(f: Float) = toFloat() * f private fun VisualGroup3D.addSolid( @@ -77,9 +79,9 @@ private fun VisualGroup3D.addSolid( addSolid(context, innerSolid) { block() - scale.x *= solid.scale.x.toFloat() - scale.y *= solid.scale.y.toFloat() - scale.z = solid.scale.z.toFloat() + scaleX *= solid.scale.x.toFloat() + scaleY *= solid.scale.y.toFloat() + scaleZ = solid.scale.z.toFloat() } } is GDMLSphere -> sphere(solid.rmax * lScale, solid.deltaphi * aScale, solid.deltatheta * aScale, name) { diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt index b2a5e36d..0c6d887f 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt @@ -27,7 +27,7 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { } } -data class Layer(var x: Number, var y: Number, var z: Number, var scale: Number) +data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) class Extruded : VisualLeaf3D(), Shape { @@ -41,7 +41,7 @@ class Extruded : VisualLeaf3D(), Shape { val layers: MutableList = ArrayList() fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { - layers.add(Layer(x, y, z, scale)) + layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) //TODO send invalidation signal } @@ -55,8 +55,8 @@ class Extruded : VisualLeaf3D(), Shape { */ val layers: List> = layers.map { layer -> shape.map { (x, y) -> - val newX = layer.x.toDouble() + x.toDouble() * layer.scale.toDouble() - val newY = layer.y.toDouble() + y.toDouble() * layer.scale.toDouble() + val newX = layer.x + x * layer.scale + val newY = layer.y + y * layer.scale Point3D(newX, newY, layer.z) } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt index a3c239a5..07ea1612 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/GeometryBuilder.kt @@ -1,35 +1,7 @@ package hep.dataforge.vis.spatial -import hep.dataforge.meta.* - -data class Point2D(val x: Number, val y: Number) : MetaRepr { - override fun toMeta(): Meta = buildMeta { - "x" to x - "y" to y - } - - companion object { - fun from(meta: Meta): Point2D { - return Point2D(meta["x"].number ?: 0, meta["y"].number ?: 0) - } - } -} - -data class Point3D(val x: Number, val y: Number, val z: Number) : MetaRepr { - override fun toMeta(): Meta = buildMeta { - "x" to x - "y" to y - "z" to z - } - - companion object { - fun from(meta: Meta): Point3D { - return Point3D(meta["x"].number ?: 0, meta["y"].number ?: 0, meta["y"].number ?: 0) - } - - val zero = Point3D(0, 0, 0) - } -} +import hep.dataforge.meta.EmptyMeta +import hep.dataforge.meta.Meta /** * @param T the type of resulting geometry @@ -66,9 +38,9 @@ interface Shape : VisualObject3D { fun GeometryBuilder.cap(shape: List, normal: Point3D? = null) { //FIXME won't work for non-convex shapes val center = Point3D( - shape.map { it.x.toDouble() }.average(), - shape.map { it.y.toDouble() }.average(), - shape.map { it.z.toDouble() }.average() + shape.map { it.x }.average(), + shape.map { it.y }.average(), + shape.map { it.z }.average() ) for (i in 0 until (shape.size - 1)) { face(shape[i], shape[i + 1], center, normal) diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt index fe48af2e..fb4bf8e5 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt @@ -9,21 +9,18 @@ import hep.dataforge.vis.common.AbstractVisualObject * A proxy [VisualObject3D] to reuse a template object */ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualObject3D { - override var position: Value3 = Value3() - override var rotation: Value3 = Value3() - override var scale: Value3 = Value3(1f, 1f, 1f) - - val template by lazy { getTemplate() } + override var position: Point3D? = null + override var rotation: Point3D? = null + override var scale: Point3D? = null /** * Recursively search for defined template in the parent */ - private fun getTemplate(): VisualObject3D { - return (parent as? VisualGroup3D)?.getTemplate(templateName) + val template by lazy { + (parent as? VisualGroup3D)?.getTemplate(templateName) ?: error("Template with name $templateName not found in $parent") } - override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { return if (inherit) { super.getProperty(name, false) ?: template.getProperty(name, false) ?: parent?.getProperty(name, inherit) diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Visual3DPlugin.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Visual3DPlugin.kt index 67eb9adc..77177070 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Visual3DPlugin.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Visual3DPlugin.kt @@ -27,7 +27,7 @@ class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) { } internal fun VisualObject3D.update(meta: Meta) { - fun Meta.toVector(default: Float = 0f) = Value3( + fun Meta.toVector(default: Float = 0f) = Point3D( this[VisualObject3D.x].float ?: default, this[VisualObject3D.y].float ?: default, this[VisualObject3D.z].float ?: default diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt index ec9655b3..65d3e47c 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt @@ -12,23 +12,21 @@ import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.MATERIAL_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY -data class Value3(var x: Float = 0f, var y: Float = 0f, var z: Float = 0f) - interface VisualObject3D : VisualObject { - var position: Value3 - var rotation: Value3 - var scale: Value3 + var position: Point3D? + var rotation: Point3D? + var scale: Point3D? fun MetaBuilder.updatePosition() { - xPos to position.x - yPos to position.y - zPos to position.z - xRotation to rotation.x - yRotation to rotation.y - zRotation to rotation.z - xScale to scale.x - yScale to scale.y - zScale to scale.z + xPos to position?.x + yPos to position?.y + zPos to position?.z + xRotation to rotation?.x + yRotation to rotation?.y + zRotation to rotation?.z + xScale to scale?.x + yScale to scale?.y + zScale to scale?.z } companion object { @@ -63,16 +61,16 @@ interface VisualObject3D : VisualObject { } abstract class VisualLeaf3D : AbstractVisualObject(), VisualObject3D, Configurable { - override var position: Value3 = Value3() - override var rotation: Value3 = Value3() - override var scale: Value3 = Value3(1f, 1f, 1f) + override var position: Point3D? = null + override var rotation: Point3D? = null + override var scale: Point3D? = null } class VisualGroup3D : VisualGroup(), VisualObject3D, Configurable { - override var position: Value3 = Value3() - override var rotation: Value3 = Value3() - override var scale: Value3 = Value3(1f, 1f, 1f) + override var position: Point3D? = null + override var rotation: Point3D? = null + override var scale: Point3D? = null /** * A container for templates visible inside this group @@ -145,66 +143,75 @@ fun VisualObject3D.color(r: Int, g: Int, b: Int) = material { "blue" to b } +private fun VisualObject3D.position(): Point3D = + position ?: Point3D(0.0, 0.0, 0.0).also { position = it } + var VisualObject3D.x: Number - get() = position.x + get() = position?.x ?: 0f set(value) { - position.x = value.toFloat() + position().x = value.toDouble() propertyChanged(VisualObject3D.xPos) } var VisualObject3D.y: Number - get() = position.y + get() = position?.y ?: 0f set(value) { - position.y = value.toFloat() + position().y = value.toDouble() propertyChanged(VisualObject3D.yPos) } var VisualObject3D.z: Number - get() = position.z + get() = position?.z ?: 0f set(value) { - position.z = value.toFloat() + position().z = value.toDouble() propertyChanged(VisualObject3D.zPos) } +private fun VisualObject3D.rotation(): Point3D = + rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it } + var VisualObject3D.rotationX: Number - get() = rotation.x + get() = rotation?.x ?: 0f set(value) { - rotation.x = value.toFloat() + rotation().x = value.toDouble() propertyChanged(VisualObject3D.xRotation) } var VisualObject3D.rotationY: Number - get() = rotation.y + get() = rotation?.y ?: 0f set(value) { - rotation.y = value.toFloat() + rotation().y = value.toDouble() propertyChanged(VisualObject3D.xRotation) } var VisualObject3D.rotationZ: Number - get() = rotation.z + get() = rotation?.z ?: 0f set(value) { - rotation.z = value.toFloat() + rotation().z = value.toDouble() propertyChanged(VisualObject3D.zRotation) } +private fun VisualObject3D.scale(): Point3D = + scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it } + var VisualObject3D.scaleX: Number - get() = scale.x + get() = scale?.x ?: 1f set(value) { - scale.x = value.toFloat() + scale().x = value.toDouble() propertyChanged(VisualObject3D.xScale) } var VisualObject3D.scaleY: Number - get() = scale.y + get() = scale?.y ?: 1f set(value) { - scale.y = value.toFloat() + scale().y = value.toDouble() propertyChanged(VisualObject3D.yScale) } var VisualObject3D.scaleZ: Number - get() = scale.z + get() = scale?.z ?: 1f set(value) { - scale.z = value.toFloat() + scale().z = value.toDouble() propertyChanged(VisualObject3D.zScale) } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt new file mode 100644 index 00000000..20b537b2 --- /dev/null +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/geometry.kt @@ -0,0 +1,41 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.Meta +import hep.dataforge.meta.buildMeta +import hep.dataforge.meta.get +import hep.dataforge.meta.number + +expect class Point2D(x: Number, y: Number) { + var x: Double + var y: Double +} + +operator fun Point2D.component1() = x +operator fun Point2D.component2() = y + +fun Point2D.toMeta() = buildMeta { + VisualObject3D.x to x + VisualObject3D.y to y +} + +fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0) + +expect class Point3D(x: Number, y: Number, z: Number) { + var x: Double + var y: Double + var z: Double +} + +operator fun Point3D.component1() = x +operator fun Point3D.component2() = y +operator fun Point3D.component3() = z + +fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0) + +val zero = Point3D(0, 0, 0) + +fun Point3D.toMeta() = buildMeta { + VisualObject3D.x to x + VisualObject3D.y to y + VisualObject3D.z to z +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/geometryJs.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/geometryJs.kt new file mode 100644 index 00000000..cacb3600 --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/geometryJs.kt @@ -0,0 +1,8 @@ +package hep.dataforge.vis.spatial + +import info.laht.threekt.math.Vector2 +import info.laht.threekt.math.Vector3 + +actual typealias Point2D = Vector2 + +actual typealias Point3D = Vector3 \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeConvexFactory.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeConvexFactory.kt index 7546c86f..728e19fb 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeConvexFactory.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeConvexFactory.kt @@ -2,10 +2,11 @@ package hep.dataforge.vis.spatial.three import hep.dataforge.vis.spatial.Convex import info.laht.threekt.external.geometries.ConvexBufferGeometry +import info.laht.threekt.math.Vector3 object ThreeConvexFactory : MeshThreeFactory(Convex::class) { override fun buildGeometry(obj: Convex): ConvexBufferGeometry { - val vectors = obj.points.map { it.asVector() }.toTypedArray() + @Suppress("USELESS_CAST") val vectors = obj.points.toTypedArray() as Array return ConvexBufferGeometry(vectors) } } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt index 086bf269..1b93b1bc 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeFactory.kt @@ -71,6 +71,7 @@ internal fun Mesh.updateFrom(obj: T) { */ operator fun ThreeFactory.invoke(obj: Any): Object3D { if (type.isInstance(obj)) { + @Suppress("UNCHECKED_CAST") return invoke(obj as T) } else { error("The object of type ${obj::class} could not be rendered by this factory") diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeGeometryBuilder.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeGeometryBuilder.kt index e4030fa6..a7a6b606 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeGeometryBuilder.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/three/ThreeGeometryBuilder.kt @@ -4,19 +4,12 @@ import hep.dataforge.meta.Meta import hep.dataforge.meta.get import hep.dataforge.meta.int import hep.dataforge.vis.spatial.GeometryBuilder -import hep.dataforge.vis.spatial.Point2D import hep.dataforge.vis.spatial.Point3D import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.Face3 import info.laht.threekt.core.Geometry -import info.laht.threekt.math.Vector2 import info.laht.threekt.math.Vector3 -// TODO use unsafe cast instead -fun Point3D.asVector(): Vector3 = Vector3(this.x, this.y, this.z) - -fun Point2D.asVector(): Vector2 = Vector2(this.x, this.y) - class ThreeGeometryBuilder : GeometryBuilder { private val vertices = ArrayList() @@ -36,7 +29,7 @@ class ThreeGeometryBuilder : GeometryBuilder { } override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) { - val face = Face3(append(vertex1), append(vertex2), append(vertex3), normal?.asVector() ?: Vector3(0, 0, 0)) + val face = Face3(append(vertex1), append(vertex2), append(vertex3), normal ?: Vector3(0, 0, 0)) meta["materialIndex"].int?.let { face.materialIndex = it } meta["color"]?.color()?.let { face.color = it } faces.add(face) @@ -45,7 +38,7 @@ class ThreeGeometryBuilder : GeometryBuilder { override fun build(): BufferGeometry { return Geometry().apply { - vertices = this@ThreeGeometryBuilder.vertices.map { it.asVector() }.toTypedArray() + vertices = this@ThreeGeometryBuilder.vertices.toTypedArray() faces = this@ThreeGeometryBuilder.faces.toTypedArray() computeBoundingSphere() computeFaceNormals() diff --git a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/Canvas3D.kt b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/Canvas3D.kt index cfbc3375..211c0d41 100644 --- a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/Canvas3D.kt +++ b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/Canvas3D.kt @@ -1,6 +1,5 @@ package hep.dataforge.vis.spatial.fx -import com.sun.tools.javac.util.JCDiagnostic import hep.dataforge.vis.spatial.World.CAMERA_FAR_CLIP import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_DISTANCE import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_X_ANGLE diff --git a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FX3DOutput.kt b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FX3DOutput.kt index 9e1ab369..b910b17e 100644 --- a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FX3DOutput.kt +++ b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/fx/FX3DOutput.kt @@ -3,9 +3,9 @@ package hep.dataforge.vis.spatial.fx import hep.dataforge.context.Context import hep.dataforge.meta.Meta import hep.dataforge.output.Output -import hep.dataforge.vis.common.VisualNode import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.spatial.Box +import hep.dataforge.vis.spatial.VisualGroup3D import javafx.scene.Group import javafx.scene.Node import org.fxyz3d.shapes.primitives.CuboidMesh @@ -28,12 +28,12 @@ class FX3DOutput(override val context: Context) : Output { org.fxyz3d.geometry.Point3D(x.value ?: 0f, y.value ?: 0f, z.value ?: 0f) } return when (obj) { - is VisualNode -> Group(obj.map { buildNode(it) }).apply { + is VisualGroup3D -> Group(obj.map { buildNode(it) }).apply { this.translateXProperty().bind(x) this.translateYProperty().bind(y) this.translateZProperty().bind(z) } - is Box -> CuboidMesh(obj.xSize, obj.ySize, obj.zSize).apply { + is Box -> CuboidMesh(obj.xSize.toDouble(), obj.ySize.toDouble(), obj.zSize.toDouble()).apply { this.centerProperty().bind(center) this.materialProperty().bind(listener["color"].transform { it.material() }) } diff --git a/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/geometryJVM.kt b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/geometryJVM.kt new file mode 100644 index 00000000..3e56de87 --- /dev/null +++ b/dataforge-vis-spatial/src/jvmMain/kotlin/hep/dataforge/vis/spatial/geometryJVM.kt @@ -0,0 +1,12 @@ +package hep.dataforge.vis.spatial + +actual class Point2D actual constructor(x: Number, y: Number) { + actual var x = x.toDouble() + actual var y = y.toDouble() +} + +actual class Point3D actual constructor(x: Number, y: Number, z: Number) { + actual var x = x.toDouble() + actual var y = y.toDouble() + actual var z = z.toDouble() +} \ No newline at end of file