forked from kscience/visionforge
Memory optimization
This commit is contained in:
parent
5cb62c8f6e
commit
4e2955615a
@ -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) {
|
||||
|
@ -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<Layer> = 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<List<Point3D>> = 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)
|
||||
}
|
||||
}
|
||||
|
@ -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 <T : Any> GeometryBuilder<T>.cap(shape: List<Point3D>, 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)
|
||||
|
@ -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)
|
||||
|
@ -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
|
||||
|
@ -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>(), 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)
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
@ -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
|
@ -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>(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<Vector3>
|
||||
return ConvexBufferGeometry(vectors)
|
||||
}
|
||||
}
|
@ -71,6 +71,7 @@ internal fun <T : VisualObject3D> Mesh.updateFrom(obj: T) {
|
||||
*/
|
||||
operator fun <T : VisualObject3D> ThreeFactory<T>.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")
|
||||
|
@ -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<BufferGeometry> {
|
||||
|
||||
private val vertices = ArrayList<Point3D>()
|
||||
@ -36,7 +29,7 @@ class ThreeGeometryBuilder : GeometryBuilder<BufferGeometry> {
|
||||
}
|
||||
|
||||
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<BufferGeometry> {
|
||||
|
||||
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()
|
||||
|
@ -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
|
||||
|
@ -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<VisualObject> {
|
||||
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() })
|
||||
}
|
||||
|
@ -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()
|
||||
}
|
Loading…
Reference in New Issue
Block a user