From e5a27ab56f2f9283018d05bd29f00ad3a261e0c8 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Sun, 15 Sep 2019 11:30:25 +0300 Subject: [PATCH] Updated plugin and GDML conversion optimization --- build.gradle.kts | 15 ++--- dataforge-vis-common/build.gradle.kts | 2 +- .../vis/common/AbstractVisualGroup.kt | 2 +- dataforge-vis-spatial-gdml/build.gradle.kts | 6 +- .../vis/spatial/gdml/GDMLTransformer.kt | 13 ++++- .../vis/spatial/gdml/optimizations.kt | 58 +++++++++++++++++++ .../dataforge/vis/spatial/gdml/visualGDML.kt | 52 +++++++++++------ .../dataforge/vis/spatial/gdml/testMain.kt | 24 ++++++-- dataforge-vis-spatial/build.gradle.kts | 2 +- .../kotlin/hep/dataforge/vis/spatial/Proxy.kt | 6 +- .../dataforge/vis/spatial/Visual3DPlugin.kt | 5 +- .../dataforge/vis/spatial/VisualGroup3D.kt | 5 +- .../hep/dataforge/vis/spatial/geometry.kt | 18 ++++++ .../hep/dataforge/vis/spatial/GroupTest.kt | 15 ++--- .../vis/spatial/SerializationTest.kt | 2 +- 15 files changed, 172 insertions(+), 53 deletions(-) create mode 100644 dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/optimizations.kt diff --git a/build.gradle.kts b/build.gradle.kts index ada9bd4c..4a01e294 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,17 +1,15 @@ val dataforgeVersion by extra("0.1.3") plugins{ - val kotlinVersion = "1.3.50-eap-5" + val kotlinVersion = "1.3.50" kotlin("jvm") version kotlinVersion apply false - id("kotlin2js") version kotlinVersion apply false id("kotlin-dce-js") version kotlinVersion apply false - id("org.jetbrains.kotlin.frontend") version "0.0.45" apply false - id("scientifik.mpp") version "0.1.4" apply false - id("scientifik.jvm") version "0.1.4" apply false - id("scientifik.js") version "0.1.4" apply false - id("scientifik.publish") version "0.1.4" apply false - id("org.openjfx.javafxplugin") version "0.0.7" apply false + id("scientifik.mpp") version "0.1.7" apply false + id("scientifik.jvm") version "0.1.7" apply false + id("scientifik.js") version "0.1.7" apply false + id("scientifik.publish") version "0.1.7" apply false + id("org.openjfx.javafxplugin") version "0.0.8" apply false } allprojects { @@ -19,7 +17,6 @@ allprojects { mavenLocal() jcenter() maven("https://kotlin.bintray.com/kotlinx") - maven("http://npm.mipt.ru:8081/artifactory/gradle-dev-local") maven("https://kotlin.bintray.com/js-externals") maven("https://dl.bintray.com/pdvrieze/maven") maven("https://dl.bintray.com/kotlin/kotlin-eap") diff --git a/dataforge-vis-common/build.gradle.kts b/dataforge-vis-common/build.gradle.kts index e57c78bb..2898a778 100644 --- a/dataforge-vis-common/build.gradle.kts +++ b/dataforge-vis-common/build.gradle.kts @@ -3,7 +3,7 @@ plugins { } scientifik{ - serialization = true + withSerialization() } val dataforgeVersion: String by rootProject.extra diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt index aed504e9..73b5bbf2 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/AbstractVisualGroup.kt @@ -108,7 +108,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup { set(key.asName(), child) } - operator fun set(key: String?, child: VisualObject?) = set(key ?: "", child) +// operator fun set(key: String?, child: VisualObject?) = set(key ?: "", child) protected fun MetaBuilder.updateChildren() { //adding named children diff --git a/dataforge-vis-spatial-gdml/build.gradle.kts b/dataforge-vis-spatial-gdml/build.gradle.kts index e2c711c6..1a76a7a7 100644 --- a/dataforge-vis-spatial-gdml/build.gradle.kts +++ b/dataforge-vis-spatial-gdml/build.gradle.kts @@ -2,12 +2,16 @@ plugins { id("scientifik.mpp") } +scientifik{ + withSerialization() +} + kotlin { sourceSets { val commonMain by getting { dependencies { api(project(":dataforge-vis-spatial")) - api("scientifik:gdml:0.1.4-dev-1") + api("scientifik:gdml:0.1.4-dev-3") } } val jsMain by getting { diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt index b4b4e3a4..200ab034 100644 --- a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/GDMLTransformer.kt @@ -64,9 +64,18 @@ class GDMLTransformer(val root: GDML) { var onFinish: GDMLTransformer.() -> Unit = {} - internal fun finished(final: VisualGroup3D) { + var optimizeSingleChild = false + + //var optimizations: List = emptyList() + + internal fun finalize(final: VisualGroup3D): VisualGroup3D { +// var res = final +// optimizations.forEach { +// res = it(res) +// } final.templates = templates onFinish(this@GDMLTransformer) + return final } -} \ No newline at end of file +} diff --git a/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/optimizations.kt b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/optimizations.kt new file mode 100644 index 00000000..ef842aa7 --- /dev/null +++ b/dataforge-vis-spatial-gdml/src/commonMain/kotlin/hep/dataforge/vis/spatial/gdml/optimizations.kt @@ -0,0 +1,58 @@ +package hep.dataforge.vis.spatial.gdml + +import hep.dataforge.meta.update +import hep.dataforge.names.asName +import hep.dataforge.vis.common.VisualGroup +import hep.dataforge.vis.spatial.Point3D +import hep.dataforge.vis.spatial.VisualGroup3D +import hep.dataforge.vis.spatial.VisualObject3D +import hep.dataforge.vis.spatial.plus +import kotlin.collections.component1 +import kotlin.collections.component2 + +typealias GDMLOptimization = GDMLTransformer.(VisualGroup3D) -> VisualGroup3D + +/** + * Collapse nodes with single child + */ +val optimizeSingleChild: GDMLOptimization = { tree -> + fun VisualGroup.replaceChildren() { + children.forEach { (key, child) -> + if (child is VisualGroup3D && child.children.size == 1) { + val newChild = child.children.values.first().apply { + config.update(child.config) + } + + if (newChild is VisualObject3D) { + newChild.apply { + position += child.position + rotation += child.rotation + scale = when { + scale == null && child.scale == null -> null + scale == null -> child.scale + child.scale == null -> scale + else -> Point3D( + scale!!.x * child.scale!!.x, + scale!!.y * child.scale!!.y, + scale!!.z * child.scale!!.z + ) + } + } + } + + if (newChild is VisualGroup) { + newChild.replaceChildren() + } + + //actual replacement + set(key.asName(), newChild) + } else if (child is VisualGroup) { + child.replaceChildren() + } + } + } + + tree.replaceChildren() + + tree +} \ No newline at end of file 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 a59b1a58..030b173b 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 @@ -149,13 +149,32 @@ private fun VisualGroup3D.addPhysicalVolume( when (context.volumeAction(volume)) { GDMLTransformer.Action.ACCEPT -> { - this[physVolume.name] = volume(context, volume).apply { - withPosition( - context.lUnit, - physVolume.resolvePosition(context.root), - physVolume.resolveRotation(context.root), - physVolume.resolveScale(context.root) - ) + val group = volume(context, volume) + //optimizing single child case + if (context.optimizeSingleChild && group.children.size == 1) { + this[physVolume.name ?: "@unnamed"] = group.children.values.first().apply { + //Must ser this to avoid parent reset error + parent = null + //setting offset from physical volume + withPosition( + context.lUnit, + physVolume.resolvePosition(context.root), + physVolume.resolveRotation(context.root), + physVolume.resolveScale(context.root) + ) + // in case when both phys volume and underlying volume have offset + position += group.position + rotation += group.rotation + } + } else { + this[physVolume.name ?: "@unnamed"] = group.apply { + withPosition( + context.lUnit, + physVolume.resolvePosition(context.root), + physVolume.resolveRotation(context.root), + physVolume.resolveScale(context.root) + ) + } } } GDMLTransformer.Action.CACHE -> { @@ -164,7 +183,7 @@ private fun VisualGroup3D.addPhysicalVolume( context.templates[name] = volume(context, volume) } - this[physVolume.name] = Proxy(name).apply { + this[physVolume.name ?: ""] = Proxy(name).apply { withPosition( context.lUnit, physVolume.resolvePosition(context.root), @@ -196,12 +215,12 @@ private fun VisualGroup3D.addDivisionVolume( ) } -private fun VisualGroup3D.addVolume( - context: GDMLTransformer, - group: GDMLGroup -) { - this[group.name] = volume(context, group) -} +//private fun VisualGroup3D.addVolume( +// context: GDMLTransformer, +// group: GDMLGroup +//) { +// this[group.name] = volume(context, group) +//} private fun volume( context: GDMLTransformer, @@ -211,7 +230,6 @@ private fun volume( if (group is GDMLVolume) { val solid = group.solidref.resolve(context.root) ?: error("Solid with tag ${group.solidref.ref} for volume ${group.name} not defined") - //val material = group.materialref.resolve(context.root) ?: GDMLElement(group.materialref.ref) when (context.solidAction(solid)) { GDMLTransformer.Action.ACCEPT -> { @@ -248,7 +266,5 @@ fun GDML.toVisual(block: GDMLTransformer.() -> Unit = {}): VisualGroup3D { val context = GDMLTransformer(this).apply(block) - return volume(context, world).also { - context.finished(it) - } + return context.finalize(volume(context, world)) } \ No newline at end of file diff --git a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt b/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt index 943b4afc..36584814 100644 --- a/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt +++ b/dataforge-vis-spatial-gdml/src/jvmMain/kotlin/hep/dataforge/vis/spatial/gdml/testMain.kt @@ -1,6 +1,6 @@ package hep.dataforge.vis.spatial.gdml -import hep.dataforge.names.toName +import hep.dataforge.vis.spatial.Visual3DPlugin import hep.dataforge.vis.spatial.VisualGroup3D import nl.adaptivity.xmlutil.StAXReader import scientifik.gdml.GDML @@ -19,17 +19,29 @@ fun main() { volume.name.startsWith("ecal") -> GDMLTransformer.Action.CACHE volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE + volume.name.startsWith("tof") -> GDMLTransformer.Action.CACHE else -> GDMLTransformer.Action.ACCEPT } } + optimizeSingleChild = true + //optimizations = listOf(optimizeSingleChild) onFinish = { printStatistics() } } - val template = visual.getTemplate("volumes.ecal01mod".toName()) - println(template) - visual.flatMap { (it as? VisualGroup3D) ?: listOf(it) }.forEach { - if(it.parent==null) error("") - } + val string = Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual) + + val tmpFile = File.createTempFile("dataforge-visual", ".json") + + tmpFile.writeText(string) + + println(tmpFile.canonicalPath) + + +// val template = visual.getTemplate("volumes.ecal01mod".toName()) +// println(template) +// visual.flatMap { (it as? VisualGroup3D) ?: listOf(it) }.forEach { +// if(it.parent==null) error("") +// } //readLine() //val meta = visual.toMeta() // val tmpFile = File.createTempFile("dataforge-visual", "json") diff --git a/dataforge-vis-spatial/build.gradle.kts b/dataforge-vis-spatial/build.gradle.kts index d2eb5d37..25a1dc19 100644 --- a/dataforge-vis-spatial/build.gradle.kts +++ b/dataforge-vis-spatial/build.gradle.kts @@ -6,7 +6,7 @@ plugins { } scientifik{ - serialization = true + withSerialization() } kotlin { 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 e1e0d559..3c9ca492 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 @@ -33,10 +33,10 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua /** * Recursively search for defined template in the parent */ - val template: VisualObject3D by lazy { - (parent as? VisualGroup3D)?.getTemplate(templateName) + val template: VisualObject3D + get() = (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) { 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 6057f628..2d5089e8 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 @@ -8,6 +8,7 @@ import hep.dataforge.io.MetaSerializer import hep.dataforge.io.NameSerializer import hep.dataforge.meta.* import hep.dataforge.names.Name +import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.VisualPlugin import kotlinx.serialization.json.Json import kotlinx.serialization.json.JsonConfiguration @@ -38,13 +39,15 @@ class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) { contextual(NameTokenSerializer) contextual(MetaSerializer) contextual(ConfigSerializer) - polymorphic(VisualObject3D::class) { + + polymorphic(VisualObject::class,VisualObject3D::class) { VisualGroup3D::class with VisualGroup3D.serializer() Proxy::class with Proxy.serializer() Composite::class with Composite.serializer() Tube::class with Tube.serializer() Box::class with Box.serializer() Convex::class with Convex.serializer() + addSubclass(Extruded.serializer()) } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt index 20024ad9..5cf750a0 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualGroup3D.kt @@ -12,6 +12,7 @@ import hep.dataforge.names.asName import hep.dataforge.names.isEmpty import hep.dataforge.vis.common.AbstractVisualGroup import hep.dataforge.vis.common.VisualObject +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers @@ -26,13 +27,13 @@ class VisualGroup3D() : AbstractVisualGroup(), VisualObject3D { field = value } - @Serializable(ConfigSerializer::class) - override var properties: Config? = null + public override var properties: Config? = null override var position: Point3D? = null override var rotation: Point3D? = null override var scale: Point3D? = null + @SerialName("children") private val _children = HashMap() override val children: Map get() = _children 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 index 20b537b2..4ef1510c 100644 --- 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 @@ -26,6 +26,24 @@ expect class Point3D(x: Number, y: Number, z: Number) { var z: Double } +operator fun Point3D?.plus(other: Point3D?): Point3D? { + return when { + this == null && other == null -> null + this == null -> other + other == null -> this + else -> Point3D(x + other.x, y + other.y, z + other.z) + } +} + +operator fun Point3D?.minus(other: Point3D?): Point3D? { + return when { + this == null && other == null -> null + this == null -> Point3D(-other!!.x, -other.y, -other.z) + other == null -> this + else -> Point3D(x - other.x, y - other.y, z - other.z) + } +} + operator fun Point3D.component1() = x operator fun Point3D.component2() = y operator fun Point3D.component3() = z diff --git a/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/GroupTest.kt b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/GroupTest.kt index e7ef1eeb..c1e81721 100644 --- a/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/GroupTest.kt +++ b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/GroupTest.kt @@ -1,15 +1,16 @@ package hep.dataforge.vis.spatial import hep.dataforge.vis.common.Colors +import hep.dataforge.vis.common.get import kotlin.math.PI import kotlin.test.Test import kotlin.test.assertEquals class GroupTest { @Test - fun testGroupWithComposite(){ - val group = VisualGroup3D().apply{ - union { + fun testGroupWithComposite() { + val group = VisualGroup3D().apply { + union("union") { box(100, 100, 100) { z = 100 rotationX = PI / 4 @@ -21,7 +22,7 @@ class GroupTest { "opacity" to 0.3 } } - intersect{ + intersect("intersect") { box(100, 100, 100) { z = 100 rotationX = PI / 4 @@ -31,7 +32,7 @@ class GroupTest { y = 300 color(Colors.red) } - subtract{ + subtract("subtract") { box(100, 100, 100) { z = 100 rotationX = PI / 4 @@ -44,7 +45,7 @@ class GroupTest { } assertEquals(3, group.count()) - assertEquals(300.0,group.toList()[1].y.toDouble()) - assertEquals(-300.0,group.toList()[2].y.toDouble()) + assertEquals(300.0, (group["intersect"] as VisualObject3D).y.toDouble()) + assertEquals(-300.0, (group["subtract"] as VisualObject3D).y.toDouble()) } } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/SerializationTest.kt b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/SerializationTest.kt index 87668852..805fee43 100644 --- a/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/SerializationTest.kt +++ b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/SerializationTest.kt @@ -15,6 +15,6 @@ class SerializationTest { val meta = cube.toMeta() println(meta) val newCube = Box(Global,null, meta) - assertEquals(cube,newCube) + assertEquals(cube.toMeta(),newCube.toMeta()) } } \ No newline at end of file