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 61580cb2..a09db3ed 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 @@ -27,7 +27,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup override fun getStyle(name: Name): Meta? = styleSheet[name] - override fun addStyle(name: Name, meta: Meta) { + override fun addStyle(name: Name, meta: Meta, apply: Boolean) { fun VisualObject.applyStyle(name: Name, meta: Meta) { if (styles.contains(name)) { //full update @@ -45,7 +45,9 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup } } styleSheet[name] = meta - applyStyle(name, meta) + if (apply) { + applyStyle(name, meta) + } } diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/MutableVisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/MutableVisualGroup.kt index 9aa90f0c..e2682817 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/MutableVisualGroup.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/MutableVisualGroup.kt @@ -41,7 +41,7 @@ interface VisualGroup : Provider, Iterable, VisualObject { /** * Add or replace style with given name */ - fun addStyle(name: Name, meta: Meta) + fun addStyle(name: Name, meta: Meta, apply: Boolean = true) operator fun get(name: Name): VisualObject? { return when { diff --git a/dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/HMR.kt b/dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/HMR.kt similarity index 97% rename from dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/HMR.kt rename to dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/HMR.kt index 37b4c4c1..5353fb03 100644 --- a/dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/HMR.kt +++ b/dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/HMR.kt @@ -1,4 +1,4 @@ -package hep.dataforge.vis.hmr +package hep.dataforge.vis import kotlin.browser.document import kotlin.dom.hasClass diff --git a/dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/jsExtra.kt b/dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/jsExtra.kt similarity index 89% rename from dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/jsExtra.kt rename to dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/jsExtra.kt index c22f1aa5..56751272 100644 --- a/dataforge-vis-common/src/jsMain/kotlin/hep.dataforge.vis.hmr/jsExtra.kt +++ b/dataforge-vis-common/src/jsMain/kotlin/hep/dataforge/vis/jsExtra.kt @@ -1,6 +1,4 @@ -package hep.dataforge.vis.hmr - -import kotlinext.js.objectAssign +package hep.dataforge.vis inline fun jsObject(builder: T.() -> Unit): T { val obj: T = js("({})") as T 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 d2199861..ee646f7a 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 @@ -69,7 +69,7 @@ class GDMLTransformer(val root: GDML) { internal fun finalize(final: VisualGroup3D): VisualGroup3D { final.templates = templates styleCache.forEach { - final.addStyle(it.key, it.value) + final.addStyle(it.key, it.value, false) } final.rotationOrder = RotationOrder.ZXY onFinish(this@GDMLTransformer) diff --git a/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt b/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt index b8a8b44e..cacc796b 100644 --- a/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt +++ b/dataforge-vis-spatial-gdml/src/jsMain/kotlin/hep/dataforge/vis/spatial/gdml/demo/GDMLDemoApp.kt @@ -1,36 +1,26 @@ package hep.dataforge.vis.spatial.gdml.demo import hep.dataforge.context.Global -import hep.dataforge.vis.common.VisualGroup -import hep.dataforge.vis.hmr.ApplicationBase -import hep.dataforge.vis.hmr.startApplication +import hep.dataforge.vis.ApplicationBase import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY import hep.dataforge.vis.spatial.Visual3DPlugin import hep.dataforge.vis.spatial.VisualGroup3D import hep.dataforge.vis.spatial.VisualObject3D import hep.dataforge.vis.spatial.attachChildren +import hep.dataforge.vis.spatial.editor.propertyEditor +import hep.dataforge.vis.spatial.editor.threeOutputConfig +import hep.dataforge.vis.spatial.editor.visualObjectTree import hep.dataforge.vis.spatial.gdml.GDMLTransformer import hep.dataforge.vis.spatial.gdml.LUnit import hep.dataforge.vis.spatial.gdml.toVisual -import hep.dataforge.vis.spatial.three.ThreeOutput import hep.dataforge.vis.spatial.three.ThreePlugin import hep.dataforge.vis.spatial.three.output -import hep.dataforge.vis.spatial.transform.RemoveSingleChild -import hep.dataforge.vis.spatial.transform.UnRef -import hep.dataforge.vis.spatial.transform.transformInPlace -import hep.dataforge.vis.spatial.editor.propertyEditor -import hep.dataforge.vis.spatial.editor.render -import hep.dataforge.vis.spatial.editor.toTree -import kotlinx.html.InputType +import hep.dataforge.vis.startApplication import kotlinx.html.dom.append -import kotlinx.html.js.input -import kotlinx.html.js.li import kotlinx.html.js.p -import kotlinx.html.js.ul -import org.w3c.dom.Element +import org.w3c.dom.DragEvent import org.w3c.dom.HTMLDivElement import org.w3c.dom.HTMLElement -import org.w3c.dom.events.Event import org.w3c.files.FileList import org.w3c.files.FileReader import org.w3c.files.get @@ -43,33 +33,27 @@ private class GDMLDemoApp : ApplicationBase() { /** * Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/ */ - private fun handleDragOver(event: Event) { + private fun handleDragOver(event: DragEvent) { event.stopPropagation() event.preventDefault() - event.asDynamic().dataTransfer.dropEffect = "copy" + event.dataTransfer?.dropEffect = "copy" } /** * Load data from text file */ - private fun loadData(event: Event, block: (name: String, data: String) -> Unit) { + private fun loadData(event: DragEvent, block: (name: String, data: String) -> Unit) { event.stopPropagation() event.preventDefault() - val file = (event.asDynamic().dataTransfer.files as FileList)[0] + val file = (event.dataTransfer?.files as FileList)[0] ?: throw RuntimeException("Failed to load file") FileReader().apply { onload = { val string = result as String - -// try { block(file.name, string) -// } catch (ex: Exception) { -// console.error(ex) -// } - } readAsText(file) } @@ -102,52 +86,22 @@ private class GDMLDemoApp : ApplicationBase() { } } - fun setupLayers(element: Element, output: ThreeOutput) { - element.clear() - element.append { - ul("list-group") { - (0..9).forEach { layer -> - li("list-group-item") { - +"layer $layer" - input(type = InputType.checkBox).apply { - if (layer == 0) { - checked = true - } - onchange = { - if (checked) { - output.camera.layers.enable(layer) - } else { - output.camera.layers.disable(layer) - } - } - } - } - } - } - } - } - private val gdmlConfiguration: GDMLTransformer.() -> Unit = { lUnit = LUnit.CM volumeAction = { volume -> when { volume.name.startsWith("ecal01lay") -> GDMLTransformer.Action.REJECT -// volume.name.startsWith("ecal") -> GDMLTransformer.Action.CACHE volume.name.startsWith("UPBL") -> GDMLTransformer.Action.REJECT volume.name.startsWith("USCL") -> GDMLTransformer.Action.REJECT - // volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE volume.name.startsWith("VPBL") -> GDMLTransformer.Action.REJECT volume.name.startsWith("VSCL") -> GDMLTransformer.Action.REJECT -// volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE else -> GDMLTransformer.Action.CACHE } } solidConfiguration = { parent, solid -> if ( - solid.name.startsWith("Coil") - || solid.name.startsWith("Yoke") - || solid.name.startsWith("Magnet") + solid.name.startsWith("Yoke") || solid.name.startsWith("Pole") || parent.physVolumes.isNotEmpty() ) { @@ -193,17 +147,13 @@ private class GDMLDemoApp : ApplicationBase() { //(visual as? VisualGroup3D)?.transformInPlace(UnRef, RemoveSingleChild) message("Rendering") - val output = three.output(canvas as HTMLElement) //output.camera.layers.enable(1) - output.camera.layers.set(0) - setupLayers(layers, output) + val output = three.output(canvas as HTMLElement) - if (visual is VisualGroup) { - visual.toTree(editor::propertyEditor).render(tree as HTMLElement) { - showCheckboxes = false - } - } + output.camera.layers.set(0) + layers.threeOutputConfig(output) + tree.visualObjectTree(visual, editor::propertyEditor) output.render(visual) message(null) @@ -211,8 +161,8 @@ private class GDMLDemoApp : ApplicationBase() { } (document.getElementById("drop_zone") as? HTMLDivElement)?.apply { - addEventListener("dragover", { handleDragOver(it) }, false) - addEventListener("drop", { loadData(it, action) }, false) + addEventListener("dragover", { handleDragOver(it as DragEvent) }, false) + addEventListener("drop", { loadData(it as DragEvent, action) }, false) } } diff --git a/dataforge-vis-spatial-gdml/src/jsMain/web/index.html b/dataforge-vis-spatial-gdml/src/jsMain/web/index.html index f99f2803..22603bcf 100644 --- a/dataforge-vis-spatial-gdml/src/jsMain/web/index.html +++ b/dataforge-vis-spatial-gdml/src/jsMain/web/index.html @@ -29,45 +29,12 @@
-
-
- -
-
-
-
-

- -

-
- -
-
-
-
-
-
-
-
-

- -

-
-
-
-
-
-
-
-
+
+
+
+
+
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 b0a82a03..e4125590 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 @@ -5,8 +5,14 @@ package hep.dataforge.vis.spatial import hep.dataforge.io.ConfigSerializer import hep.dataforge.io.NameSerializer import hep.dataforge.meta.* -import hep.dataforge.names.* -import hep.dataforge.vis.common.* +import hep.dataforge.names.Name +import hep.dataforge.names.NameToken +import hep.dataforge.names.asName +import hep.dataforge.names.plus +import hep.dataforge.vis.common.AbstractVisualObject +import hep.dataforge.vis.common.MutableVisualGroup +import hep.dataforge.vis.common.VisualGroup +import hep.dataforge.vis.common.VisualObject import kotlinx.serialization.Serializable import kotlinx.serialization.UseSerializers import kotlin.collections.component1 @@ -35,16 +41,21 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua override fun getStyle(name: Name): Meta? = (parent as VisualGroup?)?.getStyle(name) - override fun addStyle(name: Name, meta: Meta) { - (parent as VisualGroup?)?.addStyle(name, meta) + override fun addStyle(name: Name, meta: Meta, apply: Boolean) { + (parent as VisualGroup?)?.addStyle(name, meta, apply) //do nothing } override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { return if (inherit) { - super.getProperty(name, false) ?: prototype.getProperty(name, false) ?: parent?.getProperty(name, inherit) + properties?.get(name) + ?: mergedStyles[name] + ?: prototype.getProperty(name, false) + ?: parent?.getProperty(name, inherit) } else { - super.getProperty(name, false) ?: prototype.getProperty(name, false) + properties?.get(name) + ?: mergedStyles[name] + ?: prototype.getProperty(name, false) } } @@ -93,8 +104,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua override fun getStyle(name: Name): Meta? = this@Proxy.getStyle(name) - override fun addStyle(name: Name, meta: Meta) { - this@Proxy.addStyle(name, meta) + override fun addStyle(name: Name, meta: Meta, apply: Boolean) { + this@Proxy.addStyle(name, meta, apply) } override var properties: Config? @@ -118,8 +129,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua return if (inherit) { properties?.get(name) ?: mergedStyles[name] - ?: parent?.getProperty(name, inherit) ?: prototype.getProperty(name, inherit) + ?: parent?.getProperty(name, inherit) } else { properties?.get(name) ?: mergedStyles[name] diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/bootstrap.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/bootstrap.kt new file mode 100644 index 00000000..7be121b1 --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/bootstrap.kt @@ -0,0 +1,15 @@ +package hep.dataforge.vis.spatial.editor + +import kotlinx.html.TagConsumer +import kotlinx.html.js.div +import kotlinx.html.js.h3 +import org.w3c.dom.HTMLElement + +inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { + div("card w-100") { + div("card-body") { + h3(classes = "card-title") { +title } + block() + } + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/jsVisualTree.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/jsVisualTree.kt index 6749e3d2..13868fdf 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/jsVisualTree.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/jsVisualTree.kt @@ -9,21 +9,19 @@ import hep.dataforge.names.NameToken import hep.dataforge.vis.common.VisualGroup import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.getProperty +import hep.dataforge.vis.jsObject import hep.dataforge.vis.spatial.Proxy import hep.dataforge.vis.spatial.visible -import org.w3c.dom.HTMLElement +import info.laht.threekt.loaders.Cache.clear +import kotlinx.html.div +import kotlinx.html.dom.append +import org.w3c.dom.Element import kotlin.js.json operator fun Name.plus(other: NameToken): Name = Name(tokens + other) -fun InspireTree.render(element: HTMLElement, block: DomConfig.() -> Unit = {}) { - val config = (json( - "target" to element - ) as DomConfig).apply(block) - InspireTreeDOM(this, config) -} -internal fun createInspireTree(block: Config.() -> Unit = {}): InspireTree { +private fun createInspireTree(block: Config.() -> Unit = {}): InspireTree { val config = (json( "checkbox" to json( "autoCheckChildren" to false @@ -32,7 +30,7 @@ internal fun createInspireTree(block: Config.() -> Unit = {}): InspireTree { return InspireTree(config) } -fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): InspireTree { +private fun VisualObject.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): InspireTree { val map = HashMap() @@ -67,15 +65,17 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): } - fun TreeNode.fillChildren(group: VisualGroup, groupName: Name) { - group.children.forEach { (token, obj) -> - if(! token.body.startsWith("@")) { - val name = groupName + token - val nodeConfig = generateNodeConfig(obj, name) - val childNode = addChild(nodeConfig) - map[childNode.id] = obj - if (obj is VisualGroup) { - childNode.fillChildren(obj, name) + fun TreeNode.fillChildren(group: VisualObject, groupName: Name) { + if(group is VisualGroup) { + group.children.forEach { (token, obj) -> + if (!token.body.startsWith("@")) { + val name = groupName + token + val nodeConfig = generateNodeConfig(obj, name) + val childNode = addChild(nodeConfig) + map[childNode.id] = obj + if (obj is VisualGroup) { + childNode.fillChildren(obj, name) + } } } } @@ -121,3 +121,16 @@ fun VisualGroup.toTree(onFocus: (VisualObject?, String?) -> Unit = { _, _ -> }): return inspireTree } + +fun Element.visualObjectTree(group: VisualObject, onFocus: (VisualObject?, String?) -> Unit) { + clear() + append { + card("Visual object tree") { + val domConfig = jsObject { + target = div() + showCheckboxes = false + } + InspireTreeDOM(group.toTree(onFocus), domConfig) + } + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/outputConfig.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/outputConfig.kt new file mode 100644 index 00000000..f667fc99 --- /dev/null +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/outputConfig.kt @@ -0,0 +1,37 @@ +package hep.dataforge.vis.spatial.editor + +import hep.dataforge.vis.spatial.three.ThreeOutput +import kotlinx.html.InputType +import kotlinx.html.dom.append +import kotlinx.html.js.div +import kotlinx.html.js.input +import kotlinx.html.js.label +import org.w3c.dom.Element +import kotlin.dom.clear + +fun Element.threeOutputConfig(output: ThreeOutput) { + clear() + append { + card("Layers"){ + div("row") { + (0..11).forEach { layer -> + div("col-1") { + label { +layer.toString() } + input(type = InputType.checkBox).apply { + if (layer == 0) { + checked = true + } + onchange = { + if (checked) { + output.camera.layers.enable(layer) + } else { + output.camera.layers.disable(layer) + } + } + } + } + } + } + } + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/propertyEditor.kt b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/propertyEditor.kt index 2a70b7d2..d718127e 100644 --- a/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/propertyEditor.kt +++ b/dataforge-vis-spatial/src/jsMain/kotlin/hep/dataforge/vis/spatial/editor/propertyEditor.kt @@ -2,10 +2,9 @@ package hep.dataforge.vis.spatial.editor import hep.dataforge.io.toJson import hep.dataforge.meta.* -import hep.dataforge.names.toName import hep.dataforge.vis.common.VisualObject import hep.dataforge.vis.common.findStyle -import hep.dataforge.vis.hmr.jsObject +import hep.dataforge.vis.jsObject import hep.dataforge.vis.spatial.Material3D.Companion.COLOR_KEY import hep.dataforge.vis.spatial.Material3D.Companion.OPACITY_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY @@ -15,11 +14,11 @@ import hep.dataforge.vis.spatial.prototype import hep.dataforge.vis.spatial.visible import kotlinx.html.dom.append import kotlinx.html.js.div -import kotlinx.html.js.h3 import kotlinx.html.js.h4 import org.w3c.dom.Element import kotlin.dom.clear +//FIXME something rotten in JS-Meta converter fun Meta.toDynamic() = JSON.parse(toJson().toString()) @@ -27,41 +26,34 @@ fun Element.propertyEditor(item: VisualObject?, name: String?) { clear() if (item != null) { append { - div("card") { - div("card-body") { - h3(classes = "card-title") { +"Properties" } - }.apply { - val config = (item.properties ?: item.prototype?.properties) ?: EmptyMeta - val metaToEdit = config.builder().apply { - VISIBLE_KEY to (item.visible ?: true) - COLOR_KEY to (item.color ?: "#ffffff") - OPACITY_KEY to (item.opacity ?: 1.0) - } - //FIXME something rotten in JS-Meta converter - val dMeta: dynamic = metaToEdit.toDynamic() - //jsObject.material.color != null - val options: JSONEditorOptions = jsObject{ - mode = "form" - onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) } - } - JSONEditor(this, options, dMeta) + card("Properties") { + val config = (item.properties ?: item.prototype?.properties) ?: EmptyMeta + val metaToEdit = config.builder().apply { + VISIBLE_KEY to (item.visible ?: true) + COLOR_KEY to (item.color ?: "#ffffff") + OPACITY_KEY to (item.opacity ?: 1.0) } + val dMeta: dynamic = metaToEdit.toDynamic() + val options: JSONEditorOptions = jsObject { + mode = "form" + onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) } + } + JSONEditor(div(), options, dMeta) } - - div("card") { - div("card-body") { - h3(classes = "card-title") { +"Styles" } - } - item.styles.forEach { style -> - val styleMeta = item.findStyle(style) - h4 { +style.toString() } - if (styleMeta != null) { - div("container").apply { - val options: JSONEditorOptions = jsObject{ - mode = "view" + val styles = item.styles + if (styles.isNotEmpty()) { + card("Styles") { + item.styles.forEach { style -> + val styleMeta = item.findStyle(style) + h4("container") { +style.toString() } + if (styleMeta != null) { + div("container").apply { + val options: JSONEditorOptions = jsObject { + mode = "view" + } + JSONEditor(this, options, styleMeta.toDynamic()) } - JSONEditor(this, options, styleMeta.toDynamic()) } } } diff --git a/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt index 496ec8fe..de2d6d0e 100644 --- a/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt +++ b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt @@ -1,10 +1,10 @@ package hep.dataforge.vis.spatial.demo import hep.dataforge.context.ContextBuilder +import hep.dataforge.vis.ApplicationBase import hep.dataforge.vis.common.Colors -import hep.dataforge.vis.hmr.ApplicationBase -import hep.dataforge.vis.hmr.startApplication import hep.dataforge.vis.spatial.* +import hep.dataforge.vis.startApplication import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.isActive