diff --git a/build.gradle.kts b/build.gradle.kts index c3b3cadc..b23dbe59 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -9,7 +9,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.1-dev-5") + val dataforgeVersion: String by rootProject.extra("0.1.2-dev-1") repositories { jcenter() @@ -40,6 +40,7 @@ allprojects { jcenter() maven("https://kotlin.bintray.com/kotlinx") maven("http://npm.mipt.ru:8081/artifactory/gradle-dev") + mavenLocal() } group = "hep.dataforge" diff --git a/dataforge-vis-common/build.gradle.kts b/dataforge-vis-common/build.gradle.kts index d0b33bb3..5feddc5a 100644 --- a/dataforge-vis-common/build.gradle.kts +++ b/dataforge-vis-common/build.gradle.kts @@ -11,19 +11,19 @@ kotlin { sourceSets { val commonMain by getting { dependencies { - api("hep.dataforge:dataforge-io:$dataforgeVersion") - api("hep.dataforge:dataforge-io-metadata:$dataforgeVersion") + api("hep.dataforge:dataforge-output:$dataforgeVersion") + //api("hep.dataforge:dataforge-output-metadata:$dataforgeVersion") } } val jvmMain by getting { dependencies { - api("hep.dataforge:dataforge-io-jvm:$dataforgeVersion") + api("hep.dataforge:dataforge-output-jvm:$dataforgeVersion") //api("no.tornado:tornadofx:1.7.18") } } val jsMain by getting { dependencies { - api("hep.dataforge:dataforge-io-js:$dataforgeVersion") + api("hep.dataforge:dataforge-output-js:$dataforgeVersion") } } } 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 ad139154..3e7d977e 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,12 +1,14 @@ 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 -import hep.dataforge.vis.spatial.gdml.gdml +import hep.dataforge.vis.spatial.jsroot.JSRootPlugin +import hep.dataforge.vis.spatial.jsroot.jsRoot import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.delay import kotlinx.coroutines.isActive @@ -22,6 +24,23 @@ class ThreeDemoApp : ApplicationBase() { 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) + + println(Global.plugins.count()) + + Global.plugins.forEach { + println(it) + } + + Global.members>(ThreeFactory.TYPE).forEach { + println(it) + } + val renderer = ThreeOutput(Global) renderer.start(document.getElementById("canvas")!!) println("started") @@ -53,7 +72,7 @@ class ThreeDemoApp : ApplicationBase() { // point(-50, -50, 50) // point(-50, 50, 50) // } - gdml { + jsRoot { y = 110.0 shape = box(50, 50, 50) } 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 new file mode 100644 index 00000000..a85493da --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeFactory.kt @@ -0,0 +1,100 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.meta.boolean +import hep.dataforge.provider.Type +import hep.dataforge.vis.DisplayObject +import hep.dataforge.vis.get +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.EdgesGeometry +import hep.dataforge.vis.spatial.three.euler +import info.laht.threekt.core.BufferGeometry +import info.laht.threekt.core.Object3D +import info.laht.threekt.geometries.BoxBufferGeometry +import info.laht.threekt.geometries.WireframeGeometry +import info.laht.threekt.math.Vector3 +import info.laht.threekt.objects.LineSegments +import info.laht.threekt.objects.Mesh +import kotlin.reflect.KClass + +internal val DisplayObject.material get() = this["color"].material() + +/** + * Builder and updater for three.js object + */ +@Type(TYPE) +interface ThreeFactory { + + val type: KClass + + operator fun invoke(obj: T): Object3D + + companion object { + const val TYPE = "threeFactory" + + /** + * Update position, rotation and visibility + */ + internal fun updatePosition(obj: DisplayObject, target: Object3D) { + target.apply { + position.set(obj.x, obj.y, obj.z) + setRotationFromEuler(obj.euler) + scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) + visible = obj.visible + } + } + + internal fun buildMesh(obj: DisplayObject, geometry: BufferGeometry): Mesh { + val mesh = Mesh(geometry, obj.material) + if (obj["edges.enabled"]?.boolean != false) { + val material = obj["edges.material"]?.material() ?: Materials.DEFAULT + mesh.add(LineSegments(EdgesGeometry(mesh.geometry as BufferGeometry), material)) + } + + if (obj["wireframe.enabled"]?.boolean == true) { + val material = obj["edges.material"]?.material() ?: Materials.DEFAULT + mesh.add(LineSegments(WireframeGeometry(mesh.geometry as BufferGeometry), material)) + } + return mesh + } + + internal fun updateMesh(obj: DisplayObject, geometry: BufferGeometry, mesh: Mesh) { + mesh.geometry = geometry + mesh.material = obj.material + } + } +} + +abstract class MeshThreeFactory(override val type: KClass) : ThreeFactory { + /** + * Build an object + */ + abstract fun buildGeometry(obj: T): BufferGeometry + + + override fun invoke(obj: T): Mesh { + val geometry = buildGeometry(obj) + val mesh = buildMesh(obj, geometry) + ThreeFactory.updatePosition(obj, mesh) + obj.onChange(this) { _, _, _ -> + ThreeFactory.updatePosition(obj, mesh) + updateMesh(obj, buildGeometry(obj), mesh) + } + return mesh + } +} + +object ThreeBoxFactory : MeshThreeFactory(Box::class) { + override fun buildGeometry(obj: Box) = + BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) +} + +fun Point3D.asVector(): Vector3 = this.asDynamic() as Vector3 + +object ThreeConvexFactory : MeshThreeFactory(Convex::class) { + override fun buildGeometry(obj: Convex) = + ConvexGeometry(obj.points.map { it.asVector() }.toTypedArray()) +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeObjectBuilder.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeObjectBuilder.kt deleted file mode 100644 index c3e672b4..00000000 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreeObjectBuilder.kt +++ /dev/null @@ -1,87 +0,0 @@ -package hep.dataforge.vis.spatial - -import hep.dataforge.vis.DisplayObject -import hep.dataforge.vis.get -import hep.dataforge.vis.onChange -import hep.dataforge.vis.spatial.three.ConvexGeometry -import hep.dataforge.vis.spatial.three.EdgesGeometry -import hep.dataforge.vis.spatial.three.euler -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.BoxBufferGeometry -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh - -/** - * Builder and updater for three.js object - */ -interface ThreeObjectBuilder { - - operator fun invoke(obj: T): Object3D - - companion object { - /** - * Update position, rotation and visibility - */ - internal fun updatePosition(obj: DisplayObject, target: Object3D) { - target.apply { - position.set(obj.x, obj.y, obj.z) - setRotationFromEuler(obj.euler) - scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) - visible = obj.visible - } - } - } -} - -abstract class GenericThreeBuilder : ThreeObjectBuilder { - /** - * Build an object - */ - abstract fun build(obj: T): R - - /** - * Update an object - */ - abstract fun update(obj: T, target: R) - - override fun invoke(obj: T): R { - val target = build(obj) - ThreeObjectBuilder.updatePosition(obj, target) - obj.onChange(this) { _, _, _ -> - ThreeObjectBuilder.updatePosition(obj, target) - update(obj, target) - } - return target - } -} - -object ThreeBoxBuilder : GenericThreeBuilder() { - override fun build(obj: Box): Mesh { - val geometry = BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) - return Mesh(geometry, obj["color"].material()).also { mesh -> - mesh.add(LineSegments(EdgesGeometry(geometry), Materials.DEFAULT)) - } - } - - override fun update(obj: Box, target: Mesh) { - target.geometry = BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) - target.material = obj["color"].material() - } -} - -fun Point3D.asVector(): Vector3 = this.asDynamic() as Vector3 - -object ThreeConvexBuilder: GenericThreeBuilder(){ - override fun build(obj: Convex): Mesh { - val geometry = ConvexGeometry(obj.points.map { it.asVector() }.toTypedArray()) - return Mesh(geometry, obj["color"].material()).also { mesh -> - mesh.add(LineSegments(EdgesGeometry(geometry), Materials.DEFAULT)) - } - } - - override fun update(obj: Convex, target: Mesh) { - target.geometry = ConvexGeometry(obj.points.map { it.asVector() }.toTypedArray()) - target.material = obj["color"].material() - } -} \ 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 8084b57e..e2e3534d 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 @@ -1,12 +1,11 @@ package hep.dataforge.vis.spatial import hep.dataforge.context.Context -import hep.dataforge.io.Output +import hep.dataforge.context.members import hep.dataforge.meta.Meta +import hep.dataforge.output.Output import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayObject -import hep.dataforge.vis.spatial.gdml.GDMLObject -import hep.dataforge.vis.spatial.gdml.ThreeGDMLBuilder import hep.dataforge.vis.spatial.three.Group import info.laht.threekt.WebGLRenderer import info.laht.threekt.cameras.PerspectiveCamera @@ -17,6 +16,7 @@ import info.laht.threekt.math.ColorConstants import info.laht.threekt.scenes.Scene import org.w3c.dom.Element import kotlin.browser.window +import kotlin.reflect.KClass class ThreeOutput(override val context: Context) : Output { @@ -65,15 +65,19 @@ class ThreeOutput(override val context: Context) : Output { private fun buildNode(obj: DisplayObject): Object3D? { return when (obj) { is DisplayGroup -> Group(obj.children.mapNotNull { buildNode(it) }).apply { - ThreeObjectBuilder.updatePosition(obj, this) + ThreeFactory.updatePosition(obj, this) } - is Box -> ThreeBoxBuilder(obj) - is GDMLObject -> ThreeGDMLBuilder(obj) - //is Convex -> ThreeConvexBuilder(obj) - else -> null + //is Box -> ThreeBoxFactory(obj) + //is JSRootObject -> ThreeJSRootFactory(obj) + //is Convex -> ThreeConvexFactory(obj) + else -> findFactory(obj::class)?.invoke(obj)?: error("Factory not found") } } + private fun findFactory(type: KClass): ThreeFactory? { + return context.members>(ThreeFactory.TYPE).find { it.type == type } as? ThreeFactory? + } + override fun render(obj: DisplayObject, meta: Meta) { buildNode(obj)?.let { scene.add(it) 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 new file mode 100644 index 00000000..09a01a47 --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/ThreePlugin.kt @@ -0,0 +1,38 @@ +package hep.dataforge.vis.spatial + +import hep.dataforge.context.AbstractPlugin +import hep.dataforge.context.PluginFactory +import hep.dataforge.context.PluginTag +import hep.dataforge.names.Name +import hep.dataforge.names.toName + +class ThreePlugin : AbstractPlugin() { + override val tag: PluginTag get() = ThreePlugin.tag + + val factories = HashMap>() + + init { + factories["box".toName()] = ThreeBoxFactory + factories["convex".toName()] = ThreeConvexFactory + } + + override fun listTop(target: String): Sequence { + return when (target) { + ThreeFactory.TYPE -> factories.keys.asSequence() + else -> return super.listTop(target) + } + } + + override fun provideTop(target: String, name: Name): Any? { + return when (target) { + ThreeFactory.TYPE -> factories[name] + else -> return super.provideTop(target, name) + } + } + + companion object : PluginFactory { + override val tag = PluginTag("vis.three", "hep.dataforge") + override val type = ThreePlugin::class + override fun build() = ThreePlugin() + } +} \ No newline at end of file diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GEO.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GEO.kt deleted file mode 100644 index 28cf0264..00000000 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GEO.kt +++ /dev/null @@ -1,7 +0,0 @@ -@file:JsModule("JSRootGeoBase.js") -@file:JsNonModule -package hep.dataforge.vis.spatial.gdml - -import info.laht.threekt.core.Geometry - -external fun createGeometry(shape: dynamic, limit: Int): Geometry 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 new file mode 100644 index 00000000..b35c1a0e --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootGEO.kt @@ -0,0 +1,8 @@ +@file:JsModule("JSRootGeoBase.js") +@file:JsNonModule + +package hep.dataforge.vis.spatial.jsroot + +import info.laht.threekt.core.BufferGeometry + +external fun createGeometry(shape: dynamic, limit: Int): BufferGeometry diff --git a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GDMLObject.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt similarity index 57% rename from dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GDMLObject.kt rename to dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt index de85ec51..5384e58e 100644 --- a/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/gdml/GDMLObject.kt +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootObject.kt @@ -1,18 +1,14 @@ -package hep.dataforge.vis.spatial.gdml +package hep.dataforge.vis.spatial.jsroot 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.GenericThreeBuilder -import hep.dataforge.vis.spatial.Materials -import hep.dataforge.vis.spatial.material -import hep.dataforge.vis.spatial.three.EdgesGeometry -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh +import hep.dataforge.vis.spatial.MeshThreeFactory +import info.laht.threekt.core.BufferGeometry -class GDMLObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) { +class JSRootObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) { var shape by node() @@ -45,6 +41,9 @@ class GDMLObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, "fNode._typename" to "TGeoSubtraction" } + /** + * Intersect two GDML geometries + */ infix fun Meta.intersect(other: Meta) = buildMeta { "fNode.fLeft" to this "fNode.fRight" to other @@ -52,13 +51,12 @@ class GDMLObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, } companion object { - const val TYPE = "geometry.spatial.gdml" + const val TYPE = "geometry.spatial.jsRoot" } } -//TODO add Zelenyy GDML builder here -fun DisplayGroup.gdml(meta: Meta = EmptyMeta, action: GDMLObject.() -> Unit = {}) = - GDMLObject(this, meta).apply(action).also { addChild(it) } +fun DisplayGroup.jsRoot(meta: Meta = EmptyMeta, action: JSRootObject.() -> Unit = {}) = + JSRootObject(this, meta).apply(action).also { addChild(it) } fun Meta.toDynamic(): dynamic { fun MetaItem<*>.toDynamic(): dynamic = when (this) { @@ -78,19 +76,9 @@ fun Meta.toDynamic(): dynamic { } -object ThreeGDMLBuilder : GenericThreeBuilder() { - override fun build(obj: GDMLObject): Mesh { +object ThreeJSRootFactory : MeshThreeFactory(JSRootObject::class) { + override fun buildGeometry(obj: JSRootObject): BufferGeometry { val shapeMeta = obj.shape?.toDynamic() ?: error("The shape not defined") - println(shapeMeta) - val geometry = createGeometry(shapeMeta, obj.facesLimit) - return Mesh(geometry, obj.color.material()).also { mesh -> - mesh.add(LineSegments(EdgesGeometry(geometry), Materials.DEFAULT)) - } - } - - override fun update(obj: GDMLObject, target: Mesh) { - val shapeMeta: dynamic = obj.shape?.toDynamic() - target.geometry = createGeometry(shapeMeta, obj.facesLimit) - target.material = obj.color.material() + 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/JSRootPlugin.kt b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt new file mode 100644 index 00000000..4d253bdb --- /dev/null +++ b/dataforge-vis-spatial-js/src/main/kotlin/hep/dataforge/vis/spatial/jsroot/JSRootPlugin.kt @@ -0,0 +1,25 @@ +package hep.dataforge.vis.spatial.jsroot + +import hep.dataforge.context.AbstractPlugin +import hep.dataforge.context.Context +import hep.dataforge.context.PluginFactory +import hep.dataforge.context.PluginTag +import hep.dataforge.names.toName +import hep.dataforge.vis.spatial.ThreePlugin + +class JSRootPlugin : AbstractPlugin() { + override val tag: PluginTag get() = JSRootPlugin.tag + + override fun dependsOn() = listOf(ThreePlugin) + + override fun attach(context: Context) { + super.attach(context) + context.plugins.get()?.factories?.set("ThreeJSRootFactory".toName(), ThreeJSRootFactory) + } + + companion object: PluginFactory { + override val tag = PluginTag("vis.jsroot", "hep.dataforge") + override val type = JSRootPlugin::class + override fun build() = JSRootPlugin() + } +} \ No newline at end of file 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 6707dfd1..b970927e 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 @@ -15,7 +15,7 @@ class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) //TODO add helper for color configuration companion object { - const val TYPE = "geometry.spatial.box" + const val TYPE = "geometry.3d.box" } } 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 59444de6..46376742 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 @@ -11,7 +11,7 @@ class Convex(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, met val points = points(properties["points"] ?: error("Vertices not defined")) companion object { - const val TYPE = "geometry.spatial.convex" + const val TYPE = "geometry.3d.convex" fun points(item: MetaItem<*>): List { return item.node?.getAll("point".toName())?.map { (_, value) -> 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 6f914ebf..773191fc 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 @@ -11,7 +11,7 @@ class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, m val shape get() = shape(properties["shape"] ?: error("Shape not defined")) companion object { - const val TYPE = "geometry.spatial.extruded" + const val TYPE = "geometry.3d.extruded" fun shape(item: MetaItem<*>): Shape2D { return item.node?.getAll("xyPoint".toName())?.map { (_, value) -> 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 33e8261a..8c2ccab9 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 @@ -1,7 +1,7 @@ package hep.dataforge.vis.spatial -import hep.dataforge.io.Output import hep.dataforge.meta.* +import hep.dataforge.output.Output import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayNode import hep.dataforge.vis.DisplayObject