Memory optimization

This commit is contained in:
Alexander Nozik 2019-08-04 16:51:38 +03:00
parent 5cb62c8f6e
commit 4e2955615a
14 changed files with 143 additions and 110 deletions

View File

@ -16,24 +16,26 @@ private fun VisualObject3D.withPosition(
scale: GDMLScale? = null scale: GDMLScale? = null
): VisualObject3D = apply { ): VisualObject3D = apply {
pos?.let { pos?.let {
this@withPosition.position.x = pos.x(lUnit) this@withPosition.x = pos.x(lUnit)
this@withPosition.position.y = pos.y(lUnit) this@withPosition.y = pos.y(lUnit)
this@withPosition.position.z = pos.z(lUnit) this@withPosition.z = pos.z(lUnit)
} }
rotation?.let { rotation?.let {
this@withPosition.rotation.x = rotation.x() this@withPosition.rotationX = rotation.x()
this@withPosition.rotation.y = rotation.y() this@withPosition.rotationY = rotation.y()
this@withPosition.rotation.z = rotation.z() this@withPosition.rotationZ = rotation.z()
} }
scale?.let { scale?.let {
this@withPosition.scale.x = scale.x.toFloat() this@withPosition.scaleX = scale.x.toFloat()
this@withPosition.scale.y = scale.y.toFloat() this@withPosition.scaleY = scale.y.toFloat()
this@withPosition.scale.z = scale.z.toFloat() this@withPosition.scaleZ = scale.z.toFloat()
} }
//TODO convert units if needed //TODO convert units if needed
} }
@Suppress("NOTHING_TO_INLINE")
private inline operator fun Number.times(d: Double) = toDouble() * d 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 inline operator fun Number.times(f: Float) = toFloat() * f
private fun VisualGroup3D.addSolid( private fun VisualGroup3D.addSolid(
@ -77,9 +79,9 @@ private fun VisualGroup3D.addSolid(
addSolid(context, innerSolid) { addSolid(context, innerSolid) {
block() block()
scale.x *= solid.scale.x.toFloat() scaleX *= solid.scale.x.toFloat()
scale.y *= solid.scale.y.toFloat() scaleY *= solid.scale.y.toFloat()
scale.z = solid.scale.z.toFloat() scaleZ = solid.scale.z.toFloat()
} }
} }
is GDMLSphere -> sphere(solid.rmax * lScale, solid.deltaphi * aScale, solid.deltatheta * aScale, name) { is GDMLSphere -> sphere(solid.rmax * lScale, solid.deltaphi * aScale, solid.deltatheta * aScale, name) {

View File

@ -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 { class Extruded : VisualLeaf3D(), Shape {
@ -41,7 +41,7 @@ class Extruded : VisualLeaf3D(), Shape {
val layers: MutableList<Layer> = ArrayList() val layers: MutableList<Layer> = ArrayList()
fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { 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 //TODO send invalidation signal
} }
@ -55,8 +55,8 @@ class Extruded : VisualLeaf3D(), Shape {
*/ */
val layers: List<List<Point3D>> = layers.map { layer -> val layers: List<List<Point3D>> = layers.map { layer ->
shape.map { (x, y) -> shape.map { (x, y) ->
val newX = layer.x.toDouble() + x.toDouble() * layer.scale.toDouble() val newX = layer.x + x * layer.scale
val newY = layer.y.toDouble() + y.toDouble() * layer.scale.toDouble() val newY = layer.y + y * layer.scale
Point3D(newX, newY, layer.z) Point3D(newX, newY, layer.z)
} }
} }

View File

@ -1,35 +1,7 @@
package hep.dataforge.vis.spatial package hep.dataforge.vis.spatial
import hep.dataforge.meta.* import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.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)
}
}
/** /**
* @param T the type of resulting geometry * @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) { fun <T : Any> GeometryBuilder<T>.cap(shape: List<Point3D>, normal: Point3D? = null) {
//FIXME won't work for non-convex shapes //FIXME won't work for non-convex shapes
val center = Point3D( val center = Point3D(
shape.map { it.x.toDouble() }.average(), shape.map { it.x }.average(),
shape.map { it.y.toDouble() }.average(), shape.map { it.y }.average(),
shape.map { it.z.toDouble() }.average() shape.map { it.z }.average()
) )
for (i in 0 until (shape.size - 1)) { for (i in 0 until (shape.size - 1)) {
face(shape[i], shape[i + 1], center, normal) face(shape[i], shape[i + 1], center, normal)

View File

@ -9,21 +9,18 @@ import hep.dataforge.vis.common.AbstractVisualObject
* A proxy [VisualObject3D] to reuse a template object * A proxy [VisualObject3D] to reuse a template object
*/ */
class Proxy(val templateName: Name) : AbstractVisualObject(), VisualObject3D { class Proxy(val templateName: Name) : AbstractVisualObject(), VisualObject3D {
override var position: Value3 = Value3() override var position: Point3D? = null
override var rotation: Value3 = Value3() override var rotation: Point3D? = null
override var scale: Value3 = Value3(1f, 1f, 1f) override var scale: Point3D? = null
val template by lazy { getTemplate() }
/** /**
* Recursively search for defined template in the parent * Recursively search for defined template in the parent
*/ */
private fun getTemplate(): VisualObject3D { val template by lazy {
return (parent as? VisualGroup3D)?.getTemplate(templateName) (parent as? VisualGroup3D)?.getTemplate(templateName)
?: error("Template with name $templateName not found in $parent") ?: error("Template with name $templateName not found in $parent")
} }
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) { return if (inherit) {
super.getProperty(name, false) ?: template.getProperty(name, false) ?: parent?.getProperty(name, inherit) super.getProperty(name, false) ?: template.getProperty(name, false) ?: parent?.getProperty(name, inherit)

View File

@ -27,7 +27,7 @@ class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) {
} }
internal fun VisualObject3D.update(meta: 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.x].float ?: default,
this[VisualObject3D.y].float ?: default, this[VisualObject3D.y].float ?: default,
this[VisualObject3D.z].float ?: default this[VisualObject3D.z].float ?: default

View File

@ -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.MATERIAL_KEY
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_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 { interface VisualObject3D : VisualObject {
var position: Value3 var position: Point3D?
var rotation: Value3 var rotation: Point3D?
var scale: Value3 var scale: Point3D?
fun MetaBuilder.updatePosition() { fun MetaBuilder.updatePosition() {
xPos to position.x xPos to position?.x
yPos to position.y yPos to position?.y
zPos to position.z zPos to position?.z
xRotation to rotation.x xRotation to rotation?.x
yRotation to rotation.y yRotation to rotation?.y
zRotation to rotation.z zRotation to rotation?.z
xScale to scale.x xScale to scale?.x
yScale to scale.y yScale to scale?.y
zScale to scale.z zScale to scale?.z
} }
companion object { companion object {
@ -63,16 +61,16 @@ interface VisualObject3D : VisualObject {
} }
abstract class VisualLeaf3D : AbstractVisualObject(), VisualObject3D, Configurable { abstract class VisualLeaf3D : AbstractVisualObject(), VisualObject3D, Configurable {
override var position: Value3 = Value3() override var position: Point3D? = null
override var rotation: Value3 = Value3() override var rotation: Point3D? = null
override var scale: Value3 = Value3(1f, 1f, 1f) override var scale: Point3D? = null
} }
class VisualGroup3D : VisualGroup<VisualObject3D>(), VisualObject3D, Configurable { class VisualGroup3D : VisualGroup<VisualObject3D>(), VisualObject3D, Configurable {
override var position: Value3 = Value3() override var position: Point3D? = null
override var rotation: Value3 = Value3() override var rotation: Point3D? = null
override var scale: Value3 = Value3(1f, 1f, 1f) override var scale: Point3D? = null
/** /**
* A container for templates visible inside this group * 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 "blue" to b
} }
private fun VisualObject3D.position(): Point3D =
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
var VisualObject3D.x: Number var VisualObject3D.x: Number
get() = position.x get() = position?.x ?: 0f
set(value) { set(value) {
position.x = value.toFloat() position().x = value.toDouble()
propertyChanged(VisualObject3D.xPos) propertyChanged(VisualObject3D.xPos)
} }
var VisualObject3D.y: Number var VisualObject3D.y: Number
get() = position.y get() = position?.y ?: 0f
set(value) { set(value) {
position.y = value.toFloat() position().y = value.toDouble()
propertyChanged(VisualObject3D.yPos) propertyChanged(VisualObject3D.yPos)
} }
var VisualObject3D.z: Number var VisualObject3D.z: Number
get() = position.z get() = position?.z ?: 0f
set(value) { set(value) {
position.z = value.toFloat() position().z = value.toDouble()
propertyChanged(VisualObject3D.zPos) propertyChanged(VisualObject3D.zPos)
} }
private fun VisualObject3D.rotation(): Point3D =
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
var VisualObject3D.rotationX: Number var VisualObject3D.rotationX: Number
get() = rotation.x get() = rotation?.x ?: 0f
set(value) { set(value) {
rotation.x = value.toFloat() rotation().x = value.toDouble()
propertyChanged(VisualObject3D.xRotation) propertyChanged(VisualObject3D.xRotation)
} }
var VisualObject3D.rotationY: Number var VisualObject3D.rotationY: Number
get() = rotation.y get() = rotation?.y ?: 0f
set(value) { set(value) {
rotation.y = value.toFloat() rotation().y = value.toDouble()
propertyChanged(VisualObject3D.xRotation) propertyChanged(VisualObject3D.xRotation)
} }
var VisualObject3D.rotationZ: Number var VisualObject3D.rotationZ: Number
get() = rotation.z get() = rotation?.z ?: 0f
set(value) { set(value) {
rotation.z = value.toFloat() rotation().z = value.toDouble()
propertyChanged(VisualObject3D.zRotation) propertyChanged(VisualObject3D.zRotation)
} }
private fun VisualObject3D.scale(): Point3D =
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
var VisualObject3D.scaleX: Number var VisualObject3D.scaleX: Number
get() = scale.x get() = scale?.x ?: 1f
set(value) { set(value) {
scale.x = value.toFloat() scale().x = value.toDouble()
propertyChanged(VisualObject3D.xScale) propertyChanged(VisualObject3D.xScale)
} }
var VisualObject3D.scaleY: Number var VisualObject3D.scaleY: Number
get() = scale.y get() = scale?.y ?: 1f
set(value) { set(value) {
scale.y = value.toFloat() scale().y = value.toDouble()
propertyChanged(VisualObject3D.yScale) propertyChanged(VisualObject3D.yScale)
} }
var VisualObject3D.scaleZ: Number var VisualObject3D.scaleZ: Number
get() = scale.z get() = scale?.z ?: 1f
set(value) { set(value) {
scale.z = value.toFloat() scale().z = value.toDouble()
propertyChanged(VisualObject3D.zScale) propertyChanged(VisualObject3D.zScale)
} }

View File

@ -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
}

View File

@ -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

View File

@ -2,10 +2,11 @@ package hep.dataforge.vis.spatial.three
import hep.dataforge.vis.spatial.Convex import hep.dataforge.vis.spatial.Convex
import info.laht.threekt.external.geometries.ConvexBufferGeometry import info.laht.threekt.external.geometries.ConvexBufferGeometry
import info.laht.threekt.math.Vector3
object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) { object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) {
override fun buildGeometry(obj: Convex): ConvexBufferGeometry { 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) return ConvexBufferGeometry(vectors)
} }
} }

View File

@ -71,6 +71,7 @@ internal fun <T : VisualObject3D> Mesh.updateFrom(obj: T) {
*/ */
operator fun <T : VisualObject3D> ThreeFactory<T>.invoke(obj: Any): Object3D { operator fun <T : VisualObject3D> ThreeFactory<T>.invoke(obj: Any): Object3D {
if (type.isInstance(obj)) { if (type.isInstance(obj)) {
@Suppress("UNCHECKED_CAST")
return invoke(obj as T) return invoke(obj as T)
} else { } else {
error("The object of type ${obj::class} could not be rendered by this factory") error("The object of type ${obj::class} could not be rendered by this factory")

View File

@ -4,19 +4,12 @@ import hep.dataforge.meta.Meta
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.int import hep.dataforge.meta.int
import hep.dataforge.vis.spatial.GeometryBuilder import hep.dataforge.vis.spatial.GeometryBuilder
import hep.dataforge.vis.spatial.Point2D
import hep.dataforge.vis.spatial.Point3D import hep.dataforge.vis.spatial.Point3D
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Face3 import info.laht.threekt.core.Face3
import info.laht.threekt.core.Geometry import info.laht.threekt.core.Geometry
import info.laht.threekt.math.Vector2
import info.laht.threekt.math.Vector3 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> { class ThreeGeometryBuilder : GeometryBuilder<BufferGeometry> {
private val vertices = ArrayList<Point3D>() 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) { 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["materialIndex"].int?.let { face.materialIndex = it }
meta["color"]?.color()?.let { face.color = it } meta["color"]?.color()?.let { face.color = it }
faces.add(face) faces.add(face)
@ -45,7 +38,7 @@ class ThreeGeometryBuilder : GeometryBuilder<BufferGeometry> {
override fun build(): BufferGeometry { override fun build(): BufferGeometry {
return Geometry().apply { return Geometry().apply {
vertices = this@ThreeGeometryBuilder.vertices.map { it.asVector() }.toTypedArray() vertices = this@ThreeGeometryBuilder.vertices.toTypedArray()
faces = this@ThreeGeometryBuilder.faces.toTypedArray() faces = this@ThreeGeometryBuilder.faces.toTypedArray()
computeBoundingSphere() computeBoundingSphere()
computeFaceNormals() computeFaceNormals()

View File

@ -1,6 +1,5 @@
package hep.dataforge.vis.spatial.fx 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_FAR_CLIP
import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_DISTANCE import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_DISTANCE
import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_X_ANGLE import hep.dataforge.vis.spatial.World.CAMERA_INITIAL_X_ANGLE

View File

@ -3,9 +3,9 @@ package hep.dataforge.vis.spatial.fx
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.vis.common.VisualNode
import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.Box import hep.dataforge.vis.spatial.Box
import hep.dataforge.vis.spatial.VisualGroup3D
import javafx.scene.Group import javafx.scene.Group
import javafx.scene.Node import javafx.scene.Node
import org.fxyz3d.shapes.primitives.CuboidMesh 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) org.fxyz3d.geometry.Point3D(x.value ?: 0f, y.value ?: 0f, z.value ?: 0f)
} }
return when (obj) { return when (obj) {
is VisualNode -> Group(obj.map { buildNode(it) }).apply { is VisualGroup3D -> Group(obj.map { buildNode(it) }).apply {
this.translateXProperty().bind(x) this.translateXProperty().bind(x)
this.translateYProperty().bind(y) this.translateYProperty().bind(y)
this.translateZProperty().bind(z) 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.centerProperty().bind(center)
this.materialProperty().bind(listener["color"].transform { it.material() }) this.materialProperty().bind(listener["color"].transform { it.material() })
} }

View File

@ -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()
}