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 {
|
||||
val kotlinVersion = "1.3.61"
|
||||
val toolsVersion = "0.3.2"
|
||||
|
||||
kotlin("jvm") version kotlinVersion apply false
|
||||
id("kotlin-dce-js") version kotlinVersion apply false
|
||||
val toolsVersion = "0.4.2"
|
||||
id("scientifik.mpp") version toolsVersion apply false
|
||||
id("scientifik.jvm") version toolsVersion apply false
|
||||
id("scientifik.js") version toolsVersion apply false
|
||||
@ -21,21 +18,23 @@ allprojects {
|
||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
||||
maven("http://maven.jzy3d.org/releases")
|
||||
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/rjaros/kotlin")
|
||||
}
|
||||
|
||||
group = "hep.dataforge"
|
||||
version = "0.1.1"
|
||||
}
|
||||
|
||||
subprojects{
|
||||
this.useSerialization()
|
||||
version = "0.1.3-dev"
|
||||
}
|
||||
|
||||
val githubProject by extra("dataforge-vis")
|
||||
val bintrayRepo by extra("dataforge")
|
||||
val fxVersion by extra("14")
|
||||
|
||||
subprojects {
|
||||
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 {
|
||||
id("scientifik.mpp")
|
||||
id("org.openjfx.javafxplugin")
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
|
||||
|
||||
useSerialization()
|
||||
|
||||
kotlin {
|
||||
jvm{
|
||||
withJava()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain{
|
||||
commonMain {
|
||||
dependencies {
|
||||
api("hep.dataforge:dataforge-output:$dataforgeVersion")
|
||||
}
|
||||
}
|
||||
jvmMain{
|
||||
jvmMain {
|
||||
dependencies {
|
||||
api("no.tornado:tornadofx:1.7.19")
|
||||
api("no.tornado:tornadofx:1.7.20")
|
||||
//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")
|
||||
}
|
||||
api("de.jensd:fontawesomefx-commons:11.0"){
|
||||
api("de.jensd:fontawesomefx-commons:11.0") {
|
||||
exclude(group = "org.openjfx")
|
||||
}
|
||||
}
|
||||
}
|
||||
jsMain{
|
||||
jsMain {
|
||||
dependencies {
|
||||
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||
//api(npm("bootstrap","4.4.1"))
|
||||
implementation(npm("jsoneditor"))
|
||||
implementation(npm("file-saver"))
|
||||
|
||||
//React, React DOM + Wrappers (chapter 3)
|
||||
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.names.Name
|
||||
@ -20,6 +20,17 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
||||
*/
|
||||
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<*>?) {
|
||||
super.propertyChanged(name, before, after)
|
||||
forEach {
|
||||
@ -37,7 +48,12 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
||||
* Add listener for children change
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
*/
|
||||
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
|
||||
@ -91,16 +136,17 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
|
||||
if (child == null) {
|
||||
removeChild(token)
|
||||
} else {
|
||||
attach(child)
|
||||
setChild(token, child)
|
||||
}
|
||||
}
|
||||
else -> {
|
||||
//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
|
||||
}
|
||||
}
|
||||
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.names.Name
|
||||
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
|
||||
|
||||
internal data class PropertyListener(
|
||||
@ -14,7 +15,7 @@ internal data class PropertyListener(
|
||||
abstract class AbstractVisualObject : VisualObject {
|
||||
|
||||
@Transient
|
||||
override var parent: VisualObject? = null
|
||||
override var parent: VisualGroup? = null
|
||||
|
||||
protected abstract var properties: Config?
|
||||
|
||||
@ -22,7 +23,7 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
get() = properties?.get(STYLE_KEY).stringList
|
||||
set(value) {
|
||||
//val allStyles = (field + value).distinct()
|
||||
setProperty(STYLE_KEY, value)
|
||||
setProperty(STYLE_KEY, Value.of(value))
|
||||
updateStyles(value)
|
||||
}
|
||||
|
||||
@ -66,7 +67,7 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
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
|
||||
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.int
|
||||
import kotlin.math.max
|
||||
@ -234,7 +237,7 @@ object Colors {
|
||||
/**
|
||||
* 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()
|
||||
GREEN_KEY put g.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)
|
||||
|
||||
package hep.dataforge.vis.common
|
||||
package hep.dataforge.vis
|
||||
|
||||
import hep.dataforge.io.serialization.MetaSerializer
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
/**
|
||||
* A container for styles
|
||||
*/
|
||||
@Serializable
|
||||
class StyleSheet() {
|
||||
class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta> = LinkedHashMap()) {
|
||||
@Transient
|
||||
internal var owner: VisualObject? = null
|
||||
|
||||
@ -20,12 +21,10 @@ class StyleSheet() {
|
||||
this.owner = owner
|
||||
}
|
||||
|
||||
private val styleMap = HashMap<String, Meta>()
|
||||
|
||||
val items: Map<String, Meta> get() = styleMap
|
||||
|
||||
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) {
|
||||
val newStyle = get(key)?.let { buildMeta(it, builder) } ?: buildMeta(builder)
|
||||
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
||||
set(key, newStyle.seal())
|
||||
}
|
||||
|
||||
companion object: KSerializer<StyleSheet>{
|
||||
override val descriptor: SerialDescriptor
|
||||
get() = TODO("Not yet implemented")
|
||||
@Serializer(StyleSheet::class)
|
||||
companion object : KSerializer<StyleSheet> {
|
||||
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||
|
||||
|
||||
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) {
|
||||
TODO("Not yet implemented")
|
||||
override fun serialize(encoder: Encoder, value: StyleSheet) {
|
||||
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.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 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"
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
package hep.dataforge.vis.common
|
||||
package hep.dataforge.vis
|
||||
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.provider.Provider
|
||||
@ -6,7 +6,8 @@ import hep.dataforge.provider.Provider
|
||||
/**
|
||||
* 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
|
||||
*/
|
@ -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.asName
|
||||
import hep.dataforge.names.toName
|
||||
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
|
||||
|
||||
//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.
|
||||
*/
|
||||
@Transient
|
||||
var parent: VisualObject?
|
||||
var parent: VisualGroup?
|
||||
|
||||
/**
|
||||
* All properties including styles and prototypes if present, but without inheritance
|
||||
*/
|
||||
fun allProperties(): Laminate
|
||||
|
||||
/**
|
||||
* Set property for this object
|
||||
*/
|
||||
fun setProperty(name: Name, value: Any?) {
|
||||
config[name] = value
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -66,6 +65,10 @@ interface VisualObject : Configurable {
|
||||
const val TYPE = "visual"
|
||||
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 TAGS_KEY = "@tags"
|
||||
|
||||
@ -77,11 +80,6 @@ interface VisualObject : Configurable {
|
||||
*/
|
||||
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.
|
||||
*/
|
@ -1,4 +1,4 @@
|
||||
package hep.dataforge.vis.common
|
||||
package hep.dataforge.vis
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
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) =
|
||||
VisualObjectDelegateWrapper(this, name, default, inherited) {
|
||||
item -> item.string?.let { enumValueOf<E>(it) }
|
||||
VisualObjectDelegateWrapper(this, name, default, inherited) { item ->
|
||||
item.string?.let { enumValueOf<E>(it) }
|
||||
}
|
||||
|
||||
//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.js.div
|
||||
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) {
|
||||
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>) {
|
||||
div("container-fluid") {
|
||||
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.plus
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.isEmpty
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.isEmpty
|
||||
import kotlinx.html.TagConsumer
|
||||
import kotlinx.html.dom.append
|
||||
import kotlinx.html.js.*
|
||||
@ -13,18 +13,18 @@ import org.w3c.dom.HTMLElement
|
||||
import org.w3c.dom.HTMLSpanElement
|
||||
import kotlin.dom.clear
|
||||
|
||||
fun Element.displayObjectTree(
|
||||
obj: VisualObject,
|
||||
clickCallback: (Name) -> Unit = {}
|
||||
) {
|
||||
clear()
|
||||
append {
|
||||
card("Object tree") {
|
||||
subTree(Name.EMPTY, obj, clickCallback)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//fun Element.displayObjectTree(
|
||||
// obj: VisualObject,
|
||||
// clickCallback: (Name) -> Unit = {}
|
||||
//) {
|
||||
// clear()
|
||||
// append {
|
||||
// card("Object tree") {
|
||||
// subTree(Name.EMPTY, obj, clickCallback)
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
//
|
||||
private fun TagConsumer<HTMLElement>.subTree(
|
||||
name: Name,
|
||||
obj: VisualObject,
|
@ -6,7 +6,7 @@
|
||||
"EXTERNAL_DELEGATION"
|
||||
)
|
||||
|
||||
package hep.dataforge.vis.js.editor
|
||||
package hep.dataforge.vis.editor
|
||||
|
||||
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 {
|
||||
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.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.boolean
|
||||
import javafx.application.Application
|
||||
@ -20,7 +19,7 @@ import kotlin.reflect.KClass
|
||||
/**
|
||||
* 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
|
||||
|
||||
private val stages: ObservableSet<Stage> = FXCollections.observableSet()
|
||||
@ -96,7 +95,8 @@ class FXPlugin(meta: Meta = EmptyMeta) : AbstractPlugin(meta) {
|
||||
companion object : PluginFactory<FXPlugin> {
|
||||
override val type: KClass<out FXPlugin> = FXPlugin::class
|
||||
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.names.Name
|
@ -3,7 +3,7 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* 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.get
|
@ -3,15 +3,15 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* 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.FontAwesomeIconView
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vis.fx.dfIconView
|
||||
import hep.dataforge.vis.dfIconView
|
||||
import javafx.scene.Node
|
||||
import javafx.scene.control.*
|
||||
import javafx.scene.control.cell.TextFieldTreeTableCell
|
||||
@ -128,7 +128,11 @@ class ConfigEditor(
|
||||
when (item) {
|
||||
is FXMetaValue<Config> -> {
|
||||
text = null
|
||||
val chooser = ValueChooser.build(Global, item.valueProperty, item.descriptor) {
|
||||
val chooser = ValueChooser.build(
|
||||
Global,
|
||||
item.valueProperty,
|
||||
item.descriptor
|
||||
) {
|
||||
item.set(it)
|
||||
}
|
||||
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.descriptors.ItemDescriptor
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
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 index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||
val newName = name.withIndex(index.toString())
|
||||
set(newName, EmptyMeta)
|
||||
set(newName, Meta.EMPTY)
|
||||
get(newName).node!!
|
||||
} else {
|
||||
this.setNode(token.asName(), EmptyMeta)
|
||||
this.setNode(token.asName(), Meta.EMPTY)
|
||||
//FIXME possible concurrency bug
|
||||
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) {
|
||||
val parent = getOrCreateNode()
|
||||
if (descriptor?.multiple == true) {
|
||||
parent.append(key, EmptyMeta)
|
||||
parent.append(key, Meta.EMPTY)
|
||||
} else {
|
||||
parent[key] = EmptyMeta
|
||||
parent[key] = Meta.EMPTY
|
||||
}
|
||||
}
|
||||
|
@ -14,18 +14,23 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
package hep.dataforge.vis.fx.editor
|
||||
package hep.dataforge.vis.editor
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vis.fx.dfIconView
|
||||
import hep.dataforge.vis.dfIconView
|
||||
import javafx.beans.property.SimpleStringProperty
|
||||
import javafx.scene.control.TreeItem
|
||||
import javafx.scene.control.TreeSortMode
|
||||
import javafx.scene.control.TreeTableView
|
||||
import tornadofx.*
|
||||
|
||||
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title, dfIconView) {
|
||||
constructor(meta: Meta, title: String = "Meta viewer"): this(FXMeta.root(meta),title = title)
|
||||
class MetaViewer(val rootNode: FXMetaNode<*>, title: String = "Meta viewer") : Fragment(title,
|
||||
dfIconView
|
||||
) {
|
||||
constructor(meta: Meta, title: String = "Meta viewer"): this(
|
||||
FXMeta.root(
|
||||
meta
|
||||
),title = title)
|
||||
|
||||
override val root = borderpane {
|
||||
center {
|
@ -3,7 +3,7 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* 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.names.Name
|
@ -3,7 +3,7 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* and open the template in the editor.
|
||||
*/
|
||||
package hep.dataforge.vis.fx.editor
|
||||
package hep.dataforge.vis.editor
|
||||
|
||||
import hep.dataforge.values.Value
|
||||
|
@ -3,20 +3,19 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* 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.Named
|
||||
import hep.dataforge.descriptors.ValueDescriptor
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.provider.provideByType
|
||||
import hep.dataforge.values.Null
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.vis.common.widget
|
||||
import hep.dataforge.vis.common.widgetType
|
||||
import hep.dataforge.vis.widget
|
||||
import hep.dataforge.vis.widgetType
|
||||
import javafx.beans.property.ObjectProperty
|
||||
import javafx.beans.value.ObservableValue
|
||||
import javafx.scene.Node
|
||||
@ -66,7 +65,7 @@ interface ValueChooser {
|
||||
|
||||
@Type("hep.dataforge.vis.fx.valueChooserFactory")
|
||||
interface Factory : Named {
|
||||
operator fun invoke(meta: Meta = EmptyMeta): ValueChooser
|
||||
operator fun invoke(meta: Meta = Meta.EMPTY): ValueChooser
|
||||
}
|
||||
|
||||
companion object {
|
||||
@ -108,8 +107,7 @@ interface ValueChooser {
|
||||
descriptor: ValueDescriptor? = null,
|
||||
setter: (Value) -> Unit
|
||||
): ValueChooser {
|
||||
val chooser =
|
||||
build(context, descriptor)
|
||||
val chooser = build(context, descriptor)
|
||||
chooser.setDisplayValue(value.value ?: Null)
|
||||
value.onChange {
|
||||
chooser.setDisplayValue(it ?: Null)
|
@ -3,9 +3,9 @@
|
||||
* To change this template file, choose Tools | Templates
|
||||
* 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.Value
|
||||
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.Meta
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.findStyle
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.findStyle
|
||||
import javafx.beans.binding.Binding
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
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.common.VisualObject
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
import javafx.scene.control.SelectionMode
|
||||
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.buildMeta
|
||||
import hep.dataforge.meta.toConfig
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.asConfig
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.vis.fx.editor.ConfigEditor
|
||||
import hep.dataforge.vis.fx.editor.FXMeta
|
||||
import hep.dataforge.vis.fx.editor.MetaViewer
|
||||
import hep.dataforge.vis.editor.ConfigEditor
|
||||
import hep.dataforge.vis.editor.FXMeta
|
||||
import hep.dataforge.vis.editor.MetaViewer
|
||||
import javafx.geometry.Orientation
|
||||
import tornadofx.*
|
||||
|
||||
@ -15,7 +15,7 @@ class MetaEditorDemoApp : App(MetaEditorDemo::class)
|
||||
|
||||
class MetaEditorDemo : View("Meta editor demo") {
|
||||
|
||||
val meta = buildMeta {
|
||||
val meta = Meta {
|
||||
"aNode" put {
|
||||
"innerNode" put {
|
||||
"innerValue" put true
|
||||
@ -23,33 +23,35 @@ class MetaEditorDemo : View("Meta editor demo") {
|
||||
"b" put 223
|
||||
"c" put "StringValue"
|
||||
}
|
||||
}.toConfig()
|
||||
}.asConfig()
|
||||
|
||||
val descriptor = NodeDescriptor {
|
||||
node("aNode") {
|
||||
defineNode("aNode") {
|
||||
info = "A root demo node"
|
||||
value("b") {
|
||||
defineValue("b") {
|
||||
info = "b number value"
|
||||
type(ValueType.NUMBER)
|
||||
}
|
||||
node("otherNode") {
|
||||
value("otherValue") {
|
||||
defineNode("otherNode") {
|
||||
defineValue("otherValue") {
|
||||
type(ValueType.BOOLEAN)
|
||||
default(false)
|
||||
info = "default value"
|
||||
}
|
||||
}
|
||||
}
|
||||
value("multiple"){
|
||||
defineValue("multiple") {
|
||||
info = "A sns value"
|
||||
multiple = true
|
||||
}
|
||||
}
|
||||
|
||||
private val rootNode = FXMeta.root(meta,descriptor)
|
||||
private val rootNode = FXMeta.root(meta, descriptor)
|
||||
|
||||
override val root =
|
||||
splitpane(Orientation.HORIZONTAL, MetaViewer(rootNode).root, ConfigEditor(rootNode).root)
|
||||
splitpane(Orientation.HORIZONTAL, MetaViewer(rootNode).root, ConfigEditor(
|
||||
rootNode
|
||||
).root)
|
||||
}
|
||||
|
||||
fun main() {
|
@ -7,7 +7,7 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
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.MetaBuilder
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.useStyle
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
|
||||
import hep.dataforge.vis.useStyle
|
||||
import scientifik.gdml.*
|
||||
import kotlin.random.Random
|
||||
|
||||
@ -44,7 +44,7 @@ class GDMLTransformer(val root: GDML) {
|
||||
|
||||
fun VisualObject3D.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
|
||||
styleCache.getOrPut(name.toName()) {
|
||||
buildMeta(builder)
|
||||
Meta(builder)
|
||||
}
|
||||
useStyle(name)
|
||||
}
|
||||
@ -69,7 +69,13 @@ class GDMLTransformer(val root: GDML) {
|
||||
var onFinish: GDMLTransformer.() -> Unit = {}
|
||||
|
||||
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 {
|
||||
final.styleSheet {
|
||||
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.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.get
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.get
|
||||
import hep.dataforge.vis.set
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import hep.dataforge.vis.spatial.World.ONE
|
||||
import hep.dataforge.vis.spatial.World.ZERO
|
||||
|
@ -1,43 +1,29 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.vis.spatial.stringify
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
import scientifik.gdml.GDML
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
import kotlin.test.Ignore
|
||||
|
||||
class TestConvertor {
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
fun testBMNGeometry() {
|
||||
val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO")
|
||||
val file = File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\BM@N.gdml")
|
||||
val stream = if (file.exists()) {
|
||||
file.inputStream()
|
||||
} else {
|
||||
url.openStream()
|
||||
}
|
||||
|
||||
val 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 stream = javaClass.getResourceAsStream("/gdml/BM@N.gdml")
|
||||
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||
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.useSerialization
|
||||
import scientifik.serialization
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("org.openjfx.javafxplugin")
|
||||
}
|
||||
|
||||
useSerialization()
|
||||
serialization()
|
||||
|
||||
kotlin {
|
||||
jvm {
|
||||
withJava()
|
||||
}
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
@ -32,14 +27,9 @@ kotlin {
|
||||
jsMain {
|
||||
dependencies {
|
||||
// api(project(":wrappers"))
|
||||
implementation(npm("three", "0.106.2"))
|
||||
implementation(npm("@hi-level/three-csg", "1.0.6"))
|
||||
implementation(npm("three", "0.114.0"))
|
||||
implementation(npm("three-csg-ts", "1.0.1"))
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configure<JavaFXOptions> {
|
||||
modules("javafx.controls")
|
||||
}
|
||||
|
||||
|
@ -2,15 +2,11 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.float
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.VisualFactory
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.*
|
||||
import hep.dataforge.vis.spatial.Box.Companion.TYPE_NAME
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -29,7 +25,6 @@ class Box(
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
//TODO add helper for color configuration
|
||||
@ -69,7 +64,7 @@ class Box(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun VisualGroup3D.box(
|
||||
inline fun MutableVisualGroup.box(
|
||||
xSize: Number,
|
||||
ySize: Number,
|
||||
zSize: Number,
|
||||
|
@ -2,11 +2,10 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vis.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -23,7 +22,7 @@ class Composite(
|
||||
val compositeType: CompositeType,
|
||||
val first: VisualObject3D,
|
||||
val second: VisualObject3D
|
||||
) : AbstractVisualObject(), VisualObject3D {
|
||||
) : AbstractVisualObject(), VisualObject3D, VisualGroup {
|
||||
|
||||
init {
|
||||
first.parent = this
|
||||
@ -34,11 +33,16 @@ class Composite(
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
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,
|
||||
name: String = "",
|
||||
builder: VisualGroup3D.() -> Unit
|
||||
@ -50,24 +54,24 @@ inline fun VisualGroup3D.composite(
|
||||
it.config.update(group.config)
|
||||
//it.material = group.material
|
||||
|
||||
if(group.position!=null) {
|
||||
if (group.position != null) {
|
||||
it.position = group.position
|
||||
}
|
||||
if(group.rotation!=null) {
|
||||
if (group.rotation != null) {
|
||||
it.rotation = group.rotation
|
||||
}
|
||||
if(group.scale!=null) {
|
||||
if (group.scale != null) {
|
||||
it.scale = group.scale
|
||||
}
|
||||
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)
|
||||
|
||||
fun VisualGroup3D.subtract(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
||||
inline fun MutableVisualGroup.subtract(name: String = "", builder: VisualGroup3D.() -> Unit) =
|
||||
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)
|
@ -2,10 +2,10 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -25,7 +25,6 @@ class ConeSegment(
|
||||
var angle: Float = PI2
|
||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
override var position: Point3D? = null
|
||||
@ -76,7 +75,7 @@ class ConeSegment(
|
||||
|
||||
}
|
||||
|
||||
inline fun VisualGroup3D.cylinder(
|
||||
inline fun MutableVisualGroup.cylinder(
|
||||
r: Number,
|
||||
height: Number,
|
||||
name: String = "",
|
||||
@ -88,7 +87,7 @@ inline fun VisualGroup3D.cylinder(
|
||||
).apply(block).also { set(name, it) }
|
||||
|
||||
|
||||
inline fun VisualGroup3D.cone(
|
||||
inline fun MutableVisualGroup.cone(
|
||||
bottomRadius: Number,
|
||||
height: Number,
|
||||
upperRadius: Number = 0.0,
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -14,7 +14,6 @@ import kotlinx.serialization.UseSerializers
|
||||
@SerialName("3d.convex")
|
||||
class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = 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) }
|
||||
|
||||
class ConvexBuilder {
|
||||
|
@ -1,10 +1,10 @@
|
||||
@file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class)
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -45,7 +45,6 @@ class Extruded(
|
||||
var layers: MutableList<Layer> = ArrayList()
|
||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = 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) }
|
@ -1,6 +1,5 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
|
||||
/**
|
||||
@ -14,7 +13,7 @@ interface GeometryBuilder<T : Any> {
|
||||
* @param normal optional external normal to the face
|
||||
* @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
|
||||
}
|
||||
@ -25,7 +24,7 @@ fun GeometryBuilder<*>.face4(
|
||||
vertex3: Point3D,
|
||||
vertex4: Point3D,
|
||||
normal: Point3D? = null,
|
||||
meta: Meta = EmptyMeta
|
||||
meta: Meta = Meta.EMPTY
|
||||
) {
|
||||
face(vertex1, vertex2, vertex3, normal, meta)
|
||||
face(vertex1, vertex3, vertex4, normal, meta)
|
||||
|
@ -2,19 +2,17 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
@SerialName("3d.label")
|
||||
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(),
|
||||
VisualObject3D {
|
||||
@Serializable(ConfigSerializer::class)
|
||||
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(), VisualObject3D {
|
||||
override var properties: Config? = 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,
|
||||
fontSize: Number = 20,
|
||||
fontFamily: String = "Arial",
|
||||
|
@ -1,16 +1,17 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
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_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
|
||||
@ -32,8 +33,7 @@ class Material3D(override val config: Config) : Specific {
|
||||
*/
|
||||
var wireframe by boolean(false, WIREFRAME_KEY)
|
||||
|
||||
companion object : Specification<Material3D> {
|
||||
override fun wrap(config: Config): Material3D = Material3D(config)
|
||||
companion object : SchemeSpec<Material3D>(::Material3D) {
|
||||
|
||||
val MATERIAL_KEY = "material".asName()
|
||||
internal val COLOR_KEY = "color".asName()
|
||||
@ -44,23 +44,26 @@ class Material3D(override val config: Config) : Specific {
|
||||
internal val WIREFRAME_KEY = "wireframe".asName()
|
||||
val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY
|
||||
|
||||
val descriptor = NodeDescriptor {
|
||||
value(VisualObject3D.VISIBLE_KEY) {
|
||||
type(ValueType.BOOLEAN)
|
||||
default(true)
|
||||
}
|
||||
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) {
|
||||
val descriptor by lazy {
|
||||
//must be lazy to avoid initialization bug
|
||||
NodeDescriptor {
|
||||
defineValue(VisualObject3D.VISIBLE_KEY) {
|
||||
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
|
||||
*/
|
||||
fun VisualObject3D.color(webColor: String) {
|
||||
setProperty(MATERIAL_COLOR_KEY, webColor)
|
||||
setProperty(MATERIAL_COLOR_KEY, webColor.asValue())
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color as integer
|
||||
*/
|
||||
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(
|
||||
@ -92,7 +95,7 @@ fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty(
|
||||
var VisualObject3D.color: String?
|
||||
get() = getProperty(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
||||
set(value) {
|
||||
setProperty(MATERIAL_COLOR_KEY, value)
|
||||
setProperty(MATERIAL_COLOR_KEY, value?.asValue())
|
||||
}
|
||||
|
||||
val VisualObject3D.material: Material3D?
|
||||
@ -110,5 +113,5 @@ fun VisualObject3D.material(builder: Material3D.() -> Unit) {
|
||||
var VisualObject3D.opacity: Double?
|
||||
get() = getProperty(MATERIAL_OPACITY_KEY).double
|
||||
set(value) {
|
||||
setProperty(MATERIAL_OPACITY_KEY, value)
|
||||
setProperty(MATERIAL_OPACITY_KEY, value?.asValue())
|
||||
}
|
@ -2,13 +2,13 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -16,7 +16,6 @@ import kotlinx.serialization.UseSerializers
|
||||
@Serializable
|
||||
@SerialName("3d.line")
|
||||
class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = 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) }
|
@ -1,18 +1,13 @@
|
||||
@file:UseSerializers(Point3DSerializer::class, NameSerializer::class, ConfigSerializer::class)
|
||||
@file:UseSerializers(Point3DSerializer::class)
|
||||
|
||||
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.Laminate
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.*
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vis.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
@ -26,7 +21,9 @@ import kotlin.collections.set
|
||||
*/
|
||||
@Serializable
|
||||
@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) {
|
||||
this.parent = parent
|
||||
@ -36,7 +33,6 @@ class Proxy private constructor(val templateName: Name) : AbstractVisualObject()
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
/**
|
||||
@ -44,10 +40,12 @@ class Proxy private constructor(val templateName: Name) : AbstractVisualObject()
|
||||
*/
|
||||
val prototype: VisualObject3D
|
||||
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
|
||||
get() = (parent as? VisualGroup)?.styleSheet ?: StyleSheet(this)
|
||||
get() = parent?.styleSheet ?: StyleSheet(
|
||||
this
|
||||
)
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
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) })
|
||||
|
||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(),
|
||||
VisualGroup {
|
||||
|
||||
val prototype: VisualObject get() = prototypeFor(name)
|
||||
|
||||
@ -155,20 +154,18 @@ val VisualObject.prototype: VisualObject
|
||||
/**
|
||||
* Create ref for existing prototype
|
||||
*/
|
||||
inline fun VisualGroup3D.ref(
|
||||
fun VisualGroup3D.ref(
|
||||
templateName: Name,
|
||||
name: String = "",
|
||||
block: Proxy.() -> Unit = {}
|
||||
) = Proxy(this, templateName).apply(block).also { set(name, it) }
|
||||
name: String = ""
|
||||
): Proxy = Proxy(this, templateName).also { set(name, it) }
|
||||
|
||||
/**
|
||||
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
||||
*/
|
||||
fun VisualGroup3D.proxy(
|
||||
templateName: Name,
|
||||
name: String,
|
||||
obj: VisualObject3D,
|
||||
name: String = "",
|
||||
block: Proxy.() -> Unit = {}
|
||||
templateName: Name = name.toName()
|
||||
): Proxy {
|
||||
val existing = getPrototype(templateName)
|
||||
if (existing == null) {
|
||||
@ -178,5 +175,14 @@ fun VisualGroup3D.proxy(
|
||||
} else if (existing != obj) {
|
||||
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
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -23,7 +23,6 @@ class Sphere(
|
||||
var theta: Float = PI.toFloat()
|
||||
) : AbstractVisualObject(), VisualObject3D, Shape {
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
override var position: Point3D? = null
|
||||
@ -61,7 +60,7 @@ class Sphere(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun VisualGroup3D.sphere(
|
||||
inline fun MutableVisualGroup.sphere(
|
||||
radius: Number,
|
||||
phi: Number = 2 * PI,
|
||||
theta: Number = PI,
|
||||
|
@ -1,10 +1,10 @@
|
||||
@file:UseSerializers(Point3DSerializer::class)
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vis.common.AbstractVisualObject
|
||||
import hep.dataforge.vis.common.set
|
||||
import hep.dataforge.vis.AbstractVisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
@ -29,7 +29,6 @@ class Tube(
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
init {
|
||||
@ -129,7 +128,7 @@ class Tube(
|
||||
|
||||
}
|
||||
|
||||
inline fun VisualGroup3D.tube(
|
||||
inline fun MutableVisualGroup.tube(
|
||||
r: Number,
|
||||
height: Number,
|
||||
innerRadius: Number = 0f,
|
||||
|
@ -4,14 +4,12 @@ import hep.dataforge.context.AbstractPlugin
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.PluginFactory
|
||||
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.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.Visual
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.SimpleVisualGroup
|
||||
import hep.dataforge.vis.Visual
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonConfiguration
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
@ -39,29 +37,28 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
|
||||
val serialModule = SerializersModule {
|
||||
contextual(Point3DSerializer)
|
||||
contextual(Point2DSerializer)
|
||||
contextual(NameSerializer)
|
||||
contextual(NameTokenSerializer)
|
||||
contextual(MetaSerializer)
|
||||
contextual(ConfigSerializer)
|
||||
|
||||
polymorphic(VisualObject::class, VisualObject3D::class) {
|
||||
VisualGroup3D::class with VisualGroup3D.serializer()
|
||||
Proxy::class with Proxy.serializer()
|
||||
Composite::class with Composite.serializer()
|
||||
Tube::class with Tube.serializer()
|
||||
Box::class with Box.serializer()
|
||||
Convex::class with Convex.serializer()
|
||||
Extruded::class with Extruded.serializer()
|
||||
addSubclass(PolyLine.serializer())
|
||||
addSubclass(Label3D.serializer())
|
||||
subclass(SimpleVisualGroup.serializer())
|
||||
subclass(VisualGroup3D.serializer())
|
||||
subclass(Proxy.serializer())
|
||||
subclass(Composite.serializer())
|
||||
subclass(Tube.serializer())
|
||||
subclass(Box.serializer())
|
||||
subclass(Convex.serializer())
|
||||
subclass(Extruded.serializer())
|
||||
subclass(PolyLine.serializer())
|
||||
subclass(Label3D.serializer())
|
||||
subclass(Sphere.serializer())
|
||||
}
|
||||
}
|
||||
|
||||
val json = Json(
|
||||
internal val json = Json(
|
||||
JsonConfiguration(
|
||||
prettyPrint = true,
|
||||
useArrayPolymorphism = false,
|
||||
encodeDefaults = false
|
||||
encodeDefaults = false,
|
||||
ignoreUnknownKeys = true
|
||||
),
|
||||
context = serialModule
|
||||
)
|
||||
|
@ -1,48 +1,49 @@
|
||||
@file:UseSerializers(
|
||||
Point3DSerializer::class,
|
||||
ConfigSerializer::class,
|
||||
NameTokenSerializer::class,
|
||||
NameSerializer::class,
|
||||
MetaSerializer::class
|
||||
Point3DSerializer::class
|
||||
)
|
||||
|
||||
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.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
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 hep.dataforge.vis.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.collections.set
|
||||
|
||||
interface PrototypeHolder {
|
||||
val parent: VisualGroup?
|
||||
val prototypes: MutableVisualGroup?
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents 3-dimensional Visual Group
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("group.3d")
|
||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
|
||||
|
||||
override var styleSheet: StyleSheet? = null
|
||||
private set
|
||||
|
||||
/**
|
||||
* A container for templates visible inside this group
|
||||
*/
|
||||
var prototypes: VisualGroup3D? = null
|
||||
set(value) {
|
||||
value?.parent = this
|
||||
field = value
|
||||
}
|
||||
@Serializable(PrototypesSerializer::class)
|
||||
override var prototypes: MutableVisualGroup? = null
|
||||
private set
|
||||
|
||||
/**
|
||||
* 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
|
||||
override var properties: Config? = null
|
||||
@ -55,38 +56,18 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
|
||||
private val _children = HashMap<NameToken, VisualObject>()
|
||||
override val children: Map<NameToken, VisualObject> get() = _children
|
||||
|
||||
// init {
|
||||
// //Do after deserialization
|
||||
// attachChildren()
|
||||
// }
|
||||
|
||||
override fun attachChildren() {
|
||||
prototypes?.parent = this
|
||||
prototypes?.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) {
|
||||
_children.remove(token)?.run { parent = null }
|
||||
childrenChanged(token.asName(), null)
|
||||
_children.remove(token)?.apply { parent = null }
|
||||
}
|
||||
|
||||
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
|
||||
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 createGroup(name: Name): 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())
|
||||
}
|
||||
}
|
||||
override fun createGroup(): VisualGroup3D = VisualGroup3D()
|
||||
|
||||
|
||||
companion object {
|
||||
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
||||
|
||||
fun fromJson(json: String): VisualGroup3D =
|
||||
fun parseJson(json: String): VisualGroup3D =
|
||||
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
|
||||
*/
|
||||
tailrec fun VisualGroup3D.getPrototype(name: Name): VisualObject3D? =
|
||||
tailrec fun PrototypeHolder.getPrototype(name: Name): VisualObject3D? =
|
||||
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 {
|
||||
(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 =
|
||||
fun MutableVisualGroup.group(name: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
|
||||
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
|
||||
|
||||
import hep.dataforge.io.serialization.NameSerializer
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
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.IGNORE_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
|
||||
@ -25,7 +27,8 @@ interface VisualObject3D : VisualObject {
|
||||
companion object {
|
||||
|
||||
val VISIBLE_KEY = "visible".asName()
|
||||
// val SELECTED_KEY = "selected".asName()
|
||||
|
||||
// val SELECTED_KEY = "selected".asName()
|
||||
val DETAIL_KEY = "detail".asName()
|
||||
val LAYER_KEY = "layer".asName()
|
||||
val IGNORE_KEY = "ignore".asName()
|
||||
@ -55,6 +58,22 @@ interface VisualObject3D : VisualObject {
|
||||
val xScale = scale + x
|
||||
val yScale = scale + y
|
||||
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
|
||||
get() = getProperty(LAYER_KEY).int ?: 0
|
||||
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)
|
||||
|
||||
// Common properties
|
||||
@ -86,7 +105,7 @@ enum class RotationOrder {
|
||||
*/
|
||||
var VisualObject3D.rotationOrder: RotationOrder
|
||||
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?
|
||||
get() = getProperty(DETAIL_KEY, false).int
|
||||
set(value) = setProperty(DETAIL_KEY, value)
|
||||
set(value) = setProperty(DETAIL_KEY, value?.asValue())
|
||||
|
||||
var VisualObject.visible: 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.
|
||||
* Property is not inherited.
|
||||
*/
|
||||
var VisualObject.ignore: Boolean?
|
||||
get() = getProperty(IGNORE_KEY,false).boolean
|
||||
set(value) = setProperty(IGNORE_KEY, value)
|
||||
get() = getProperty(IGNORE_KEY, false).boolean
|
||||
set(value) = setProperty(IGNORE_KEY, value?.asValue())
|
||||
|
||||
//var VisualObject.selected: 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
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.meta.get
|
||||
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) {
|
||||
var x: Double
|
||||
@ -13,7 +20,7 @@ expect class Point2D(x: Number, y: Number) {
|
||||
operator fun Point2D.component1() = x
|
||||
operator fun Point2D.component2() = y
|
||||
|
||||
fun Point2D.toMeta() = buildMeta {
|
||||
fun Point2D.toMeta() = Meta {
|
||||
VisualObject3D.x put x
|
||||
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 Point3D.toMeta() = buildMeta {
|
||||
fun Point3D.toMeta() = Meta {
|
||||
VisualObject3D.x put x
|
||||
VisualObject3D.y put y
|
||||
VisualObject3D.z put z
|
||||
|
@ -1,17 +1,19 @@
|
||||
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.toName
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.internal.DoubleSerializer
|
||||
import kotlinx.serialization.internal.StringDescriptor
|
||||
import kotlinx.serialization.internal.nullable
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
import kotlinx.serialization.builtins.nullable
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
|
||||
inline fun <R> Decoder.decodeStructure(
|
||||
desc: SerialDescriptor,
|
||||
vararg typeParams: KSerializer<*> = emptyArray(),
|
||||
crossinline block: CompositeDecoder.() -> R
|
||||
crossinline block: CompositeDecoder.() -> R
|
||||
): R {
|
||||
val decoder = beginStructure(desc, *typeParams)
|
||||
val res = decoder.block()
|
||||
@ -31,7 +33,7 @@ inline fun Encoder.encodeStructure(
|
||||
|
||||
@Serializer(Point3D::class)
|
||||
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("y", true)
|
||||
double("z", true)
|
||||
@ -45,28 +47,28 @@ object Point3DSerializer : KSerializer<Point3D> {
|
||||
loop@ while (true) {
|
||||
when (val i = decodeElementIndex(descriptor)) {
|
||||
CompositeDecoder.READ_DONE -> break@loop
|
||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, DoubleSerializer.nullable) ?: 0.0
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, DoubleSerializer.nullable) ?: 0.0
|
||||
2 -> z = decodeNullableSerializableElement(descriptor, 2, DoubleSerializer.nullable) ?: 0.0
|
||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||
2 -> z = decodeNullableSerializableElement(descriptor, 2, Double.serializer().nullable) ?: 0.0
|
||||
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) {
|
||||
if (obj.x != 0.0) encodeDoubleElement(descriptor, 0, obj.x)
|
||||
if (obj.y != 0.0) encodeDoubleElement(descriptor, 1, obj.y)
|
||||
if (obj.z != 0.0) encodeDoubleElement(descriptor, 2, obj.z)
|
||||
if (value.x != 0.0) encodeDoubleElement(descriptor, 0, value.x)
|
||||
if (value.y != 0.0) encodeDoubleElement(descriptor, 1, value.y)
|
||||
if (value.z != 0.0) encodeDoubleElement(descriptor, 2, value.z)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializer(Point2D::class)
|
||||
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("y", true)
|
||||
}
|
||||
@ -78,32 +80,48 @@ object Point2DSerializer : KSerializer<Point2D> {
|
||||
loop@ while (true) {
|
||||
when (val i = decodeElementIndex(descriptor)) {
|
||||
CompositeDecoder.READ_DONE -> break@loop
|
||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, DoubleSerializer.nullable) ?: 0.0
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, DoubleSerializer.nullable) ?: 0.0
|
||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||
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) {
|
||||
if (obj.x != 0.0) encodeDoubleElement(descriptor, 0, obj.x)
|
||||
if (obj.y != 0.0) encodeDoubleElement(descriptor, 1, obj.y)
|
||||
if (value.x != 0.0) encodeDoubleElement(descriptor, 0, value.x)
|
||||
if (value.y != 0.0) encodeDoubleElement(descriptor, 1, value.y)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Serializer(NameToken::class)
|
||||
object NameTokenSerializer : KSerializer<NameToken> {
|
||||
override val descriptor: SerialDescriptor = StringDescriptor.withName("NameToken")
|
||||
@Serializer(MutableVisualGroup::class)
|
||||
internal object PrototypesSerializer : KSerializer<MutableVisualGroup> {
|
||||
|
||||
override fun deserialize(decoder: Decoder): NameToken {
|
||||
return decoder.decodeString().toName().first()!!
|
||||
private val mapSerializer: KSerializer<Map<NameToken, VisualObject>> =
|
||||
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) {
|
||||
encoder.encodeString(obj.toString())
|
||||
override fun serialize(encoder: Encoder, value: MutableVisualGroup) {
|
||||
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.*
|
||||
|
||||
class AxesSpec(override val config: Config) : Specific {
|
||||
class Axes : Scheme() {
|
||||
var visible by boolean(!config.isEmpty())
|
||||
var size by double(AXIS_SIZE)
|
||||
var width by double(AXIS_WIDTH)
|
||||
|
||||
companion object : Specification<AxesSpec> {
|
||||
override fun wrap(config: Config): AxesSpec = AxesSpec(config)
|
||||
|
||||
companion object : SchemeSpec<Axes>(::Axes) {
|
||||
const val AXIS_SIZE = 1000.0
|
||||
const val AXIS_WIDTH = 3.0
|
||||
|
||||
}
|
||||
}
|
@ -1,10 +1,14 @@
|
||||
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
|
||||
|
||||
class CameraSpec(override val config: Config) : Specific {
|
||||
class Camera : Scheme() {
|
||||
var fov by int(FIELD_OF_VIEW)
|
||||
|
||||
//var aspect by double(1.0)
|
||||
var nearClip by double(NEAR_CLIP)
|
||||
var farClip by double(FAR_CLIP)
|
||||
@ -14,11 +18,10 @@ class CameraSpec(override val config: Config) : Specific {
|
||||
var latitude by double(INITIAL_LATITUDE)
|
||||
val zenith: Double get() = PI / 2 - latitude
|
||||
|
||||
companion object : Specification<CameraSpec> {
|
||||
override fun wrap(config: Config): CameraSpec = CameraSpec(config)
|
||||
companion object : SchemeSpec<Camera>(::Camera) {
|
||||
const val INITIAL_DISTANCE = 300.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 FAR_CLIP = 10000.0
|
||||
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.names.asName
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.spatial.*
|
||||
|
||||
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.asName
|
||||
import hep.dataforge.vis.common.MutableVisualGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.MutableVisualGroup
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.spatial.Proxy
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
import hep.dataforge.vis.spatial.prototypes
|
||||
|
||||
object UnRef : VisualTreeTransform<VisualGroup3D>() {
|
||||
private fun VisualGroup.countRefs(): Map<Name, Int> {
|
||||
|
@ -1,6 +1,6 @@
|
||||
package hep.dataforge.vis.spatial.transform
|
||||
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.VisualObject
|
||||
|
||||
/**
|
||||
* A root class for [VisualObject] tree optimization
|
||||
|
@ -1,8 +1,9 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.toMeta
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.getIndexed
|
||||
import hep.dataforge.meta.node
|
||||
import hep.dataforge.meta.toMetaItem
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -26,9 +27,9 @@ class ConvexTest {
|
||||
val convex = group.first() as 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, convex.points.size)
|
||||
|
@ -1,7 +1,7 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.get
|
||||
import hep.dataforge.vis.Colors
|
||||
import hep.dataforge.vis.get
|
||||
import kotlin.math.PI
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.meta.int
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.vis.common.useStyle
|
||||
import hep.dataforge.vis.useStyle
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
|
@ -1,12 +1,12 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.vis.spatial.Visual3D.Companion.json
|
||||
import kotlinx.serialization.ImplicitReflectionSerializer
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.get
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class SerializationTest {
|
||||
@ImplicitReflectionSerializer
|
||||
@Test
|
||||
fun testCubeSerialization() {
|
||||
val cube = Box(100f, 100f, 100f).apply {
|
||||
@ -14,9 +14,30 @@ class SerializationTest {
|
||||
x = 100
|
||||
z = -100
|
||||
}
|
||||
val string = json.stringify(Box.serializer(), cube)
|
||||
val string = cube.stringify()
|
||||
println(string)
|
||||
val newCube = json.parse(Box.serializer(), string)
|
||||
val newCube = VisualObject.parseJson(string)
|
||||
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.meta.Meta
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.getProperty
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.names.toName
|
||||
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.specifications.CameraSpec
|
||||
import hep.dataforge.vis.spatial.specifications.CanvasSpec
|
||||
import hep.dataforge.vis.spatial.specifications.ControlsSpec
|
||||
import hep.dataforge.vis.spatial.specifications.Camera
|
||||
import hep.dataforge.vis.spatial.specifications.Canvas
|
||||
import hep.dataforge.vis.spatial.specifications.Controls
|
||||
import hep.dataforge.vis.spatial.three.ThreeMaterials.HIGHLIGHT_MATERIAL
|
||||
import info.laht.threekt.WebGLRenderer
|
||||
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
|
||||
|
||||
@ -53,15 +53,15 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
||||
|
||||
var clickListener: ((Name) -> Unit)? = null
|
||||
|
||||
val axes = AxesHelper(spec.axes.size.toInt()).apply {
|
||||
visible = spec.axes.visible
|
||||
val axes = AxesHelper(canvas.axes.size.toInt()).apply {
|
||||
visible = canvas.axes.visible
|
||||
}
|
||||
|
||||
val scene: Scene = Scene().apply {
|
||||
add(axes)
|
||||
}
|
||||
|
||||
val camera = buildCamera(spec.camera)
|
||||
val camera = buildCamera(canvas.camera)
|
||||
|
||||
init {
|
||||
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() {
|
||||
val mesh = pick()
|
||||
@ -108,7 +108,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val spec: Canvas
|
||||
|
||||
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 = {
|
||||
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,
|
||||
1.0,
|
||||
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))
|
||||
}
|
||||
|
||||
private fun addControls(element: Node, controlsSpec: ControlsSpec) {
|
||||
when (controlsSpec["type"].string) {
|
||||
private fun addControls(element: Node, controls: Controls) {
|
||||
when (controls.getProperty("type").string) {
|
||||
"trackball" -> TrackballControls(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 =
|
||||
ThreeCanvas(element, this, spec)
|
||||
fun ThreePlugin.output(element: HTMLElement, spec: Canvas = Canvas.empty()): ThreeCanvas =
|
||||
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.startsWith
|
||||
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.Material3D.Companion.MATERIAL_KEY
|
||||
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.values.ValueType
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.Colors
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.spatial.Material3D
|
||||
import info.laht.threekt.materials.LineBasicMaterial
|
||||
import info.laht.threekt.materials.Material
|
||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial.three
|
||||
import hep.dataforge.context.*
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import info.laht.threekt.core.Object3D
|
||||
import kotlin.collections.set
|
||||
|
@ -2,9 +2,8 @@
|
||||
|
||||
package hep.dataforge.vis.spatial.three
|
||||
|
||||
import hep.dataforge.io.serialization.ConfigSerializer
|
||||
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.Point3DSerializer
|
||||
import hep.dataforge.vis.spatial.VisualObject3D
|
||||
@ -26,7 +25,6 @@ class CustomThreeVisualObject(val threeFactory: ThreeFactory<VisualObject3D>) :
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
override fun toObject3D(): Object3D = threeFactory(this)
|
||||
|
@ -1,4 +1,4 @@
|
||||
@file:JsModule("@hi-level/three-csg")
|
||||
@file:JsModule("three-csg-ts")
|
||||
@file:JsNonModule
|
||||
@file:Suppress(
|
||||
"INTERFACE_WITH_SUPERCLASS",
|
||||
|
@ -1,7 +1,7 @@
|
||||
package hep.dataforge.vis.spatial.three
|
||||
|
||||
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.VisualGroup3D
|
||||
import kotlinx.html.InputType
|
||||
|
@ -5,7 +5,7 @@ import hep.dataforge.context.ContextAware
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.output.Renderer
|
||||
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.beans.property.ObjectProperty
|
||||
import javafx.beans.property.SimpleObjectProperty
|
||||
@ -14,7 +14,7 @@ import javafx.scene.paint.Color
|
||||
import org.fxyz3d.scene.Axes
|
||||
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 {
|
||||
|
||||
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.int
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.Colors
|
||||
import hep.dataforge.vis.spatial.Material3D
|
||||
import javafx.scene.paint.Color
|
||||
import javafx.scene.paint.Material
|
||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vis.spatial.fx
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.spatial.Proxy
|
||||
import javafx.scene.Group
|
||||
import javafx.scene.Node
|
||||
|
@ -1,6 +1,5 @@
|
||||
package hep.dataforge.vis.spatial.fx
|
||||
|
||||
import hep.dataforge.vis.spatial.specifications.CameraSpec
|
||||
import javafx.beans.InvalidationListener
|
||||
import javafx.beans.property.SimpleDoubleProperty
|
||||
import javafx.event.EventHandler
|
||||
@ -15,6 +14,7 @@ import javafx.scene.transform.Rotate
|
||||
import javafx.scene.transform.Translate
|
||||
import tornadofx.*
|
||||
import kotlin.math.*
|
||||
import hep.dataforge.vis.spatial.specifications.Camera as 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.startsWith
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import javafx.application.Platform
|
||||
import javafx.beans.binding.ObjectBinding
|
||||
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.vis.spatial.*
|
||||
import hep.dataforge.meta.JSON_PRETTY
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.modules.SerialModule
|
||||
import kotlinx.serialization.modules.SerialModuleCollector
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal val SerialDescriptor.jsonType
|
||||
get() = when (this.kind) {
|
||||
StructureKind.LIST -> "array"
|
||||
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||
PrimitiveKind.BOOLEAN -> "boolean"
|
||||
else -> "object"
|
||||
}
|
||||
private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
||||
StructureKind.LIST -> "array"
|
||||
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||
PrimitiveKind.BOOLEAN -> "boolean"
|
||||
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> {
|
||||
val list = ArrayList<SerialDescriptor>()
|
||||
@ -60,13 +61,16 @@ private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor>
|
||||
*/
|
||||
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.Point2D",
|
||||
Meta::class.qualifiedName
|
||||
"hep.dataforge.vis.spatial.Point2D?",
|
||||
"hep.dataforge.meta.Meta",
|
||||
"hep.dataforge.meta.Meta?"
|
||||
)
|
||||
) 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 ->
|
||||
val elementName = descriptor.getElementName(index)
|
||||
|
||||
properties[elementName] = when (elementName) {
|
||||
"templates" -> json {
|
||||
"\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D"
|
||||
val elementSchema = when (elementName) {
|
||||
"properties" -> json {
|
||||
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
||||
}
|
||||
"properties" -> json {
|
||||
"\$ref" to "#/definitions/${Meta::class.qualifiedName}"
|
||||
}
|
||||
"first", "second" -> json{
|
||||
"\$ref" to "#/definitions/children"
|
||||
"first", "second" -> json {
|
||||
"\$ref" to "#/$definitionNode/children"
|
||||
}
|
||||
"styleSheet" -> json {
|
||||
"type" to "object"
|
||||
"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"
|
||||
"additionalProperties" to json {
|
||||
"\$ref" to "#/definitions/children"
|
||||
"\$ref" to "#/$definitionNode/children"
|
||||
}
|
||||
}
|
||||
else -> jsonSchema(child, context)
|
||||
}
|
||||
properties[elementName] = elementSchema
|
||||
|
||||
if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
||||
}
|
||||
|
||||
val jsonType = descriptor.jsonType
|
||||
val jsonType = descriptor.getJsonType()
|
||||
val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
||||
"description" to JsonLiteral(descriptor.name),
|
||||
"description" to JsonLiteral(descriptor.serialName),
|
||||
"type" to JsonLiteral(jsonType)
|
||||
)
|
||||
if (isEnum) {
|
||||
@ -118,6 +120,11 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso
|
||||
}
|
||||
when (jsonType) {
|
||||
"object" -> {
|
||||
if(descriptor.isVisualObject()) {
|
||||
properties["type"] = json {
|
||||
"const" to descriptor.serialName
|
||||
}
|
||||
}
|
||||
objectData["properties"] = JsonObject(properties)
|
||||
val required = requiredProperties.map { JsonLiteral(it) }
|
||||
if (required.isNotEmpty()) {
|
||||
@ -140,9 +147,9 @@ fun main() {
|
||||
"children" to json {
|
||||
"anyOf" to jsonArray {
|
||||
context.enumerate(VisualObject3D::class).forEach {
|
||||
if (it.name == "hep.dataforge.vis.spatial.VisualGroup3D") {
|
||||
if (it.serialName == "hep.dataforge.vis.spatial.VisualGroup3D") {
|
||||
+json {
|
||||
"\$ref" to "#/definitions/${it.name}"
|
||||
"\$ref" to "#/$definitionNode/${it.serialName}"
|
||||
}
|
||||
} else {
|
||||
+jsonSchema(it, context)
|
||||
@ -150,18 +157,47 @@ fun main() {
|
||||
}
|
||||
}
|
||||
}
|
||||
"hep.dataforge.vis.spatial.Point3D" to jsonSchema(Point3DSerializer.descriptor, context)
|
||||
"hep.dataforge.vis.spatial.Point2D" to jsonSchema(Point2DSerializer.descriptor, context)
|
||||
"hep.dataforge.vis.spatial.VisualGroup3D" to jsonSchema(VisualGroup3D.serializer().descriptor, context)
|
||||
"hep.dataforge.meta.Meta" to json {
|
||||
"type" to "object"
|
||||
}
|
||||
"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(
|
||||
Json.indented.stringify(
|
||||
JSON_PRETTY.stringify(
|
||||
JsonObjectSerializer,
|
||||
json {
|
||||
"definitions" to definitions
|
||||
"\$ref" to "#/definitions/hep.dataforge.vis.spatial.VisualGroup3D"
|
||||
"\$defs" to definitions
|
||||
"\$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 {
|
||||
id("scientifik.mpp")
|
||||
id("org.openjfx.javafxplugin")
|
||||
id("application")
|
||||
}
|
||||
|
||||
val fxVersion: String by rootProject.extra
|
||||
fx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||
|
||||
kotlin {
|
||||
|
||||
jvm {
|
||||
@ -27,18 +31,9 @@ kotlin {
|
||||
api(project(":dataforge-vis-spatial-gdml"))
|
||||
}
|
||||
}
|
||||
jvmMain{
|
||||
dependencies {
|
||||
api("org.fxyz3d:fxyz3d:0.5.2")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "hep.dataforge.vis.spatial.gdml.demo.GDMLDemoAppKt"
|
||||
}
|
||||
|
||||
configure<JavaFXOptions> {
|
||||
modules("javafx.controls")
|
||||
}
|
@ -1,7 +1,9 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.setProperty
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vis.spatial.Material3D
|
||||
import hep.dataforge.vis.spatial.gdml.demo.cubes
|
||||
import kotlin.test.Test
|
||||
@ -12,7 +14,7 @@ class GDMLVisualTest {
|
||||
fun testPrototypeProperty() {
|
||||
val gdml = cubes()
|
||||
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)
|
||||
}
|
||||
}
|
@ -3,14 +3,12 @@ package hep.dataforge.vis.spatial.gdml.demo
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.js.Application
|
||||
import hep.dataforge.js.startApplication
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.meta.withBottom
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.js.editor.displayObjectTree
|
||||
import hep.dataforge.vis.js.editor.displayPropertyEditor
|
||||
import hep.dataforge.vis.VisualGroup
|
||||
import hep.dataforge.vis.VisualObject
|
||||
import hep.dataforge.vis.editor.objectTree
|
||||
import hep.dataforge.vis.editor.visualPropertyEditor
|
||||
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_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.displayCanvasControls
|
||||
import hep.dataforge.vis.spatial.three.output
|
||||
import hep.dataforge.vis.spatial.visible
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.files.FileList
|
||||
import org.w3c.files.FileReader
|
||||
@ -139,7 +136,7 @@ private class GDMLDemoApp : Application {
|
||||
message("Converting GDML into DF-VIS format")
|
||||
gdml.toVisual(gdmlConfiguration)
|
||||
}
|
||||
name.endsWith(".json") -> VisualGroup3D.fromJson(data)
|
||||
name.endsWith(".json") -> VisualGroup3D.parseJson(data)
|
||||
else -> {
|
||||
window.alert("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
|
||||
else -> return
|
||||
}
|
||||
editorElement.displayPropertyEditor(name, child) { item ->
|
||||
//val descriptorMeta = Material3D.descriptor
|
||||
|
||||
val properties = item.allProperties()
|
||||
val bottom = buildMeta {
|
||||
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
|
||||
}
|
||||
editorElement.visualPropertyEditor(name, child) {
|
||||
VISIBLE_KEY put true
|
||||
if (child is VisualObject3D) {
|
||||
MATERIAL_COLOR_KEY put "#ffffff"
|
||||
MATERIAL_OPACITY_KEY put 1.0
|
||||
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
|
||||
|
||||
//tree.visualObjectTree(visual, editor::propertyEditor)
|
||||
treeElement.displayObjectTree(visual) { treeName ->
|
||||
treeElement.objectTree(visual) { treeName ->
|
||||
selectElement(treeName)
|
||||
canvas.highlight(treeName)
|
||||
}
|
||||
canvas.render(visual)
|
||||
|
||||
|
||||
|
||||
canvas.render(visual)
|
||||
message(null)
|
||||
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
|
||||
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.vis.fx.editor.VisualObjectEditorFragment
|
||||
import hep.dataforge.vis.fx.editor.VisualObjectTreeFragment
|
||||
import hep.dataforge.vis.editor.VisualObjectEditorFragment
|
||||
import hep.dataforge.vis.editor.VisualObjectTreeFragment
|
||||
import hep.dataforge.vis.spatial.Material3D
|
||||
import hep.dataforge.vis.spatial.Visual3D
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
|
@ -1,5 +1,7 @@
|
||||
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.Visual3D
|
||||
import hep.dataforge.vis.spatial.VisualGroup3D
|
||||
@ -18,7 +20,7 @@ fun Visual3D.Companion.readFile(file: File): VisualGroup3D = when {
|
||||
|
||||
solidConfiguration = { parent, solid ->
|
||||
if (solid.name == "cave") {
|
||||
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true)
|
||||
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue())
|
||||
}
|
||||
if (parent.physVolumes.isNotEmpty()) {
|
||||
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.inputStream().use {
|
||||
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
||||
val text = unzip.readAllBytes().decodeToString()
|
||||
VisualGroup3D.fromJson(text)
|
||||
val text = unzip.readBytes().decodeToString()
|
||||
VisualGroup3D.parseJson(text)
|
||||
}
|
||||
}
|
||||
file.name.endsWith("json.gz") -> {
|
||||
file.inputStream().use {
|
||||
val unzip = GZIPInputStream(it)
|
||||
val text = unzip.readAllBytes().decodeToString()
|
||||
VisualGroup3D.fromJson(text)
|
||||
val text = unzip.readBytes().decodeToString()
|
||||
VisualGroup3D.parseJson(text)
|
||||
}
|
||||
}
|
||||
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.readFile
|
||||
import hep.dataforge.vis.spatial.gdml.toVisual
|
||||
import hep.dataforge.vis.spatial.stringify
|
||||
import scientifik.gdml.GDML
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
@ -14,6 +15,6 @@ fun main() {
|
||||
val visual = gdml.toVisual {
|
||||
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)
|
||||
}
|
@ -1,15 +1,15 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.names.asName
|
||||
import org.junit.Test
|
||||
import org.junit.jupiter.api.Test
|
||||
import kotlin.test.Ignore
|
||||
|
||||
class FileSerializationTest {
|
||||
@Test
|
||||
@Ignore
|
||||
fun testFileRead(){
|
||||
val text = this::class.java.getResourceAsStream("/cubes.json").readAllBytes().decodeToString()
|
||||
val visual = VisualGroup3D.fromJson(text)
|
||||
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
|
||||
val visual = VisualGroup3D.parseJson(text)
|
||||
visual["composite_001".asName()]
|
||||
}
|
||||
}
|
@ -1,36 +1,25 @@
|
||||
import scientifik.useSerialization
|
||||
import scientifik.jsDistDirectory
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
//id("org.openjfx.javafxplugin")
|
||||
id("application")
|
||||
}
|
||||
|
||||
group = "ru.mipt.npm"
|
||||
|
||||
useSerialization()
|
||||
|
||||
val ktor_version = "1.3.0-rc"
|
||||
val ktorVersion = "1.3.2"
|
||||
|
||||
kotlin {
|
||||
|
||||
js {
|
||||
browser {
|
||||
webpackTask {
|
||||
sourceMaps = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
val installJS = tasks.getByName<Copy>("installJsDist")
|
||||
val installJS = tasks.getByName("jsBrowserDistribution")
|
||||
|
||||
jvm {
|
||||
withJava()
|
||||
compilations.findByName("main").apply {
|
||||
compilations.findByName("jvmMain").apply {
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(installJS)
|
||||
afterEvaluate {
|
||||
from(installJS.destinationDir)
|
||||
from(project.jsDistDirectory)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -45,23 +34,29 @@ kotlin {
|
||||
jvmMain {
|
||||
dependencies {
|
||||
implementation("org.apache.commons:commons-math3:3.6.1")
|
||||
implementation("io.ktor:ktor-server-cio:$ktor_version")
|
||||
implementation("io.ktor:ktor-serialization:$ktor_version")
|
||||
implementation("io.ktor:ktor-server-cio:$ktorVersion")
|
||||
implementation("io.ktor:ktor-serialization:$ktorVersion")
|
||||
}
|
||||
}
|
||||
jsMain{
|
||||
dependencies{
|
||||
implementation("io.ktor:ktor-client-js:$ktor_version")
|
||||
implementation("io.ktor:ktor-client-serialization-js:$ktor_version")
|
||||
jsMain {
|
||||
dependencies {
|
||||
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
||||
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
|
||||
implementation(npm("text-encoding"))
|
||||
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 {
|
||||
mainClassName = "ru.mipt.npm.muon.monitor.server/MMServerKt"
|
||||
mainClassName = "ru.mipt.npm.muon.monitor.server.MMServerKt"
|
||||
}
|
||||
|
||||
//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