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
): 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) {

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

View File

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

View File

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

View File

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

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.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)
}

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

View File

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

View File

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

View File

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

View File

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

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