diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt new file mode 100644 index 00000000..4adeeabc --- /dev/null +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt @@ -0,0 +1,130 @@ +package hep.dataforge.vis.common + +import hep.dataforge.meta.MetaBuilder +import hep.dataforge.meta.MetaItem +import hep.dataforge.names.Name +import hep.dataforge.names.get +import hep.dataforge.provider.Provider +import kotlinx.serialization.Transient +import kotlin.collections.set + +open class VisualGroup : AbstractVisualObject(), Iterable, Provider { + + protected val namedChildren = HashMap() + protected val unnamedChildren = ArrayList() + + override val defaultTarget: String get() = VisualObject.TYPE + + override fun iterator(): Iterator = (namedChildren.values + unnamedChildren).iterator() + + override fun provideTop(target: String): Map { + return when (target) { + VisualObject.TYPE -> namedChildren + else -> emptyMap() + } + } + + override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { + super.propertyChanged(name, before, after) + forEach { + it.propertyChanged(name, before, after) + } + } + + private data class Listener(val owner: Any?, val callback: (Name?, T?) -> Unit) + + @Transient + private val listeners = HashSet>() + + /** + * Add listener for children change + */ + fun onChildrenChange(owner: Any?, action: (Name?, T?) -> Unit) { + listeners.add(Listener(owner, action)) + } + + + /** + * Remove children change listener + */ + fun removeChildrenChangeListener(owner: Any?) { + listeners.removeAll { it.owner === owner } + } + + operator fun set(name: Name, child: T?) { + if (child == null) { + namedChildren.remove(name) + } else { + if (child.parent == null) { + child.parent = this + } else { + error("Can't reassign existing parent for $child") + } + namedChildren[name] = child + } + listeners.forEach { it.callback(name, child) } + } + + /** + * Add named or unnamed child to the group. If key is [null] the child is considered unnamed. Both key and value are not + * allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed. + */ + operator fun set(name: Name?, child: T?) { + when { + name != null -> set(name, child) + child != null -> add(child) + else -> error("Both key and child element are empty") + } + } + + operator fun set(key: String?, child: T?) = set(key?.asName(), child) + + /** + * Get named child by name + */ + operator fun get(name: Name): T? = namedChildren[name] + + /** + * Get named child by string + */ + operator fun get(key: String): T? = namedChildren.get(key) + + /** + * Get an unnamed child + */ + operator fun get(index: Int): T? = unnamedChildren[index] + + /** + * Append unnamed child + */ + fun add(child: T) { + if (child.parent == null) { + child.parent = this + } else { + error("Can't reassign existing parent for $child") + } + unnamedChildren.add(child) + listeners.forEach { it.callback(null, child) } + } + + /** + * remove unnamed child + */ + fun remove(child: VisualObject) { + unnamedChildren.remove(child) + listeners.forEach { it.callback(null, null) } + } + + protected fun MetaBuilder.updateChildren() { + //adding unnamed children + "unnamedChildren" to unnamedChildren.map { it.toMeta() } + //adding named children + namedChildren.forEach { + "children[${it.key}]" to it.value.toMeta() + } + } + + override fun MetaBuilder.updateMeta() { + updateChildren() + } +} \ No newline at end of file diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualLeaf.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualLeaf.kt index 4c450ae5..5f17dd33 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualLeaf.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualLeaf.kt @@ -6,10 +6,7 @@ import hep.dataforge.names.Name /** * Basic [VisualObject] leaf element */ -open class VisualLeaf( - parent: VisualObject? = null, - meta: Meta = EmptyMeta -) : AbstractVisualObject(parent), Configurable { +open class VisualLeaf(meta: Meta = EmptyMeta) : AbstractVisualObject(), Configurable { val properties = Styled(meta) diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt index 2425e693..b0e278d9 100644 --- a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualObject.kt @@ -1,12 +1,13 @@ package hep.dataforge.vis.common +import hep.dataforge.io.ConfigSerializer import hep.dataforge.meta.* import hep.dataforge.names.Name -import hep.dataforge.names.get -import hep.dataforge.provider.Provider import hep.dataforge.provider.Type import hep.dataforge.vis.common.VisualObject.Companion.TYPE -import kotlin.collections.set +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient private fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers) private fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta) @@ -22,7 +23,8 @@ interface VisualObject : MetaRepr, Configurable { /** * The parent object of this one. If null, this one is a root. */ - val parent: VisualObject? + @Transient + var parent: VisualObject? /** * Set property for this object @@ -62,8 +64,10 @@ internal data class MetaListener( val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit ) +abstract class AbstractVisualObject : VisualObject { + override var parent: VisualObject? = null -abstract class AbstractVisualObject(override val parent: VisualObject?) : VisualObject { + @Transient private val listeners = HashSet() override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { @@ -80,6 +84,8 @@ abstract class AbstractVisualObject(override val parent: VisualObject?) : Visual listeners.removeAll { it.owner == owner } } + @Serializable(ConfigSerializer::class) + @SerialName("properties") private var _config: Config? = null override val config: Config get() = _config ?: Config().also { config -> @@ -103,117 +109,9 @@ abstract class AbstractVisualObject(override val parent: VisualObject?) : Visual override fun toMeta(): Meta = buildMeta { "type" to type - "properties" to _config + "properties" to config updateMeta() } } -open class VisualGroup(parent: VisualObject?) : AbstractVisualObject(parent), Iterable, Provider { - - protected val namedChildren = HashMap() - protected val unnamedChildren = ArrayList() - - override val defaultTarget: String get() = VisualObject.TYPE - - override fun iterator(): Iterator = (namedChildren.values + unnamedChildren).iterator() - - override fun provideTop(target: String): Map { - return when (target) { - TYPE -> namedChildren - else -> emptyMap() - } - } - - override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { - super.propertyChanged(name, before, after) - forEach { - it.propertyChanged(name, before, after) - } - } - - private data class Listener(val owner: Any?, val callback: (Name?, T?) -> Unit) - - private val listeners = HashSet>() - - /** - * Add listener for children change - */ - fun onChildrenChange(owner: Any?, action: (Name?, T?) -> Unit) { - listeners.add(Listener(owner, action)) - } - - - /** - * Remove children change listener - */ - fun removeChildrenChangeListener(owner: Any?) { - listeners.removeAll { it.owner === owner } - } - - /** - * Add named or unnamed child to the group. If key is [null] the child is considered unnamed. Both key and value are not - * allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed. - */ - operator fun set(name: Name?, child: T?) { - when { - name != null -> { - if (child == null) { - namedChildren.remove(name) - } else { - namedChildren[name] = child - } - listeners.forEach { it.callback(name, child) } - } - child != null -> unnamedChildren.add(child) - else -> error("Both key and child element are empty") - } - } - - operator fun set(key: String?, child: T?) = set(key?.asName(), child) - - /** - * Get named child by name - */ - operator fun get(name: Name): T? = namedChildren[name] - - /** - * Get named child by string - */ - operator fun get(key: String): T? = namedChildren[key] - - /** - * Get an unnamed child - */ - operator fun get(index: Int): T? = unnamedChildren[index] - - /** - * Append unnamed child - */ - fun add(child: T) { - unnamedChildren.add(child) - listeners.forEach { it.callback(null, child) } - } - - /** - * remove unnamed child - */ - fun remove(child: VisualObject) { - unnamedChildren.remove(child) - listeners.forEach { it.callback(null, null) } - } - - protected fun MetaBuilder.updateChildren() { - //adding unnamed children - "children" to unnamedChildren.map { it.toMeta() } - //adding named children - namedChildren.forEach { - "children[${it.key}" to it.value.toMeta() - } - } - - override fun MetaBuilder.updateMeta() { - updateChildren() - } -} - diff --git a/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualPlugin.kt b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualPlugin.kt new file mode 100644 index 00000000..933e4736 --- /dev/null +++ b/dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualPlugin.kt @@ -0,0 +1,37 @@ +package hep.dataforge.vis.common + +import hep.dataforge.context.* +import hep.dataforge.meta.Meta +import kotlin.reflect.KClass + +interface VisualFactory { + val type: KClass + operator fun invoke( + context: Context, + parent: VisualObject?, + meta: Meta + ): T +} + +class VisualPlugin(meta: Meta) : AbstractPlugin(meta) { + override val tag: PluginTag get() = Companion.tag + + /** + * Create a list of factories on first call and cache it + */ + val visualFactories by lazy { + context.content>(VISUAL_FACTORY_TYPE).mapKeys { it.value.type } + } + + inline fun buildVisual(parent: VisualObject?, meta: Meta): T? { + return visualFactories[T::class]?.invoke(context, parent, meta) as T? + } + + companion object : PluginFactory { + override val tag: PluginTag = PluginTag(name = "visual", group = PluginTag.DATAFORGE_GROUP) + override val type: KClass = VisualPlugin::class + override fun invoke(meta: Meta): VisualPlugin = VisualPlugin(meta) + + const val VISUAL_FACTORY_TYPE = "visual.factory" + } +} \ No newline at end of file diff --git a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt index 9dbeef6b..82d48491 100644 --- a/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt +++ b/dataforge-vis-fx/src/main/kotlin/hep/dataforge/vis/fx/meta/FXMeta.kt @@ -96,14 +96,14 @@ class FXMetaNode>( if (name.length == 1) invalidate() } - (node as? MutableMeta<*>)?.onChange(this, listener) + (node as? Config)?.onChange(this, listener) nodeProperty.addListener { _, oldValue, newValue -> if (newValue == null) { - (oldValue as? MutableMeta<*>)?.removeListener(this) + (oldValue as? Config)?.removeListener(this) } - if (newValue is MutableMeta<*>) { + if (newValue is Config) { newValue.onChange(this, listener) } } diff --git a/dataforge-vis-spatial-gdml/build.gradle.kts b/dataforge-vis-spatial-gdml/build.gradle.kts index cc390536..43ce211f 100644 --- a/dataforge-vis-spatial-gdml/build.gradle.kts +++ b/dataforge-vis-spatial-gdml/build.gradle.kts @@ -7,11 +7,11 @@ kotlin { val commonMain by getting { dependencies { api(project(":dataforge-vis-spatial")) - api("scientifik:gdml:0.1.3") + api("scientifik:gdml:0.1.4-dev-1") } } - val jsMain by getting{ - dependencies{ + val jsMain by getting { + dependencies { api(project(":dataforge-vis-spatial-js")) } } 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 3c1f7c72..12fc2aee 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 @@ -14,6 +14,12 @@ class GDMLTransformer(val root: GDML) { private val materialCache = HashMap() private val random = Random(111) + enum class Action{ + ACCEPT, + REJECT, + CACHE + } + /** * A special group for local templates */ @@ -34,15 +40,15 @@ class GDMLTransformer(val root: GDML) { } } - var acceptSolid: (GDMLSolid) -> Boolean = { true } - var acceptGroup: (GDMLGroup) -> Boolean = { true } + var solidAction: (GDMLSolid) -> Action = { Action.CACHE } + var volumeAction: (GDMLGroup) -> Action = { Action.ACCEPT } fun printStatistics() { println("Solids:") solidCounter.entries.sortedByDescending { it.value }.forEach { println("\t$it") } - println(println("Solids total: ${solidCounter.values.sum()}")) + println("Solids total: ${solidCounter.values.sum()}") } private val solidCounter = HashMap() @@ -53,8 +59,9 @@ class GDMLTransformer(val root: GDML) { var onFinish: GDMLTransformer.() -> Unit = {} - internal fun finished() { - onFinish(this) + internal fun finished(final: VisualGroup3D) { + final.templates = templates + onFinish(this@GDMLTransformer) } } \ 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 b92cf102..f92a27af 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 @@ -1,6 +1,8 @@ package hep.dataforge.vis.spatial.gdml import hep.dataforge.meta.Meta +import hep.dataforge.names.plus +import hep.dataforge.vis.common.asName import hep.dataforge.vis.spatial.* import scientifik.gdml.* import kotlin.math.cos @@ -131,6 +133,8 @@ private fun VisualGroup3D.addSolid( }.apply(block) } +private val volumesName = "volumes".asName() + private fun VisualGroup3D.addPhysicalVolume( context: GDMLTransformer, physVolume: GDMLPhysVolume @@ -138,15 +142,35 @@ private fun VisualGroup3D.addPhysicalVolume( val volume: GDMLGroup = physVolume.volumeref.resolve(context.root) ?: error("Volume with ref ${physVolume.volumeref.ref} could not be resolved") - if (context.acceptGroup(volume)) { + 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) + ) + } + } + GDMLTransformer.Action.CACHE -> { + val name = volumesName + volume.name.asName() + if (context.templates[name] == null) { + context.templates[name] = volume(context, volume) + } - this[physVolume.name] = volume( - context, - volume, - physVolume.resolvePosition(context.root), - physVolume.resolveRotation(context.root), - physVolume.resolveScale(context.root) - ) + this[physVolume.name] = Proxy(name).apply { + withPosition( + context.lUnit, + physVolume.resolvePosition(context.root), + physVolume.resolveRotation(context.root), + physVolume.resolveScale(context.root) + ) + } + } + GDMLTransformer.Action.REJECT -> { + //ignore + } } } @@ -168,36 +192,38 @@ private fun VisualGroup3D.addDivisionVolume( private fun VisualGroup3D.addVolume( context: GDMLTransformer, - group: GDMLGroup, - position: GDMLPosition? = null, - rotation: GDMLRotation? = null, - scale: GDMLScale? = null + group: GDMLGroup ) { - this[group.name] = volume(context, group, position, rotation, scale) + this[group.name] = volume(context, group) } private fun volume( context: GDMLTransformer, - group: GDMLGroup, - position: GDMLPosition? = null, - rotation: GDMLRotation? = null, - scale: GDMLScale? = null + group: GDMLGroup ): VisualGroup3D { - return VisualGroup3D().apply { - withPosition(context.lUnit, position, rotation, scale) - 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) - if (context.acceptSolid(solid)) { - val cachedSolid = context.templates[solid.name] - ?: context.templates.addSolid(context, solid, solid.name) { + when (context.solidAction(solid)) { + GDMLTransformer.Action.ACCEPT -> { + addSolid(context, solid, solid.name) { this.material = context.resolveColor(group, material, solid) } - proxy(cachedSolid, solid.name) + } + GDMLTransformer.Action.CACHE -> { + if (context.templates[solid.name] == null) { + context.templates.addSolid(context, solid, solid.name) { + this.material = context.resolveColor(group, material, solid) + } + } + ref(solid.name.asName(), solid.name) + } + GDMLTransformer.Action.REJECT -> { + //ignore + } } when (val vol = group.placement) { @@ -220,6 +246,6 @@ fun GDML.toVisual(block: GDMLTransformer.() -> Unit = {}): VisualGroup3D { val context = GDMLTransformer(this).apply(block) return volume(context, world).also { - context.finished() + context.finished(it) } } \ No newline at end of file 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 9a61c632..b6205062 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 @@ -3,6 +3,7 @@ package hep.dataforge.vis.spatial.gdml.demo import hep.dataforge.context.Global import hep.dataforge.vis.hmr.ApplicationBase import hep.dataforge.vis.hmr.startApplication +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.ThreePlugin @@ -82,7 +83,7 @@ private class GDMLDemoApp : ApplicationBase() { val canvas = document.getElementById("canvas") ?: error("Element with id canvas not found on page") canvas.clear() - val action: suspend CoroutineScope.(String) -> Unit = { + val action: suspend CoroutineScope.(String) -> Unit = { it -> canvas.clear() launch { spinner(true) } launch { message("Loading GDML") } @@ -90,11 +91,15 @@ private class GDMLDemoApp : ApplicationBase() { launch { message("Converting GDML into DF-VIS format") } val visual = gdml.toVisual { lUnit = LUnit.CM - acceptSolid = { solid -> - !solid.name.startsWith("ecal") -// && !solid.name.startsWith("V") -// && !solid.name.startsWith("U") + volumeAction = { volume -> + when { + volume.name.startsWith("ecal") -> GDMLTransformer.Action.REJECT + volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE + volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE + else -> GDMLTransformer.Action.ACCEPT + } } + } launch { message("Rendering") } val output = three.output(canvas) 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 7d5d2758..943b4afc 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,25 +1,38 @@ package hep.dataforge.vis.spatial.gdml +import hep.dataforge.names.toName +import hep.dataforge.vis.spatial.VisualGroup3D import nl.adaptivity.xmlutil.StAXReader import scientifik.gdml.GDML import java.io.File -import java.net.URL fun main() { - val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO") val file = File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\BM@N.gdml") - val stream = if (file.exists()) { - file.inputStream() - } else { - url.openStream() - } + //val file = File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.gdml") - val xmlReader = StAXReader(stream, "UTF-8") + val xmlReader = StAXReader(file.inputStream(), "UTF-8") val xml = GDML.format.parse(GDML.serializer(), xmlReader) - xml.toVisual { + val visual = xml.toVisual { lUnit = LUnit.CM - //acceptSolid = { solid -> !solid.name.startsWith("ecal") && !solid.name.startsWith("V") } + volumeAction = { volume -> + when { + volume.name.startsWith("ecal") -> GDMLTransformer.Action.CACHE + volume.name.startsWith("U") -> GDMLTransformer.Action.CACHE + volume.name.startsWith("V") -> GDMLTransformer.Action.CACHE + else -> GDMLTransformer.Action.ACCEPT + } + } onFinish = { printStatistics() } } - readLine() + + 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") + //tmpFile.writeText(meta.toString()) + //println(tmpFile.absoluteFile) } \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt index 42af3a05..16bffea0 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreePlugin.kt @@ -49,7 +49,7 @@ class ThreePlugin : AbstractPlugin() { updatePosition(obj) } is Composite -> compositeFactory(obj) - is Proxy3D -> proxyFactory(obj) + is Proxy -> proxyFactory(obj) else -> { //find specialized factory for this type if it is present val factory = findObjectFactory(obj::class) @@ -84,7 +84,7 @@ class ThreePlugin : AbstractPlugin() { } companion object : PluginFactory { - override val tag = PluginTag("vis.three", "hep.dataforge") + override val tag = PluginTag("visual.three", PluginTag.DATAFORGE_GROUP) override val type = ThreePlugin::class override fun invoke(meta: Meta) = ThreePlugin() } diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeProxyFactory.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeProxyFactory.kt index 49260019..bb037270 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeProxyFactory.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/three/ThreeProxyFactory.kt @@ -1,22 +1,22 @@ package hep.dataforge.vis.spatial.three -import hep.dataforge.vis.spatial.Proxy3D +import hep.dataforge.vis.spatial.Proxy import hep.dataforge.vis.spatial.VisualObject3D import info.laht.threekt.core.Object3D -import info.laht.threekt.objects.Mesh -class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory { - private val cache = HashMap() +class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory { + private val cache = HashMap() - override val type = Proxy3D::class + override val type = Proxy::class - override fun invoke(obj: Proxy3D): Object3D { - val templateMesh = cache.getOrPut(obj.template) { - three.buildObject3D(obj.template) as Mesh + override fun invoke(obj: Proxy): Object3D { + val template = obj.template + val cachedObject = cache.getOrPut(template) { + three.buildObject3D(template) } //val mesh = Mesh(templateMesh.geometry as BufferGeometry, templateMesh.material) - val mesh = templateMesh.clone() + val mesh = cachedObject.clone() mesh.updatePosition(obj) return mesh diff --git a/dataforge-vis-spatial/build.gradle.kts b/dataforge-vis-spatial/build.gradle.kts index 29cc4387..f5f9cc60 100644 --- a/dataforge-vis-spatial/build.gradle.kts +++ b/dataforge-vis-spatial/build.gradle.kts @@ -2,13 +2,34 @@ plugins { id("scientifik.mpp") } +scientifik{ + serialization = true +} + kotlin { + jvm{ + withJava() + } sourceSets { - val commonMain by getting { + commonMain { dependencies { api(project(":dataforge-vis-common")) } } + jvmMain{ + dependencies { + + } + } + jsMain{ + dependencies { + api("info.laht.threekt:threejs-wrapper:0.106-npm-3") + implementation(npm("three", "0.106.2")) + implementation(npm("@hi-level/three-csg")) + implementation(npm("style-loader")) + implementation(npm("element-resize-event")) + } + } } } diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt index 0f720a9e..adc96842 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Box.kt @@ -1,9 +1,19 @@ package hep.dataforge.vis.spatial +import hep.dataforge.context.Context +import hep.dataforge.meta.Meta +import hep.dataforge.meta.MetaBuilder +import hep.dataforge.meta.float +import hep.dataforge.meta.get +import hep.dataforge.vis.common.VisualFactory import hep.dataforge.vis.common.VisualObject +import kotlin.reflect.KClass -class Box(parent: VisualObject?, val xSize: Number, val ySize: Number, val zSize: Number) : - VisualLeaf3D(parent), Shape { +data class Box( + val xSize: Float, + val ySize: Float, + val zSize: Float +) : VisualLeaf3D(), Shape { //TODO add helper for color configuration override fun toGeometry(geometryBuilder: GeometryBuilder) { @@ -26,9 +36,24 @@ class Box(parent: VisualObject?, val xSize: Number, val ySize: Number, val zSize geometryBuilder.face4(node8, node5, node6, node7) } - companion object { + override fun MetaBuilder.updateMeta() { + "xSize" to xSize + "ySize" to ySize + "zSize" to ySize + } + + companion object : VisualFactory { const val TYPE = "geometry.3d.box" + override val type: KClass get() = Box::class + + override fun invoke(context: Context, parent: VisualObject?, meta: Meta): Box = Box( + meta["xSize"].float!!, + meta["ySize"].float!!, + meta["zSize"].float!! + ).apply { + update(meta) + } } } @@ -38,4 +63,4 @@ inline fun VisualGroup3D.box( zSize: Number, name: String? = null, action: Box.() -> Unit = {} -) = Box(this, xSize, ySize, zSize).apply(action).also { set(name, it) } \ No newline at end of file +) = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Composite.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Composite.kt index 85248893..079ed5c9 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Composite.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Composite.kt @@ -2,7 +2,6 @@ package hep.dataforge.vis.spatial import hep.dataforge.meta.isEmpty import hep.dataforge.meta.update -import hep.dataforge.vis.common.VisualObject enum class CompositeType { UNION, @@ -11,13 +10,12 @@ enum class CompositeType { } open class Composite( - parent: VisualObject?, val first: VisualObject3D, val second: VisualObject3D, val compositeType: CompositeType = CompositeType.UNION -) : VisualLeaf3D(parent) +) : VisualLeaf3D() -fun VisualGroup3D.composite( +inline fun VisualGroup3D.composite( type: CompositeType, name: String? = null, builder: VisualGroup3D.() -> Unit @@ -25,7 +23,7 @@ fun VisualGroup3D.composite( val group = VisualGroup3D().apply(builder) val children = group.filterIsInstance() if (children.size != 2) error("Composite requires exactly two children") - return Composite(this, children[0], children[1], type).also { + return Composite(children[0], children[1], type).also { if (!group.config.isEmpty()) { it.config.update(group.config) } 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 1d85a50b..19d5a23b 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 @@ -1,17 +1,24 @@ package hep.dataforge.vis.spatial -import hep.dataforge.vis.common.VisualObject +import hep.dataforge.meta.MetaBuilder -class Convex(parent: VisualObject?, val points: List) : VisualLeaf3D(parent) { +class Convex( + val points: List +) : VisualLeaf3D() { + override fun MetaBuilder.updateMeta() { + "points" to { + "point" to points.map{it.toMeta()} + } + } companion object { const val TYPE = "geometry.3d.convex" } } -fun VisualGroup3D.convex(action: ConvexBuilder.() -> Unit = {}) = - ConvexBuilder().apply(action).build(this).also { add(it) } +inline fun VisualGroup3D.convex(name: String? = null, action: ConvexBuilder.() -> Unit = {}) = + ConvexBuilder().apply(action).build().also { set(name, it) } class ConvexBuilder { private val points = ArrayList() @@ -20,7 +27,7 @@ class ConvexBuilder { points.add(Point3D(x, y, z)) } - fun build(parent: VisualObject?): Convex { - return Convex(parent, points) + fun build(): Convex { + return Convex(points) } } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Cylinder.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Cylinder.kt index f177c5eb..f76e9d43 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Cylinder.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Cylinder.kt @@ -1,27 +1,22 @@ package hep.dataforge.vis.spatial -import hep.dataforge.vis.common.VisualObject -import kotlin.math.PI - /** * A cylinder or cut cone segment */ class Cylinder( - parent: VisualObject?, - var radius: Number, - var height: Number, - var upperRadius: Number = radius, - var startAngle: Number = 0f, - var angle: Number = 2 * PI -) : VisualLeaf3D(parent) + var radius: Float, + var height: Float, + var upperRadius: Float = radius, + var startAngle: Float = 0f, + var angle: Float = PI2 +) : VisualLeaf3D() -fun VisualGroup3D.cylinder( +inline fun VisualGroup3D.cylinder( r: Number, height: Number, name: String? = null, block: Cylinder.() -> Unit = {} -): Cylinder { - val cylinder = Cylinder(this, r, height) - cylinder.apply(block) - return cylinder.also { set(name, it) } -} \ No newline at end of file +): Cylinder = Cylinder( + r.toFloat(), + height.toFloat() +).apply(block).also { set(name, it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt index 34bca242..b2a5e36d 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Extruded.kt @@ -1,6 +1,5 @@ package hep.dataforge.vis.spatial -import hep.dataforge.vis.common.VisualObject import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -30,7 +29,7 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { data class Layer(var x: Number, var y: Number, var z: Number, var scale: Number) -class Extruded(parent: VisualObject?) : VisualLeaf3D(parent), Shape { +class Extruded : VisualLeaf3D(), Shape { var shape: List = ArrayList() @@ -98,4 +97,4 @@ class Extruded(parent: VisualObject?) : VisualLeaf3D(parent), Shape { } fun VisualGroup3D.extrude(name: String? = null, action: Extruded.() -> Unit = {}) = - Extruded(this).apply(action).also { set(name, it) } \ No newline at end of file + Extruded().apply(action).also { set(name, it) } \ No newline at end of file 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 new file mode 100644 index 00000000..fe48af2e --- /dev/null +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy.kt @@ -0,0 +1,54 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.MetaBuilder +import hep.dataforge.meta.MetaItem +import hep.dataforge.names.Name +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() } + + /** + * Recursively search for defined template in the parent + */ + private fun getTemplate(): VisualObject3D { + return (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) + } else { + super.getProperty(name, false) ?: template.getProperty(name, false) + } + } + + override fun MetaBuilder.updateMeta() { + //TODO add reference to child + updatePosition() + } +} + +//fun VisualGroup3D.proxy( +// templateName: Name, +// //name: String? = null, +// builder: VisualGroup3D.() -> Unit +//): Proxy { +// val template = getTemplate(templateName) ?: templates.builder() +// return Proxy(this, templateName).also { set(name, it) } +//} + +inline fun VisualGroup3D.ref( + templateName: Name, + name: String? = null, + action: Proxy.() -> Unit = {} +) = Proxy(templateName).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy3D.kt deleted file mode 100644 index f3cdcc1e..00000000 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Proxy3D.kt +++ /dev/null @@ -1,34 +0,0 @@ -package hep.dataforge.vis.spatial - -import hep.dataforge.meta.MetaBuilder -import hep.dataforge.meta.MetaItem -import hep.dataforge.names.Name -import hep.dataforge.vis.common.AbstractVisualObject -import hep.dataforge.vis.common.VisualObject - -/** - * A proxy [VisualObject3D] to reuse a [template] object - */ -class Proxy3D(parent: VisualObject?, val template: VisualObject3D) : AbstractVisualObject(parent), VisualObject3D { - override var position: Value3 = Value3() - override var rotation: Value3 = Value3() - override var scale: Value3 = Value3(1f, 1f, 1f) - - override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { - return if (inherit) { - super.getProperty(name, false) ?: template.getProperty(name, false) ?: parent?.getProperty(name, inherit) - } else { - super.getProperty(name, false) ?: template.getProperty(name, false) - } - } - - override fun MetaBuilder.updateMeta() { - updatePosition() - } -} - -inline fun VisualGroup3D.proxy( - template: VisualObject3D, - name: String? = null, - action: Proxy3D.() -> Unit = {} -) = Proxy3D(this, template).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt index 0c679976..f633b002 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Sphere.kt @@ -1,23 +1,23 @@ package hep.dataforge.vis.spatial -import hep.dataforge.vis.common.VisualObject -import hep.dataforge.vis.common.number import kotlin.math.PI -class Sphere(parent: VisualObject?, var radius: Number) : VisualLeaf3D(parent) { - var phiStart by number(0.0) - var phi by number(2 * PI) - var thetaStart by number(0.0) - var theta by number(PI) -} +class Sphere( + var radius: Float, + var phiStart: Float = 0f, + var phi: Float = PI2, + var thetaStart: Float = 0f, + var theta: Float = PI.toFloat() +) : VisualLeaf3D() -fun VisualGroup3D.sphere( +inline fun VisualGroup3D.sphere( radius: Number, phi: Number = 2 * PI, theta: Number = PI, name: String? = null, action: Sphere.() -> Unit = {} -) = Sphere(this, radius).apply(action).apply { - this.phi = phi.toDouble() - this.theta = theta.toDouble() -}.also { set(name, it) } \ No newline at end of file +) = Sphere( + radius.toFloat(), + phi = phi.toFloat(), + theta = theta.toFloat() +).apply(action).also { set(name, it) } \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Tube.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Tube.kt index a0cfa6ee..bf64ffc9 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Tube.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Tube.kt @@ -1,21 +1,19 @@ package hep.dataforge.vis.spatial -import hep.dataforge.vis.common.VisualObject import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin /** - * Stright tube segment + * Straight tube segment */ class Tube( - parent: VisualObject?, var radius: Float, var height: Float, var innerRadius: Float = 0f, var startAngle: Float = 0f, var angle: Float = PI2 -) : VisualLeaf3D(parent), Shape { +) : VisualLeaf3D(), Shape { init { require(radius > 0) @@ -108,7 +106,7 @@ class Tube( } } -fun VisualGroup3D.tube( +inline fun VisualGroup3D.tube( r: Number, height: Number, innerRadius: Number = 0f, @@ -116,16 +114,12 @@ fun VisualGroup3D.tube( angle: Number = 2 * PI, name: String? = null, block: Tube.() -> Unit = {} -): Tube { - val tube = Tube( - this, - r.toFloat(), - height.toFloat(), - innerRadius.toFloat(), - startAngle.toFloat(), - angle.toFloat() - ).apply( - block - ) - return tube.also { set(name, it) } -} \ No newline at end of file +): Tube = Tube( + r.toFloat(), + height.toFloat(), + innerRadius.toFloat(), + startAngle.toFloat(), + angle.toFloat() +).apply( + block +).also { set(name, it) } \ No newline at end of file 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 new file mode 100644 index 00000000..67eb9adc --- /dev/null +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/Visual3DPlugin.kt @@ -0,0 +1,40 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.context.AbstractPlugin +import hep.dataforge.context.PluginFactory +import hep.dataforge.context.PluginTag +import hep.dataforge.meta.* +import hep.dataforge.names.Name +import hep.dataforge.vis.common.VisualPlugin +import kotlin.reflect.KClass + +class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) { + override val tag: PluginTag get() = Companion.tag + + override fun provideTop(target: String): Map { + return if (target == VisualPlugin.VISUAL_FACTORY_TYPE) { + mapOf() + } else { + emptyMap() + } + } + + companion object : PluginFactory { + override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP) + override val type: KClass = Visual3DPlugin::class + override fun invoke(meta: Meta): Visual3DPlugin = Visual3DPlugin(meta) + } +} + +internal fun VisualObject3D.update(meta: Meta) { + fun Meta.toVector(default: Float = 0f) = Value3( + this[VisualObject3D.x].float ?: default, + this[VisualObject3D.y].float ?: default, + this[VisualObject3D.z].float ?: default + ) + + meta[VisualObject3D.position].node?.toVector()?.let { position = it } + meta[VisualObject3D.rotation].node?.toVector()?.let { rotation = it } + meta[VisualObject3D.scale].node?.toVector(1f)?.let { scale = it } + meta["properties"].node?.let { configure(it) } +} \ No newline at end of file diff --git a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt index 7d4ac372..ec9655b3 100644 --- a/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt +++ b/dataforge-vis-spatial/src/commonMain/kotlin/hep/dataforge/vis/spatial/VisualObject3D.kt @@ -1,6 +1,7 @@ package hep.dataforge.vis.spatial import hep.dataforge.meta.* +import hep.dataforge.names.Name import hep.dataforge.names.plus import hep.dataforge.output.Output import hep.dataforge.vis.common.AbstractVisualObject @@ -61,18 +62,29 @@ interface VisualObject3D : VisualObject { } } -abstract class VisualLeaf3D(parent: VisualObject?) : AbstractVisualObject(parent), VisualObject3D, Configurable { +abstract class VisualLeaf3D : AbstractVisualObject(), VisualObject3D, Configurable { override var position: Value3 = Value3() override var rotation: Value3 = Value3() override var scale: Value3 = Value3(1f, 1f, 1f) } -class VisualGroup3D(parent: VisualObject? = null) : VisualGroup(parent), VisualObject3D, Configurable { +class VisualGroup3D : VisualGroup(), VisualObject3D, Configurable { override var position: Value3 = Value3() override var rotation: Value3 = Value3() override var scale: Value3 = Value3(1f, 1f, 1f) + /** + * A container for templates visible inside this group + */ + var templates: VisualGroup3D? = null + set(value) { + value?.parent = this + field = value + } + + fun getTemplate(name: Name): VisualObject3D? = templates?.get(name) ?: (parent as? VisualGroup3D)?.getTemplate(name) + override fun MetaBuilder.updateMeta() { updatePosition() updateChildren() @@ -80,7 +92,7 @@ class VisualGroup3D(parent: VisualObject? = null) : VisualGroup( } fun VisualGroup3D.group(key: String? = null, action: VisualGroup3D.() -> Unit = {}): VisualGroup3D = - VisualGroup3D(this).apply(action).also { set(key, it) } + VisualGroup3D().apply(action).also { set(key, it) } fun Output.render(meta: Meta = EmptyMeta, action: VisualGroup3D.() -> Unit) = render(VisualGroup3D().apply(action), meta) @@ -108,7 +120,7 @@ var VisualObject3D.rotationOrder: RotationOrder * Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited */ var VisualObject3D.detail: Int? - get() = getProperty(DETAIL_KEY,false).int + get() = getProperty(DETAIL_KEY, false).int set(value) = setProperty(DETAIL_KEY, value) var VisualObject3D.material: Meta? 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 index 05b3b957..810e4772 100644 --- 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 @@ -10,7 +10,7 @@ import kotlin.test.assertEquals class ConvexTest { @Test fun testConvexBuilder() { - val group = VisualNode().apply { + val group = VisualGroup3D().apply { convex { point(50, 50, -50) point(50, -50, -50) @@ -25,7 +25,7 @@ class ConvexTest { val convex = group.first() as Convex - val pointsNode = convex.config["points"].node + val pointsNode = convex.toMeta()["points"].node assertEquals(8, pointsNode?.items?.count()) val points = pointsNode?.getAll("point".toName()) 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 4ce69f73..e7ef1eeb 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,7 +1,6 @@ package hep.dataforge.vis.spatial import hep.dataforge.vis.common.Colors -import hep.dataforge.vis.common.color import kotlin.math.PI import kotlin.test.Test import kotlin.test.assertEquals @@ -9,7 +8,7 @@ import kotlin.test.assertEquals class GroupTest { @Test fun testGroupWithComposite(){ - val group = VisualNode().apply{ + val group = VisualGroup3D().apply{ union { box(100, 100, 100) { z = 100 @@ -30,7 +29,7 @@ class GroupTest { } box(100, 100, 100) y = 300 - material(Colors.red) + color(Colors.red) } subtract{ box(100, 100, 100) { @@ -40,7 +39,7 @@ class GroupTest { } box(100, 100, 100) y = -300 - material(Colors.blue) + color(Colors.blue) } } 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 new file mode 100644 index 00000000..e36c6d42 --- /dev/null +++ b/dataforge-vis-spatial/src/commonTest/kotlin/hep/dataforge/vis/spatial/SerializationTest.kt @@ -0,0 +1,18 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.context.Global +import kotlin.test.Test +import kotlin.test.assertEquals + +class SerializationTest { + @Test + fun testCubeSerialization(){ + val cube = Box(null,100f,100f,100f).apply{ + color(222) + } + val meta = cube.toMeta() + println(meta) + val newCube = Box(Global,null, meta) + assertEquals(cube,newCube) + } +} \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 6f929d72..a295cc94 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -37,7 +37,8 @@ include( ":dataforge-vis-spatial-fx", ":dataforge-vis-spatial-js", // ":dataforge-vis-jsroot", - ":dataforge-vis-spatial-gdml" + ":dataforge-vis-spatial-gdml", + ":spatial-js-demo" ) //if(file("../dataforge-core").exists()) { diff --git a/spatial-js-demo/build.gradle.kts b/spatial-js-demo/build.gradle.kts new file mode 100644 index 00000000..87ad08a2 --- /dev/null +++ b/spatial-js-demo/build.gradle.kts @@ -0,0 +1,19 @@ +plugins { + id("scientifik.js") + //id("kotlin-dce-js") +} + +dependencies { + api(project(":dataforge-vis-spatial-js")) + api("info.laht.threekt:threejs-wrapper:0.106-npm-3") + testCompile(kotlin("test-js")) +} + +//kotlin{ +// sourceSets["main"].dependencies{ +// implementation(npm("three","0.106.2")) +// implementation(npm("@hi-level/three-csg")) +// implementation(npm("style-loader")) +// implementation(npm("element-resize-event")) +// } +//} diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt similarity index 100% rename from dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt rename to spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoApp.kt diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt b/spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt similarity index 100% rename from dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt rename to spatial-js-demo/src/main/kotlin/hep/dataforge/vis/spatial/demo/ThreeDemoGrid.kt diff --git a/dataforge-vis-spatial-js/src/main/web/index.html b/spatial-js-demo/src/main/web/index.html similarity index 100% rename from dataforge-vis-spatial-js/src/main/web/index.html rename to spatial-js-demo/src/main/web/index.html