forked from kscience/visionforge
commit
9567f7db93
@ -1,13 +1,10 @@
|
|||||||
import scientifik.useSerialization
|
import scientifik.fx
|
||||||
|
import scientifik.serialization
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.1.5-dev-6")
|
val dataforgeVersion by extra("0.1.7")
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
val kotlinVersion = "1.3.61"
|
val toolsVersion = "0.4.2"
|
||||||
val toolsVersion = "0.3.2"
|
|
||||||
|
|
||||||
kotlin("jvm") version kotlinVersion apply false
|
|
||||||
id("kotlin-dce-js") version kotlinVersion apply false
|
|
||||||
id("scientifik.mpp") version toolsVersion apply false
|
id("scientifik.mpp") version toolsVersion apply false
|
||||||
id("scientifik.jvm") version toolsVersion apply false
|
id("scientifik.jvm") version toolsVersion apply false
|
||||||
id("scientifik.js") version toolsVersion apply false
|
id("scientifik.js") version toolsVersion apply false
|
||||||
@ -21,21 +18,23 @@ allprojects {
|
|||||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
maven("https://dl.bintray.com/pdvrieze/maven")
|
||||||
maven("http://maven.jzy3d.org/releases")
|
maven("http://maven.jzy3d.org/releases")
|
||||||
maven("https://kotlin.bintray.com/js-externals")
|
maven("https://kotlin.bintray.com/js-externals")
|
||||||
|
maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
|
||||||
// maven("https://dl.bintray.com/gbaldeck/kotlin")
|
// maven("https://dl.bintray.com/gbaldeck/kotlin")
|
||||||
// maven("https://dl.bintray.com/rjaros/kotlin")
|
// maven("https://dl.bintray.com/rjaros/kotlin")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "hep.dataforge"
|
group = "hep.dataforge"
|
||||||
version = "0.1.1"
|
version = "0.1.3-dev"
|
||||||
}
|
|
||||||
|
|
||||||
subprojects{
|
|
||||||
this.useSerialization()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val githubProject by extra("dataforge-vis")
|
val githubProject by extra("dataforge-vis")
|
||||||
val bintrayRepo by extra("dataforge")
|
val bintrayRepo by extra("dataforge")
|
||||||
|
val fxVersion by extra("14")
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
apply(plugin = "scientifik.publish")
|
apply(plugin = "scientifik.publish")
|
||||||
|
serialization()
|
||||||
|
afterEvaluate {
|
||||||
|
fx(scientifik.FXModule.CONTROLS, version = fxVersion)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,50 +1,49 @@
|
|||||||
import org.openjfx.gradle.JavaFXOptions
|
|
||||||
import scientifik.useSerialization
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("scientifik.mpp")
|
||||||
id("org.openjfx.javafxplugin")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
|
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
|
||||||
|
|
||||||
useSerialization()
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm{
|
|
||||||
withJava()
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain{
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("hep.dataforge:dataforge-output:$dataforgeVersion")
|
api("hep.dataforge:dataforge-output:$dataforgeVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvmMain{
|
jvmMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("no.tornado:tornadofx:1.7.19")
|
api("no.tornado:tornadofx:1.7.20")
|
||||||
//api("no.tornado:tornadofx-controlsfx:0.1.1")
|
//api("no.tornado:tornadofx-controlsfx:0.1.1")
|
||||||
api("de.jensd:fontawesomefx-fontawesome:4.7.0-11"){
|
api("de.jensd:fontawesomefx-fontawesome:4.7.0-11") {
|
||||||
exclude(group = "org.openjfx")
|
exclude(group = "org.openjfx")
|
||||||
}
|
}
|
||||||
api("de.jensd:fontawesomefx-commons:11.0"){
|
api("de.jensd:fontawesomefx-commons:11.0") {
|
||||||
exclude(group = "org.openjfx")
|
exclude(group = "org.openjfx")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain{
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||||
//api(npm("bootstrap","4.4.1"))
|
|
||||||
implementation(npm("jsoneditor"))
|
//React, React DOM + Wrappers (chapter 3)
|
||||||
implementation(npm("file-saver"))
|
api("org.jetbrains:kotlin-react:16.13.0-pre.94-kotlin-1.3.70")
|
||||||
|
api("org.jetbrains:kotlin-react-dom:16.13.0-pre.94-kotlin-1.3.70")
|
||||||
|
api(npm("react", "16.13.0"))
|
||||||
|
api(npm("react-dom", "16.13.0"))
|
||||||
|
|
||||||
|
//Kotlin Styled (chapter 3)
|
||||||
|
api("org.jetbrains:kotlin-styled:1.0.0-pre.94-kotlin-1.3.70")
|
||||||
|
api(npm("styled-components"))
|
||||||
|
api(npm("inline-style-prefixer"))
|
||||||
|
|
||||||
|
|
||||||
|
api(npm("bootstrap","4.3.1"))
|
||||||
|
//api(npm("jsoneditor", "8.6.1"))
|
||||||
|
api(npm("file-saver","2.0.2"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<JavaFXOptions> {
|
|
||||||
modules("javafx.controls")
|
|
||||||
}
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
@ -20,6 +20,17 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
|||||||
*/
|
*/
|
||||||
abstract override val children: Map<NameToken, VisualObject>
|
abstract override val children: Map<NameToken, VisualObject>
|
||||||
|
|
||||||
|
abstract override var styleSheet: StyleSheet?
|
||||||
|
protected set
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Update or create stylesheet
|
||||||
|
*/
|
||||||
|
fun styleSheet(block: StyleSheet.() -> Unit) {
|
||||||
|
val res = styleSheet ?: StyleSheet(this).also { styleSheet = it }
|
||||||
|
res.block()
|
||||||
|
}
|
||||||
|
|
||||||
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
|
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
|
||||||
super.propertyChanged(name, before, after)
|
super.propertyChanged(name, before, after)
|
||||||
forEach {
|
forEach {
|
||||||
@ -37,7 +48,12 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
|||||||
* Add listener for children change
|
* Add listener for children change
|
||||||
*/
|
*/
|
||||||
override fun onChildrenChange(owner: Any?, action: (Name, VisualObject?) -> Unit) {
|
override fun onChildrenChange(owner: Any?, action: (Name, VisualObject?) -> Unit) {
|
||||||
structureChangeListeners.add(StructureChangeListeners(owner, action))
|
structureChangeListeners.add(
|
||||||
|
StructureChangeListeners(
|
||||||
|
owner,
|
||||||
|
action
|
||||||
|
)
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -68,12 +84,41 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
|||||||
* Add a static child. Statics could not be found by name, removed or replaced
|
* Add a static child. Statics could not be found by name, removed or replaced
|
||||||
*/
|
*/
|
||||||
protected open fun addStatic(child: VisualObject) =
|
protected open fun addStatic(child: VisualObject) =
|
||||||
setChild(NameToken("@static(${child.hashCode()})"), child)
|
set(NameToken("@static(${child.hashCode()})").asName(), child)
|
||||||
|
|
||||||
|
protected abstract fun createGroup(): AbstractVisualGroup
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Set this node as parent for given node
|
||||||
|
*/
|
||||||
|
protected fun attach(child: VisualObject) {
|
||||||
|
if (child.parent == null) {
|
||||||
|
child.parent = this
|
||||||
|
} else if (child.parent !== this) {
|
||||||
|
error("Can't reassign existing parent for $child")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively create a child group
|
* Recursively create a child group
|
||||||
*/
|
*/
|
||||||
protected abstract fun createGroup(name: Name): MutableVisualGroup
|
private fun createGroups(name: Name): AbstractVisualGroup {
|
||||||
|
return when {
|
||||||
|
name.isEmpty() -> error("Should be unreachable")
|
||||||
|
name.length == 1 -> {
|
||||||
|
val token = name.first()!!
|
||||||
|
when (val current = children[token]) {
|
||||||
|
null -> createGroup().also { child ->
|
||||||
|
attach(child)
|
||||||
|
setChild(token, child)
|
||||||
|
}
|
||||||
|
is AbstractVisualGroup -> current
|
||||||
|
else -> error("Can't create group with name $name because it exists and not a group")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else -> createGroups(name.first()!!.asName()).createGroups(name.cutFirst())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not
|
* Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not
|
||||||
@ -91,16 +136,17 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
|||||||
if (child == null) {
|
if (child == null) {
|
||||||
removeChild(token)
|
removeChild(token)
|
||||||
} else {
|
} else {
|
||||||
|
attach(child)
|
||||||
setChild(token, child)
|
setChild(token, child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> {
|
else -> {
|
||||||
//TODO add safety check
|
//TODO add safety check
|
||||||
val parent = (get(name.cutLast()) as? MutableVisualGroup) ?: createGroup(name.cutLast())
|
val parent = (get(name.cutLast()) as? MutableVisualGroup) ?: createGroups(name.cutLast())
|
||||||
parent[name.last()!!.asName()] = child
|
parent[name.last()!!.asName()] = child
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
structureChangeListeners.forEach { it.callback(name, child) }
|
childrenChanged(name, child)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,9 +1,10 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vis.common.VisualObject.Companion.STYLE_KEY
|
import hep.dataforge.values.Value
|
||||||
|
import hep.dataforge.vis.VisualObject.Companion.STYLE_KEY
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
internal data class PropertyListener(
|
internal data class PropertyListener(
|
||||||
@ -14,7 +15,7 @@ internal data class PropertyListener(
|
|||||||
abstract class AbstractVisualObject : VisualObject {
|
abstract class AbstractVisualObject : VisualObject {
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
override var parent: VisualObject? = null
|
override var parent: VisualGroup? = null
|
||||||
|
|
||||||
protected abstract var properties: Config?
|
protected abstract var properties: Config?
|
||||||
|
|
||||||
@ -22,7 +23,7 @@ abstract class AbstractVisualObject : VisualObject {
|
|||||||
get() = properties?.get(STYLE_KEY).stringList
|
get() = properties?.get(STYLE_KEY).stringList
|
||||||
set(value) {
|
set(value) {
|
||||||
//val allStyles = (field + value).distinct()
|
//val allStyles = (field + value).distinct()
|
||||||
setProperty(STYLE_KEY, value)
|
setProperty(STYLE_KEY, Value.of(value))
|
||||||
updateStyles(value)
|
updateStyles(value)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -66,7 +67,7 @@ abstract class AbstractVisualObject : VisualObject {
|
|||||||
private var styleCache: Meta? = null
|
private var styleCache: Meta? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Collect all styles for this object in a laminate
|
* Collect all styles for this object in a single cached meta
|
||||||
*/
|
*/
|
||||||
protected val mergedStyles: Meta
|
protected val mergedStyles: Meta
|
||||||
get() = styleCache ?: findAllStyles().merge().also {
|
get() = styleCache ?: findAllStyles().merge().also {
|
@ -1,6 +1,9 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaItem
|
||||||
|
import hep.dataforge.meta.get
|
||||||
|
import hep.dataforge.meta.number
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.int
|
import hep.dataforge.values.int
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
@ -234,7 +237,7 @@ object Colors {
|
|||||||
/**
|
/**
|
||||||
* Convert three bytes representing color to Meta
|
* Convert three bytes representing color to Meta
|
||||||
*/
|
*/
|
||||||
fun rgbToMeta(r: UByte, g: UByte, b: UByte): Meta = buildMeta {
|
fun rgbToMeta(r: UByte, g: UByte, b: UByte): Meta = Meta {
|
||||||
RED_KEY put r.toInt()
|
RED_KEY put r.toInt()
|
||||||
GREEN_KEY put g.toInt()
|
GREEN_KEY put g.toInt()
|
||||||
BLUE_KEY put b.toInt()
|
BLUE_KEY put b.toInt()
|
@ -0,0 +1,31 @@
|
|||||||
|
package hep.dataforge.vis
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("group")
|
||||||
|
class SimpleVisualGroup : AbstractVisualGroup() {
|
||||||
|
|
||||||
|
override var styleSheet: StyleSheet? = null
|
||||||
|
|
||||||
|
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
||||||
|
override var properties: Config? = null
|
||||||
|
|
||||||
|
@SerialName("children")
|
||||||
|
private val _children = HashMap<NameToken, VisualObject>()
|
||||||
|
override val children: Map<NameToken, VisualObject> get() = _children
|
||||||
|
|
||||||
|
override fun removeChild(token: NameToken) {
|
||||||
|
_children.remove(token)?.apply { parent = null }
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChild(token: NameToken, child: VisualObject) {
|
||||||
|
_children[token] = child
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createGroup(): SimpleVisualGroup = SimpleVisualGroup()
|
||||||
|
}
|
@ -1,18 +1,19 @@
|
|||||||
@file:UseSerializers(MetaSerializer::class)
|
@file:UseSerializers(MetaSerializer::class)
|
||||||
|
|
||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.MetaSerializer
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for styles
|
* A container for styles
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
class StyleSheet() {
|
class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta> = LinkedHashMap()) {
|
||||||
@Transient
|
@Transient
|
||||||
internal var owner: VisualObject? = null
|
internal var owner: VisualObject? = null
|
||||||
|
|
||||||
@ -20,12 +21,10 @@ class StyleSheet() {
|
|||||||
this.owner = owner
|
this.owner = owner
|
||||||
}
|
}
|
||||||
|
|
||||||
private val styleMap = HashMap<String, Meta>()
|
|
||||||
|
|
||||||
val items: Map<String, Meta> get() = styleMap
|
val items: Map<String, Meta> get() = styleMap
|
||||||
|
|
||||||
operator fun get(key: String): Meta? {
|
operator fun get(key: String): Meta? {
|
||||||
return styleMap[key] ?: (owner?.parent as? VisualGroup)?.styleSheet?.get(key)
|
return styleMap[key] ?: owner?.parent?.styleSheet?.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -46,20 +45,23 @@ class StyleSheet() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
||||||
val newStyle = get(key)?.let { buildMeta(it, builder) } ?: buildMeta(builder)
|
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
||||||
set(key, newStyle.seal())
|
set(key, newStyle.seal())
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object: KSerializer<StyleSheet>{
|
@Serializer(StyleSheet::class)
|
||||||
override val descriptor: SerialDescriptor
|
companion object : KSerializer<StyleSheet> {
|
||||||
get() = TODO("Not yet implemented")
|
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
||||||
|
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||||
|
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): StyleSheet {
|
override fun deserialize(decoder: Decoder): StyleSheet {
|
||||||
TODO("Not yet implemented")
|
val map = mapSerializer.deserialize(decoder)
|
||||||
|
return StyleSheet(map as? MutableMap<String, Meta> ?: LinkedHashMap(map))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: StyleSheet) {
|
override fun serialize(encoder: Encoder, value: StyleSheet) {
|
||||||
TODO("Not yet implemented")
|
mapSerializer.serialize(encoder, value.items)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.context.*
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
@ -31,7 +31,8 @@ class Visual(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
override val tag: PluginTag = PluginTag(name = "visual", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag(name = "visual", group = PluginTag.DATAFORGE_GROUP)
|
||||||
override val type: KClass<out Visual> = Visual::class
|
override val type: KClass<out Visual> = Visual::class
|
||||||
|
|
||||||
override fun invoke(meta: Meta, context: Context): Visual = Visual(meta)
|
override fun invoke(meta: Meta, context: Context): Visual =
|
||||||
|
Visual(meta)
|
||||||
|
|
||||||
const val VISUAL_FACTORY_TYPE = "visual.factory"
|
const val VISUAL_FACTORY_TYPE = "visual.factory"
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.provider.Provider
|
import hep.dataforge.provider.Provider
|
||||||
@ -6,7 +6,8 @@ import hep.dataforge.provider.Provider
|
|||||||
/**
|
/**
|
||||||
* Represents a group of [VisualObject] instances
|
* Represents a group of [VisualObject] instances
|
||||||
*/
|
*/
|
||||||
interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
|
interface VisualGroup : Provider, Iterable<VisualObject>,
|
||||||
|
VisualObject {
|
||||||
/**
|
/**
|
||||||
* A map of top level named children
|
* A map of top level named children
|
||||||
*/
|
*/
|
@ -1,11 +1,15 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.Configurable
|
||||||
|
import hep.dataforge.meta.Laminate
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
import hep.dataforge.vis.common.VisualObject.Companion.TYPE
|
import hep.dataforge.vis.VisualObject.Companion.TYPE
|
||||||
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
//private fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
|
//private fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
|
||||||
@ -21,24 +25,19 @@ interface VisualObject : Configurable {
|
|||||||
* The parent object of this one. If null, this one is a root.
|
* The parent object of this one. If null, this one is a root.
|
||||||
*/
|
*/
|
||||||
@Transient
|
@Transient
|
||||||
var parent: VisualObject?
|
var parent: VisualGroup?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All properties including styles and prototypes if present, but without inheritance
|
* All properties including styles and prototypes if present, but without inheritance
|
||||||
*/
|
*/
|
||||||
fun allProperties(): Laminate
|
fun allProperties(): Laminate
|
||||||
|
|
||||||
/**
|
|
||||||
* Set property for this object
|
|
||||||
*/
|
|
||||||
fun setProperty(name: Name, value: Any?) {
|
|
||||||
config[name] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property including or excluding parent properties
|
* Get property including or excluding parent properties
|
||||||
*/
|
*/
|
||||||
fun getProperty(name: Name, inherit: Boolean = true): MetaItem<*>?
|
fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
|
||||||
|
|
||||||
|
override fun getProperty(name: Name): MetaItem<*>? = getProperty(name, true)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
||||||
@ -66,6 +65,10 @@ interface VisualObject : Configurable {
|
|||||||
const val TYPE = "visual"
|
const val TYPE = "visual"
|
||||||
val STYLE_KEY = "@style".asName()
|
val STYLE_KEY = "@style".asName()
|
||||||
|
|
||||||
|
private val VISUAL_OBJECT_SERIALIZER = PolymorphicSerializer(VisualObject::class)
|
||||||
|
|
||||||
|
fun serializer() = VISUAL_OBJECT_SERIALIZER
|
||||||
|
|
||||||
//const val META_KEY = "@meta"
|
//const val META_KEY = "@meta"
|
||||||
//const val TAGS_KEY = "@tags"
|
//const val TAGS_KEY = "@tags"
|
||||||
|
|
||||||
@ -77,11 +80,6 @@ interface VisualObject : Configurable {
|
|||||||
*/
|
*/
|
||||||
fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit)
|
fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit)
|
||||||
|
|
||||||
/**
|
|
||||||
* Set [VisualObject] property using key as a String
|
|
||||||
*/
|
|
||||||
fun VisualObject.setProperty(key: String, value: Any?) = setProperty(key.toName(), value)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
||||||
*/
|
*/
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.common
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
@ -105,8 +105,8 @@ fun VisualObject.int(default: Int, name: Name? = null, inherited: Boolean = fals
|
|||||||
|
|
||||||
|
|
||||||
inline fun <reified E : Enum<E>> VisualObject.enum(default: E, name: Name? = null, inherited: Boolean = false) =
|
inline fun <reified E : Enum<E>> VisualObject.enum(default: E, name: Name? = null, inherited: Boolean = false) =
|
||||||
VisualObjectDelegateWrapper(this, name, default, inherited) {
|
VisualObjectDelegateWrapper(this, name, default, inherited) { item ->
|
||||||
item -> item.string?.let { enumValueOf<E>(it) }
|
item.string?.let { enumValueOf<E>(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
//merge properties
|
//merge properties
|
@ -1,22 +0,0 @@
|
|||||||
package hep.dataforge.vis.common
|
|
||||||
|
|
||||||
import hep.dataforge.descriptors.ValueDescriptor
|
|
||||||
import hep.dataforge.meta.*
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension property to access the "widget" key of [ValueDescriptor]
|
|
||||||
*/
|
|
||||||
var ValueDescriptor.widget: Meta
|
|
||||||
get() = this.config["widget"].node?: EmptyMeta
|
|
||||||
set(value) {
|
|
||||||
this.config["widget"] = value
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
|
||||||
*/
|
|
||||||
var ValueDescriptor.widgetType: String?
|
|
||||||
get() = this["widget.type"].string
|
|
||||||
set(value) {
|
|
||||||
this.config["widget.type"] = value
|
|
||||||
}
|
|
@ -0,0 +1,23 @@
|
|||||||
|
package hep.dataforge.vis
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension property to access the "widget" key of [ValueDescriptor]
|
||||||
|
*/
|
||||||
|
var ValueDescriptor.widget: Meta
|
||||||
|
get() = getProperty("widget").node ?: Meta.EMPTY
|
||||||
|
set(value) {
|
||||||
|
setProperty("widget", value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
||||||
|
*/
|
||||||
|
var ValueDescriptor.widgetType: String?
|
||||||
|
get() = getProperty("widget.type").string
|
||||||
|
set(value) {
|
||||||
|
setProperty("widget.type", value?.asValue())
|
||||||
|
}
|
@ -0,0 +1,17 @@
|
|||||||
|
package hep.dataforge.js
|
||||||
|
|
||||||
|
import react.RComponent
|
||||||
|
import kotlin.properties.ReadWriteProperty
|
||||||
|
import kotlin.reflect.KProperty
|
||||||
|
|
||||||
|
fun <T> RComponent<*, *>.initState(init: () -> T): ReadWriteProperty<RComponent<*, *>, T> =
|
||||||
|
object : ReadWriteProperty<RComponent<*, *>, T> {
|
||||||
|
val pair = react.useState(init)
|
||||||
|
override fun getValue(thisRef: RComponent<*, *>, property: KProperty<*>): T {
|
||||||
|
return pair.first
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setValue(thisRef: RComponent<*, *>, property: KProperty<*>, value: T) {
|
||||||
|
pair.second(value)
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,184 @@
|
|||||||
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.meta.descriptors.defaultItem
|
||||||
|
import hep.dataforge.meta.descriptors.get
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
|
import kotlinx.html.InputType
|
||||||
|
import kotlinx.html.classes
|
||||||
|
import kotlinx.html.js.onChangeFunction
|
||||||
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import org.w3c.dom.events.Event
|
||||||
|
import react.RBuilder
|
||||||
|
import react.RComponent
|
||||||
|
import react.RProps
|
||||||
|
import react.dom.*
|
||||||
|
import react.setState
|
||||||
|
|
||||||
|
interface ConfigEditorProps : RProps {
|
||||||
|
/**
|
||||||
|
* Root config object - always non null
|
||||||
|
*/
|
||||||
|
var root: Config
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Full path to the displayed node in [root]. Could be empty
|
||||||
|
*/
|
||||||
|
var name: Name
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root default
|
||||||
|
*/
|
||||||
|
var default: Meta?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Root descriptor
|
||||||
|
*/
|
||||||
|
var descriptor: NodeDescriptor?
|
||||||
|
|
||||||
|
var listen: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class ConfigEditorComponent : RComponent<ConfigEditorProps, TreeState>() {
|
||||||
|
|
||||||
|
override fun TreeState.init() {
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun componentDidMount() {
|
||||||
|
if (props.listen) {
|
||||||
|
props.root.onChange(this) { name, _, _ ->
|
||||||
|
if (name == props.name) {
|
||||||
|
forceUpdate()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun componentWillUnmount() {
|
||||||
|
props.root.removeListener(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val onClick: (Event) -> Unit = {
|
||||||
|
setState {
|
||||||
|
expanded = !expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
override fun RBuilder.render() {
|
||||||
|
val item = props.root[props.name]
|
||||||
|
val descriptorItem = props.descriptor?.get(props.name)
|
||||||
|
val defaultItem = props.default?.get(props.name)
|
||||||
|
val actualItem = item ?: defaultItem ?: descriptorItem?.defaultItem()
|
||||||
|
val token = props.name.last()
|
||||||
|
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
when (actualItem) {
|
||||||
|
null -> {
|
||||||
|
}
|
||||||
|
is MetaItem.ValueItem -> {
|
||||||
|
i("tree-caret") { }
|
||||||
|
}
|
||||||
|
is MetaItem.NodeItem -> {
|
||||||
|
i("tree-caret fa fa-caret-right") {
|
||||||
|
attrs {
|
||||||
|
if (state.expanded) {
|
||||||
|
classes += "rotate"
|
||||||
|
}
|
||||||
|
onClickFunction = onClick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label("tree-label") {
|
||||||
|
+token.toString()
|
||||||
|
attrs {
|
||||||
|
if (item == null) {
|
||||||
|
classes += "tree-label-inactive"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (actualItem is MetaItem.NodeItem && state.expanded) {
|
||||||
|
ul("tree") {
|
||||||
|
val keys = buildList<NameToken> {
|
||||||
|
item?.node?.items?.keys?.let { addAll(it) }
|
||||||
|
defaultItem?.node?.items?.keys?.let { addAll(it) }
|
||||||
|
(descriptorItem as? NodeDescriptor)?.items?.keys?.forEach {
|
||||||
|
add(NameToken(it))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
keys.forEach { token ->
|
||||||
|
li("tree-item") {
|
||||||
|
child(ConfigEditorComponent::class) {
|
||||||
|
attrs {
|
||||||
|
root = props.root
|
||||||
|
name = props.name + token
|
||||||
|
this.default = props.default
|
||||||
|
this.descriptor = props.descriptor
|
||||||
|
listen = false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else if (actualItem is MetaItem.ValueItem) {
|
||||||
|
div("row") {
|
||||||
|
div("col") {
|
||||||
|
label("tree-label") {
|
||||||
|
+token.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div("col") {
|
||||||
|
input(type = InputType.text) {
|
||||||
|
attrs {
|
||||||
|
value = actualItem.value.toString()
|
||||||
|
onChangeFunction = {
|
||||||
|
try {
|
||||||
|
props.root.setValue(props.name, value.asValue())
|
||||||
|
} catch (ex: Exception) {
|
||||||
|
console.error("Can't set config property $name to $value")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//+actualItem.value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Element.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null) {
|
||||||
|
render(this) {
|
||||||
|
child(ConfigEditorComponent::class) {
|
||||||
|
attrs {
|
||||||
|
root = config
|
||||||
|
name = Name.EMPTY
|
||||||
|
this.descriptor = descriptor
|
||||||
|
this.default = default
|
||||||
|
listen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RBuilder.configEditor(config: Config, descriptor: NodeDescriptor? = null, default: Meta? = null) {
|
||||||
|
child(ConfigEditorComponent::class) {
|
||||||
|
attrs {
|
||||||
|
root = config
|
||||||
|
name = Name.EMPTY
|
||||||
|
this.descriptor = descriptor
|
||||||
|
this.default = default
|
||||||
|
listen = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,84 @@
|
|||||||
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaItem
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.names.NameToken
|
||||||
|
import kotlinx.html.classes
|
||||||
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import org.w3c.dom.events.Event
|
||||||
|
import react.RBuilder
|
||||||
|
import react.RComponent
|
||||||
|
import react.RProps
|
||||||
|
import react.dom.*
|
||||||
|
import react.setState
|
||||||
|
|
||||||
|
interface MetaViewerProps : RProps {
|
||||||
|
var name: NameToken
|
||||||
|
var meta: Meta
|
||||||
|
var descriptor: NodeDescriptor?
|
||||||
|
}
|
||||||
|
|
||||||
|
class MetaViewerComponent : RComponent<MetaViewerProps, TreeState>() {
|
||||||
|
|
||||||
|
override fun TreeState.init() {
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val onClick: (Event) -> Unit = {
|
||||||
|
setState {
|
||||||
|
expanded = !expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun RBuilder.render() {
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
if (props.meta.items.isNotEmpty()) {
|
||||||
|
span("objTree-caret") {
|
||||||
|
attrs {
|
||||||
|
if (state.expanded) {
|
||||||
|
classes += "objTree-caret-down"
|
||||||
|
}
|
||||||
|
onClickFunction = onClick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label("tree-label") {
|
||||||
|
+props.name.toString()
|
||||||
|
}
|
||||||
|
ul("tree") {
|
||||||
|
props.meta.items.forEach { (token, item) ->
|
||||||
|
//val descriptor = props.
|
||||||
|
li {
|
||||||
|
when (item) {
|
||||||
|
is MetaItem.NodeItem -> {
|
||||||
|
child(MetaViewerComponent::class) {
|
||||||
|
attrs {
|
||||||
|
name = token
|
||||||
|
meta = item.node
|
||||||
|
descriptor = props.descriptor?.nodes?.get(token.body)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
is MetaItem.ValueItem -> {
|
||||||
|
div("row") {
|
||||||
|
div("col") {
|
||||||
|
label("tree-label") {
|
||||||
|
+token.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
div("col") {
|
||||||
|
label {
|
||||||
|
+item.value.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,111 @@
|
|||||||
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.plus
|
||||||
|
import hep.dataforge.vis.VisualGroup
|
||||||
|
import hep.dataforge.vis.VisualObject
|
||||||
|
import hep.dataforge.vis.isEmpty
|
||||||
|
import kotlinx.html.classes
|
||||||
|
import kotlinx.html.js.onClickFunction
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import org.w3c.dom.events.Event
|
||||||
|
import react.*
|
||||||
|
import react.dom.*
|
||||||
|
|
||||||
|
interface ObjectTreeProps : RProps {
|
||||||
|
var name: Name
|
||||||
|
var obj: VisualObject
|
||||||
|
var clickCallback: (Name) -> Unit
|
||||||
|
}
|
||||||
|
|
||||||
|
interface TreeState : RState {
|
||||||
|
var expanded: Boolean
|
||||||
|
}
|
||||||
|
|
||||||
|
class ObjectTreeComponent : RComponent<ObjectTreeProps, TreeState>() {
|
||||||
|
|
||||||
|
override fun TreeState.init() {
|
||||||
|
expanded = false
|
||||||
|
}
|
||||||
|
|
||||||
|
private val onClick: (Event) -> Unit = {
|
||||||
|
setState {
|
||||||
|
expanded = !expanded
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun RBuilder.render() {
|
||||||
|
val token = props.name.last()?.toString() ?: "World"
|
||||||
|
val obj = props.obj
|
||||||
|
|
||||||
|
//display as node if any child is visible
|
||||||
|
if (obj is VisualGroup && obj.children.keys.any { !it.body.startsWith("@") }) {
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
span("objTree-caret") {
|
||||||
|
attrs {
|
||||||
|
if (state.expanded) {
|
||||||
|
classes += "objTree-caret-down"
|
||||||
|
}
|
||||||
|
onClickFunction = onClick
|
||||||
|
}
|
||||||
|
}
|
||||||
|
label("objTree-label") {
|
||||||
|
+token
|
||||||
|
attrs {
|
||||||
|
onClickFunction = { props.clickCallback(props.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (state.expanded) {
|
||||||
|
ul("objTree-subtree") {
|
||||||
|
obj.children.entries
|
||||||
|
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
|
||||||
|
.sortedBy { (it.value as? VisualGroup)?.isEmpty ?: true }
|
||||||
|
.forEach { (childToken, child) ->
|
||||||
|
li {
|
||||||
|
child(ObjectTreeComponent::class) {
|
||||||
|
attrs {
|
||||||
|
name = props.name + childToken
|
||||||
|
this.obj = child
|
||||||
|
clickCallback = props.clickCallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
div("d-inline-block text-truncate") {
|
||||||
|
span("objTree-leaf") {}
|
||||||
|
label("objTree-label") {
|
||||||
|
+token
|
||||||
|
attrs {
|
||||||
|
onClickFunction = { props.clickCallback(props.name) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RBuilder.objectTree(
|
||||||
|
obj: VisualObject,
|
||||||
|
clickCallback: (Name) -> Unit = {}
|
||||||
|
) = card("Object tree") {
|
||||||
|
child(ObjectTreeComponent::class) {
|
||||||
|
attrs {
|
||||||
|
name = Name.EMPTY
|
||||||
|
this.obj = obj
|
||||||
|
this.clickCallback = clickCallback
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Element.objectTree(
|
||||||
|
obj: VisualObject,
|
||||||
|
clickCallback: (Name) -> Unit = {}
|
||||||
|
) {
|
||||||
|
render(this) {
|
||||||
|
objectTree(obj, clickCallback)
|
||||||
|
}
|
||||||
|
}
|
@ -1,8 +1,12 @@
|
|||||||
package hep.dataforge.vis.js.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import kotlinx.html.*
|
import kotlinx.html.*
|
||||||
import kotlinx.html.js.div
|
import kotlinx.html.js.div
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
|
import react.RBuilder
|
||||||
|
import react.ReactElement
|
||||||
|
import react.dom.div
|
||||||
|
import react.dom.h3
|
||||||
|
|
||||||
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
||||||
div("card w-100") {
|
div("card w-100") {
|
||||||
@ -13,6 +17,14 @@ inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline fun RBuilder.card(title: String, crossinline block: RBuilder.() -> Unit): ReactElement = div("card w-100") {
|
||||||
|
div("card-body") {
|
||||||
|
h3(classes = "card-title") { +title }
|
||||||
|
block()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
fun TagConsumer<HTMLElement>.accordion(id: String, elements: Map<String, DIV.() -> Unit>) {
|
fun TagConsumer<HTMLElement>.accordion(id: String, elements: Map<String, DIV.() -> Unit>) {
|
||||||
div("container-fluid") {
|
div("container-fluid") {
|
||||||
div("accordion") {
|
div("accordion") {
|
@ -1,10 +1,10 @@
|
|||||||
package hep.dataforge.vis.js.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.vis.common.VisualGroup
|
import hep.dataforge.vis.VisualGroup
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.common.isEmpty
|
import hep.dataforge.vis.isEmpty
|
||||||
import kotlinx.html.TagConsumer
|
import kotlinx.html.TagConsumer
|
||||||
import kotlinx.html.dom.append
|
import kotlinx.html.dom.append
|
||||||
import kotlinx.html.js.*
|
import kotlinx.html.js.*
|
||||||
@ -13,18 +13,18 @@ import org.w3c.dom.HTMLElement
|
|||||||
import org.w3c.dom.HTMLSpanElement
|
import org.w3c.dom.HTMLSpanElement
|
||||||
import kotlin.dom.clear
|
import kotlin.dom.clear
|
||||||
|
|
||||||
fun Element.displayObjectTree(
|
//fun Element.displayObjectTree(
|
||||||
obj: VisualObject,
|
// obj: VisualObject,
|
||||||
clickCallback: (Name) -> Unit = {}
|
// clickCallback: (Name) -> Unit = {}
|
||||||
) {
|
//) {
|
||||||
clear()
|
// clear()
|
||||||
append {
|
// append {
|
||||||
card("Object tree") {
|
// card("Object tree") {
|
||||||
subTree(Name.EMPTY, obj, clickCallback)
|
// subTree(Name.EMPTY, obj, clickCallback)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
private fun TagConsumer<HTMLElement>.subTree(
|
private fun TagConsumer<HTMLElement>.subTree(
|
||||||
name: Name,
|
name: Name,
|
||||||
obj: VisualObject,
|
obj: VisualObject,
|
@ -6,7 +6,7 @@
|
|||||||
"EXTERNAL_DELEGATION"
|
"EXTERNAL_DELEGATION"
|
||||||
)
|
)
|
||||||
|
|
||||||
package hep.dataforge.vis.js.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
|
|
@ -0,0 +1,107 @@
|
|||||||
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaBuilder
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.isEmpty
|
||||||
|
import hep.dataforge.vis.VisualObject
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import react.RBuilder
|
||||||
|
import react.ReactElement
|
||||||
|
import react.dom.li
|
||||||
|
import react.dom.nav
|
||||||
|
import react.dom.ol
|
||||||
|
import react.dom.render
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
////FIXME something rotten in JS-Meta converter
|
||||||
|
//fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
|
||||||
|
//
|
||||||
|
////TODO add node descriptor instead of configuring property selector
|
||||||
|
//fun Element.displayPropertyEditor(
|
||||||
|
// name: Name,
|
||||||
|
// item: VisualObject,
|
||||||
|
// propertySelector: (VisualObject) -> Meta = { it.config }
|
||||||
|
//) {
|
||||||
|
// clear()
|
||||||
|
//
|
||||||
|
// append {
|
||||||
|
// card("Properties") {
|
||||||
|
// if (!name.isEmpty()) {
|
||||||
|
// nav {
|
||||||
|
// attributes["aria-label"] = "breadcrumb"
|
||||||
|
// ol("breadcrumb") {
|
||||||
|
// name.tokens.forEach { token ->
|
||||||
|
// li("breadcrumb-item") {
|
||||||
|
// +token.toString()
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// val dMeta: dynamic = propertySelector(item).toDynamic()
|
||||||
|
// val options: JSONEditorOptions = jsObject {
|
||||||
|
// mode = "form"
|
||||||
|
// onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
|
||||||
|
// }
|
||||||
|
// JSONEditor(div(), options, dMeta)
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// val styles = item.styles
|
||||||
|
// if (styles.isNotEmpty()) {
|
||||||
|
// card("Styles") {
|
||||||
|
// item.styles.forEach { style ->
|
||||||
|
// val styleMeta = item.findStyle(style)
|
||||||
|
// h4("container") { +style }
|
||||||
|
// if (styleMeta != null) {
|
||||||
|
// div("container").apply {
|
||||||
|
// val options: JSONEditorOptions = jsObject {
|
||||||
|
// mode = "view"
|
||||||
|
// }
|
||||||
|
// JSONEditor(
|
||||||
|
// this,
|
||||||
|
// options,
|
||||||
|
// styleMeta.toDynamic()
|
||||||
|
// )
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
|
||||||
|
fun RBuilder.visualPropertyEditor(
|
||||||
|
path: Name,
|
||||||
|
item: VisualObject,
|
||||||
|
descriptor: NodeDescriptor? = item.descriptor,
|
||||||
|
title: String = "Properties",
|
||||||
|
default: MetaBuilder.() -> Unit = {}
|
||||||
|
): ReactElement = card(title) {
|
||||||
|
if (!path.isEmpty()) {
|
||||||
|
nav {
|
||||||
|
attrs {
|
||||||
|
attributes["aria-label"] = "breadcrumb"
|
||||||
|
}
|
||||||
|
ol("breadcrumb") {
|
||||||
|
path.tokens.forEach { token ->
|
||||||
|
li("breadcrumb-item") {
|
||||||
|
+token.toString()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
configEditor(item.config, descriptor, Meta(default))
|
||||||
|
}
|
||||||
|
|
||||||
|
fun Element.visualPropertyEditor(
|
||||||
|
path: Name,
|
||||||
|
item: VisualObject,
|
||||||
|
descriptor: NodeDescriptor? = item.descriptor,
|
||||||
|
title: String = "Properties",
|
||||||
|
default: MetaBuilder.() -> Unit = {}
|
||||||
|
) = render(this) {
|
||||||
|
visualPropertyEditor(path, item, descriptor, title, default)
|
||||||
|
}
|
@ -1,75 +0,0 @@
|
|||||||
package hep.dataforge.vis.js.editor
|
|
||||||
|
|
||||||
import hep.dataforge.io.toJson
|
|
||||||
import hep.dataforge.js.jsObject
|
|
||||||
import hep.dataforge.meta.DynamicMeta
|
|
||||||
import hep.dataforge.meta.Meta
|
|
||||||
import hep.dataforge.meta.update
|
|
||||||
import hep.dataforge.names.Name
|
|
||||||
import hep.dataforge.names.isEmpty
|
|
||||||
import hep.dataforge.vis.common.VisualObject
|
|
||||||
import hep.dataforge.vis.common.findStyle
|
|
||||||
import kotlinx.html.dom.append
|
|
||||||
import kotlinx.html.js.*
|
|
||||||
import org.w3c.dom.Element
|
|
||||||
import kotlin.collections.forEach
|
|
||||||
import kotlin.collections.isNotEmpty
|
|
||||||
import kotlin.collections.set
|
|
||||||
import kotlin.dom.clear
|
|
||||||
|
|
||||||
//FIXME something rotten in JS-Meta converter
|
|
||||||
fun Meta.toDynamic() = JSON.parse<dynamic>(toJson().toString())
|
|
||||||
|
|
||||||
//TODO add node descriptor instead of configuring property selector
|
|
||||||
fun Element.displayPropertyEditor(
|
|
||||||
name: Name,
|
|
||||||
item: VisualObject,
|
|
||||||
propertySelector: (VisualObject) -> Meta = { it.config }
|
|
||||||
) {
|
|
||||||
clear()
|
|
||||||
|
|
||||||
append {
|
|
||||||
card("Properties") {
|
|
||||||
if (!name.isEmpty()) {
|
|
||||||
nav {
|
|
||||||
attributes["aria-label"] = "breadcrumb"
|
|
||||||
ol("breadcrumb") {
|
|
||||||
name.tokens.forEach { token ->
|
|
||||||
li("breadcrumb-item") {
|
|
||||||
+token.toString()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val dMeta: dynamic = propertySelector(item).toDynamic()
|
|
||||||
val options: JSONEditorOptions = jsObject {
|
|
||||||
mode = "form"
|
|
||||||
onChangeJSON = { item.config.update(DynamicMeta(it.asDynamic())) }
|
|
||||||
}
|
|
||||||
JSONEditor(div(), options, dMeta)
|
|
||||||
}
|
|
||||||
|
|
||||||
val styles = item.styles
|
|
||||||
if (styles.isNotEmpty()) {
|
|
||||||
card("Styles") {
|
|
||||||
item.styles.forEach { style ->
|
|
||||||
val styleMeta = item.findStyle(style)
|
|
||||||
h4("container") { +style }
|
|
||||||
if (styleMeta != null) {
|
|
||||||
div("container").apply {
|
|
||||||
val options: JSONEditorOptions = jsObject {
|
|
||||||
mode = "view"
|
|
||||||
}
|
|
||||||
JSONEditor(
|
|
||||||
this,
|
|
||||||
options,
|
|
||||||
styleMeta.toDynamic()
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -21,3 +21,20 @@ ul, .objTree-subtree {
|
|||||||
.objTree-caret-down::before {
|
.objTree-caret-down::before {
|
||||||
transform: rotate(90deg);
|
transform: rotate(90deg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ul, .tree {
|
||||||
|
list-style-type: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
i, .tree-caret{
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 6px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.rotate {
|
||||||
|
transform: rotate(90deg);
|
||||||
|
}
|
||||||
|
|
||||||
|
.tree-label-inactive {
|
||||||
|
color: gray;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package hep.dataforge.vis.fx
|
package hep.dataforge.vis
|
||||||
|
|
||||||
import hep.dataforge.context.*
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.meta.EmptyMeta
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.boolean
|
import hep.dataforge.meta.boolean
|
||||||
import javafx.application.Application
|
import javafx.application.Application
|
||||||
@ -20,7 +19,7 @@ import kotlin.reflect.KClass
|
|||||||
/**
|
/**
|
||||||
* Plugin holding JavaFX application instance and its root stage
|
* Plugin holding JavaFX application instance and its root stage
|
||||||
*/
|
*/
|
||||||
class FXPlugin(meta: Meta = EmptyMeta) : AbstractPlugin(meta) {
|
class FXPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(meta) {
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
private val stages: ObservableSet<Stage> = FXCollections.observableSet()
|
private val stages: ObservableSet<Stage> = FXCollections.observableSet()
|
||||||
@ -96,7 +95,8 @@ class FXPlugin(meta: Meta = EmptyMeta) : AbstractPlugin(meta) {
|
|||||||
companion object : PluginFactory<FXPlugin> {
|
companion object : PluginFactory<FXPlugin> {
|
||||||
override val type: KClass<out FXPlugin> = FXPlugin::class
|
override val type: KClass<out FXPlugin> = FXPlugin::class
|
||||||
override val tag: PluginTag = PluginTag("vis.fx", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag("vis.fx", group = PluginTag.DATAFORGE_GROUP)
|
||||||
override fun invoke(meta: Meta, context: Context): FXPlugin = FXPlugin(meta)
|
override fun invoke(meta: Meta, context: Context): FXPlugin =
|
||||||
|
FXPlugin(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -1,4 +1,4 @@
|
|||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
@ -3,7 +3,7 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
@ -3,15 +3,15 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon
|
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIcon
|
||||||
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView
|
import de.jensd.fx.glyphs.fontawesome.FontAwesomeIconView
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.descriptors.NodeDescriptor
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vis.fx.dfIconView
|
import hep.dataforge.vis.dfIconView
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
import javafx.scene.control.*
|
import javafx.scene.control.*
|
||||||
import javafx.scene.control.cell.TextFieldTreeTableCell
|
import javafx.scene.control.cell.TextFieldTreeTableCell
|
||||||
@ -128,7 +128,11 @@ class ConfigEditor(
|
|||||||
when (item) {
|
when (item) {
|
||||||
is FXMetaValue<Config> -> {
|
is FXMetaValue<Config> -> {
|
||||||
text = null
|
text = null
|
||||||
val chooser = ValueChooser.build(Global, item.valueProperty, item.descriptor) {
|
val chooser = ValueChooser.build(
|
||||||
|
Global,
|
||||||
|
item.valueProperty,
|
||||||
|
item.descriptor
|
||||||
|
) {
|
||||||
item.set(it)
|
item.set(it)
|
||||||
}
|
}
|
||||||
graphic = chooser.node
|
graphic = chooser.node
|
@ -1,9 +1,9 @@
|
|||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.descriptors.ItemDescriptor
|
|
||||||
import hep.dataforge.descriptors.NodeDescriptor
|
|
||||||
import hep.dataforge.descriptors.ValueDescriptor
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
@ -174,10 +174,10 @@ private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boo
|
|||||||
val name = token.asName()
|
val name = token.asName()
|
||||||
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||||
val newName = name.withIndex(index.toString())
|
val newName = name.withIndex(index.toString())
|
||||||
set(newName, EmptyMeta)
|
set(newName, Meta.EMPTY)
|
||||||
get(newName).node!!
|
get(newName).node!!
|
||||||
} else {
|
} else {
|
||||||
this.setNode(token.asName(), EmptyMeta)
|
this.setNode(token.asName(), Meta.EMPTY)
|
||||||
//FIXME possible concurrency bug
|
//FIXME possible concurrency bug
|
||||||
get(token).node!!
|
get(token).node!!
|
||||||
}
|
}
|
||||||
@ -211,9 +211,9 @@ fun <M : MutableMeta<M>> FXMetaNode<M>.addValue(key: String) {
|
|||||||
fun <M : MutableMeta<M>> FXMetaNode<M>.addNode(key: String) {
|
fun <M : MutableMeta<M>> FXMetaNode<M>.addNode(key: String) {
|
||||||
val parent = getOrCreateNode()
|
val parent = getOrCreateNode()
|
||||||
if (descriptor?.multiple == true) {
|
if (descriptor?.multiple == true) {
|
||||||
parent.append(key, EmptyMeta)
|
parent.append(key, Meta.EMPTY)
|
||||||
} else {
|
} else {
|
||||||
parent[key] = EmptyMeta
|
parent[key] = Meta.EMPTY
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -14,18 +14,23 @@
|
|||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.vis.fx.dfIconView
|
import hep.dataforge.vis.dfIconView
|
||||||
import javafx.beans.property.SimpleStringProperty
|
import javafx.beans.property.SimpleStringProperty
|
||||||
import javafx.scene.control.TreeItem
|
import javafx.scene.control.TreeItem
|
||||||
import javafx.scene.control.TreeSortMode
|
import javafx.scene.control.TreeSortMode
|
||||||
import javafx.scene.control.TreeTableView
|
import javafx.scene.control.TreeTableView
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title, dfIconView) {
|
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title,
|
||||||
constructor(meta: Meta, title: String = "Meta viewer"): this(FXMeta.root(meta),title = title)
|
dfIconView
|
||||||
|
) {
|
||||||
|
constructor(meta: Meta, title: String = "Meta viewer"): this(
|
||||||
|
FXMeta.root(
|
||||||
|
meta
|
||||||
|
),title = title)
|
||||||
|
|
||||||
override val root = borderpane {
|
override val root = borderpane {
|
||||||
center {
|
center {
|
@ -3,7 +3,7 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
@ -3,7 +3,7 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
|
|
@ -3,20 +3,19 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.context.Named
|
import hep.dataforge.context.Named
|
||||||
import hep.dataforge.descriptors.ValueDescriptor
|
|
||||||
import hep.dataforge.meta.EmptyMeta
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
import hep.dataforge.provider.provideByType
|
import hep.dataforge.provider.provideByType
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import hep.dataforge.vis.common.widget
|
import hep.dataforge.vis.widget
|
||||||
import hep.dataforge.vis.common.widgetType
|
import hep.dataforge.vis.widgetType
|
||||||
import javafx.beans.property.ObjectProperty
|
import javafx.beans.property.ObjectProperty
|
||||||
import javafx.beans.value.ObservableValue
|
import javafx.beans.value.ObservableValue
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
@ -66,7 +65,7 @@ interface ValueChooser {
|
|||||||
|
|
||||||
@Type("hep.dataforge.vis.fx.valueChooserFactory")
|
@Type("hep.dataforge.vis.fx.valueChooserFactory")
|
||||||
interface Factory : Named {
|
interface Factory : Named {
|
||||||
operator fun invoke(meta: Meta = EmptyMeta): ValueChooser
|
operator fun invoke(meta: Meta = Meta.EMPTY): ValueChooser
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
@ -108,8 +107,7 @@ interface ValueChooser {
|
|||||||
descriptor: ValueDescriptor? = null,
|
descriptor: ValueDescriptor? = null,
|
||||||
setter: (Value) -> Unit
|
setter: (Value) -> Unit
|
||||||
): ValueChooser {
|
): ValueChooser {
|
||||||
val chooser =
|
val chooser = build(context, descriptor)
|
||||||
build(context, descriptor)
|
|
||||||
chooser.setDisplayValue(value.value ?: Null)
|
chooser.setDisplayValue(value.value ?: Null)
|
||||||
value.onChange {
|
value.onChange {
|
||||||
chooser.setDisplayValue(it ?: Null)
|
chooser.setDisplayValue(it ?: Null)
|
@ -3,9 +3,9 @@
|
|||||||
* To change this template file, choose Tools | Templates
|
* To change this template file, choose Tools | Templates
|
||||||
* and open the template in the editor.
|
* and open the template in the editor.
|
||||||
*/
|
*/
|
||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.descriptors.ValueDescriptor
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
@ -1,11 +1,11 @@
|
|||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.descriptors.NodeDescriptor
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.common.findStyle
|
import hep.dataforge.vis.findStyle
|
||||||
import javafx.beans.binding.Binding
|
import javafx.beans.binding.Binding
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
@ -1,7 +1,7 @@
|
|||||||
package hep.dataforge.vis.fx.editor
|
package hep.dataforge.vis.editor
|
||||||
|
|
||||||
import hep.dataforge.vis.common.VisualGroup
|
import hep.dataforge.vis.VisualGroup
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
import javafx.scene.control.SelectionMode
|
import javafx.scene.control.SelectionMode
|
||||||
import javafx.scene.control.TreeItem
|
import javafx.scene.control.TreeItem
|
@ -1,12 +1,12 @@
|
|||||||
package hep.dataforge.vis.fx.demo
|
package hep.dataforge.vis.demo
|
||||||
|
|
||||||
import hep.dataforge.descriptors.NodeDescriptor
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.buildMeta
|
import hep.dataforge.meta.asConfig
|
||||||
import hep.dataforge.meta.toConfig
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.vis.fx.editor.ConfigEditor
|
import hep.dataforge.vis.editor.ConfigEditor
|
||||||
import hep.dataforge.vis.fx.editor.FXMeta
|
import hep.dataforge.vis.editor.FXMeta
|
||||||
import hep.dataforge.vis.fx.editor.MetaViewer
|
import hep.dataforge.vis.editor.MetaViewer
|
||||||
import javafx.geometry.Orientation
|
import javafx.geometry.Orientation
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ class MetaEditorDemoApp : App(MetaEditorDemo::class)
|
|||||||
|
|
||||||
class MetaEditorDemo : View("Meta editor demo") {
|
class MetaEditorDemo : View("Meta editor demo") {
|
||||||
|
|
||||||
val meta = buildMeta {
|
val meta = Meta {
|
||||||
"aNode" put {
|
"aNode" put {
|
||||||
"innerNode" put {
|
"innerNode" put {
|
||||||
"innerValue" put true
|
"innerValue" put true
|
||||||
@ -23,33 +23,35 @@ class MetaEditorDemo : View("Meta editor demo") {
|
|||||||
"b" put 223
|
"b" put 223
|
||||||
"c" put "StringValue"
|
"c" put "StringValue"
|
||||||
}
|
}
|
||||||
}.toConfig()
|
}.asConfig()
|
||||||
|
|
||||||
val descriptor = NodeDescriptor {
|
val descriptor = NodeDescriptor {
|
||||||
node("aNode") {
|
defineNode("aNode") {
|
||||||
info = "A root demo node"
|
info = "A root demo node"
|
||||||
value("b") {
|
defineValue("b") {
|
||||||
info = "b number value"
|
info = "b number value"
|
||||||
type(ValueType.NUMBER)
|
type(ValueType.NUMBER)
|
||||||
}
|
}
|
||||||
node("otherNode") {
|
defineNode("otherNode") {
|
||||||
value("otherValue") {
|
defineValue("otherValue") {
|
||||||
type(ValueType.BOOLEAN)
|
type(ValueType.BOOLEAN)
|
||||||
default(false)
|
default(false)
|
||||||
info = "default value"
|
info = "default value"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
value("multiple"){
|
defineValue("multiple") {
|
||||||
info = "A sns value"
|
info = "A sns value"
|
||||||
multiple = true
|
multiple = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rootNode = FXMeta.root(meta,descriptor)
|
private val rootNode = FXMeta.root(meta, descriptor)
|
||||||
|
|
||||||
override val root =
|
override val root =
|
||||||
splitpane(Orientation.HORIZONTAL, MetaViewer(rootNode).root, ConfigEditor(rootNode).root)
|
splitpane(Orientation.HORIZONTAL, MetaViewer(rootNode).root, ConfigEditor(
|
||||||
|
rootNode
|
||||||
|
).root)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
@ -7,7 +7,7 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":dataforge-vis-spatial"))
|
api(project(":dataforge-vis-spatial"))
|
||||||
api("scientifik:gdml:0.1.6")
|
api("scientifik:gdml:0.1.7")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,12 +2,12 @@ package hep.dataforge.vis.spatial.gdml
|
|||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.MetaBuilder
|
import hep.dataforge.meta.MetaBuilder
|
||||||
import hep.dataforge.meta.buildMeta
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.common.useStyle
|
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
||||||
|
import hep.dataforge.vis.useStyle
|
||||||
import scientifik.gdml.*
|
import scientifik.gdml.*
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@ -44,7 +44,7 @@ class GDMLTransformer(val root: GDML) {
|
|||||||
|
|
||||||
fun VisualObject3D.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
|
fun VisualObject3D.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
|
||||||
styleCache.getOrPut(name.toName()) {
|
styleCache.getOrPut(name.toName()) {
|
||||||
buildMeta(builder)
|
Meta(builder)
|
||||||
}
|
}
|
||||||
useStyle(name)
|
useStyle(name)
|
||||||
}
|
}
|
||||||
@ -69,7 +69,13 @@ class GDMLTransformer(val root: GDML) {
|
|||||||
var onFinish: GDMLTransformer.() -> Unit = {}
|
var onFinish: GDMLTransformer.() -> Unit = {}
|
||||||
|
|
||||||
internal fun finalize(final: VisualGroup3D): VisualGroup3D {
|
internal fun finalize(final: VisualGroup3D): VisualGroup3D {
|
||||||
final.prototypes = proto
|
//final.prototypes = proto
|
||||||
|
final.prototypes {
|
||||||
|
proto.children.forEach { (token, item) ->
|
||||||
|
item.parent = null
|
||||||
|
set(token.asName(), item)
|
||||||
|
}
|
||||||
|
}
|
||||||
styleCache.forEach {
|
styleCache.forEach {
|
||||||
final.styleSheet {
|
final.styleSheet {
|
||||||
define(it.key.toString(), it.value)
|
define(it.key.toString(), it.value)
|
||||||
|
@ -4,8 +4,8 @@ package hep.dataforge.vis.spatial.gdml
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.vis.common.get
|
import hep.dataforge.vis.get
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.set
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import hep.dataforge.vis.spatial.World.ONE
|
import hep.dataforge.vis.spatial.World.ONE
|
||||||
import hep.dataforge.vis.spatial.World.ZERO
|
import hep.dataforge.vis.spatial.World.ZERO
|
||||||
|
@ -1,43 +1,29 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml
|
package hep.dataforge.vis.spatial.gdml
|
||||||
|
|
||||||
|
import hep.dataforge.vis.spatial.stringify
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
import nl.adaptivity.xmlutil.StAXReader
|
||||||
import org.junit.Test
|
import org.junit.jupiter.api.Test
|
||||||
import scientifik.gdml.GDML
|
import scientifik.gdml.GDML
|
||||||
import java.io.File
|
|
||||||
import java.net.URL
|
|
||||||
import kotlin.test.Ignore
|
|
||||||
|
|
||||||
class TestConvertor {
|
class TestConvertor {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
|
||||||
fun testBMNGeometry() {
|
fun testBMNGeometry() {
|
||||||
val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO")
|
val stream = javaClass.getResourceAsStream("/gdml/BM@N.gdml")
|
||||||
val file = File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\BM@N.gdml")
|
|
||||||
val stream = if (file.exists()) {
|
|
||||||
file.inputStream()
|
|
||||||
} else {
|
|
||||||
url.openStream()
|
|
||||||
}
|
|
||||||
|
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
|
||||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
|
||||||
xml.toVisual()
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
@Ignore
|
|
||||||
fun testCubes() {
|
|
||||||
val file = File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.gdml ")
|
|
||||||
val stream = if (file.exists()) {
|
|
||||||
file.inputStream()
|
|
||||||
} else {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val xmlReader = StAXReader(stream, "UTF-8")
|
||||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||||
val visual = xml.toVisual()
|
val visual = xml.toVisual()
|
||||||
println(visual)
|
println(visual.stringify())
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testCubes() {
|
||||||
|
val stream = javaClass.getResourceAsStream("/gdml/cubes.gdml")
|
||||||
|
|
||||||
|
val xmlReader = StAXReader(stream, "UTF-8")
|
||||||
|
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||||
|
val visual = xml.toVisual()
|
||||||
|
// println(visual)
|
||||||
}
|
}
|
||||||
}
|
}
|
5601
dataforge-vis-spatial-gdml/src/jvmTest/resources/gdml/BM@N.gdml
Normal file
5601
dataforge-vis-spatial-gdml/src/jvmTest/resources/gdml/BM@N.gdml
Normal file
File diff suppressed because it is too large
Load Diff
254
dataforge-vis-spatial-gdml/src/jvmTest/resources/gdml/cubes.gdml
Normal file
254
dataforge-vis-spatial-gdml/src/jvmTest/resources/gdml/cubes.gdml
Normal file
@ -0,0 +1,254 @@
|
|||||||
|
<gdml>
|
||||||
|
<define>
|
||||||
|
<position name="center" x="0.0" y="0.0" z="0.0" unit="cm"/>
|
||||||
|
<position name="box_position" x="25.0" y="50.0" z="75.0" unit="cm"/>
|
||||||
|
<rotation name="Rot0" x="0.0" y="0.0" z="0.0" unit="deg"/>
|
||||||
|
<rotation name="Rot1" x="0.0" y="0.0" z="60.0" unit="deg"/>
|
||||||
|
<rotation name="Rot2" x="0.0" y="0.0" z="120.0" unit="deg"/>
|
||||||
|
<rotation name="Rot3" x="0.0" y="0.0" z="180.0" unit="deg"/>
|
||||||
|
<rotation name="Rot4" x="0.0" y="0.0" z="240.0" unit="deg"/>
|
||||||
|
<rotation name="Rot5" x="0.0" y="0.0" z="300.0" unit="deg"/>
|
||||||
|
<rotation name="Rot000" x="0.0" y="0.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos000" x="-50.0" y="-50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot001" x="0.0" y="0.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos001" x="-50.0" y="-50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot002" x="0.0" y="0.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos002" x="-50.0" y="-50.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot010" x="0.0" y="120.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos010" x="-50.0" y="0.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot011" x="0.0" y="120.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos011" x="-50.0" y="0.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot012" x="0.0" y="120.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos012" x="-50.0" y="0.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot020" x="0.0" y="240.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos020" x="-50.0" y="50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot021" x="0.0" y="240.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos021" x="-50.0" y="50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot022" x="0.0" y="240.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos022" x="-50.0" y="50.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot100" x="120.0" y="0.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos100" x="0.0" y="-50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot101" x="120.0" y="0.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos101" x="0.0" y="-50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot102" x="120.0" y="0.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos102" x="0.0" y="-50.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot110" x="120.0" y="120.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos110" x="0.0" y="0.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot111" x="120.0" y="120.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos111" x="0.0" y="0.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot112" x="120.0" y="120.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos112" x="0.0" y="0.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot120" x="120.0" y="240.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos120" x="0.0" y="50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot121" x="120.0" y="240.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos121" x="0.0" y="50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot122" x="120.0" y="240.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos122" x="0.0" y="50.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot200" x="240.0" y="0.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos200" x="50.0" y="-50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot201" x="240.0" y="0.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos201" x="50.0" y="-50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot202" x="240.0" y="0.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos202" x="50.0" y="-50.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot210" x="240.0" y="120.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos210" x="50.0" y="0.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot211" x="240.0" y="120.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos211" x="50.0" y="0.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot212" x="240.0" y="120.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos212" x="50.0" y="0.0" z="50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot220" x="240.0" y="240.0" z="0.0" unit="deg"/>
|
||||||
|
<position name="Pos220" x="50.0" y="50.0" z="-50.0" unit="cm"/>
|
||||||
|
<rotation name="Rot221" x="240.0" y="240.0" z="120.0" unit="deg"/>
|
||||||
|
<position name="Pos221" x="50.0" y="50.0" z="0.0" unit="cm"/>
|
||||||
|
<rotation name="Rot222" x="240.0" y="240.0" z="240.0" unit="deg"/>
|
||||||
|
<position name="Pos222" x="50.0" y="50.0" z="50.0" unit="cm"/>
|
||||||
|
</define>
|
||||||
|
<materials/>
|
||||||
|
<solids>
|
||||||
|
<tube aunit="degree" name="segment" rmax="20.0" z="5.0" rmin="17.0" startphi="0.0" deltaphi="60.0"/>
|
||||||
|
<box name="cave" x="200.0" y="200.0" z="200.0"/>
|
||||||
|
<box name="box" x="30.0" y="30.0" z="30.0"/>
|
||||||
|
</solids>
|
||||||
|
<structure>
|
||||||
|
<volume name="segment_vol">
|
||||||
|
<materialref ref="G4_WATER"/>
|
||||||
|
<solidref ref="segment"/>
|
||||||
|
</volume>
|
||||||
|
<volume name="composite">
|
||||||
|
<physvol name="segment_0">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot0"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="segment_1">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot1"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="segment_2">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot2"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="segment_3">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot3"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="segment_4">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot4"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="segment_5">
|
||||||
|
<volumeref ref="segment_vol"/>
|
||||||
|
<positionref ref="center"/>
|
||||||
|
<rotationref ref="Rot5"/>
|
||||||
|
</physvol>
|
||||||
|
<materialref ref="G4_AIR"/>
|
||||||
|
<solidref ref="box"/>
|
||||||
|
</volume>
|
||||||
|
<volume name="world">
|
||||||
|
<physvol name="composite_000">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos000"/>
|
||||||
|
<rotationref ref="Rot000"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_001">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos001"/>
|
||||||
|
<rotationref ref="Rot001"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_002">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos002"/>
|
||||||
|
<rotationref ref="Rot002"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_003">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos010"/>
|
||||||
|
<rotationref ref="Rot010"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_004">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos011"/>
|
||||||
|
<rotationref ref="Rot011"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_005">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos012"/>
|
||||||
|
<rotationref ref="Rot012"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol name="composite_006">
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos020"/>
|
||||||
|
<rotationref ref="Rot020"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos021"/>
|
||||||
|
<rotationref ref="Rot021"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos022"/>
|
||||||
|
<rotationref ref="Rot022"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos100"/>
|
||||||
|
<rotationref ref="Rot100"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos101"/>
|
||||||
|
<rotationref ref="Rot101"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos102"/>
|
||||||
|
<rotationref ref="Rot102"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos110"/>
|
||||||
|
<rotationref ref="Rot110"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos111"/>
|
||||||
|
<rotationref ref="Rot111"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos112"/>
|
||||||
|
<rotationref ref="Rot112"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos120"/>
|
||||||
|
<rotationref ref="Rot120"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos121"/>
|
||||||
|
<rotationref ref="Rot121"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos122"/>
|
||||||
|
<rotationref ref="Rot122"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos200"/>
|
||||||
|
<rotationref ref="Rot200"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos201"/>
|
||||||
|
<rotationref ref="Rot201"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos202"/>
|
||||||
|
<rotationref ref="Rot202"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos210"/>
|
||||||
|
<rotationref ref="Rot210"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos211"/>
|
||||||
|
<rotationref ref="Rot211"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos212"/>
|
||||||
|
<rotationref ref="Rot212"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos220"/>
|
||||||
|
<rotationref ref="Rot220"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos221"/>
|
||||||
|
<rotationref ref="Rot221"/>
|
||||||
|
</physvol>
|
||||||
|
<physvol>
|
||||||
|
<volumeref ref="composite"/>
|
||||||
|
<positionref ref="Pos222"/>
|
||||||
|
<rotationref ref="Rot222"/>
|
||||||
|
</physvol>
|
||||||
|
<materialref ref="G4_AIR"/>
|
||||||
|
<solidref ref="cave"/>
|
||||||
|
</volume>
|
||||||
|
</structure>
|
||||||
|
<setup name="Default" version="1.0">
|
||||||
|
<world ref="world"/>
|
||||||
|
</setup>
|
||||||
|
</gdml>
|
@ -1,17 +1,12 @@
|
|||||||
import org.openjfx.gradle.JavaFXOptions
|
import scientifik.serialization
|
||||||
import scientifik.useSerialization
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("scientifik.mpp")
|
||||||
id("org.openjfx.javafxplugin")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
useSerialization()
|
serialization()
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
jvm {
|
|
||||||
withJava()
|
|
||||||
}
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
@ -32,14 +27,9 @@ kotlin {
|
|||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
// api(project(":wrappers"))
|
// api(project(":wrappers"))
|
||||||
implementation(npm("three", "0.106.2"))
|
implementation(npm("three", "0.114.0"))
|
||||||
implementation(npm("@hi-level/three-csg", "1.0.6"))
|
implementation(npm("three-csg-ts", "1.0.1"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<JavaFXOptions> {
|
|
||||||
modules("javafx.controls")
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@ -2,15 +2,11 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.float
|
import hep.dataforge.meta.float
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.*
|
||||||
import hep.dataforge.vis.common.VisualFactory
|
|
||||||
import hep.dataforge.vis.common.VisualObject
|
|
||||||
import hep.dataforge.vis.common.set
|
|
||||||
import hep.dataforge.vis.spatial.Box.Companion.TYPE_NAME
|
import hep.dataforge.vis.spatial.Box.Companion.TYPE_NAME
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -29,7 +25,6 @@ class Box(
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
//TODO add helper for color configuration
|
//TODO add helper for color configuration
|
||||||
@ -69,7 +64,7 @@ class Box(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.box(
|
inline fun MutableVisualGroup.box(
|
||||||
xSize: Number,
|
xSize: Number,
|
||||||
ySize: Number,
|
ySize: Number,
|
||||||
zSize: Number,
|
zSize: Number,
|
||||||
|
@ -2,11 +2,10 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.*
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -23,7 +22,7 @@ class Composite(
|
|||||||
val compositeType: CompositeType,
|
val compositeType: CompositeType,
|
||||||
val first: VisualObject3D,
|
val first: VisualObject3D,
|
||||||
val second: VisualObject3D
|
val second: VisualObject3D
|
||||||
) : AbstractVisualObject(), VisualObject3D {
|
) : AbstractVisualObject(), VisualObject3D, VisualGroup {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
first.parent = this
|
first.parent = this
|
||||||
@ -34,11 +33,16 @@ class Composite(
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
|
override val children: Map<NameToken, VisualObject>
|
||||||
|
get() = mapOf(NameToken("first") to first, NameToken("second") to second)
|
||||||
|
|
||||||
|
override val styleSheet: StyleSheet?
|
||||||
|
get() = null
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.composite(
|
inline fun MutableVisualGroup.composite(
|
||||||
type: CompositeType,
|
type: CompositeType,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
builder: VisualGroup3D.() -> Unit
|
builder: VisualGroup3D.() -> Unit
|
||||||
@ -50,24 +54,24 @@ inline fun VisualGroup3D.composite(
|
|||||||
it.config.update(group.config)
|
it.config.update(group.config)
|
||||||
//it.material = group.material
|
//it.material = group.material
|
||||||
|
|
||||||
if(group.position!=null) {
|
if (group.position != null) {
|
||||||
it.position = group.position
|
it.position = group.position
|
||||||
}
|
}
|
||||||
if(group.rotation!=null) {
|
if (group.rotation != null) {
|
||||||
it.rotation = group.rotation
|
it.rotation = group.rotation
|
||||||
}
|
}
|
||||||
if(group.scale!=null) {
|
if (group.scale != null) {
|
||||||
it.scale = group.scale
|
it.scale = group.scale
|
||||||
}
|
}
|
||||||
set(name, it)
|
set(name, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualGroup3D.union(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
inline fun MutableVisualGroup.union(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
||||||
composite(CompositeType.UNION, name, builder = builder)
|
composite(CompositeType.UNION, name, builder = builder)
|
||||||
|
|
||||||
fun VisualGroup3D.subtract(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
inline fun MutableVisualGroup.subtract(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
||||||
composite(CompositeType.SUBTRACT, name, builder = builder)
|
composite(CompositeType.SUBTRACT, name, builder = builder)
|
||||||
|
|
||||||
fun VisualGroup3D.intersect(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
inline fun MutableVisualGroup.intersect(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
||||||
composite(CompositeType.INTERSECT, name, builder = builder)
|
composite(CompositeType.INTERSECT, name, builder = builder)
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -25,7 +25,6 @@ class ConeSegment(
|
|||||||
var angle: Float = PI2
|
var angle: Float = PI2
|
||||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -76,7 +75,7 @@ class ConeSegment(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.cylinder(
|
inline fun MutableVisualGroup.cylinder(
|
||||||
r: Number,
|
r: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
@ -88,7 +87,7 @@ inline fun VisualGroup3D.cylinder(
|
|||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { set(name, it) }
|
||||||
|
|
||||||
|
|
||||||
inline fun VisualGroup3D.cone(
|
inline fun MutableVisualGroup.cone(
|
||||||
bottomRadius: Number,
|
bottomRadius: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
upperRadius: Number = 0.0,
|
upperRadius: Number = 0.0,
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -14,7 +14,6 @@ import kotlinx.serialization.UseSerializers
|
|||||||
@SerialName("3d.convex")
|
@SerialName("3d.convex")
|
||||||
class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -26,7 +25,7 @@ class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}) =
|
inline fun MutableVisualGroup.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}) =
|
||||||
ConvexBuilder().apply(action).build().also { set(name, it) }
|
ConvexBuilder().apply(action).build().also { set(name, it) }
|
||||||
|
|
||||||
class ConvexBuilder {
|
class ConvexBuilder {
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
@file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class)
|
@file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class)
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -45,7 +45,6 @@ class Extruded(
|
|||||||
var layers: MutableList<Layer> = ArrayList()
|
var layers: MutableList<Layer> = ArrayList()
|
||||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -113,5 +112,5 @@ class Extruded(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualGroup3D.extrude(name: String = "", action: Extruded.() -> Unit = {}) =
|
fun MutableVisualGroup.extrude(name: String = "", action: Extruded.() -> Unit = {}) =
|
||||||
Extruded().apply(action).also { set(name, it) }
|
Extruded().apply(action).also { set(name, it) }
|
@ -1,6 +1,5 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.meta.EmptyMeta
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -14,7 +13,7 @@ interface GeometryBuilder<T : Any> {
|
|||||||
* @param normal optional external normal to the face
|
* @param normal optional external normal to the face
|
||||||
* @param meta optional additional platform-specific parameters like color or texture index
|
* @param meta optional additional platform-specific parameters like color or texture index
|
||||||
*/
|
*/
|
||||||
fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = EmptyMeta)
|
fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY)
|
||||||
|
|
||||||
fun build(): T
|
fun build(): T
|
||||||
}
|
}
|
||||||
@ -25,7 +24,7 @@ fun GeometryBuilder<*>.face4(
|
|||||||
vertex3: Point3D,
|
vertex3: Point3D,
|
||||||
vertex4: Point3D,
|
vertex4: Point3D,
|
||||||
normal: Point3D? = null,
|
normal: Point3D? = null,
|
||||||
meta: Meta = EmptyMeta
|
meta: Meta = Meta.EMPTY
|
||||||
) {
|
) {
|
||||||
face(vertex1, vertex2, vertex3, normal, meta)
|
face(vertex1, vertex2, vertex3, normal, meta)
|
||||||
face(vertex1, vertex3, vertex4, normal, meta)
|
face(vertex1, vertex3, vertex4, normal, meta)
|
||||||
|
@ -2,19 +2,17 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("3d.label")
|
@SerialName("3d.label")
|
||||||
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(),
|
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(), VisualObject3D {
|
||||||
VisualObject3D {
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -23,7 +21,7 @@ class Label3D(var text: String, var fontSize: Double, var fontFamily: String) :
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualGroup3D.label(
|
fun MutableVisualGroup.label(
|
||||||
text: String,
|
text: String,
|
||||||
fontSize: Number = 20,
|
fontSize: Number = 20,
|
||||||
fontFamily: String = "Arial",
|
fontFamily: String = "Arial",
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.descriptors.NodeDescriptor
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.values.asValue
|
||||||
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_KEY
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
|
||||||
|
|
||||||
class Material3D(override val config: Config) : Specific {
|
class Material3D : Scheme() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primary web-color for the material
|
* Primary web-color for the material
|
||||||
@ -32,8 +33,7 @@ class Material3D(override val config: Config) : Specific {
|
|||||||
*/
|
*/
|
||||||
var wireframe by boolean(false, WIREFRAME_KEY)
|
var wireframe by boolean(false, WIREFRAME_KEY)
|
||||||
|
|
||||||
companion object : Specification<Material3D> {
|
companion object : SchemeSpec<Material3D>(::Material3D) {
|
||||||
override fun wrap(config: Config): Material3D = Material3D(config)
|
|
||||||
|
|
||||||
val MATERIAL_KEY = "material".asName()
|
val MATERIAL_KEY = "material".asName()
|
||||||
internal val COLOR_KEY = "color".asName()
|
internal val COLOR_KEY = "color".asName()
|
||||||
@ -44,23 +44,26 @@ class Material3D(override val config: Config) : Specific {
|
|||||||
internal val WIREFRAME_KEY = "wireframe".asName()
|
internal val WIREFRAME_KEY = "wireframe".asName()
|
||||||
val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY
|
val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY
|
||||||
|
|
||||||
val descriptor = NodeDescriptor {
|
val descriptor by lazy {
|
||||||
value(VisualObject3D.VISIBLE_KEY) {
|
//must be lazy to avoid initialization bug
|
||||||
type(ValueType.BOOLEAN)
|
NodeDescriptor {
|
||||||
default(true)
|
defineValue(VisualObject3D.VISIBLE_KEY) {
|
||||||
}
|
|
||||||
node(MATERIAL_KEY) {
|
|
||||||
value(COLOR_KEY) {
|
|
||||||
type(ValueType.STRING, ValueType.NUMBER)
|
|
||||||
default("#ffffff")
|
|
||||||
}
|
|
||||||
value(OPACITY_KEY) {
|
|
||||||
type(ValueType.NUMBER)
|
|
||||||
default(1.0)
|
|
||||||
}
|
|
||||||
value(WIREFRAME_KEY) {
|
|
||||||
type(ValueType.BOOLEAN)
|
type(ValueType.BOOLEAN)
|
||||||
default(false)
|
default(true)
|
||||||
|
}
|
||||||
|
defineNode(MATERIAL_KEY) {
|
||||||
|
defineValue(COLOR_KEY) {
|
||||||
|
type(ValueType.STRING, ValueType.NUMBER)
|
||||||
|
default("#ffffff")
|
||||||
|
}
|
||||||
|
defineValue(OPACITY_KEY) {
|
||||||
|
type(ValueType.NUMBER)
|
||||||
|
default(1.0)
|
||||||
|
}
|
||||||
|
defineValue(WIREFRAME_KEY) {
|
||||||
|
type(ValueType.BOOLEAN)
|
||||||
|
default(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,14 +74,14 @@ class Material3D(override val config: Config) : Specific {
|
|||||||
* Set color as web-color
|
* Set color as web-color
|
||||||
*/
|
*/
|
||||||
fun VisualObject3D.color(webColor: String) {
|
fun VisualObject3D.color(webColor: String) {
|
||||||
setProperty(MATERIAL_COLOR_KEY, webColor)
|
setProperty(MATERIAL_COLOR_KEY, webColor.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set color as integer
|
* Set color as integer
|
||||||
*/
|
*/
|
||||||
fun VisualObject3D.color(rgb: Int) {
|
fun VisualObject3D.color(rgb: Int) {
|
||||||
setProperty(MATERIAL_COLOR_KEY, rgb)
|
setProperty(MATERIAL_COLOR_KEY, rgb.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty(
|
fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty(
|
||||||
@ -92,7 +95,7 @@ fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty(
|
|||||||
var VisualObject3D.color: String?
|
var VisualObject3D.color: String?
|
||||||
get() = getProperty(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
get() = getProperty(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
||||||
set(value) {
|
set(value) {
|
||||||
setProperty(MATERIAL_COLOR_KEY, value)
|
setProperty(MATERIAL_COLOR_KEY, value?.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val VisualObject3D.material: Material3D?
|
val VisualObject3D.material: Material3D?
|
||||||
@ -110,5 +113,5 @@ fun VisualObject3D.material(builder: Material3D.() -> Unit) {
|
|||||||
var VisualObject3D.opacity: Double?
|
var VisualObject3D.opacity: Double?
|
||||||
get() = getProperty(MATERIAL_OPACITY_KEY).double
|
get() = getProperty(MATERIAL_OPACITY_KEY).double
|
||||||
set(value) {
|
set(value) {
|
||||||
setProperty(MATERIAL_OPACITY_KEY, value)
|
setProperty(MATERIAL_OPACITY_KEY, value?.asValue())
|
||||||
}
|
}
|
@ -2,13 +2,13 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -16,7 +16,6 @@ import kotlinx.serialization.UseSerializers
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("3d.line")
|
@SerialName("3d.line")
|
||||||
class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -32,5 +31,5 @@ class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisualGroup3D.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) =
|
fun MutableVisualGroup.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) =
|
||||||
PolyLine(points.toList()).apply(action).also { set(name, it) }
|
PolyLine(points.toList()).apply(action).also { set(name, it) }
|
@ -1,18 +1,13 @@
|
|||||||
@file:UseSerializers(Point3DSerializer::class, NameSerializer::class, ConfigSerializer::class)
|
@file:UseSerializers(Point3DSerializer::class)
|
||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.Laminate
|
import hep.dataforge.meta.Laminate
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.vis.*
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.names.plus
|
|
||||||
import hep.dataforge.vis.common.*
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
@ -26,7 +21,9 @@ import kotlin.collections.set
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("3d.proxy")
|
@SerialName("3d.proxy")
|
||||||
class Proxy private constructor(val templateName: Name) : AbstractVisualObject(), VisualGroup, VisualObject3D {
|
class Proxy private constructor(
|
||||||
|
val templateName: Name
|
||||||
|
) : AbstractVisualObject(), VisualGroup, VisualObject3D {
|
||||||
|
|
||||||
constructor(parent: VisualGroup3D, templateName: Name) : this(templateName) {
|
constructor(parent: VisualGroup3D, templateName: Name) : this(templateName) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
@ -36,7 +33,6 @@ class Proxy private constructor(val templateName: Name) : AbstractVisualObject()
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -44,10 +40,12 @@ class Proxy private constructor(val templateName: Name) : AbstractVisualObject()
|
|||||||
*/
|
*/
|
||||||
val prototype: VisualObject3D
|
val prototype: VisualObject3D
|
||||||
get() = (parent as? VisualGroup3D)?.getPrototype(templateName)
|
get() = (parent as? VisualGroup3D)?.getPrototype(templateName)
|
||||||
?: error("Template with name $templateName not found in $parent")
|
?: error("Prototype with name $templateName not found in $parent")
|
||||||
|
|
||||||
override val styleSheet: StyleSheet
|
override val styleSheet: StyleSheet
|
||||||
get() = (parent as? VisualGroup)?.styleSheet ?: StyleSheet(this)
|
get() = parent?.styleSheet ?: StyleSheet(
|
||||||
|
this
|
||||||
|
)
|
||||||
|
|
||||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||||
return if (inherit) {
|
return if (inherit) {
|
||||||
@ -89,7 +87,8 @@ class Proxy private constructor(val templateName: Name) : AbstractVisualObject()
|
|||||||
|
|
||||||
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
|
||||||
|
|
||||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
inner class ProxyChild(val name: Name) : AbstractVisualObject(),
|
||||||
|
VisualGroup {
|
||||||
|
|
||||||
val prototype: VisualObject get() = prototypeFor(name)
|
val prototype: VisualObject get() = prototypeFor(name)
|
||||||
|
|
||||||
@ -155,20 +154,18 @@ val VisualObject.prototype: VisualObject
|
|||||||
/**
|
/**
|
||||||
* Create ref for existing prototype
|
* Create ref for existing prototype
|
||||||
*/
|
*/
|
||||||
inline fun VisualGroup3D.ref(
|
fun VisualGroup3D.ref(
|
||||||
templateName: Name,
|
templateName: Name,
|
||||||
name: String = "",
|
name: String = ""
|
||||||
block: Proxy.() -> Unit = {}
|
): Proxy = Proxy(this, templateName).also { set(name, it) }
|
||||||
) = Proxy(this, templateName).apply(block).also { set(name, it) }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
||||||
*/
|
*/
|
||||||
fun VisualGroup3D.proxy(
|
fun VisualGroup3D.proxy(
|
||||||
templateName: Name,
|
name: String,
|
||||||
obj: VisualObject3D,
|
obj: VisualObject3D,
|
||||||
name: String = "",
|
templateName: Name = name.toName()
|
||||||
block: Proxy.() -> Unit = {}
|
|
||||||
): Proxy {
|
): Proxy {
|
||||||
val existing = getPrototype(templateName)
|
val existing = getPrototype(templateName)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
@ -178,5 +175,14 @@ fun VisualGroup3D.proxy(
|
|||||||
} else if (existing != obj) {
|
} else if (existing != obj) {
|
||||||
error("Can't add different prototype on top of existing one")
|
error("Can't add different prototype on top of existing one")
|
||||||
}
|
}
|
||||||
return ref(templateName, name, block)
|
return ref(templateName, name)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VisualGroup3D.proxyGroup(
|
||||||
|
name: String,
|
||||||
|
templateName: Name = name.toName(),
|
||||||
|
block: MutableVisualGroup.() -> Unit
|
||||||
|
): Proxy {
|
||||||
|
val group = VisualGroup3D().apply(block)
|
||||||
|
return proxy(name, group, templateName)
|
||||||
}
|
}
|
||||||
|
@ -2,10 +2,10 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -23,7 +23,6 @@ class Sphere(
|
|||||||
var theta: Float = PI.toFloat()
|
var theta: Float = PI.toFloat()
|
||||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -61,7 +60,7 @@ class Sphere(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.sphere(
|
inline fun MutableVisualGroup.sphere(
|
||||||
radius: Number,
|
radius: Number,
|
||||||
phi: Number = 2 * PI,
|
phi: Number = 2 * PI,
|
||||||
theta: Number = PI,
|
theta: Number = PI,
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
@file:UseSerializers(Point3DSerializer::class)
|
@file:UseSerializers(Point3DSerializer::class)
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.common.set
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
@ -29,7 +29,6 @@ class Tube(
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -129,7 +128,7 @@ class Tube(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun VisualGroup3D.tube(
|
inline fun MutableVisualGroup.tube(
|
||||||
r: Number,
|
r: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
innerRadius: Number = 0f,
|
innerRadius: Number = 0f,
|
||||||
|
@ -4,14 +4,12 @@ import hep.dataforge.context.AbstractPlugin
|
|||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.context.PluginFactory
|
import hep.dataforge.context.PluginFactory
|
||||||
import hep.dataforge.context.PluginTag
|
import hep.dataforge.context.PluginTag
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.io.serialization.MetaSerializer
|
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.common.Visual
|
import hep.dataforge.vis.SimpleVisualGroup
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.Visual
|
||||||
|
import hep.dataforge.vis.VisualObject
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.json.JsonConfiguration
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
@ -39,29 +37,28 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
val serialModule = SerializersModule {
|
val serialModule = SerializersModule {
|
||||||
contextual(Point3DSerializer)
|
contextual(Point3DSerializer)
|
||||||
contextual(Point2DSerializer)
|
contextual(Point2DSerializer)
|
||||||
contextual(NameSerializer)
|
|
||||||
contextual(NameTokenSerializer)
|
|
||||||
contextual(MetaSerializer)
|
|
||||||
contextual(ConfigSerializer)
|
|
||||||
|
|
||||||
polymorphic(VisualObject::class, VisualObject3D::class) {
|
polymorphic(VisualObject::class, VisualObject3D::class) {
|
||||||
VisualGroup3D::class with VisualGroup3D.serializer()
|
subclass(SimpleVisualGroup.serializer())
|
||||||
Proxy::class with Proxy.serializer()
|
subclass(VisualGroup3D.serializer())
|
||||||
Composite::class with Composite.serializer()
|
subclass(Proxy.serializer())
|
||||||
Tube::class with Tube.serializer()
|
subclass(Composite.serializer())
|
||||||
Box::class with Box.serializer()
|
subclass(Tube.serializer())
|
||||||
Convex::class with Convex.serializer()
|
subclass(Box.serializer())
|
||||||
Extruded::class with Extruded.serializer()
|
subclass(Convex.serializer())
|
||||||
addSubclass(PolyLine.serializer())
|
subclass(Extruded.serializer())
|
||||||
addSubclass(Label3D.serializer())
|
subclass(PolyLine.serializer())
|
||||||
|
subclass(Label3D.serializer())
|
||||||
|
subclass(Sphere.serializer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val json = Json(
|
internal val json = Json(
|
||||||
JsonConfiguration(
|
JsonConfiguration(
|
||||||
prettyPrint = true,
|
prettyPrint = true,
|
||||||
useArrayPolymorphism = false,
|
useArrayPolymorphism = false,
|
||||||
encodeDefaults = false
|
encodeDefaults = false,
|
||||||
|
ignoreUnknownKeys = true
|
||||||
),
|
),
|
||||||
context = serialModule
|
context = serialModule
|
||||||
)
|
)
|
||||||
|
@ -1,48 +1,49 @@
|
|||||||
@file:UseSerializers(
|
@file:UseSerializers(
|
||||||
Point3DSerializer::class,
|
Point3DSerializer::class
|
||||||
ConfigSerializer::class,
|
|
||||||
NameTokenSerializer::class,
|
|
||||||
NameSerializer::class,
|
|
||||||
MetaSerializer::class
|
|
||||||
)
|
)
|
||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.io.serialization.MetaSerializer
|
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.vis.*
|
||||||
import hep.dataforge.vis.common.AbstractVisualGroup
|
|
||||||
import hep.dataforge.vis.common.StyleSheet
|
|
||||||
import hep.dataforge.vis.common.VisualObject
|
|
||||||
import hep.dataforge.vis.common.set
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
|
interface PrototypeHolder {
|
||||||
|
val parent: VisualGroup?
|
||||||
|
val prototypes: MutableVisualGroup?
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents 3-dimensional Visual Group
|
* Represents 3-dimensional Visual Group
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("group.3d")
|
@SerialName("group.3d")
|
||||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||||
|
|
||||||
override var styleSheet: StyleSheet? = null
|
override var styleSheet: StyleSheet? = null
|
||||||
private set
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for templates visible inside this group
|
* A container for templates visible inside this group
|
||||||
*/
|
*/
|
||||||
var prototypes: VisualGroup3D? = null
|
@Serializable(PrototypesSerializer::class)
|
||||||
set(value) {
|
override var prototypes: MutableVisualGroup? = null
|
||||||
value?.parent = this
|
private set
|
||||||
field = value
|
|
||||||
}
|
/**
|
||||||
|
* Create or edit prototype node as a group
|
||||||
|
*/
|
||||||
|
fun prototypes(builder: MutableVisualGroup.() -> Unit): Unit {
|
||||||
|
(prototypes ?: Prototypes().also {
|
||||||
|
attach(it)
|
||||||
|
prototypes = it
|
||||||
|
}).run(builder)
|
||||||
|
}
|
||||||
|
|
||||||
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
@ -55,38 +56,18 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
|||||||
private val _children = HashMap<NameToken, VisualObject>()
|
private val _children = HashMap<NameToken, VisualObject>()
|
||||||
override val children: Map<NameToken, VisualObject> get() = _children
|
override val children: Map<NameToken, VisualObject> get() = _children
|
||||||
|
|
||||||
// init {
|
|
||||||
// //Do after deserialization
|
|
||||||
// attachChildren()
|
|
||||||
// }
|
|
||||||
|
|
||||||
override fun attachChildren() {
|
override fun attachChildren() {
|
||||||
prototypes?.parent = this
|
prototypes?.parent = this
|
||||||
prototypes?.attachChildren()
|
prototypes?.attachChildren()
|
||||||
super.attachChildren()
|
super.attachChildren()
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Update or create stylesheet
|
|
||||||
*/
|
|
||||||
fun styleSheet(block: StyleSheet.() -> Unit) {
|
|
||||||
val res = styleSheet ?: StyleSheet(this).also { styleSheet = it }
|
|
||||||
res.block()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun removeChild(token: NameToken) {
|
override fun removeChild(token: NameToken) {
|
||||||
_children.remove(token)?.run { parent = null }
|
_children.remove(token)?.apply { parent = null }
|
||||||
childrenChanged(token.asName(), null)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setChild(token: NameToken, child: VisualObject) {
|
override fun setChild(token: NameToken, child: VisualObject) {
|
||||||
if (child.parent == null) {
|
|
||||||
child.parent = this
|
|
||||||
} else if (child.parent !== this) {
|
|
||||||
error("Can't reassign existing parent for $child")
|
|
||||||
}
|
|
||||||
_children[token] = child
|
_children[token] = child
|
||||||
childrenChanged(token.asName(), child)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// /**
|
// /**
|
||||||
@ -94,25 +75,13 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
|||||||
// */
|
// */
|
||||||
// override fun addStatic(child: VisualObject) = setChild(NameToken("@static(${child.hashCode()})"), child)
|
// override fun addStatic(child: VisualObject) = setChild(NameToken("@static(${child.hashCode()})"), child)
|
||||||
|
|
||||||
override fun createGroup(name: Name): VisualGroup3D {
|
override fun createGroup(): VisualGroup3D = VisualGroup3D()
|
||||||
return when {
|
|
||||||
name.isEmpty() -> error("Should be unreachable")
|
|
||||||
name.length == 1 -> {
|
|
||||||
val token = name.first()!!
|
|
||||||
when (val current = children[token]) {
|
|
||||||
null -> VisualGroup3D().also { setChild(token, it) }
|
|
||||||
is VisualGroup3D -> current
|
|
||||||
else -> error("Can't create group with name $name because it exists and not a group")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else -> createGroup(name.first()!!.asName()).createGroup(name.cutFirst())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
||||||
|
|
||||||
fun fromJson(json: String): VisualGroup3D =
|
fun parseJson(json: String): VisualGroup3D =
|
||||||
Visual3D.json.parse(serializer(), json).also { it.attachChildren() }
|
Visual3D.json.parse(serializer(), json).also { it.attachChildren() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -120,21 +89,50 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
|||||||
/**
|
/**
|
||||||
* Ger a prototype redirecting the request to the parent if prototype is not found
|
* Ger a prototype redirecting the request to the parent if prototype is not found
|
||||||
*/
|
*/
|
||||||
tailrec fun VisualGroup3D.getPrototype(name: Name): VisualObject3D? =
|
tailrec fun PrototypeHolder.getPrototype(name: Name): VisualObject3D? =
|
||||||
prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name)
|
prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create or edit prototype node as a group
|
* Define a group with given [name], attach it to this parent and return it.
|
||||||
*/
|
*/
|
||||||
inline fun VisualGroup3D.prototypes(builder: VisualGroup3D.() -> Unit): Unit {
|
fun MutableVisualGroup.group(name: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
|
||||||
(prototypes ?: VisualGroup3D().also { prototypes = it }).run(builder)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Define a group with given [key], attach it to this parent and return it.
|
|
||||||
*/
|
|
||||||
fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
|
|
||||||
VisualGroup3D().apply(action).also {
|
VisualGroup3D().apply(action).also {
|
||||||
set(key, it)
|
set(name, it)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal class Prototypes(
|
||||||
|
override var children: MutableMap<NameToken, VisualObject> = LinkedHashMap()
|
||||||
|
) : AbstractVisualGroup(), MutableVisualGroup, PrototypeHolder {
|
||||||
|
|
||||||
|
override var styleSheet: StyleSheet?
|
||||||
|
get() = null
|
||||||
|
set(_) {
|
||||||
|
error("Can't define stylesheet for prototypes block")
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun removeChild(token: NameToken) {
|
||||||
|
children.remove(token)
|
||||||
|
childrenChanged(token.asName(), null)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setChild(token: NameToken, child: VisualObject) {
|
||||||
|
children[token] = child
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun createGroup() = SimpleVisualGroup()
|
||||||
|
|
||||||
|
override var properties: Config?
|
||||||
|
get() = null
|
||||||
|
set(_) {
|
||||||
|
error("Can't define properties for prototypes block")
|
||||||
|
}
|
||||||
|
|
||||||
|
override val prototypes: MutableVisualGroup get() = this
|
||||||
|
|
||||||
|
override fun attachChildren() {
|
||||||
|
children.values.forEach {
|
||||||
|
it.parent = parent
|
||||||
|
(it as? VisualGroup)?.attachChildren()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -1,13 +1,15 @@
|
|||||||
@file:UseSerializers(Point3DSerializer::class, NameSerializer::class, NameTokenSerializer::class)
|
@file:UseSerializers(Point3DSerializer::class)
|
||||||
|
|
||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.NameSerializer
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.output.Renderer
|
import hep.dataforge.output.Renderer
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.values.ValueType
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.IGNORE_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.IGNORE_KEY
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
||||||
@ -25,7 +27,8 @@ interface VisualObject3D : VisualObject {
|
|||||||
companion object {
|
companion object {
|
||||||
|
|
||||||
val VISIBLE_KEY = "visible".asName()
|
val VISIBLE_KEY = "visible".asName()
|
||||||
// val SELECTED_KEY = "selected".asName()
|
|
||||||
|
// val SELECTED_KEY = "selected".asName()
|
||||||
val DETAIL_KEY = "detail".asName()
|
val DETAIL_KEY = "detail".asName()
|
||||||
val LAYER_KEY = "layer".asName()
|
val LAYER_KEY = "layer".asName()
|
||||||
val IGNORE_KEY = "ignore".asName()
|
val IGNORE_KEY = "ignore".asName()
|
||||||
@ -55,6 +58,22 @@ interface VisualObject3D : VisualObject {
|
|||||||
val xScale = scale + x
|
val xScale = scale + x
|
||||||
val yScale = scale + y
|
val yScale = scale + y
|
||||||
val zScale = scale + z
|
val zScale = scale + z
|
||||||
|
|
||||||
|
val descriptor by lazy {
|
||||||
|
NodeDescriptor {
|
||||||
|
defineValue(VISIBLE_KEY) {
|
||||||
|
type(ValueType.BOOLEAN)
|
||||||
|
default(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
defineItem(Material3D.MATERIAL_KEY.toString(), Material3D.descriptor)
|
||||||
|
|
||||||
|
// Material3D.MATERIAL_COLOR_KEY put "#ffffff"
|
||||||
|
// Material3D.MATERIAL_OPACITY_KEY put 1.0
|
||||||
|
// Material3D.MATERIAL_WIREFRAME_KEY put false
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,10 +83,10 @@ interface VisualObject3D : VisualObject {
|
|||||||
var VisualObject3D.layer: Int
|
var VisualObject3D.layer: Int
|
||||||
get() = getProperty(LAYER_KEY).int ?: 0
|
get() = getProperty(LAYER_KEY).int ?: 0
|
||||||
set(value) {
|
set(value) {
|
||||||
setProperty(LAYER_KEY, value)
|
setProperty(LAYER_KEY, value.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Renderer<VisualObject3D>.render(meta: Meta = EmptyMeta, action: VisualGroup3D.() -> Unit) =
|
fun Renderer<VisualObject3D>.render(meta: Meta = Meta.EMPTY, action: VisualGroup3D.() -> Unit) =
|
||||||
render(VisualGroup3D().apply(action), meta)
|
render(VisualGroup3D().apply(action), meta)
|
||||||
|
|
||||||
// Common properties
|
// Common properties
|
||||||
@ -86,7 +105,7 @@ enum class RotationOrder {
|
|||||||
*/
|
*/
|
||||||
var VisualObject3D.rotationOrder: RotationOrder
|
var VisualObject3D.rotationOrder: RotationOrder
|
||||||
get() = getProperty(VisualObject3D.rotationOrder).enum<RotationOrder>() ?: RotationOrder.XYZ
|
get() = getProperty(VisualObject3D.rotationOrder).enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||||
set(value) = setProperty(VisualObject3D.rotationOrder, value.name)
|
set(value) = setProperty(VisualObject3D.rotationOrder, value.name.asValue())
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -94,19 +113,19 @@ var VisualObject3D.rotationOrder: RotationOrder
|
|||||||
*/
|
*/
|
||||||
var VisualObject3D.detail: Int?
|
var VisualObject3D.detail: Int?
|
||||||
get() = getProperty(DETAIL_KEY, false).int
|
get() = getProperty(DETAIL_KEY, false).int
|
||||||
set(value) = setProperty(DETAIL_KEY, value)
|
set(value) = setProperty(DETAIL_KEY, value?.asValue())
|
||||||
|
|
||||||
var VisualObject.visible: Boolean?
|
var VisualObject.visible: Boolean?
|
||||||
get() = getProperty(VISIBLE_KEY).boolean
|
get() = getProperty(VISIBLE_KEY).boolean
|
||||||
set(value) = setProperty(VISIBLE_KEY, value)
|
set(value) = setProperty(VISIBLE_KEY, value?.asValue())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this property is true, the object will be ignored on render.
|
* If this property is true, the object will be ignored on render.
|
||||||
* Property is not inherited.
|
* Property is not inherited.
|
||||||
*/
|
*/
|
||||||
var VisualObject.ignore: Boolean?
|
var VisualObject.ignore: Boolean?
|
||||||
get() = getProperty(IGNORE_KEY,false).boolean
|
get() = getProperty(IGNORE_KEY, false).boolean
|
||||||
set(value) = setProperty(IGNORE_KEY, value)
|
set(value) = setProperty(IGNORE_KEY, value?.asValue())
|
||||||
|
|
||||||
//var VisualObject.selected: Boolean?
|
//var VisualObject.selected: Boolean?
|
||||||
// get() = getProperty(SELECTED_KEY).boolean
|
// get() = getProperty(SELECTED_KEY).boolean
|
||||||
|
@ -1,10 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial
|
|
||||||
|
|
||||||
import kotlin.math.PI
|
|
||||||
|
|
||||||
object World {
|
|
||||||
val ZERO = Point3D(0.0, 0.0, 0.0)
|
|
||||||
val ONE = Point3D(1.0, 1.0, 1.0)
|
|
||||||
}
|
|
||||||
|
|
||||||
const val PI2: Float = 2 * PI.toFloat()
|
|
@ -1,9 +1,16 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.buildMeta
|
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
|
import kotlin.math.PI
|
||||||
|
|
||||||
|
object World {
|
||||||
|
val ZERO = Point3D(0.0, 0.0, 0.0)
|
||||||
|
val ONE = Point3D(1.0, 1.0, 1.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
const val PI2: Float = 2 * PI.toFloat()
|
||||||
|
|
||||||
expect class Point2D(x: Number, y: Number) {
|
expect class Point2D(x: Number, y: Number) {
|
||||||
var x: Double
|
var x: Double
|
||||||
@ -13,7 +20,7 @@ expect class Point2D(x: Number, y: Number) {
|
|||||||
operator fun Point2D.component1() = x
|
operator fun Point2D.component1() = x
|
||||||
operator fun Point2D.component2() = y
|
operator fun Point2D.component2() = y
|
||||||
|
|
||||||
fun Point2D.toMeta() = buildMeta {
|
fun Point2D.toMeta() = Meta {
|
||||||
VisualObject3D.x put x
|
VisualObject3D.x put x
|
||||||
VisualObject3D.y put y
|
VisualObject3D.y put y
|
||||||
}
|
}
|
||||||
@ -34,7 +41,7 @@ operator fun Point3D.component3() = z
|
|||||||
|
|
||||||
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
||||||
|
|
||||||
fun Point3D.toMeta() = buildMeta {
|
fun Point3D.toMeta() = Meta {
|
||||||
VisualObject3D.x put x
|
VisualObject3D.x put x
|
||||||
VisualObject3D.y put y
|
VisualObject3D.y put y
|
||||||
VisualObject3D.z put z
|
VisualObject3D.z put z
|
||||||
|
@ -1,17 +1,19 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.descriptor
|
import hep.dataforge.meta.double
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
|
import hep.dataforge.vis.VisualGroup
|
||||||
|
import hep.dataforge.vis.VisualObject
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.internal.DoubleSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.internal.StringDescriptor
|
import kotlinx.serialization.builtins.nullable
|
||||||
import kotlinx.serialization.internal.nullable
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
|
||||||
inline fun <R> Decoder.decodeStructure(
|
inline fun <R> Decoder.decodeStructure(
|
||||||
desc: SerialDescriptor,
|
desc: SerialDescriptor,
|
||||||
vararg typeParams: KSerializer<*> = emptyArray(),
|
vararg typeParams: KSerializer<*> = emptyArray(),
|
||||||
crossinline block: CompositeDecoder.() -> R
|
crossinline block: CompositeDecoder.() -> R
|
||||||
): R {
|
): R {
|
||||||
val decoder = beginStructure(desc, *typeParams)
|
val decoder = beginStructure(desc, *typeParams)
|
||||||
val res = decoder.block()
|
val res = decoder.block()
|
||||||
@ -31,7 +33,7 @@ inline fun Encoder.encodeStructure(
|
|||||||
|
|
||||||
@Serializer(Point3D::class)
|
@Serializer(Point3D::class)
|
||||||
object Point3DSerializer : KSerializer<Point3D> {
|
object Point3DSerializer : KSerializer<Point3D> {
|
||||||
override val descriptor: SerialDescriptor = descriptor("hep.dataforge.vis.spatial.Point3D") {
|
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
||||||
double("x", true)
|
double("x", true)
|
||||||
double("y", true)
|
double("y", true)
|
||||||
double("z", true)
|
double("z", true)
|
||||||
@ -45,28 +47,28 @@ object Point3DSerializer : KSerializer<Point3D> {
|
|||||||
loop@ while (true) {
|
loop@ while (true) {
|
||||||
when (val i = decodeElementIndex(descriptor)) {
|
when (val i = decodeElementIndex(descriptor)) {
|
||||||
CompositeDecoder.READ_DONE -> break@loop
|
CompositeDecoder.READ_DONE -> break@loop
|
||||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, DoubleSerializer.nullable) ?: 0.0
|
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, DoubleSerializer.nullable) ?: 0.0
|
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||||
2 -> z = decodeNullableSerializableElement(descriptor, 2, DoubleSerializer.nullable) ?: 0.0
|
2 -> z = decodeNullableSerializableElement(descriptor, 2, Double.serializer().nullable) ?: 0.0
|
||||||
else -> throw SerializationException("Unknown index $i")
|
else -> throw SerializationException("Unknown index $i")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Point3D(x?:0.0, y?:0.0, z?:0.0)
|
return Point3D(x ?: 0.0, y ?: 0.0, z ?: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: Point3D) {
|
override fun serialize(encoder: Encoder, value: Point3D) {
|
||||||
encoder.encodeStructure(descriptor) {
|
encoder.encodeStructure(descriptor) {
|
||||||
if (obj.x != 0.0) encodeDoubleElement(descriptor, 0, obj.x)
|
if (value.x != 0.0) encodeDoubleElement(descriptor, 0, value.x)
|
||||||
if (obj.y != 0.0) encodeDoubleElement(descriptor, 1, obj.y)
|
if (value.y != 0.0) encodeDoubleElement(descriptor, 1, value.y)
|
||||||
if (obj.z != 0.0) encodeDoubleElement(descriptor, 2, obj.z)
|
if (value.z != 0.0) encodeDoubleElement(descriptor, 2, value.z)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializer(Point2D::class)
|
@Serializer(Point2D::class)
|
||||||
object Point2DSerializer : KSerializer<Point2D> {
|
object Point2DSerializer : KSerializer<Point2D> {
|
||||||
override val descriptor: SerialDescriptor = descriptor("hep.dataforge.vis.spatial.Point2D") {
|
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
||||||
double("x", true)
|
double("x", true)
|
||||||
double("y", true)
|
double("y", true)
|
||||||
}
|
}
|
||||||
@ -78,32 +80,48 @@ object Point2DSerializer : KSerializer<Point2D> {
|
|||||||
loop@ while (true) {
|
loop@ while (true) {
|
||||||
when (val i = decodeElementIndex(descriptor)) {
|
when (val i = decodeElementIndex(descriptor)) {
|
||||||
CompositeDecoder.READ_DONE -> break@loop
|
CompositeDecoder.READ_DONE -> break@loop
|
||||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, DoubleSerializer.nullable) ?: 0.0
|
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, DoubleSerializer.nullable) ?: 0.0
|
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||||
else -> throw SerializationException("Unknown index $i")
|
else -> throw SerializationException("Unknown index $i")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Point2D(x?:0.0, y?:0.0)
|
return Point2D(x ?: 0.0, y ?: 0.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: Point2D) {
|
override fun serialize(encoder: Encoder, value: Point2D) {
|
||||||
encoder.encodeStructure(descriptor) {
|
encoder.encodeStructure(descriptor) {
|
||||||
if (obj.x != 0.0) encodeDoubleElement(descriptor, 0, obj.x)
|
if (value.x != 0.0) encodeDoubleElement(descriptor, 0, value.x)
|
||||||
if (obj.y != 0.0) encodeDoubleElement(descriptor, 1, obj.y)
|
if (value.y != 0.0) encodeDoubleElement(descriptor, 1, value.y)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Serializer(NameToken::class)
|
@Serializer(MutableVisualGroup::class)
|
||||||
object NameTokenSerializer : KSerializer<NameToken> {
|
internal object PrototypesSerializer : KSerializer<MutableVisualGroup> {
|
||||||
override val descriptor: SerialDescriptor = StringDescriptor.withName("NameToken")
|
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): NameToken {
|
private val mapSerializer: KSerializer<Map<NameToken, VisualObject>> =
|
||||||
return decoder.decodeString().toName().first()!!
|
MapSerializer(
|
||||||
|
NameToken.serializer(),
|
||||||
|
VisualObject.serializer()
|
||||||
|
)
|
||||||
|
|
||||||
|
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||||
|
|
||||||
|
override fun deserialize(decoder: Decoder): MutableVisualGroup {
|
||||||
|
val map = mapSerializer.deserialize(decoder)
|
||||||
|
return Prototypes(map as? MutableMap<NameToken, VisualObject> ?: LinkedHashMap(map))
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun serialize(encoder: Encoder, obj: NameToken) {
|
override fun serialize(encoder: Encoder, value: MutableVisualGroup) {
|
||||||
encoder.encodeString(obj.toString())
|
mapSerializer.serialize(encoder, value.children)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VisualObject.stringify(): String = Visual3D.json.stringify(VisualObject.serializer(), this)
|
||||||
|
|
||||||
|
fun VisualObject.Companion.parseJson(str: String) = Visual3D.json.parse(VisualObject.serializer(), str).also {
|
||||||
|
if(it is VisualGroup){
|
||||||
|
it.attachChildren()
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,16 +2,13 @@ package hep.dataforge.vis.spatial.specifications
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
|
||||||
class AxesSpec(override val config: Config) : Specific {
|
class Axes : Scheme() {
|
||||||
var visible by boolean(!config.isEmpty())
|
var visible by boolean(!config.isEmpty())
|
||||||
var size by double(AXIS_SIZE)
|
var size by double(AXIS_SIZE)
|
||||||
var width by double(AXIS_WIDTH)
|
var width by double(AXIS_WIDTH)
|
||||||
|
|
||||||
companion object : Specification<AxesSpec> {
|
companion object : SchemeSpec<Axes>(::Axes) {
|
||||||
override fun wrap(config: Config): AxesSpec = AxesSpec(config)
|
|
||||||
|
|
||||||
const val AXIS_SIZE = 1000.0
|
const val AXIS_SIZE = 1000.0
|
||||||
const val AXIS_WIDTH = 3.0
|
const val AXIS_WIDTH = 3.0
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,10 +1,14 @@
|
|||||||
package hep.dataforge.vis.spatial.specifications
|
package hep.dataforge.vis.spatial.specifications
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.Scheme
|
||||||
|
import hep.dataforge.meta.SchemeSpec
|
||||||
|
import hep.dataforge.meta.double
|
||||||
|
import hep.dataforge.meta.int
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
class CameraSpec(override val config: Config) : Specific {
|
class Camera : Scheme() {
|
||||||
var fov by int(FIELD_OF_VIEW)
|
var fov by int(FIELD_OF_VIEW)
|
||||||
|
|
||||||
//var aspect by double(1.0)
|
//var aspect by double(1.0)
|
||||||
var nearClip by double(NEAR_CLIP)
|
var nearClip by double(NEAR_CLIP)
|
||||||
var farClip by double(FAR_CLIP)
|
var farClip by double(FAR_CLIP)
|
||||||
@ -14,11 +18,10 @@ class CameraSpec(override val config: Config) : Specific {
|
|||||||
var latitude by double(INITIAL_LATITUDE)
|
var latitude by double(INITIAL_LATITUDE)
|
||||||
val zenith: Double get() = PI / 2 - latitude
|
val zenith: Double get() = PI / 2 - latitude
|
||||||
|
|
||||||
companion object : Specification<CameraSpec> {
|
companion object : SchemeSpec<Camera>(::Camera) {
|
||||||
override fun wrap(config: Config): CameraSpec = CameraSpec(config)
|
|
||||||
const val INITIAL_DISTANCE = 300.0
|
const val INITIAL_DISTANCE = 300.0
|
||||||
const val INITIAL_AZIMUTH = 0.0
|
const val INITIAL_AZIMUTH = 0.0
|
||||||
const val INITIAL_LATITUDE = PI/6
|
const val INITIAL_LATITUDE = PI / 6
|
||||||
const val NEAR_CLIP = 0.1
|
const val NEAR_CLIP = 0.1
|
||||||
const val FAR_CLIP = 10000.0
|
const val FAR_CLIP = 10000.0
|
||||||
const val FIELD_OF_VIEW = 75
|
const val FIELD_OF_VIEW = 75
|
@ -0,0 +1,15 @@
|
|||||||
|
package hep.dataforge.vis.spatial.specifications
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Scheme
|
||||||
|
import hep.dataforge.meta.SchemeSpec
|
||||||
|
import hep.dataforge.meta.int
|
||||||
|
import hep.dataforge.meta.spec
|
||||||
|
|
||||||
|
class Canvas : Scheme() {
|
||||||
|
var axes by spec(Axes, Axes.empty())
|
||||||
|
var camera by spec(Camera, Camera.empty())
|
||||||
|
var controls by spec(Controls, Controls.empty())
|
||||||
|
var minSize by int(300)
|
||||||
|
|
||||||
|
companion object : SchemeSpec<Canvas>(::Canvas)
|
||||||
|
}
|
@ -1,15 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial.specifications
|
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
|
||||||
|
|
||||||
class CanvasSpec(override val config: Config) : Specific {
|
|
||||||
var axes by spec(AxesSpec)
|
|
||||||
var camera by spec(CameraSpec)
|
|
||||||
var controls by spec(ControlsSpec)
|
|
||||||
var minSize by int(300)
|
|
||||||
|
|
||||||
companion object: Specification<CanvasSpec>{
|
|
||||||
override fun wrap(config: Config): CanvasSpec = CanvasSpec(config)
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
@ -0,0 +1,9 @@
|
|||||||
|
package hep.dataforge.vis.spatial.specifications
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Scheme
|
||||||
|
import hep.dataforge.meta.SchemeSpec
|
||||||
|
|
||||||
|
|
||||||
|
class Controls : Scheme() {
|
||||||
|
companion object : SchemeSpec<Controls>(::Controls)
|
||||||
|
}
|
@ -1,11 +0,0 @@
|
|||||||
package hep.dataforge.vis.spatial.specifications
|
|
||||||
|
|
||||||
import hep.dataforge.meta.Config
|
|
||||||
import hep.dataforge.meta.Specific
|
|
||||||
import hep.dataforge.meta.Specification
|
|
||||||
|
|
||||||
class ControlsSpec(override val config: Config) : Specific {
|
|
||||||
companion object : Specification<ControlsSpec> {
|
|
||||||
override fun wrap(config: Config): ControlsSpec = ControlsSpec(config)
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,9 +2,9 @@ package hep.dataforge.vis.spatial.transform
|
|||||||
|
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vis.common.MutableVisualGroup
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
import hep.dataforge.vis.common.VisualGroup
|
import hep.dataforge.vis.VisualGroup
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
|
|
||||||
internal fun mergeChild(parent: VisualGroup, child: VisualObject): VisualObject {
|
internal fun mergeChild(parent: VisualGroup, child: VisualObject): VisualObject {
|
||||||
|
@ -2,11 +2,10 @@ package hep.dataforge.vis.spatial.transform
|
|||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vis.common.MutableVisualGroup
|
import hep.dataforge.vis.MutableVisualGroup
|
||||||
import hep.dataforge.vis.common.VisualGroup
|
import hep.dataforge.vis.VisualGroup
|
||||||
import hep.dataforge.vis.spatial.Proxy
|
import hep.dataforge.vis.spatial.Proxy
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
import hep.dataforge.vis.spatial.prototypes
|
|
||||||
|
|
||||||
object UnRef : VisualTreeTransform<VisualGroup3D>() {
|
object UnRef : VisualTreeTransform<VisualGroup3D>() {
|
||||||
private fun VisualGroup.countRefs(): Map<Name, Int> {
|
private fun VisualGroup.countRefs(): Map<Name, Int> {
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package hep.dataforge.vis.spatial.transform
|
package hep.dataforge.vis.spatial.transform
|
||||||
|
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A root class for [VisualObject] tree optimization
|
* A root class for [VisualObject] tree optimization
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.io.toMeta
|
|
||||||
import hep.dataforge.meta.MetaItem
|
import hep.dataforge.meta.MetaItem
|
||||||
import hep.dataforge.meta.getIndexed
|
import hep.dataforge.meta.getIndexed
|
||||||
|
import hep.dataforge.meta.node
|
||||||
|
import hep.dataforge.meta.toMetaItem
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -26,9 +27,9 @@ class ConvexTest {
|
|||||||
val convex = group.first() as Convex
|
val convex = group.first() as Convex
|
||||||
|
|
||||||
val json = Visual3D.json.toJson(Convex.serializer(), convex)
|
val json = Visual3D.json.toJson(Convex.serializer(), convex)
|
||||||
val meta = json.toMeta()
|
val meta = json.toMetaItem().node!!
|
||||||
|
|
||||||
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D()}
|
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
||||||
assertEquals(8, points.count())
|
assertEquals(8, points.count())
|
||||||
|
|
||||||
assertEquals(8, convex.points.size)
|
assertEquals(8, convex.points.size)
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.common.get
|
import hep.dataforge.vis.get
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial
|
|||||||
import hep.dataforge.meta.int
|
import hep.dataforge.meta.int
|
||||||
import hep.dataforge.meta.set
|
import hep.dataforge.meta.set
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vis.common.useStyle
|
import hep.dataforge.vis.useStyle
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
@ -1,12 +1,12 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.vis.spatial.Visual3D.Companion.json
|
import hep.dataforge.names.toName
|
||||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
import hep.dataforge.vis.VisualObject
|
||||||
|
import hep.dataforge.vis.get
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
class SerializationTest {
|
class SerializationTest {
|
||||||
@ImplicitReflectionSerializer
|
|
||||||
@Test
|
@Test
|
||||||
fun testCubeSerialization() {
|
fun testCubeSerialization() {
|
||||||
val cube = Box(100f, 100f, 100f).apply {
|
val cube = Box(100f, 100f, 100f).apply {
|
||||||
@ -14,9 +14,30 @@ class SerializationTest {
|
|||||||
x = 100
|
x = 100
|
||||||
z = -100
|
z = -100
|
||||||
}
|
}
|
||||||
val string = json.stringify(Box.serializer(), cube)
|
val string = cube.stringify()
|
||||||
println(string)
|
println(string)
|
||||||
val newCube = json.parse(Box.serializer(), string)
|
val newCube = VisualObject.parseJson(string)
|
||||||
assertEquals(cube.config, newCube.config)
|
assertEquals(cube.config, newCube.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testProxySerialization() {
|
||||||
|
val cube = Box(100f, 100f, 100f).apply {
|
||||||
|
color(222)
|
||||||
|
x = 100
|
||||||
|
z = -100
|
||||||
|
}
|
||||||
|
val group = VisualGroup3D().apply {
|
||||||
|
proxy("cube", cube)
|
||||||
|
proxyGroup("pg", "pg.content".toName()){
|
||||||
|
sphere(50){
|
||||||
|
x = -100
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val string = group.stringify()
|
||||||
|
println(string)
|
||||||
|
val reconstructed = VisualGroup3D.parseJson(string)
|
||||||
|
assertEquals(group["cube"]?.config, reconstructed["cube"]?.config)
|
||||||
|
}
|
||||||
}
|
}
|
@ -2,17 +2,17 @@ package hep.dataforge.vis.spatial.three
|
|||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.getProperty
|
||||||
import hep.dataforge.meta.string
|
import hep.dataforge.meta.string
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.output.Renderer
|
import hep.dataforge.output.Renderer
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
import hep.dataforge.vis.spatial.specifications.CameraSpec
|
import hep.dataforge.vis.spatial.specifications.Camera
|
||||||
import hep.dataforge.vis.spatial.specifications.CanvasSpec
|
import hep.dataforge.vis.spatial.specifications.Canvas
|
||||||
import hep.dataforge.vis.spatial.specifications.ControlsSpec
|
import hep.dataforge.vis.spatial.specifications.Controls
|
||||||
import hep.dataforge.vis.spatial.three.ThreeMaterials.HIGHLIGHT_MATERIAL
|
import hep.dataforge.vis.spatial.three.ThreeMaterials.HIGHLIGHT_MATERIAL
|
||||||
import info.laht.threekt.WebGLRenderer
|
import info.laht.threekt.WebGLRenderer
|
||||||
import info.laht.threekt.cameras.PerspectiveCamera
|
import info.laht.threekt.cameras.PerspectiveCamera
|
||||||
@ -39,7 +39,7 @@ import kotlin.math.sin
|
|||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: CanvasSpec) : Renderer<VisualObject3D> {
|
class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val canvas: Canvas) : Renderer<VisualObject3D> {
|
||||||
|
|
||||||
override val context: Context get() = three.context
|
override val context: Context get() = three.context
|
||||||
|
|
||||||
@ -53,15 +53,15 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
|
|
||||||
var clickListener: ((Name) -> Unit)? = null
|
var clickListener: ((Name) -> Unit)? = null
|
||||||
|
|
||||||
val axes = AxesHelper(spec.axes.size.toInt()).apply {
|
val axes = AxesHelper(canvas.axes.size.toInt()).apply {
|
||||||
visible = spec.axes.visible
|
visible = canvas.axes.visible
|
||||||
}
|
}
|
||||||
|
|
||||||
val scene: Scene = Scene().apply {
|
val scene: Scene = Scene().apply {
|
||||||
add(axes)
|
add(axes)
|
||||||
}
|
}
|
||||||
|
|
||||||
val camera = buildCamera(spec.camera)
|
val camera = buildCamera(canvas.camera)
|
||||||
|
|
||||||
init {
|
init {
|
||||||
element.clear()
|
element.clear()
|
||||||
@ -90,7 +90,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addControls(renderer.domElement, spec.controls)
|
addControls(renderer.domElement, canvas.controls)
|
||||||
|
|
||||||
fun animate() {
|
fun animate() {
|
||||||
val mesh = pick()
|
val mesh = pick()
|
||||||
@ -108,7 +108,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
|
|
||||||
element.appendChild(renderer.domElement)
|
element.appendChild(renderer.domElement)
|
||||||
|
|
||||||
renderer.setSize(max(spec.minSize, element.offsetWidth), max(spec.minSize, element.offsetWidth))
|
renderer.setSize(max(canvas.minSize, element.offsetWidth), max(canvas.minSize, element.offsetWidth))
|
||||||
|
|
||||||
element.onresize = {
|
element.onresize = {
|
||||||
renderer.setSize(element.offsetWidth, element.offsetWidth)
|
renderer.setSize(element.offsetWidth, element.offsetWidth)
|
||||||
@ -142,7 +142,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun buildCamera(spec: CameraSpec) = PerspectiveCamera(
|
private fun buildCamera(spec: Camera) = PerspectiveCamera(
|
||||||
spec.fov,
|
spec.fov,
|
||||||
1.0,
|
1.0,
|
||||||
spec.nearClip,
|
spec.nearClip,
|
||||||
@ -153,8 +153,8 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
translateZ(spec.distance * sin(spec.zenith) * cos(spec.azimuth))
|
translateZ(spec.distance * sin(spec.zenith) * cos(spec.azimuth))
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun addControls(element: Node, controlsSpec: ControlsSpec) {
|
private fun addControls(element: Node, controls: Controls) {
|
||||||
when (controlsSpec["type"].string) {
|
when (controls.getProperty("type").string) {
|
||||||
"trackball" -> TrackballControls(camera, element)
|
"trackball" -> TrackballControls(camera, element)
|
||||||
else -> OrbitControls(camera, element)
|
else -> OrbitControls(camera, element)
|
||||||
}
|
}
|
||||||
@ -211,5 +211,9 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ThreePlugin.output(element: HTMLElement, spec: CanvasSpec = CanvasSpec.empty()): ThreeCanvas =
|
fun ThreePlugin.output(element: HTMLElement, spec: Canvas = Canvas.empty()): ThreeCanvas =
|
||||||
ThreeCanvas(element, this, spec)
|
ThreeCanvas(element, this, spec)
|
||||||
|
|
||||||
|
fun ThreePlugin.render(element: HTMLElement, obj: VisualObject3D, spec: Canvas = Canvas.empty()): Unit =
|
||||||
|
output(element, spec).render(obj)
|
||||||
|
|
||||||
|
@ -0,0 +1,56 @@
|
|||||||
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
|
import hep.dataforge.vis.spatial.specifications.Canvas
|
||||||
|
import kotlinx.html.id
|
||||||
|
import org.w3c.dom.HTMLElement
|
||||||
|
import react.RBuilder
|
||||||
|
import react.RComponent
|
||||||
|
import react.RProps
|
||||||
|
import react.RState
|
||||||
|
import react.dom.div
|
||||||
|
import kotlin.browser.document
|
||||||
|
import kotlin.dom.clear
|
||||||
|
|
||||||
|
interface ThreeCanvasProps : RProps {
|
||||||
|
var obj: VisualObject3D
|
||||||
|
var canvasId: String
|
||||||
|
var options: Canvas
|
||||||
|
}
|
||||||
|
|
||||||
|
class ThreeCanvasComponent : RComponent<ThreeCanvasProps, RState>() {
|
||||||
|
|
||||||
|
private val three: ThreePlugin = Global.plugins.fetch(ThreePlugin)
|
||||||
|
|
||||||
|
override fun componentDidMount() {
|
||||||
|
val element = document.getElementById(props.canvasId) as? HTMLElement
|
||||||
|
?: error("Element with id 'canvas' not found on page")
|
||||||
|
val output = three.output(element, props.options)
|
||||||
|
output.render(props.obj)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun componentWillUnmount() {
|
||||||
|
val element = document.getElementById(props.canvasId) as? HTMLElement
|
||||||
|
?: error("Element with id 'canvas' not found on page")
|
||||||
|
element.clear()
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun RBuilder.render() {
|
||||||
|
div {
|
||||||
|
attrs {
|
||||||
|
id = props.canvasId
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun RBuilder.threeCanvas(object3D: VisualObject3D, id: String = "threeCanvas", options: Canvas.() -> Unit = {}) {
|
||||||
|
child(ThreeCanvasComponent::class) {
|
||||||
|
attrs {
|
||||||
|
this.obj = object3D
|
||||||
|
this.canvasId = id
|
||||||
|
this.options = Canvas.invoke(options)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial.three
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.startsWith
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_KEY
|
||||||
import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.TYPE
|
import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.TYPE
|
||||||
|
@ -2,8 +2,8 @@ package hep.dataforge.vis.spatial.three
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import info.laht.threekt.materials.LineBasicMaterial
|
import info.laht.threekt.materials.LineBasicMaterial
|
||||||
import info.laht.threekt.materials.Material
|
import info.laht.threekt.materials.Material
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial.three
|
|||||||
import hep.dataforge.context.*
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
@ -2,9 +2,8 @@
|
|||||||
|
|
||||||
package hep.dataforge.vis.spatial.three
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
import hep.dataforge.io.serialization.ConfigSerializer
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vis.common.AbstractVisualObject
|
import hep.dataforge.vis.AbstractVisualObject
|
||||||
import hep.dataforge.vis.spatial.Point3D
|
import hep.dataforge.vis.spatial.Point3D
|
||||||
import hep.dataforge.vis.spatial.Point3DSerializer
|
import hep.dataforge.vis.spatial.Point3DSerializer
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
@ -26,7 +25,6 @@ class CustomThreeVisualObject(val threeFactory: ThreeFactory<VisualObject3D>) :
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
@Serializable(ConfigSerializer::class)
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override fun toObject3D(): Object3D = threeFactory(this)
|
override fun toObject3D(): Object3D = threeFactory(this)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
@file:JsModule("@hi-level/three-csg")
|
@file:JsModule("three-csg-ts")
|
||||||
@file:JsNonModule
|
@file:JsNonModule
|
||||||
@file:Suppress(
|
@file:Suppress(
|
||||||
"INTERFACE_WITH_SUPERCLASS",
|
"INTERFACE_WITH_SUPERCLASS",
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package hep.dataforge.vis.spatial.three
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
import hep.dataforge.js.requireJS
|
import hep.dataforge.js.requireJS
|
||||||
import hep.dataforge.vis.js.editor.accordion
|
import hep.dataforge.vis.editor.accordion
|
||||||
import hep.dataforge.vis.spatial.Visual3D
|
import hep.dataforge.vis.spatial.Visual3D
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
import kotlinx.html.InputType
|
import kotlinx.html.InputType
|
||||||
|
@ -5,7 +5,7 @@ import hep.dataforge.context.ContextAware
|
|||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.output.Renderer
|
import hep.dataforge.output.Renderer
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
import hep.dataforge.vis.spatial.specifications.CanvasSpec
|
import hep.dataforge.vis.spatial.specifications.Canvas
|
||||||
import javafx.application.Platform
|
import javafx.application.Platform
|
||||||
import javafx.beans.property.ObjectProperty
|
import javafx.beans.property.ObjectProperty
|
||||||
import javafx.beans.property.SimpleObjectProperty
|
import javafx.beans.property.SimpleObjectProperty
|
||||||
@ -14,7 +14,7 @@ import javafx.scene.paint.Color
|
|||||||
import org.fxyz3d.scene.Axes
|
import org.fxyz3d.scene.Axes
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class FXCanvas3D(val plugin: FX3DPlugin, val spec: CanvasSpec = CanvasSpec.empty()) :
|
class FXCanvas3D(val plugin: FX3DPlugin, val spec: Canvas = Canvas.empty()) :
|
||||||
Fragment(), Renderer<VisualObject3D>, ContextAware {
|
Fragment(), Renderer<VisualObject3D>, ContextAware {
|
||||||
|
|
||||||
override val context: Context get() = plugin.context
|
override val context: Context get() = plugin.context
|
||||||
|
@ -5,7 +5,7 @@ import hep.dataforge.meta.double
|
|||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.int
|
import hep.dataforge.meta.int
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.vis.common.Colors
|
import hep.dataforge.vis.Colors
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import javafx.scene.paint.Color
|
import javafx.scene.paint.Color
|
||||||
import javafx.scene.paint.Material
|
import javafx.scene.paint.Material
|
||||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial.fx
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.spatial.Proxy
|
import hep.dataforge.vis.spatial.Proxy
|
||||||
import javafx.scene.Group
|
import javafx.scene.Group
|
||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package hep.dataforge.vis.spatial.fx
|
package hep.dataforge.vis.spatial.fx
|
||||||
|
|
||||||
import hep.dataforge.vis.spatial.specifications.CameraSpec
|
|
||||||
import javafx.beans.InvalidationListener
|
import javafx.beans.InvalidationListener
|
||||||
import javafx.beans.property.SimpleDoubleProperty
|
import javafx.beans.property.SimpleDoubleProperty
|
||||||
import javafx.event.EventHandler
|
import javafx.event.EventHandler
|
||||||
@ -15,6 +14,7 @@ import javafx.scene.transform.Rotate
|
|||||||
import javafx.scene.transform.Translate
|
import javafx.scene.transform.Translate
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
import kotlin.math.*
|
import kotlin.math.*
|
||||||
|
import hep.dataforge.vis.spatial.specifications.Camera as CameraSpec
|
||||||
|
|
||||||
|
|
||||||
class OrbitControls internal constructor(camera: Camera, canvas: SubScene, spec: CameraSpec) {
|
class OrbitControls internal constructor(camera: Camera, canvas: SubScene, spec: CameraSpec) {
|
||||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.*
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.startsWith
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import javafx.application.Platform
|
import javafx.application.Platform
|
||||||
import javafx.beans.binding.ObjectBinding
|
import javafx.beans.binding.ObjectBinding
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
@ -1,23 +1,24 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.JSON_PRETTY
|
||||||
import hep.dataforge.vis.spatial.*
|
|
||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.json.*
|
import kotlinx.serialization.json.*
|
||||||
import kotlinx.serialization.modules.SerialModule
|
import kotlinx.serialization.modules.SerialModule
|
||||||
import kotlinx.serialization.modules.SerialModuleCollector
|
import kotlinx.serialization.modules.SerialModuleCollector
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
internal val SerialDescriptor.jsonType
|
private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
||||||
get() = when (this.kind) {
|
StructureKind.LIST -> "array"
|
||||||
StructureKind.LIST -> "array"
|
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||||
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||||
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||||
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
PrimitiveKind.BOOLEAN -> "boolean"
|
||||||
PrimitiveKind.BOOLEAN -> "boolean"
|
else -> "object"
|
||||||
else -> "object"
|
}
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun SerialDescriptor.isVisualObject() = serialName.startsWith("3d")||serialName.startsWith("group")
|
||||||
|
|
||||||
|
private const val definitionNode = "\$defs"
|
||||||
|
|
||||||
private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
||||||
val list = ArrayList<SerialDescriptor>()
|
val list = ArrayList<SerialDescriptor>()
|
||||||
@ -60,13 +61,16 @@ private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor>
|
|||||||
*/
|
*/
|
||||||
private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
||||||
|
|
||||||
if (descriptor.name in arrayOf(
|
if (descriptor.serialName in arrayOf(
|
||||||
"hep.dataforge.vis.spatial.Point3D",
|
"hep.dataforge.vis.spatial.Point3D",
|
||||||
|
"hep.dataforge.vis.spatial.Point3D?",
|
||||||
"hep.dataforge.vis.spatial.Point2D",
|
"hep.dataforge.vis.spatial.Point2D",
|
||||||
Meta::class.qualifiedName
|
"hep.dataforge.vis.spatial.Point2D?",
|
||||||
|
"hep.dataforge.meta.Meta",
|
||||||
|
"hep.dataforge.meta.Meta?"
|
||||||
)
|
)
|
||||||
) return json {
|
) return json {
|
||||||
"\$ref" to "#/definitions/${descriptor.name}"
|
"\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -79,37 +83,35 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso
|
|||||||
if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
||||||
val elementName = descriptor.getElementName(index)
|
val elementName = descriptor.getElementName(index)
|
||||||
|
|
||||||
properties[elementName] = when (elementName) {
|
val elementSchema = when (elementName) {
|
||||||
"templates" -> json {
|
"properties" -> json {
|
||||||
"\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D"
|
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
||||||
}
|
}
|
||||||
"properties" -> json {
|
"first", "second" -> json {
|
||||||
"\$ref" to "#/definitions/${Meta::class.qualifiedName}"
|
"\$ref" to "#/$definitionNode/children"
|
||||||
}
|
|
||||||
"first", "second" -> json{
|
|
||||||
"\$ref" to "#/definitions/children"
|
|
||||||
}
|
}
|
||||||
"styleSheet" -> json {
|
"styleSheet" -> json {
|
||||||
"type" to "object"
|
"type" to "object"
|
||||||
"additionalProperties" to json {
|
"additionalProperties" to json {
|
||||||
"\$ref" to "#/definitions/${Meta::class.qualifiedName}"
|
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
in arrayOf("children") -> json {
|
in arrayOf("children", "prototypes") -> json {
|
||||||
"type" to "object"
|
"type" to "object"
|
||||||
"additionalProperties" to json {
|
"additionalProperties" to json {
|
||||||
"\$ref" to "#/definitions/children"
|
"\$ref" to "#/$definitionNode/children"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> jsonSchema(child, context)
|
else -> jsonSchema(child, context)
|
||||||
}
|
}
|
||||||
|
properties[elementName] = elementSchema
|
||||||
|
|
||||||
if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
||||||
}
|
}
|
||||||
|
|
||||||
val jsonType = descriptor.jsonType
|
val jsonType = descriptor.getJsonType()
|
||||||
val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
||||||
"description" to JsonLiteral(descriptor.name),
|
"description" to JsonLiteral(descriptor.serialName),
|
||||||
"type" to JsonLiteral(jsonType)
|
"type" to JsonLiteral(jsonType)
|
||||||
)
|
)
|
||||||
if (isEnum) {
|
if (isEnum) {
|
||||||
@ -118,6 +120,11 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso
|
|||||||
}
|
}
|
||||||
when (jsonType) {
|
when (jsonType) {
|
||||||
"object" -> {
|
"object" -> {
|
||||||
|
if(descriptor.isVisualObject()) {
|
||||||
|
properties["type"] = json {
|
||||||
|
"const" to descriptor.serialName
|
||||||
|
}
|
||||||
|
}
|
||||||
objectData["properties"] = JsonObject(properties)
|
objectData["properties"] = JsonObject(properties)
|
||||||
val required = requiredProperties.map { JsonLiteral(it) }
|
val required = requiredProperties.map { JsonLiteral(it) }
|
||||||
if (required.isNotEmpty()) {
|
if (required.isNotEmpty()) {
|
||||||
@ -140,9 +147,9 @@ fun main() {
|
|||||||
"children" to json {
|
"children" to json {
|
||||||
"anyOf" to jsonArray {
|
"anyOf" to jsonArray {
|
||||||
context.enumerate(VisualObject3D::class).forEach {
|
context.enumerate(VisualObject3D::class).forEach {
|
||||||
if (it.name == "hep.dataforge.vis.spatial.VisualGroup3D") {
|
if (it.serialName == "hep.dataforge.vis.spatial.VisualGroup3D") {
|
||||||
+json {
|
+json {
|
||||||
"\$ref" to "#/definitions/${it.name}"
|
"\$ref" to "#/$definitionNode/${it.serialName}"
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
+jsonSchema(it, context)
|
+jsonSchema(it, context)
|
||||||
@ -150,18 +157,47 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
"hep.dataforge.vis.spatial.Point3D" to jsonSchema(Point3DSerializer.descriptor, context)
|
"hep.dataforge.meta.Meta" to json {
|
||||||
"hep.dataforge.vis.spatial.Point2D" to jsonSchema(Point2DSerializer.descriptor, context)
|
"type" to "object"
|
||||||
"hep.dataforge.vis.spatial.VisualGroup3D" to jsonSchema(VisualGroup3D.serializer().descriptor, context)
|
}
|
||||||
|
"hep.dataforge.vis.spatial.Point3D" to json {
|
||||||
|
"type" to "object"
|
||||||
|
"properties" to json {
|
||||||
|
"x" to json {
|
||||||
|
"type" to "number"
|
||||||
|
}
|
||||||
|
"y" to json {
|
||||||
|
"type" to "number"
|
||||||
|
}
|
||||||
|
"z" to json {
|
||||||
|
"type" to "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"hep.dataforge.vis.spatial.Point2D" to json {
|
||||||
|
"type" to "object"
|
||||||
|
"properties" to json {
|
||||||
|
"x" to json {
|
||||||
|
"type" to "number"
|
||||||
|
}
|
||||||
|
"y" to json {
|
||||||
|
"type" to "number"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"hep.dataforge.vis.spatial.VisualGroup3D" to jsonSchema(
|
||||||
|
VisualGroup3D.serializer().descriptor,
|
||||||
|
context
|
||||||
|
)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
println(
|
println(
|
||||||
Json.indented.stringify(
|
JSON_PRETTY.stringify(
|
||||||
JsonObjectSerializer,
|
JsonObjectSerializer,
|
||||||
json {
|
json {
|
||||||
"definitions" to definitions
|
"\$defs" to definitions
|
||||||
"\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D"
|
"\$ref" to "#/$definitionNode/hep.dataforge.vis.spatial.VisualGroup3D"
|
||||||
}
|
}
|
||||||
)
|
)
|
||||||
)
|
)
|
@ -1,11 +1,15 @@
|
|||||||
import org.openjfx.gradle.JavaFXOptions
|
import scientifik.DependencyConfiguration
|
||||||
|
import scientifik.FXModule
|
||||||
|
import scientifik.fx
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("scientifik.mpp")
|
||||||
id("org.openjfx.javafxplugin")
|
|
||||||
id("application")
|
id("application")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val fxVersion: String by rootProject.extra
|
||||||
|
fx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
@ -27,18 +31,9 @@ kotlin {
|
|||||||
api(project(":dataforge-vis-spatial-gdml"))
|
api(project(":dataforge-vis-spatial-gdml"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvmMain{
|
|
||||||
dependencies {
|
|
||||||
api("org.fxyz3d:fxyz3d:0.5.2")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClassName = "hep.dataforge.vis.spatial.gdml.demo.GDMLDemoAppKt"
|
mainClassName = "hep.dataforge.vis.spatial.gdml.demo.GDMLDemoAppKt"
|
||||||
}
|
}
|
||||||
|
|
||||||
configure<JavaFXOptions> {
|
|
||||||
modules("javafx.controls")
|
|
||||||
}
|
|
@ -1,7 +1,9 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml
|
package hep.dataforge.vis.spatial.gdml
|
||||||
|
|
||||||
|
import hep.dataforge.meta.setProperty
|
||||||
import hep.dataforge.meta.string
|
import hep.dataforge.meta.string
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import hep.dataforge.vis.spatial.gdml.demo.cubes
|
import hep.dataforge.vis.spatial.gdml.demo.cubes
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -12,7 +14,7 @@ class GDMLVisualTest {
|
|||||||
fun testPrototypeProperty() {
|
fun testPrototypeProperty() {
|
||||||
val gdml = cubes()
|
val gdml = cubes()
|
||||||
val visual = gdml.toVisual()
|
val visual = gdml.toVisual()
|
||||||
visual["composite000.segment0".toName()]?.setProperty(Material3D.MATERIAL_COLOR_KEY, "red")
|
visual["composite000.segment0".toName()]?.setProperty(Material3D.MATERIAL_COLOR_KEY, "red".asValue())
|
||||||
assertEquals("red", visual["composite000.segment0".toName()]?.getProperty(Material3D.MATERIAL_COLOR_KEY).string)
|
assertEquals("red", visual["composite000.segment0".toName()]?.getProperty(Material3D.MATERIAL_COLOR_KEY).string)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,14 +3,12 @@ package hep.dataforge.vis.spatial.gdml.demo
|
|||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.js.Application
|
import hep.dataforge.js.Application
|
||||||
import hep.dataforge.js.startApplication
|
import hep.dataforge.js.startApplication
|
||||||
import hep.dataforge.meta.buildMeta
|
|
||||||
import hep.dataforge.meta.withBottom
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.vis.common.VisualGroup
|
import hep.dataforge.vis.VisualGroup
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.VisualObject
|
||||||
import hep.dataforge.vis.js.editor.displayObjectTree
|
import hep.dataforge.vis.editor.objectTree
|
||||||
import hep.dataforge.vis.js.editor.displayPropertyEditor
|
import hep.dataforge.vis.editor.visualPropertyEditor
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
|
||||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY
|
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY
|
||||||
@ -23,7 +21,6 @@ import hep.dataforge.vis.spatial.gdml.toVisual
|
|||||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||||
import hep.dataforge.vis.spatial.three.displayCanvasControls
|
import hep.dataforge.vis.spatial.three.displayCanvasControls
|
||||||
import hep.dataforge.vis.spatial.three.output
|
import hep.dataforge.vis.spatial.three.output
|
||||||
import hep.dataforge.vis.spatial.visible
|
|
||||||
import org.w3c.dom.*
|
import org.w3c.dom.*
|
||||||
import org.w3c.files.FileList
|
import org.w3c.files.FileList
|
||||||
import org.w3c.files.FileReader
|
import org.w3c.files.FileReader
|
||||||
@ -139,7 +136,7 @@ private class GDMLDemoApp : Application {
|
|||||||
message("Converting GDML into DF-VIS format")
|
message("Converting GDML into DF-VIS format")
|
||||||
gdml.toVisual(gdmlConfiguration)
|
gdml.toVisual(gdmlConfiguration)
|
||||||
}
|
}
|
||||||
name.endsWith(".json") -> VisualGroup3D.fromJson(data)
|
name.endsWith(".json") -> VisualGroup3D.parseJson(data)
|
||||||
else -> {
|
else -> {
|
||||||
window.alert("File extension is not recognized: $name")
|
window.alert("File extension is not recognized: $name")
|
||||||
error("File extension is not recognized: $name")
|
error("File extension is not recognized: $name")
|
||||||
@ -163,33 +160,38 @@ private class GDMLDemoApp : Application {
|
|||||||
visual is VisualGroup -> visual[name] ?: return
|
visual is VisualGroup -> visual[name] ?: return
|
||||||
else -> return
|
else -> return
|
||||||
}
|
}
|
||||||
editorElement.displayPropertyEditor(name, child) { item ->
|
|
||||||
//val descriptorMeta = Material3D.descriptor
|
|
||||||
|
|
||||||
val properties = item.allProperties()
|
editorElement.visualPropertyEditor(name, child) {
|
||||||
val bottom = buildMeta {
|
VISIBLE_KEY put true
|
||||||
VISIBLE_KEY put (item.visible ?: true)
|
if (child is VisualObject3D) {
|
||||||
if (item is VisualObject3D) {
|
MATERIAL_COLOR_KEY put "#ffffff"
|
||||||
MATERIAL_COLOR_KEY put "#ffffff"
|
MATERIAL_OPACITY_KEY put 1.0
|
||||||
MATERIAL_OPACITY_KEY put 1.0
|
MATERIAL_WIREFRAME_KEY put false
|
||||||
MATERIAL_WIREFRAME_KEY put false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
properties.withBottom(bottom)
|
|
||||||
}
|
}
|
||||||
|
// editorElement.displayPropertyEditor(name, child) { item ->
|
||||||
|
// //val descriptorMeta = Material3D.descriptor
|
||||||
|
//
|
||||||
|
// val properties = item.allProperties()
|
||||||
|
// val bottom = Meta {
|
||||||
|
// VISIBLE_KEY put (item.visible ?: true)
|
||||||
|
// if (item is VisualObject3D) {
|
||||||
|
// MATERIAL_COLOR_KEY put "#ffffff"
|
||||||
|
// MATERIAL_OPACITY_KEY put 1.0
|
||||||
|
// MATERIAL_WIREFRAME_KEY put false
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// properties.withBottom(bottom)
|
||||||
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
// canvas.clickListener = ::selectElement
|
// canvas.clickListener = ::selectElement
|
||||||
|
|
||||||
//tree.visualObjectTree(visual, editor::propertyEditor)
|
//tree.visualObjectTree(visual, editor::propertyEditor)
|
||||||
treeElement.displayObjectTree(visual) { treeName ->
|
treeElement.objectTree(visual) { treeName ->
|
||||||
selectElement(treeName)
|
selectElement(treeName)
|
||||||
canvas.highlight(treeName)
|
canvas.highlight(treeName)
|
||||||
}
|
}
|
||||||
canvas.render(visual)
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
canvas.render(visual)
|
canvas.render(visual)
|
||||||
message(null)
|
message(null)
|
||||||
spinner(false)
|
spinner(false)
|
||||||
|
Before Width: | Height: | Size: 31 KiB After Width: | Height: | Size: 31 KiB |
@ -1,8 +1,8 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml.demo
|
package hep.dataforge.vis.spatial.gdml.demo
|
||||||
|
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.vis.fx.editor.VisualObjectEditorFragment
|
import hep.dataforge.vis.editor.VisualObjectEditorFragment
|
||||||
import hep.dataforge.vis.fx.editor.VisualObjectTreeFragment
|
import hep.dataforge.vis.editor.VisualObjectTreeFragment
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import hep.dataforge.vis.spatial.Visual3D
|
import hep.dataforge.vis.spatial.Visual3D
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
|
@ -1,5 +1,7 @@
|
|||||||
package hep.dataforge.vis.spatial.gdml.demo
|
package hep.dataforge.vis.spatial.gdml.demo
|
||||||
|
|
||||||
|
import hep.dataforge.meta.setProperty
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vis.spatial.Material3D
|
import hep.dataforge.vis.spatial.Material3D
|
||||||
import hep.dataforge.vis.spatial.Visual3D
|
import hep.dataforge.vis.spatial.Visual3D
|
||||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||||
@ -18,7 +20,7 @@ fun Visual3D.Companion.readFile(file: File): VisualGroup3D = when {
|
|||||||
|
|
||||||
solidConfiguration = { parent, solid ->
|
solidConfiguration = { parent, solid ->
|
||||||
if (solid.name == "cave") {
|
if (solid.name == "cave") {
|
||||||
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true)
|
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue())
|
||||||
}
|
}
|
||||||
if (parent.physVolumes.isNotEmpty()) {
|
if (parent.physVolumes.isNotEmpty()) {
|
||||||
useStyle("opaque") {
|
useStyle("opaque") {
|
||||||
@ -28,19 +30,19 @@ fun Visual3D.Companion.readFile(file: File): VisualGroup3D = when {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.extension == "json" -> VisualGroup3D.fromJson(file.readText())
|
file.extension == "json" -> VisualGroup3D.parseJson(file.readText())
|
||||||
file.name.endsWith("json.zip") -> {
|
file.name.endsWith("json.zip") -> {
|
||||||
file.inputStream().use {
|
file.inputStream().use {
|
||||||
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
||||||
val text = unzip.readAllBytes().decodeToString()
|
val text = unzip.readBytes().decodeToString()
|
||||||
VisualGroup3D.fromJson(text)
|
VisualGroup3D.parseJson(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.name.endsWith("json.gz") -> {
|
file.name.endsWith("json.gz") -> {
|
||||||
file.inputStream().use {
|
file.inputStream().use {
|
||||||
val unzip = GZIPInputStream(it)
|
val unzip = GZIPInputStream(it)
|
||||||
val text = unzip.readAllBytes().decodeToString()
|
val text = unzip.readBytes().decodeToString()
|
||||||
VisualGroup3D.fromJson(text)
|
VisualGroup3D.parseJson(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> error("Unknown extension ${file.extension}")
|
else -> error("Unknown extension ${file.extension}")
|
||||||
|
@ -5,6 +5,7 @@ import hep.dataforge.vis.spatial.VisualGroup3D
|
|||||||
import hep.dataforge.vis.spatial.gdml.LUnit
|
import hep.dataforge.vis.spatial.gdml.LUnit
|
||||||
import hep.dataforge.vis.spatial.gdml.readFile
|
import hep.dataforge.vis.spatial.gdml.readFile
|
||||||
import hep.dataforge.vis.spatial.gdml.toVisual
|
import hep.dataforge.vis.spatial.gdml.toVisual
|
||||||
|
import hep.dataforge.vis.spatial.stringify
|
||||||
import scientifik.gdml.GDML
|
import scientifik.gdml.GDML
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@ -14,6 +15,6 @@ fun main() {
|
|||||||
val visual = gdml.toVisual {
|
val visual = gdml.toVisual {
|
||||||
lUnit = LUnit.CM
|
lUnit = LUnit.CM
|
||||||
}
|
}
|
||||||
val json = Visual3D.json.stringify(VisualGroup3D.serializer(), visual)
|
val json = visual.stringify()
|
||||||
File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
|
File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
|
||||||
}
|
}
|
@ -1,15 +1,15 @@
|
|||||||
package hep.dataforge.vis.spatial
|
package hep.dataforge.vis.spatial
|
||||||
|
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import org.junit.Test
|
import org.junit.jupiter.api.Test
|
||||||
import kotlin.test.Ignore
|
import kotlin.test.Ignore
|
||||||
|
|
||||||
class FileSerializationTest {
|
class FileSerializationTest {
|
||||||
@Test
|
@Test
|
||||||
@Ignore
|
@Ignore
|
||||||
fun testFileRead(){
|
fun testFileRead(){
|
||||||
val text = this::class.java.getResourceAsStream("/cubes.json").readAllBytes().decodeToString()
|
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
|
||||||
val visual = VisualGroup3D.fromJson(text)
|
val visual = VisualGroup3D.parseJson(text)
|
||||||
visual["composite_001".asName()]
|
visual["composite_001".asName()]
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,36 +1,25 @@
|
|||||||
import scientifik.useSerialization
|
import scientifik.jsDistDirectory
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("scientifik.mpp")
|
||||||
//id("org.openjfx.javafxplugin")
|
|
||||||
id("application")
|
id("application")
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.mipt.npm"
|
group = "ru.mipt.npm"
|
||||||
|
|
||||||
useSerialization()
|
val ktorVersion = "1.3.2"
|
||||||
|
|
||||||
val ktor_version = "1.3.0-rc"
|
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
js {
|
val installJS = tasks.getByName("jsBrowserDistribution")
|
||||||
browser {
|
|
||||||
webpackTask {
|
|
||||||
sourceMaps = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
val installJS = tasks.getByName<Copy>("installJsDist")
|
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
withJava()
|
withJava()
|
||||||
compilations.findByName("main").apply {
|
compilations.findByName("jvmMain").apply {
|
||||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||||
dependsOn(installJS)
|
dependsOn(installJS)
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
from(installJS.destinationDir)
|
from(project.jsDistDirectory)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,23 +34,29 @@ kotlin {
|
|||||||
jvmMain {
|
jvmMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation("org.apache.commons:commons-math3:3.6.1")
|
implementation("org.apache.commons:commons-math3:3.6.1")
|
||||||
implementation("io.ktor:ktor-server-cio:$ktor_version")
|
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-serialization:$ktor_version")
|
implementation("io.ktor:ktor-serialization:$ktorVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain{
|
jsMain {
|
||||||
dependencies{
|
dependencies {
|
||||||
implementation("io.ktor:ktor-client-js:$ktor_version")
|
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-serialization-js:$ktor_version")
|
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
|
||||||
implementation(npm("text-encoding"))
|
implementation(npm("text-encoding"))
|
||||||
implementation(npm("abort-controller"))
|
implementation(npm("abort-controller"))
|
||||||
|
implementation(npm("bufferutil"))
|
||||||
|
implementation(npm("utf-8-validate"))
|
||||||
|
implementation(npm("fs"))
|
||||||
|
// implementation(npm("jquery"))
|
||||||
|
// implementation(npm("popper.js"))
|
||||||
|
// implementation(npm("react-is"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt"
|
mainClassName = "ru.mipt.npm.muon.monitor.server.MMServerKt"
|
||||||
}
|
}
|
||||||
|
|
||||||
//configure<JavaFXOptions> {
|
//configure<JavaFXOptions> {
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user