From 9a7fcfe9c63f16cad2c30d37f9ac0d2cb635cfe9 Mon Sep 17 00:00:00 2001 From: Alexander Nozik Date: Wed, 27 Mar 2019 22:14:42 +0300 Subject: [PATCH] Updated build and used new core version --- build.gradle.kts | 77 ++++++++++++++++- dataforge-vis-spatial-js/build.gradle.kts | 2 + .../src/main/kotlin/hep/dataforge/vis/main.kt | 4 +- .../hep/dataforge/vis/spatial/ThreeDemoApp.kt | 46 +++++----- .../hep/dataforge/vis/spatial/ThreeFactory.kt | 13 ++- .../hep/dataforge/vis/spatial/ThreeOutput.kt | 12 +-- .../hep/dataforge/vis/spatial/ThreePlugin.kt | 2 +- .../vis/spatial/jsroot/JSRootDemoApp.kt | 39 +++++++++ .../dataforge/vis/spatial/jsroot/JSRootGEO.kt | 3 + .../vis/spatial/jsroot/JSRootGeometry.kt | 82 ++++++++++++++++++ .../vis/spatial/jsroot/JSRootObject.kt | 85 +++++-------------- .../vis/spatial/jsroot/JSRootPlugin.kt | 2 +- .../vis/spatial/three/ConvexGeometry.kt | 5 +- .../hep/dataforge/vis/spatial/three/three.kt | 6 +- .../src/main/resources/JSRootGeoBase.js | 4 +- .../hep/dataforge/vis/spatial/Convex.kt | 12 +-- .../dataforge/vis/spatial/displayObject3D.kt | 53 +++++++++++- .../hep/dataforge/vis/spatial/ConvexTest.kt | 37 ++++++++ 18 files changed, 367 insertions(+), 117 deletions(-) create mode 100644 dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt create mode 100644 dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGeometry.kt create mode 100644 dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/ConvexTest.kt diff --git a/build.gradle.kts b/build.gradle.kts index b23dbe59..fe4f1ca0 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,4 +1,8 @@ +import com.moowork.gradle.node.NodeExtension +import com.moowork.gradle.node.npm.NpmTask +import com.moowork.gradle.node.task.NodeTask import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension +import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile buildscript { @@ -9,7 +13,7 @@ buildscript { val dokkaVersion: String by rootProject.extra("0.9.17") val serializationVersion: String by rootProject.extra("0.10.0") - val dataforgeVersion: String by rootProject.extra("0.1.2-dev-1") + val dataforgeVersion: String by rootProject.extra("0.1.2-dev-2") repositories { jcenter() @@ -28,6 +32,7 @@ buildscript { plugins { id("com.jfrog.artifactory") version "4.8.1" apply false + id("com.moowork.node") version "1.3.1" apply false // id("org.jetbrains.kotlin.multiplatform") apply false } @@ -86,6 +91,7 @@ subprojects { afterEvaluate { extensions.findByType()?.apply { + apply(plugin = "com.moowork.node") jvm { compilations.all { kotlinOptions { @@ -113,6 +119,75 @@ subprojects { } } } + + configure{ + nodeModulesDir = file("$buildDir/node_modules") + } + + val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class) + val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class) + + val populateNodeModules by tasks.registering(Copy::class) { + dependsOn(compileKotlinJs) + from(compileKotlinJs.destinationDir) + + compilations["test"].runtimeDependencyFiles.forEach { + if (it.exists() && !it.isDirectory) { + from(zipTree(it.absolutePath).matching { include("*.js") }) + } + } + + into("$buildDir/node_modules") + } + + val installMocha by tasks.registering(NpmTask::class) { + setWorkingDir(buildDir) + setArgs(listOf("install", "mocha")) + } + + val runMocha by tasks.registering(NodeTask::class) { + dependsOn(compileTestKotlinJs, populateNodeModules, installMocha) + setScript(file("$buildDir/node_modules/mocha/bin/mocha")) + setArgs(listOf(compileTestKotlinJs.outputFile)) + } + + tasks["jsTest"].dependsOn(runMocha) + } + + sourceSets { + + val commonMain by getting { + dependencies { + api(kotlin("stdlib")) + } + } + val commonTest by getting { + dependencies { + implementation(kotlin("test-common")) + implementation(kotlin("test-annotations-common")) + } + } + val jvmMain by getting { + dependencies { + api(kotlin("stdlib-jdk8")) + } + } + val jvmTest by getting { + dependencies { + implementation(kotlin("test")) + implementation(kotlin("test-junit")) + } + } + val jsMain by getting { + dependencies { + api(kotlin("stdlib-js")) + } + } + val jsTest by getting { + dependencies { + implementation(kotlin("test-js")) + } + } } targets.all { diff --git a/dataforge-vis-spatial-js/build.gradle.kts b/dataforge-vis-spatial-js/build.gradle.kts index 65f47fba..6d91fa39 100644 --- a/dataforge-vis-spatial-js/build.gradle.kts +++ b/dataforge-vis-spatial-js/build.gradle.kts @@ -8,10 +8,12 @@ plugins { id("org.jetbrains.kotlin.frontend") } +val kotlinVersion: String by rootProject.extra dependencies { api(project(":dataforge-vis-spatial")) implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2") + testCompile("org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion") } configure { diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt index e00d3a71..3bd77d6c 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/main.kt @@ -1,6 +1,6 @@ package hep.dataforge.vis -import hep.dataforge.vis.spatial.ThreeDemoApp +import hep.dataforge.vis.spatial.jsroot.JSRootDemoApp import kotlin.browser.document import kotlin.dom.hasClass @@ -37,7 +37,7 @@ fun main() { fun start(state: dynamic): ApplicationBase? { return if (document.body?.hasClass("testApp") == true) { - val application = ThreeDemoApp() + val application = JSRootDemoApp() @Suppress("UnsafeCastFromDynamic") application.start(state?.appState ?: emptyMap()) diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt index 3e7d977e..4f68eaa6 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeDemoApp.kt @@ -1,9 +1,7 @@ package hep.dataforge.vis.spatial import hep.dataforge.context.Global -import hep.dataforge.context.members import hep.dataforge.meta.number -import hep.dataforge.meta.set import hep.dataforge.vis.ApplicationBase import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.require @@ -26,20 +24,10 @@ class ThreeDemoApp : ApplicationBase() { //TODO remove after DI fix - Global.plugins.load(ThreePlugin()) - Global.plugins.load(JSRootPlugin()) +// Global.plugins.load(ThreePlugin()) +// Global.plugins.load(JSRootPlugin()) -// Global.plugins.load(JSRootPlugin) - - println(Global.plugins.count()) - - Global.plugins.forEach { - println(it) - } - - Global.members>(ThreeFactory.TYPE).forEach { - println(it) - } + Global.plugins.load(JSRootPlugin) val renderer = ThreeOutput(Global) renderer.start(document.getElementById("canvas")!!) @@ -50,31 +38,37 @@ class ThreeDemoApp : ApplicationBase() { renderer.render { group = group { box { + z = 110.0 xSize = 100.0 ySize = 100.0 zSize = 100.0 } box { + visible = false x = 110.0 xSize = 100.0 ySize = 100.0 zSize = 100.0 - properties.style["color"] = 1530 + color(1530) + + GlobalScope.launch { + while (isActive) { + delay(500) + visible = !visible + } + } } } -// convex { -// point(50, 50, -50) -// point(50, -50, -50) -// point(-50, -50, -50) -// point(-50, 50, -50) -// point(50, 50, 50) -// point(50, -50, 50) -// point(-50, -50, 50) -// point(-50, 50, 50) -// } + convex { + point(50,50,50) + point(-50,-50,50) + point(-50,50,-50) + point(50,-50,-50) + } jsRoot { y = 110.0 shape = box(50, 50, 50) + color(12285) } } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt index a85493da..118c6126 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt @@ -8,7 +8,7 @@ import hep.dataforge.vis.onChange import hep.dataforge.vis.spatial.ThreeFactory.Companion.TYPE import hep.dataforge.vis.spatial.ThreeFactory.Companion.buildMesh import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh -import hep.dataforge.vis.spatial.three.ConvexGeometry +import hep.dataforge.vis.spatial.three.ConvexBufferGeometry import hep.dataforge.vis.spatial.three.EdgesGeometry import hep.dataforge.vis.spatial.three.euler import info.laht.threekt.core.BufferGeometry @@ -77,6 +77,9 @@ abstract class MeshThreeFactory(override val type: KClass @@ -92,9 +95,11 @@ object ThreeBoxFactory : MeshThreeFactory(Box::class) { BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) } -fun Point3D.asVector(): Vector3 = this.asDynamic() as Vector3 +fun Point3D.asVector(): Vector3 = Vector3(this.x, this.y, this.z) object ThreeConvexFactory : MeshThreeFactory(Convex::class) { - override fun buildGeometry(obj: Convex) = - ConvexGeometry(obj.points.map { it.asVector() }.toTypedArray()) + override fun buildGeometry(obj: Convex): ConvexBufferGeometry { + val vectors = obj.points.map { it.asVector() }.toTypedArray() + return ConvexBufferGeometry(vectors) + } } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt index e2e3534d..2945daa8 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeOutput.kt @@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial import hep.dataforge.context.Context import hep.dataforge.context.members -import hep.dataforge.meta.Meta +import hep.dataforge.meta.* import hep.dataforge.output.Output import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayObject @@ -18,7 +18,7 @@ import org.w3c.dom.Element import kotlin.browser.window import kotlin.reflect.KClass -class ThreeOutput(override val context: Context) : Output { +class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output { private val renderer = WebGLRenderer { antialias = true }.apply { setClearColor(ColorConstants.skyblue, 1) @@ -30,10 +30,10 @@ class ThreeOutput(override val context: Context) : Output { } val camera = PerspectiveCamera( - 75, + meta["fov"].int ?: 75, window.innerWidth.toDouble() / window.innerHeight, - World.CAMERA_NEAR_CLIP, - World.CAMERA_FAR_CLIP + meta["camera.nearClip"].double?: World.CAMERA_NEAR_CLIP, + meta["camera.farClip"].double?: World.CAMERA_FAR_CLIP ).apply { position.setZ(World.CAMERA_INITIAL_DISTANCE) rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE) @@ -70,7 +70,7 @@ class ThreeOutput(override val context: Context) : Output { //is Box -> ThreeBoxFactory(obj) //is JSRootObject -> ThreeJSRootFactory(obj) //is Convex -> ThreeConvexFactory(obj) - else -> findFactory(obj::class)?.invoke(obj)?: error("Factory not found") + else -> findFactory(obj::class)?.invoke(obj) ?: error("Factory not found") } } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt index 09a01a47..67836113 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt @@ -33,6 +33,6 @@ class ThreePlugin : AbstractPlugin() { companion object : PluginFactory { override val tag = PluginTag("vis.three", "hep.dataforge") override val type = ThreePlugin::class - override fun build() = ThreePlugin() + override fun invoke() = ThreePlugin() } } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt new file mode 100644 index 00000000..697f2def --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootDemoApp.kt @@ -0,0 +1,39 @@ +package hep.dataforge.vis.spatial.jsroot + +import hep.dataforge.context.Global +import hep.dataforge.vis.ApplicationBase +import hep.dataforge.vis.DisplayGroup +import hep.dataforge.vis.require +import hep.dataforge.vis.spatial.ThreeOutput +import hep.dataforge.vis.spatial.render +import kotlin.browser.document + + +class JSRootDemoApp : ApplicationBase() { + + override val stateKeys: List = emptyList() + + override fun start(state: Map) { + require("JSRootGeoBase.js") + + + //TODO remove after DI fix +// Global.plugins.load(ThreePlugin()) +// Global.plugins.load(JSRootPlugin()) + + Global.plugins.load(JSRootPlugin) + + val renderer = ThreeOutput(Global) + renderer.start(document.getElementById("canvas")!!) + println("started") + + lateinit var group: DisplayGroup + + renderer.render { + jsRoot ("./geofile_full.json") + } + + } + + override fun dispose() = emptyMap()//mapOf("lines" to presenter.dispose()) +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGEO.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGEO.kt index b35c1a0e..9f587494 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGEO.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGEO.kt @@ -4,5 +4,8 @@ package hep.dataforge.vis.spatial.jsroot import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.Object3D external fun createGeometry(shape: dynamic, limit: Int): BufferGeometry + +external fun build(obj: dynamic, opt: dynamic): Object3D diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGeometry.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGeometry.kt new file mode 100644 index 00000000..bf3687e8 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGeometry.kt @@ -0,0 +1,82 @@ +package hep.dataforge.vis.spatial.jsroot + +import hep.dataforge.meta.EmptyMeta +import hep.dataforge.meta.Meta +import hep.dataforge.meta.buildMeta +import hep.dataforge.meta.toDynamic +import hep.dataforge.vis.* +import hep.dataforge.vis.spatial.MeshThreeFactory +import info.laht.threekt.core.BufferGeometry + +class JSRootGeometry(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) { + + var shape by node() + + var facesLimit by int(0) + + fun box(xSize: Number, ySize: Number, zSize: Number) = buildMeta { + "_typename" to "TGeoBBox" + "fDX" to xSize + "fDY" to ySize + "fDZ" to zSize + } + + /** + * Create a GDML union + */ + operator fun Meta.plus(other: Meta) = buildMeta { + "fNode.fLeft" to this + "fNode.fRight" to other + "fNode._typename" to "TGeoUnion" + } + + /** + * Create a GDML subtraction + */ + operator fun Meta.minus(other: Meta) = buildMeta { + "fNode.fLeft" to this + "fNode.fRight" to other + "fNode._typename" to "TGeoSubtraction" + } + + /** + * Intersect two GDML geometries + */ + infix fun Meta.intersect(other: Meta) = buildMeta { + "fNode.fLeft" to this + "fNode.fRight" to other + "fNode._typename" to "TGeoIntersection" + } + + companion object { + const val TYPE = "geometry.spatial.jsRoot.geometry" + } +} + +fun DisplayGroup.jsRoot(meta: Meta = EmptyMeta, action: JSRootGeometry.() -> Unit = {}) = + JSRootGeometry(this, meta).apply(action).also { addChild(it) } + +//fun Meta.toDynamic(): dynamic { +// fun MetaItem<*>.toDynamic(): dynamic = when (this) { +// is MetaItem.ValueItem -> this.value.value.asDynamic() +// is MetaItem.NodeItem -> this.node.toDynamic() +// } +// +// val res = js("{}") +// this.items.entries.groupBy { it.key.body }.forEach { (key, value) -> +// val list = value.map { it.value } +// res[key] = when (list.size) { +// 1 -> list.first().toDynamic() +// else -> list.map { it.toDynamic() } +// } +// } +// return res +//} + + +object ThreeJSRootFactory : MeshThreeFactory(JSRootGeometry::class) { + override fun buildGeometry(obj: JSRootGeometry): BufferGeometry { + val shapeMeta = obj.shape?.toDynamic() ?: error("The shape not defined") + return createGeometry(shapeMeta, obj.facesLimit) + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt index 5384e58e..cf2de9f8 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt @@ -1,84 +1,37 @@ package hep.dataforge.vis.spatial.jsroot +import hep.dataforge.meta.DynamicMeta import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.Meta -import hep.dataforge.meta.MetaItem -import hep.dataforge.meta.buildMeta -import hep.dataforge.vis.* -import hep.dataforge.vis.spatial.MeshThreeFactory -import info.laht.threekt.core.BufferGeometry +import hep.dataforge.meta.toDynamic +import hep.dataforge.vis.DisplayGroup +import hep.dataforge.vis.DisplayLeaf +import hep.dataforge.vis.DisplayObject +import hep.dataforge.vis.node +import hep.dataforge.vis.spatial.ThreeFactory +import info.laht.threekt.core.Object3D class JSRootObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) { - var shape by node() - - var color by item() - - var facesLimit by int(0) - - fun box(xSize: Number, ySize: Number, zSize: Number) = buildMeta { - "_typename" to "TGeoBBox" - "fDX" to xSize - "fDY" to ySize - "fDZ" to zSize - } - - /** - * Create a GDML union - */ - operator fun Meta.plus(other: Meta) = buildMeta { - "fNode.fLeft" to this - "fNode.fRight" to other - "fNode._typename" to "TGeoUnion" - } - - /** - * Create a GDML subtraction - */ - operator fun Meta.minus(other: Meta) = buildMeta { - "fNode.fLeft" to this - "fNode.fRight" to other - "fNode._typename" to "TGeoSubtraction" - } - - /** - * Intersect two GDML geometries - */ - infix fun Meta.intersect(other: Meta) = buildMeta { - "fNode.fLeft" to this - "fNode.fRight" to other - "fNode._typename" to "TGeoIntersection" - } + var data by node() + var options by node() companion object { - const val TYPE = "geometry.spatial.jsRoot" + const val TYPE = "geometry.spatial.jsRoot.object" } } -fun DisplayGroup.jsRoot(meta: Meta = EmptyMeta, action: JSRootObject.() -> Unit = {}) = - JSRootObject(this, meta).apply(action).also { addChild(it) } +object JSRootObjectFactory : ThreeFactory { -fun Meta.toDynamic(): dynamic { - fun MetaItem<*>.toDynamic(): dynamic = when (this) { - is MetaItem.ValueItem -> this.value.value.asDynamic() - is MetaItem.NodeItem -> this.node.toDynamic() - } + override val type = JSRootObject::class - val res = js("{}") - this.items.entries.groupBy { it.key.body }.forEach { (key, value) -> - val list = value.map { it.value } - res[key] = when (list.size) { - 1 -> list.first().toDynamic() - else -> list.map { it.toDynamic() } - } + override fun invoke(obj: JSRootObject): Object3D { + return build(obj.data?.toDynamic(), obj.options?.toDynamic()) } - return res } - -object ThreeJSRootFactory : MeshThreeFactory(JSRootObject::class) { - override fun buildGeometry(obj: JSRootObject): BufferGeometry { - val shapeMeta = obj.shape?.toDynamic() ?: error("The shape not defined") - return createGeometry(shapeMeta, obj.facesLimit) - } +fun DisplayGroup.jsRoot(path: String) { + JSRootObject(this, EmptyMeta).apply{ + data = DynamicMeta(hep.dataforge.vis.require(path)) + }.also { addChild(it) } } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt index 4d253bdb..29676b04 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt @@ -20,6 +20,6 @@ class JSRootPlugin : AbstractPlugin() { companion object: PluginFactory { override val tag = PluginTag("vis.jsroot", "hep.dataforge") override val type = JSRootPlugin::class - override fun build() = JSRootPlugin() + override fun invoke() = JSRootPlugin() } } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ConvexGeometry.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ConvexGeometry.kt index 3949958d..40ebf221 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ConvexGeometry.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ConvexGeometry.kt @@ -3,6 +3,9 @@ package hep.dataforge.vis.spatial.three import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.Geometry import info.laht.threekt.math.Vector3 -external class ConvexGeometry(points: Array) : BufferGeometry \ No newline at end of file +external class ConvexGeometry(points: Array) : Geometry + +external class ConvexBufferGeometry(points: Array) : BufferGeometry \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/three.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/three.kt index c00eee28..97b61721 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/three.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/three.kt @@ -9,6 +9,8 @@ import hep.dataforge.vis.spatial.rotationOrder import hep.dataforge.vis.spatial.rotationX import hep.dataforge.vis.spatial.rotationY import hep.dataforge.vis.spatial.rotationZ +import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.Geometry import info.laht.threekt.core.Object3D import info.laht.threekt.math.Euler import info.laht.threekt.math.Vector3 @@ -25,4 +27,6 @@ fun Group(children: Collection) = info.laht.threekt.objects.Group().ap val DisplayObject.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name) -val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f) \ No newline at end of file +val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f) + +fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/resources/JSRootGeoBase.js b/dataforge-vis-spatial-js/src/main/resources/JSRootGeoBase.js index 7fb5f061..82df4b08 100644 --- a/dataforge-vis-spatial-js/src/main/resources/JSRootGeoBase.js +++ b/dataforge-vis-spatial-js/src/main/resources/JSRootGeoBase.js @@ -3398,7 +3398,7 @@ process(toplevel, 0, 1, 1000000); }; - GEO.build = function (obj, opt, call_back) { + GEO.build = function (obj, opt) { // function can be used to build three.js model for TGeo object if (!obj) return; @@ -3510,7 +3510,7 @@ // mesh.renderOrder = clones.maxdepth - entry.stack.length; } - JSROOT.CallBack(call_back, toplevel); + //JSROOT.CallBack(call_back, toplevel); return toplevel; }; diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Convex.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Convex.kt index 46376742..1f57be85 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Convex.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Convex.kt @@ -32,10 +32,12 @@ class ConvexBuilder { } fun build(parent: DisplayObject?, meta: Meta): Convex { - val builder = meta.builder() - points.forEachIndexed { index, value -> - builder["points.point[$index]"] = value.toMeta() - } - return Convex(parent, builder.seal()) + val points = buildMeta { + points.forEachIndexed { index, value -> + "points.point[$index]" to value.toMeta() + } + }.seal() + + return Convex(parent, points) } } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt index 8c2ccab9..1f1ccd62 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/displayObject3D.kt @@ -6,6 +6,7 @@ import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayNode import hep.dataforge.vis.DisplayObject import hep.dataforge.vis.DisplayObject.Companion.DEFAULT_TYPE +import hep.dataforge.vis.get fun DisplayGroup.group(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit = {}) = DisplayNode(this, DEFAULT_TYPE, meta).apply(action).also { addChild(it) } @@ -18,26 +19,38 @@ fun Output.render(meta: Meta = EmptyMeta, action: DisplayGroup.() // Common properties +/** + * Visibility property. Inherited from parent + */ var DisplayObject.visible - get() = properties["visible"].boolean ?: true + get() = this["visible"].boolean ?: true set(value) { properties.style["visible"] = value } // 3D Object position +/** + * x position property relative to parent. Not inherited + */ var DisplayObject.x get() = properties["pos.x"].number ?: 0.0 set(value) { properties.style["pos.x"] = value } +/** + * y position property. Not inherited + */ var DisplayObject.y get() = properties["pos.y"].number ?: 0.0 set(value) { properties.style["pos.y"] = value } +/** + * z position property. Not inherited + */ var DisplayObject.z get() = properties["pos.z"].number ?: 0.0 set(value) { @@ -46,18 +59,27 @@ var DisplayObject.z // 3D Object rotation +/** + * x rotation relative to parent. Not inherited + */ var DisplayObject.rotationX get() = properties["rotation.x"].number ?: 0.0 set(value) { properties.style["rotation.x"] = value } +/** + * y rotation relative to parent. Not inherited + */ var DisplayObject.rotationY get() = properties["rotation.y"].number ?: 0.0 set(value) { properties.style["rotation.y"] = value } +/** + * z rotation relative to parent. Not inherited + */ var DisplayObject.rotationZ get() = properties["rotation.z"].number ?: 0.0 set(value) { @@ -73,6 +95,9 @@ enum class RotationOrder { ZYX } +/** + * Rotation order. Not inherited + */ var DisplayObject.rotationOrder: RotationOrder get() = properties["rotation.order"].enum() ?: RotationOrder.XYZ set(value) { @@ -81,24 +106,50 @@ var DisplayObject.rotationOrder: RotationOrder // 3D object scale +/** + * X scale. Not inherited + */ var DisplayObject.scaleX get() = properties["scale.x"].number ?: 1.0 set(value) { properties.style["scale.x"] = value } +/** + * Y scale. Not inherited + */ var DisplayObject.scaleY get() = properties["scale.y"].number ?: 1.0 set(value) { properties.style["scale.y"] = value } +/** + * Z scale. Not inherited + */ var DisplayObject.scaleZ get() = properties["scale.z"].number ?: 1.0 set(value) { properties.style["scale.z"] = value } +fun DisplayObject.color(rgb: Int){ + this.properties.style["color"] = rgb +} + +fun DisplayObject.color(meta: Meta){ + this.properties.style["color"] = meta +} + +fun DisplayObject.color(r: Int, g: Int, b: Int) = color(buildMeta { + "red" to r + "green" to g + "blue" to b +}) + + +//TODO add inherited scale + object World { const val CAMERA_INITIAL_DISTANCE = -500.0 const val CAMERA_INITIAL_X_ANGLE = -50.0 diff --git a/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/ConvexTest.kt b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/ConvexTest.kt new file mode 100644 index 00000000..1b83c1e0 --- /dev/null +++ b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/ConvexTest.kt @@ -0,0 +1,37 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.get +import hep.dataforge.meta.getAll +import hep.dataforge.meta.node +import hep.dataforge.names.toName +import hep.dataforge.vis.DisplayNode +import kotlin.test.Test +import kotlin.test.assertEquals + +class ConvexTest { + @Test + fun testConvexBuilder() { + val group = DisplayNode().apply { + convex { + point(50, 50, -50) + point(50, -50, -50) + point(-50, -50, -50) + point(-50, 50, -50) + point(50, 50, 50) + point(50, -50, 50) + point(-50, -50, 50) + point(-50, 50, 50) + } + } + + val convex = group.children.first() as Convex + + val pointsNode = convex.properties["points"].node + + assertEquals(8, pointsNode?.items?.count()) + val points = pointsNode?.getAll("point".toName()) + + assertEquals(8, convex.points.size) + } + +} \ No newline at end of file