Code and API cleanup

This commit is contained in:
Alexander Nozik 2020-08-05 15:24:39 +03:00
parent f484d5d1ff
commit 373145b90a
60 changed files with 166 additions and 322 deletions

0
CHANGELOG.md Normal file
View File

View File

@ -42,7 +42,6 @@ The main framework's features for now include:
- Settings export and import - Settings export and import
- Multiple platform support - Multiple platform support
## About DataForge ## About DataForge
DataForge is a software framework for automated scientific data processing. DataForge Visualization DataForge is a software framework for automated scientific data processing. DataForge Visualization
@ -64,7 +63,7 @@ This module is not specific to 3D-visualization.
The `dataforge-vis-common` module also includes configuration editors for JS (in `jsMain`) and JVM (in `jvmMain`). The `dataforge-vis-common` module also includes configuration editors for JS (in `jsMain`) and JVM (in `jvmMain`).
##### Class diagram: **Class diagram:**
![](doc/resources/class-diag-common.png) ![](doc/resources/class-diag-common.png)
@ -73,7 +72,7 @@ The `dataforge-vis-common` module also includes configuration editors for JS (in
Includes common classes and serializers for 3D visualization, Three.js and JavaFX implementations. Includes common classes and serializers for 3D visualization, Three.js and JavaFX implementations.
##### Class diagram: **Class diagram:**
![](doc/resources/class-diag-3d.png) ![](doc/resources/class-diag-3d.png)
@ -125,7 +124,7 @@ Some shapes will also periodically change their color and visibility.
[More details](demo/spatial-showcase/README.md) [More details](demo/spatial-showcase/README.md)
##### Example view: **Example view:**
![](doc/resources/spatial-showcase.png) ![](doc/resources/spatial-showcase.png)
@ -137,7 +136,7 @@ A full-stack application example, showing the
[More details](demo/muon-monitor/README.md) [More details](demo/muon-monitor/README.md)
##### Example view: **Example view:**
![](doc/resources/muon-monitor.png) ![](doc/resources/muon-monitor.png)

View File

@ -1,14 +1,14 @@
import scientifik.useFx import scientifik.useFx
import scientifik.useSerialization import scientifik.useSerialization
val dataforgeVersion by extra("0.1.8-dev-2") val dataforgeVersion by extra("0.1.8")
plugins { plugins {
val toolsVersion = "0.5.0" id("scientifik.mpp") apply false
id("scientifik.mpp") version toolsVersion apply false id("scientifik.jvm") apply false
id("scientifik.jvm") version toolsVersion apply false id("scientifik.js") apply false
id("scientifik.js") version toolsVersion apply false id("scientifik.publish") apply false
id("scientifik.publish") version toolsVersion apply false id("org.jetbrains.changelog") version "0.4.0"
} }
allprojects { allprojects {
@ -16,15 +16,10 @@ allprojects {
mavenLocal() mavenLocal()
maven("https://dl.bintray.com/pdvrieze/maven") maven("https://dl.bintray.com/pdvrieze/maven")
maven("http://maven.jzy3d.org/releases") maven("http://maven.jzy3d.org/releases")
maven("https://kotlin.bintray.com/js-externals")
maven("https://kotlin.bintray.com/kotlin-js-wrappers/")
maven("https://dl.bintray.com/mipt-npm/dataforge")
// maven("https://dl.bintray.com/gbaldeck/kotlin")
// maven("https://dl.bintray.com/rjaros/kotlin")
} }
group = "hep.dataforge" group = "hep.dataforge"
version = "0.1.4-dev" version = "0.1.4"
} }
val githubProject by extra("dataforge-vis") val githubProject by extra("dataforge-vis")

View File

@ -3,7 +3,6 @@ plugins {
} }
val dataforgeVersion: String by rootProject.extra val dataforgeVersion: String by rootProject.extra
//val kvisionVersion: String by rootProject.extra("2.0.0-M1")
kotlin { kotlin {
js { js {

View File

@ -1,10 +1,9 @@
package hep.dataforge.properties package hep.dataforge.properties
import hep.dataforge.meta.Config import hep.dataforge.meta.*
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.get
import hep.dataforge.names.Name import hep.dataforge.names.Name
@DFExperimental
class ConfigProperty(val config: Config, val name: Name) : Property<MetaItem<*>?> { class ConfigProperty(val config: Config, val name: Name) : Property<MetaItem<*>?> {
override var value: MetaItem<*>? override var value: MetaItem<*>?
get() = config[name] get() = config[name]

View File

@ -11,6 +11,7 @@ import kotlinx.coroutines.launch
//TODO move to core //TODO move to core
@DFExperimental
interface Property<T> { interface Property<T> {
var value: T var value: T
@ -18,6 +19,7 @@ interface Property<T> {
fun removeChangeListener(owner: Any? = null) fun removeChangeListener(owner: Any? = null)
} }
@DFExperimental
@OptIn(ExperimentalCoroutinesApi::class) @OptIn(ExperimentalCoroutinesApi::class)
fun <T> Property<T>.flow() = callbackFlow<T> { fun <T> Property<T>.flow() = callbackFlow<T> {
send(value) send(value)
@ -35,6 +37,7 @@ fun <T> Property<T>.flow() = callbackFlow<T> {
* *
* @return a mirroring job * @return a mirroring job
*/ */
@DFExperimental
fun <T> Property<T>.mirror(source: Property<T>, scope: CoroutineScope): Job { fun <T> Property<T>.mirror(source: Property<T>, scope: CoroutineScope): Job {
return scope.launch { return scope.launch {
source.flow().collect { source.flow().collect {

View File

@ -33,8 +33,8 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
super.propertyChanged(name, before, after) super.propertyChanged(name, before, after)
forEach { for(obj in this) {
it.propertyChanged(name, before, after) obj.propertyChanged(name, before, after)
} }
} }

View File

@ -19,12 +19,15 @@ abstract class AbstractVisualObject : VisualObject {
@Transient @Transient
override var parent: VisualGroup? = null override var parent: VisualGroup? = null
protected abstract var properties: Config? /**
* Object own properties excluding styles and inheritance
*/
protected abstract var ownProperties: Config?
final override var styles: List<String> final override var styles: List<String>
get() = properties?.get(STYLE_KEY).stringList get() = ownProperties?.get(STYLE_KEY).stringList
set(value) { set(value) {
setProperty(STYLE_KEY, Value.of(value)) setItem(STYLE_KEY, Value.of(value))
updateStyles(value) updateStyles(value)
} }
@ -40,11 +43,11 @@ abstract class AbstractVisualObject : VisualObject {
/** /**
* The config is initialized and assigned on-demand. * The config is initialized and assigned on-demand.
* To avoid unnecessary allocations, one should access [properties] via [getProperty] instead. * To avoid unnecessary allocations, one should access [ownProperties] via [getProperty] instead.
*/ */
override val config: Config override val config: Config
get() = properties ?: Config().also { config -> get() = ownProperties ?: Config().also { config ->
properties = config.apply { onChange(this, ::propertyChanged) } ownProperties = config.apply { onChange(this, ::propertyChanged) }
} }
@Transient @Transient
@ -79,18 +82,18 @@ abstract class AbstractVisualObject : VisualObject {
/** /**
* All available properties in a layered form * All available properties in a layered form
*/ */
override fun allProperties(): Laminate = Laminate(properties, mergedStyles, parent?.allProperties()) override fun properties(): Laminate = Laminate(ownProperties, mergedStyles, parent?.properties())
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) { return if (inherit) {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
yield(parent?.getProperty(name, inherit)) yield(parent?.getProperty(name, inherit))
}.merge() }.merge()
} else { } else {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
}.merge() }.merge()
} }
@ -100,8 +103,8 @@ abstract class AbstractVisualObject : VisualObject {
* Reset all properties to their default values * Reset all properties to their default values
*/ */
fun resetProperties() { fun resetProperties() {
properties?.removeListener(this) ownProperties?.removeListener(this)
properties = null ownProperties = null
} }
companion object { companion object {

View File

@ -13,7 +13,7 @@ class SimpleVisualGroup : AbstractVisualGroup() {
override var styleSheet: StyleSheet? = null override var styleSheet: StyleSheet? = null
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed //FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var properties: Config? = null override var ownProperties: Config? = null
@SerialName("children") @SerialName("children")
private val _children = HashMap<NameToken, VisualObject>() private val _children = HashMap<NameToken, VisualObject>()

View File

@ -38,12 +38,18 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
} }
} }
/**
* Set or clear the style
*/
operator fun set(key: String, style: Meta?) { operator fun set(key: String, style: Meta?) {
val oldStyle = styleMap[key] val oldStyle = styleMap[key]
define(key, style) define(key, style)
owner?.styleChanged(key, oldStyle, style) owner?.styleChanged(key, oldStyle, style)
} }
/**
* Create and set a style
*/
operator fun set(key: String, builder: MetaBuilder.() -> Unit) { operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
val newStyle = get(key)?.edit(builder) ?: Meta(builder) val newStyle = get(key)?.edit(builder) ?: Meta(builder)
set(key, newStyle.seal()) set(key, newStyle.seal())
@ -75,6 +81,8 @@ private fun VisualObject.styleChanged(key: String, oldStyle: Meta?, newStyle: Me
tokens.forEach { parent?.propertyChanged(it, oldStyle?.get(it), newStyle?.get(it)) } tokens.forEach { parent?.propertyChanged(it, oldStyle?.get(it), newStyle?.get(it)) }
} }
if (this is VisualGroup) { if (this is VisualGroup) {
this.forEach { it.styleChanged(key, oldStyle, newStyle) } for (obj in this) {
obj.styleChanged(key, oldStyle, newStyle)
}
} }
} }

View File

@ -6,8 +6,7 @@ import hep.dataforge.provider.Provider
/** /**
* Represents a group of [VisualObject] instances * Represents a group of [VisualObject] instances
*/ */
interface VisualGroup : Provider, Iterable<VisualObject>, interface VisualGroup : Provider, VisualObject {
VisualObject {
/** /**
* A map of top level named children * A map of top level named children
*/ */
@ -15,6 +14,10 @@ interface VisualGroup : Provider, Iterable<VisualObject>,
override val defaultTarget: String get() = VisualObject.TYPE override val defaultTarget: String get() = VisualObject.TYPE
/**
* A stylesheet for this group and its descendants. Stylesheet is not applied directly,
* but instead is just a repository for named configutations
*/
val styleSheet: StyleSheet? val styleSheet: StyleSheet?
/** /**
@ -35,12 +38,6 @@ interface VisualGroup : Provider, Iterable<VisualObject>,
else -> emptyMap() else -> emptyMap()
} }
/**
* Iterate over children of this group
*/
override fun iterator(): Iterator<VisualObject> = children.values.iterator()
operator fun get(name: Name): VisualObject? { operator fun get(name: Name): VisualObject? {
return when { return when {
name.isEmpty() -> this name.isEmpty() -> this
@ -65,7 +62,10 @@ interface VisualGroup : Provider, Iterable<VisualObject>,
} }
} }
data class StyleRef(val group: VisualGroup, val styleName: Name) /**
* Iterate over children of this group
*/
operator fun VisualGroup.iterator(): Iterator<VisualObject> = children.values.iterator()
val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty() val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty()

View File

@ -12,9 +12,6 @@ import hep.dataforge.vis.VisualObject.Companion.TYPE
import kotlinx.serialization.PolymorphicSerializer import kotlinx.serialization.PolymorphicSerializer
import kotlinx.serialization.Transient import kotlinx.serialization.Transient
//private fun Laminate.withTop(meta: Meta): Laminate = Laminate(listOf(meta) + layers)
//private fun Laminate.withBottom(meta: Meta): Laminate = Laminate(layers + meta)
/** /**
* A root type for display hierarchy * A root type for display hierarchy
*/ */
@ -28,16 +25,19 @@ interface VisualObject : Configurable {
var parent: VisualGroup? var parent: VisualGroup?
/** /**
* All properties including styles and prototypes if present, but without inheritance * All properties including styles and prototypes if present, including inherited ones
*/ */
fun allProperties(): Laminate fun properties(): Laminate
/** /**
* Get property including or excluding parent properties * Get property including or excluding parent properties
*/ */
fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
override fun getProperty(name: Name): MetaItem<*>? = getProperty(name, true) /**
* Ger a property including inherited values
*/
override fun getItem(name: Name): MetaItem<*>? = getProperty(name, true)
/** /**
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed * Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
@ -71,17 +71,14 @@ interface VisualObject : Configurable {
private val VISUAL_OBJECT_SERIALIZER = PolymorphicSerializer(VisualObject::class) private val VISUAL_OBJECT_SERIALIZER = PolymorphicSerializer(VisualObject::class)
fun serializer() = VISUAL_OBJECT_SERIALIZER fun serializer() = VISUAL_OBJECT_SERIALIZER
//const val META_KEY = "@meta"
//const val TAGS_KEY = "@tags"
} }
} }
/** /**
* Get [VisualObject] property using key as a String * Get [VisualObject] property using key as a String
*/ */
fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit) fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
getProperty(key.toName(), inherit)
/** /**
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
@ -90,35 +87,7 @@ fun VisualObject.useStyle(name: String) {
styles = styles + name styles = styles + name
} }
//private tailrec fun VisualObject.topGroup(): VisualGroup? {
// val parent = this.parent
// return if (parent == null) {
// this as? VisualGroup
// }
// else {
// parent.topGroup()
// }
//}
//
///**
// * Add or update given style on a top-most reachable parent group and apply it to this object
// */
//fun VisualObject.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
// val styleName = name.toName()
// topGroup()?.updateStyle(styleName, builder) ?: error("Can't find parent group for $this")
// useStyle(styleName)
//}
tailrec fun VisualObject.findStyle(name: String): Meta? = tailrec fun VisualObject.findStyle(name: String): Meta? =
(this as? VisualGroup)?.styleSheet?.get(name) ?: parent?.findStyle(name) (this as? VisualGroup)?.styleSheet?.get(name) ?: parent?.findStyle(name)
fun VisualObject.findAllStyles(): Laminate = Laminate(styles.mapNotNull(::findStyle)) fun VisualObject.findAllStyles(): Laminate = Laminate(styles.mapNotNull(::findStyle))
//operator fun VisualObject.get(name: Name): VisualObject?{
// return when {
// name.isEmpty() -> this
// this is VisualGroup -> this[name]
// else -> null
// }
//}

View File

@ -1,131 +0,0 @@
package hep.dataforge.vis
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.values.Value
import kotlin.jvm.JvmName
import kotlin.properties.ReadOnlyProperty
import kotlin.properties.ReadWriteProperty
import kotlin.reflect.KProperty
/**
* A delegate for display object properties
*/
class VisualObjectDelegate(
val key: Name?,
val default: MetaItem<*>?,
val inherited: Boolean
) : ReadWriteProperty<VisualObject, MetaItem<*>?> {
override fun getValue(thisRef: VisualObject, property: KProperty<*>): MetaItem<*>? {
val name = key ?: property.name.asName()
return if (inherited) {
thisRef.getProperty(name)
} else {
thisRef.config[name]
} ?: default
}
override fun setValue(thisRef: VisualObject, property: KProperty<*>, value: MetaItem<*>?) {
val name = key ?: property.name.asName()
thisRef.config[name] = value
}
}
class VisualObjectDelegateWrapper<T>(
val obj: VisualObject,
val key: Name?,
val default: T,
val inherited: Boolean,
val write: Config.(name: Name, value: T) -> Unit = { name, value -> set(name, value) },
val read: (MetaItem<*>?) -> T?
) : ReadWriteProperty<Any?, T> {
//private var cachedName: Name? = null
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
val name = key ?: property.name.asName()
return read(obj.getProperty(name, inherited)) ?: default
}
override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) {
val name = key ?: property.name.asName()
obj.config[name] = value
}
}
fun VisualObject.value(default: Value? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.value }
fun VisualObject.string(default: String? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.string }
fun VisualObject.boolean(default: Boolean? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.boolean }
fun VisualObject.number(default: Number? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.number }
fun VisualObject.double(default: Double? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.double }
fun VisualObject.int(default: Int? = null, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.int }
fun VisualObject.node(name: Name? = null, inherited: Boolean = true) =
VisualObjectDelegateWrapper(this, name, null, inherited) { it.node }
fun VisualObject.item(name: Name? = null, inherited: Boolean = true) =
VisualObjectDelegateWrapper(this, name, null, inherited) { it }
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
@JvmName("safeString")
fun VisualObject.string(default: String, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.string }
@JvmName("safeBoolean")
fun VisualObject.boolean(default: Boolean, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.boolean }
@JvmName("safeNumber")
fun VisualObject.number(default: Number, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.number }
@JvmName("safeDouble")
fun VisualObject.double(default: Double, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.double }
@JvmName("safeInt")
fun VisualObject.int(default: Int, name: Name? = null, inherited: Boolean = false) =
VisualObjectDelegateWrapper(this, name, default, inherited) { it.int }
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) }
}
//merge properties
fun <T> VisualObject.merge(
name: Name? = null,
transformer: (Sequence<MetaItem<*>>) -> T
): ReadOnlyProperty<VisualObject, T> {
return object : ReadOnlyProperty<Any?, T> {
override fun getValue(thisRef: Any?, property: KProperty<*>): T {
val actualName = name ?: property.name.asName()
val sequence = sequence<MetaItem<*>> {
var thisObj: VisualObject? = this@merge
while (thisObj != null) {
thisObj.config[actualName]?.let { yield(it) }
thisObj = thisObj.parent
}
}
return transformer(sequence)
}
}
}

View File

@ -5,25 +5,9 @@ import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.node import hep.dataforge.meta.node
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.isEmpty
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
/**
* Return nearest selectable parent [Name]
*/
tailrec fun Name.selectable(): Name? = when {
isEmpty() -> {
null
}
last()?.body?.startsWith("@") != true -> {
this
}
else -> {
cutLast().selectable()
}
}
fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? { fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? {
return when (val first = filterNotNull().firstOrNull()) { return when (val first = filterNotNull().firstOrNull()) {
null -> null null -> null

View File

@ -40,7 +40,7 @@ interface Application {
fun startApplication(builder: () -> Application) { fun startApplication(builder: () -> Application) {
fun start(state: dynamic): Application? { fun start(state: dynamic): Application? {
return if (document.body?.hasClass("testApp") == true) { return if (document.body?.hasClass("application") == true) {
val application = builder() val application = builder()
@Suppress("UnsafeCastFromDynamic") @Suppress("UnsafeCastFromDynamic")

View File

@ -1,8 +1,10 @@
package hep.dataforge.js package hep.dataforge.js
import hep.dataforge.meta.DFExperimental
import hep.dataforge.properties.Property import hep.dataforge.properties.Property
import org.w3c.dom.HTMLInputElement import org.w3c.dom.HTMLInputElement
@DFExperimental
fun HTMLInputElement.bindValue(property: Property<String>) { fun HTMLInputElement.bindValue(property: Property<String>) {
if (this.onchange != null) error("Input element already bound") if (this.onchange != null) error("Input element already bound")
this.onchange = { this.onchange = {
@ -16,6 +18,7 @@ fun HTMLInputElement.bindValue(property: Property<String>) {
} }
} }
@DFExperimental
fun HTMLInputElement.bindChecked(property: Property<Boolean>) { fun HTMLInputElement.bindChecked(property: Property<Boolean>) {
if (this.onchange != null) error("Input element already bound") if (this.onchange != null) error("Input element already bound")
this.onchange = { this.onchange = {

View File

@ -36,7 +36,7 @@ class VisualObjectEditorFragment(val selector: (VisualObject) -> Meta) : Fragmen
val config = Config().apply { val config = Config().apply {
update(meta) update(meta)
onChange(this@VisualObjectEditorFragment) { key, _, after -> onChange(this@VisualObjectEditorFragment) { key, _, after ->
visualObject.setProperty(key, after) visualObject.setItem(key, after)
} }
} }
//remember old config reference to cleanup listeners //remember old config reference to cleanup listeners

View File

@ -35,7 +35,7 @@ fun main() {
} }
fun start(state: dynamic): ApplicationBase? { fun start(state: dynamic): ApplicationBase? {
return if (document.body?.hasClass("testApp") == true) { return if (document.body?.hasClass("application") == true) {
val application = JSRootDemoApp() val application = JSRootDemoApp()
@Suppress("UnsafeCastFromDynamic") @Suppress("UnsafeCastFromDynamic")

View File

@ -8,7 +8,7 @@
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous"> integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
<script type="text/javascript" src="dataforge-vis-spatial-gdml-0.1.0-dev.js"></script> <script type="text/javascript" src="dataforge-vis-spatial-gdml-0.1.0-dev.js"></script>
</head> </head>
<body class="testApp"> <body class="application">
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right" <div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда"> title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
Загрузить данные Загрузить данные

View File

@ -7,7 +7,7 @@ kotlin {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
api(project(":dataforge-vis-spatial")) api(project(":dataforge-vis-spatial"))
api("scientifik:gdml:0.1.7") api("scientifik:gdml:0.1.8")
} }
} }
} }

View File

@ -1,9 +1,9 @@
package hep.dataforge.vis.spatial.gdml package hep.dataforge.vis.spatial.gdml
import scientifik.gdml.AUnit
import scientifik.gdml.GDMLPosition import scientifik.gdml.GDMLPosition
import scientifik.gdml.GDMLRotation import scientifik.gdml.GDMLRotation
import scientifik.gdml.GDMLSolid import scientifik.gdml.GDMLSolid
import kotlin.math.PI
enum class LUnit(val value: Float) { enum class LUnit(val value: Float) {
MM(1f), MM(1f),
@ -11,13 +11,6 @@ enum class LUnit(val value: Float) {
M(1000f) M(1000f)
} }
enum class AUnit(val value: Float) {
DEG(PI.toFloat() / 180),
DEGREE(PI.toFloat() / 180),
RAD(1f),
RADIAN(1f)
}
fun GDMLPosition.unit(): LUnit = LUnit.valueOf(unit.toUpperCase()) fun GDMLPosition.unit(): LUnit = LUnit.valueOf(unit.toUpperCase())
fun GDMLPosition.x(unit: LUnit): Float = if (unit.name == this.unit) { fun GDMLPosition.x(unit: LUnit): Float = if (unit.name == this.unit) {

View File

@ -148,6 +148,7 @@ private fun VisualGroup3D.addSolid(
} }
} }
} }
else -> error("Renderer for $solid not supported yet")
}.apply(block) }.apply(block)
} }

View File

@ -25,7 +25,7 @@ class Box(
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var properties: Config? = null override var ownProperties: Config? = null
//TODO add helper for color configuration //TODO add helper for color configuration
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) { override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {

View File

@ -33,7 +33,7 @@ class Composite(
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var properties: Config? = null override var ownProperties: Config? = null
override val children: Map<NameToken, VisualObject> override val children: Map<NameToken, VisualObject>
get() = mapOf(NameToken("first") to first, NameToken("second") to second) get() = mapOf(NameToken("first") to first, NameToken("second") to second)
@ -48,7 +48,7 @@ inline fun MutableVisualGroup.composite(
builder: VisualGroup3D.() -> Unit builder: VisualGroup3D.() -> Unit
): Composite { ): Composite {
val group = VisualGroup3D().apply(builder) val group = VisualGroup3D().apply(builder)
val children = group.filterIsInstance<VisualObject3D>() val children = group.children.values.filterIsInstance<VisualObject3D>()
if (children.size != 2) error("Composite requires exactly two children") if (children.size != 2) error("Composite requires exactly two children")
return Composite(type, children[0], children[1]).also { return Composite(type, children[0], children[1]).also {
it.config.update(group.config) it.config.update(group.config)

View File

@ -25,7 +25,7 @@ class ConeSegment(
var angle: Float = PI2 var angle: Float = PI2
) : AbstractVisualObject(), VisualObject3D, Shape { ) : AbstractVisualObject(), VisualObject3D, Shape {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -14,7 +14,7 @@ import kotlinx.serialization.UseSerializers
@SerialName("3d.convex") @SerialName("3d.convex")
class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D { class Convex(val points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -45,7 +45,7 @@ class Extruded(
var layers: MutableList<Layer> = ArrayList() var layers: MutableList<Layer> = ArrayList()
) : AbstractVisualObject(), VisualObject3D, Shape { ) : AbstractVisualObject(), VisualObject3D, Shape {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -13,7 +13,7 @@ import kotlinx.serialization.UseSerializers
@Serializable @Serializable
@SerialName("3d.label") @SerialName("3d.label")
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(), VisualObject3D { class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVisualObject(), VisualObject3D {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -78,17 +78,17 @@ class Material3D : Scheme() {
* Set color as web-color * Set color as web-color
*/ */
fun VisualObject3D.color(webColor: String) { fun VisualObject3D.color(webColor: String) {
setProperty(MATERIAL_COLOR_KEY, webColor.asValue()) setItem(MATERIAL_COLOR_KEY, webColor.asValue())
} }
/** /**
* Set color as integer * Set color as integer
*/ */
fun VisualObject3D.color(rgb: Int) { fun VisualObject3D.color(rgb: Int) {
setProperty(MATERIAL_COLOR_KEY, rgb.asValue()) setItem(MATERIAL_COLOR_KEY, rgb.asValue())
} }
fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty( fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setItem(
MATERIAL_COLOR_KEY, MATERIAL_COLOR_KEY,
Colors.rgbToMeta(r, g, b) Colors.rgbToMeta(r, g, b)
) )
@ -97,13 +97,13 @@ fun VisualObject3D.color(r: UByte, g: UByte, b: UByte) = setProperty(
* Web colors representation of the color in `#rrggbb` format or HTML name * Web colors representation of the color in `#rrggbb` format or HTML name
*/ */
var VisualObject3D.color: String? var VisualObject3D.color: String?
get() = getProperty(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) } get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
set(value) { set(value) {
setProperty(MATERIAL_COLOR_KEY, value?.asValue()) setItem(MATERIAL_COLOR_KEY, value?.asValue())
} }
val VisualObject3D.material: Material3D? val VisualObject3D.material: Material3D?
get() = getProperty(MATERIAL_KEY).node?.let { Material3D.wrap(it) } get() = getItem(MATERIAL_KEY).node?.let { Material3D.wrap(it) }
fun VisualObject3D.material(builder: Material3D.() -> Unit) { fun VisualObject3D.material(builder: Material3D.() -> Unit) {
val node = config[MATERIAL_KEY].node val node = config[MATERIAL_KEY].node
@ -115,7 +115,7 @@ fun VisualObject3D.material(builder: Material3D.() -> Unit) {
} }
var VisualObject3D.opacity: Double? var VisualObject3D.opacity: Double?
get() = getProperty(MATERIAL_OPACITY_KEY).double get() = getItem(MATERIAL_OPACITY_KEY).double
set(value) { set(value) {
setProperty(MATERIAL_OPACITY_KEY, value?.asValue()) setItem(MATERIAL_OPACITY_KEY, value?.asValue())
} }

View File

@ -16,7 +16,7 @@ import kotlinx.serialization.UseSerializers
@Serializable @Serializable
@SerialName("3d.line") @SerialName("3d.line")
class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject3D { class PolyLine(var points: List<Point3D>) : AbstractVisualObject(), VisualObject3D {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -34,7 +34,7 @@ class Proxy private constructor(
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var properties: Config? = null override var ownProperties: Config? = null
/** /**
* Recursively search for defined template in the parent * Recursively search for defined template in the parent
@ -51,14 +51,14 @@ class Proxy private constructor(
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) { return if (inherit) {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
yield(prototype.getProperty(name)) yield(prototype.getItem(name))
yield(parent?.getProperty(name, inherit)) yield(parent?.getProperty(name, inherit))
}.merge() }.merge()
} else { } else {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
yield(prototype.getProperty(name, false)) yield(prototype.getProperty(name, false))
}.merge() }.merge()
@ -84,8 +84,8 @@ class Proxy private constructor(
?: error("Prototype with name $name not found in $this") ?: error("Prototype with name $name not found in $this")
} }
override fun allProperties(): Laminate = override fun properties(): Laminate =
Laminate(properties, mergedStyles, prototype.allProperties(), parent?.allProperties()) Laminate(ownProperties, mergedStyles, prototype.properties(), parent?.properties())
override fun attachChildren() { override fun attachChildren() {
//do nothing //do nothing
@ -110,7 +110,7 @@ class Proxy private constructor(
) )
} ?: emptyMap() } ?: emptyMap()
override var properties: Config? override var ownProperties: Config?
get() = propertyCache[name] get() = propertyCache[name]
set(value) { set(value) {
if (value == null) { if (value == null) {
@ -130,14 +130,14 @@ class Proxy private constructor(
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? { override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) { return if (inherit) {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
yield(prototype.getProperty(name)) yield(prototype.getItem(name))
yield(parent?.getProperty(name, inherit)) yield(parent?.getProperty(name, inherit))
}.merge() }.merge()
} else { } else {
sequence { sequence {
yield(properties?.get(name)) yield(ownProperties?.get(name))
yield(mergedStyles[name]) yield(mergedStyles[name])
yield(prototype.getProperty(name, false)) yield(prototype.getProperty(name, false))
}.merge() }.merge()
@ -148,8 +148,8 @@ class Proxy private constructor(
//do nothing //do nothing
} }
override fun allProperties(): Laminate = override fun properties(): Laminate =
Laminate(properties, mergedStyles, prototype.allProperties(), parent?.allProperties()) Laminate(ownProperties, mergedStyles, prototype.properties(), parent?.properties())
override val descriptor: NodeDescriptor? override val descriptor: NodeDescriptor?

View File

@ -23,7 +23,7 @@ class Sphere(
var theta: Float = PI.toFloat() var theta: Float = PI.toFloat()
) : AbstractVisualObject(), VisualObject3D, Shape { ) : AbstractVisualObject(), VisualObject3D, Shape {
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null

View File

@ -29,7 +29,7 @@ class Tube(
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var properties: Config? = null override var ownProperties: Config? = null
init { init {
require(radius > 0) require(radius > 0)

View File

@ -55,7 +55,7 @@ class Visual3D(meta: Meta) : AbstractPlugin(meta) {
} }
@OptIn(UnstableDefault::class) @OptIn(UnstableDefault::class)
internal val json = Json( val json = Json(
JsonConfiguration( JsonConfiguration(
prettyPrint = true, prettyPrint = true,
useArrayPolymorphism = false, useArrayPolymorphism = false,

View File

@ -46,7 +46,7 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, PrototypeHolder {
} }
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed //FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var properties: Config? = null override var ownProperties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null
@ -121,7 +121,7 @@ internal class Prototypes(
override fun createGroup() = SimpleVisualGroup() override fun createGroup() = SimpleVisualGroup()
override var properties: Config? override var ownProperties: Config?
get() = null get() = null
set(_) { set(_) {
error("Can't define properties for prototypes block") error("Can't define properties for prototypes block")

View File

@ -87,9 +87,9 @@ interface VisualObject3D : VisualObject {
* Count number of layers to the top object. Return 1 if this is top layer * Count number of layers to the top object. Return 1 if this is top layer
*/ */
var VisualObject3D.layer: Int var VisualObject3D.layer: Int
get() = getProperty(LAYER_KEY).int ?: 0 get() = getItem(LAYER_KEY).int ?: 0
set(value) { set(value) {
setProperty(LAYER_KEY, value.asValue()) setItem(LAYER_KEY, value.asValue())
} }
fun Renderer<VisualObject3D>.render(meta: Meta = Meta.EMPTY, action: VisualGroup3D.() -> Unit) = fun Renderer<VisualObject3D>.render(meta: Meta = Meta.EMPTY, action: VisualGroup3D.() -> Unit) =
@ -110,8 +110,8 @@ enum class RotationOrder {
* Rotation order * Rotation order
*/ */
var VisualObject3D.rotationOrder: RotationOrder var VisualObject3D.rotationOrder: RotationOrder
get() = getProperty(VisualObject3D.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ get() = getItem(VisualObject3D.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) = setProperty(VisualObject3D.ROTATION_ORDER_KEY, value.name.asValue()) set(value) = setItem(VisualObject3D.ROTATION_ORDER_KEY, value.name.asValue())
/** /**
@ -119,11 +119,11 @@ var VisualObject3D.rotationOrder: RotationOrder
*/ */
var VisualObject3D.detail: Int? var VisualObject3D.detail: Int?
get() = getProperty(DETAIL_KEY, false).int get() = getProperty(DETAIL_KEY, false).int
set(value) = setProperty(DETAIL_KEY, value?.asValue()) set(value) = setItem(DETAIL_KEY, value?.asValue())
var VisualObject.visible: Boolean? var VisualObject.visible: Boolean?
get() = getProperty(VISIBLE_KEY).boolean get() = getItem(VISIBLE_KEY).boolean
set(value) = setProperty(VISIBLE_KEY, value?.asValue()) set(value) = setItem(VISIBLE_KEY, value?.asValue())
/** /**
* If this property is true, the object will be ignored on render. * If this property is true, the object will be ignored on render.
@ -131,7 +131,7 @@ var VisualObject.visible: Boolean?
*/ */
var VisualObject.ignore: Boolean? var VisualObject.ignore: Boolean?
get() = getProperty(IGNORE_KEY, false).boolean get() = getProperty(IGNORE_KEY, false).boolean
set(value) = setProperty(IGNORE_KEY, value?.asValue()) set(value) = setItem(IGNORE_KEY, value?.asValue())
//var VisualObject.selected: Boolean? //var VisualObject.selected: Boolean?
// get() = getProperty(SELECTED_KEY).boolean // get() = getProperty(SELECTED_KEY).boolean

View File

@ -24,7 +24,7 @@ class ConvexTest {
} }
} }
val convex = group.first() as Convex val convex = group.children.values.first() as Convex
val json = Visual3D.json.toJson(Convex.serializer(), convex) val json = Visual3D.json.toJson(Convex.serializer(), convex)
val meta = json.toMetaItem().node!! val meta = json.toMetaItem().node!!

View File

@ -44,7 +44,7 @@ class GroupTest {
} }
} }
assertEquals(3, group.count()) assertEquals(3, group.children.count())
assertEquals(300.0, (group["intersect"] as VisualObject3D).y.toDouble()) assertEquals(300.0, (group["intersect"] as VisualObject3D).y.toDouble())
assertEquals(-300.0, (group["subtract"] as VisualObject3D).y.toDouble()) assertEquals(-300.0, (group["subtract"] as VisualObject3D).y.toDouble())
} }

View File

@ -18,7 +18,7 @@ class PropertyTest {
box = box(100, 100, 100) box = box(100, 100, 100)
} }
} }
assertEquals(22, box?.getProperty("test".asName()).int) assertEquals(22, box?.getItem("test".asName()).int)
} }
@Test @Test
@ -36,7 +36,7 @@ class PropertyTest {
} }
} }
} }
assertEquals(22, box?.getProperty("test".asName()).int) assertEquals(22, box?.getItem("test".asName()).int)
} }
@Test @Test

View File

@ -85,9 +85,9 @@ fun Mesh.applyEdges(obj: VisualObject3D) {
(it as LineSegments).dispose() (it as LineSegments).dispose()
} }
//inherited edges definition, enabled by default //inherited edges definition, enabled by default
if (obj.getProperty(MeshThreeFactory.EDGES_ENABLED_KEY).boolean != false) { if (obj.getItem(MeshThreeFactory.EDGES_ENABLED_KEY).boolean != false) {
val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node) val material = ThreeMaterials.getLineMaterial(obj.getItem(MeshThreeFactory.EDGES_MATERIAL_KEY).node)
add( add(
LineSegments( LineSegments(
EdgesGeometry(geometry as BufferGeometry), EdgesGeometry(geometry as BufferGeometry),
@ -105,8 +105,8 @@ fun Mesh.applyWireFrame(obj: VisualObject3D) {
(it as LineSegments).dispose() (it as LineSegments).dispose()
} }
//inherited wireframe definition, disabled by default //inherited wireframe definition, disabled by default
if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) { if (obj.getItem(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) {
val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node) val material = ThreeMaterials.getLineMaterial(obj.getItem(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node)
add( add(
LineSegments( LineSegments(
WireframeGeometry(geometry as BufferGeometry), WireframeGeometry(geometry as BufferGeometry),

View File

@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial.three
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.getProperty import hep.dataforge.meta.getItem
import hep.dataforge.meta.string import hep.dataforge.meta.string
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.plus import hep.dataforge.names.plus
@ -160,7 +160,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val canvas: Canv
} }
private fun addControls(element: Node, controls: Controls) { private fun addControls(element: Node, controls: Controls) {
when (controls.getProperty("type").string) { when (controls.getItem("type").string) {
"trackball" -> TrackballControls(camera, element) "trackball" -> TrackballControls(camera, element)
else -> OrbitControls(camera, element) else -> OrbitControls(camera, element)
} }

View File

@ -18,7 +18,7 @@ object ThreeLineFactory : ThreeFactory<PolyLine> {
vertices = obj.points.toTypedArray() vertices = obj.points.toTypedArray()
} }
val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node) val material = ThreeMaterials.getLineMaterial(obj.getItem(MeshThreeFactory.EDGES_MATERIAL_KEY).node)
material.linewidth = obj.thickness.toDouble() material.linewidth = obj.thickness.toDouble()
material.color = obj.color?.let { Color(it) } ?: DEFAULT_LINE_COLOR material.color = obj.color?.let { Color(it) } ?: DEFAULT_LINE_COLOR

View File

@ -5,7 +5,6 @@ import hep.dataforge.values.ValueType
import hep.dataforge.vis.Colors import hep.dataforge.vis.Colors
import hep.dataforge.vis.VisualObject import hep.dataforge.vis.VisualObject
import hep.dataforge.vis.spatial.Material3D import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_SPECULAR_COLOR_KEY
import info.laht.threekt.materials.LineBasicMaterial import info.laht.threekt.materials.LineBasicMaterial
import info.laht.threekt.materials.Material import info.laht.threekt.materials.Material
import info.laht.threekt.materials.MeshBasicMaterial import info.laht.threekt.materials.MeshBasicMaterial
@ -45,7 +44,7 @@ object ThreeMaterials {
} }
fun getMaterial(visualObject3D: VisualObject): Material { fun getMaterial(visualObject3D: VisualObject): Material {
val meta = visualObject3D.getProperty(Material3D.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT val meta = visualObject3D.getItem(Material3D.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT
return if (meta[Material3D.SPECULAR_COLOR_KEY] != null) { return if (meta[Material3D.SPECULAR_COLOR_KEY] != null) {
MeshPhongMaterial().apply { MeshPhongMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR

View File

@ -25,7 +25,7 @@ class CustomThreeVisualObject(val threeFactory: ThreeFactory<VisualObject3D>) :
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var properties: Config? = null override var ownProperties: Config? = null
override fun toObject3D(): Object3D = threeFactory(this) override fun toObject3D(): Object3D = threeFactory(this)

View File

@ -73,7 +73,7 @@ class FX3DPlugin : AbstractPlugin() {
is PolyLine -> PolyLine3D( is PolyLine -> PolyLine3D(
obj.points.map { it.point }, obj.points.map { it.point },
obj.thickness.toFloat(), obj.thickness.toFloat(),
obj.getProperty(Material3D.MATERIAL_COLOR_KEY)?.color() obj.getItem(Material3D.MATERIAL_COLOR_KEY)?.color()
).apply { ).apply {
this.meshView.cullFace = CullFace.FRONT this.meshView.cullFace = CullFace.FRONT
} }

View File

@ -34,7 +34,7 @@ class VisualObjectFXBinding(val obj: VisualObject) {
operator fun get(key: Name): ObjectBinding<MetaItem<*>?> { operator fun get(key: Name): ObjectBinding<MetaItem<*>?> {
return bindings.getOrPut(key) { return bindings.getOrPut(key) {
object : ObjectBinding<MetaItem<*>?>() { object : ObjectBinding<MetaItem<*>?>() {
override fun computeValue(): MetaItem<*>? = obj.getProperty(key) override fun computeValue(): MetaItem<*>? = obj.getItem(key)
} }
} }
} }

View File

@ -12,7 +12,7 @@ fun cubes(): GDML = GDML {
val segment = solids.tube("segment", 20, 5.0) { val segment = solids.tube("segment", 20, 5.0) {
rmin = 17 rmin = 17
deltaphi = 60 deltaphi = 60
aunit = DEG aunit = AUnit.DEG.title
} }
val worldBox = solids.box("LargeBox", 200, 200, 200) val worldBox = solids.box("LargeBox", 200, 200, 200)
val smallBox = solids.box("smallBox", 30, 30, 30) val smallBox = solids.box("smallBox", 30, 30, 30)
@ -24,7 +24,7 @@ fun cubes(): GDML = GDML {
positionref = center.ref() positionref = center.ref()
rotation { rotation {
z = 60 * i z = 60 * i
unit = DEG unit = AUnit.DEG.title
} }
} }
} }

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis.spatial.gdml package hep.dataforge.vis.spatial.gdml
import hep.dataforge.meta.setProperty import hep.dataforge.meta.setItem
import hep.dataforge.meta.string import hep.dataforge.meta.string
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
@ -14,7 +14,7 @@ class GDMLVisualTest {
fun testPrototypeProperty() { fun testPrototypeProperty() {
val gdml = cubes() val gdml = cubes()
val visual = gdml.toVisual() val visual = gdml.toVisual()
visual["composite000.segment0".toName()]?.setProperty(Material3D.MATERIAL_COLOR_KEY, "red".asValue()) visual["composite000.segment0".toName()]?.setItem(Material3D.MATERIAL_COLOR_KEY, "red".asValue())
assertEquals("red", visual["composite000.segment0".toName()]?.getProperty(Material3D.MATERIAL_COLOR_KEY).string) assertEquals("red", visual["composite000.segment0".toName()]?.getItem(Material3D.MATERIAL_COLOR_KEY).string)
} }
} }

View File

@ -143,7 +143,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
else -> (visual as? VisualGroup)?.get(selected) else -> (visual as? VisualGroup)?.get(selected)
} }
if (selectedObject != null) { if (selectedObject != null) {
configEditor(selectedObject, default = selectedObject.allProperties(), key = selected) configEditor(selectedObject, default = selectedObject.properties(), key = selected)
} }
} }
} }

View File

@ -11,7 +11,7 @@
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script> <script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script> <script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
</head> </head>
<body class="testApp"> <body class="application">
<div class="container-fluid" id = "app"> </div> <div class="container-fluid" id = "app"> </div>
</body> </body>
</html> </html>

View File

@ -24,7 +24,7 @@ class GDMLView : View() {
} }
private val propertyEditor = VisualObjectEditorFragment { private val propertyEditor = VisualObjectEditorFragment {
it.allProperties() it.properties()
}.apply { }.apply {
descriptorProperty.set(Material3D.descriptor) descriptorProperty.set(Material3D.descriptor)
itemProperty.bind(treeFragment.selectedProperty) itemProperty.bind(treeFragment.selectedProperty)

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis.spatial.gdml.demo package hep.dataforge.vis.spatial.gdml.demo
import hep.dataforge.meta.setProperty import hep.dataforge.meta.setItem
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vis.spatial.Material3D import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.Visual3D import hep.dataforge.vis.spatial.Visual3D
@ -20,7 +20,7 @@ fun Visual3D.Companion.readFile(file: File): VisualGroup3D = when {
solidConfiguration = { parent, solid -> solidConfiguration = { parent, solid ->
if (solid.name == "cave") { if (solid.name == "cave") {
setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue()) setItem(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue())
} }
if (parent.physVolumes.isNotEmpty()) { if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") { useStyle("opaque") {

View File

@ -1,4 +1,3 @@
import kotlinx.atomicfu.plugin.gradle.withKotlinTargets
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
import scientifik.jsDistDirectory import scientifik.jsDistDirectory
@ -74,4 +73,15 @@ kotlin {
application { application {
mainClassName = "ru.mipt.npm.muon.monitor.server.MMServerKt" mainClassName = "ru.mipt.npm.muon.monitor.server.MMServerKt"
}
distributions {
main {
contents {
from("$buildDir/libs") {
rename("${rootProject.name}-jvm", rootProject.name)
into("lib")
}
}
}
} }

View File

@ -63,7 +63,7 @@ class Model {
fun reset() { fun reset() {
map.values.forEach { map.values.forEach {
it.config it.config
it.setProperty(Material3D.MATERIAL_COLOR_KEY, null) it.setItem(Material3D.MATERIAL_COLOR_KEY, null)
} }
tracks.removeAll() tracks.removeAll()
} }

View File

@ -155,7 +155,7 @@ val MMApp = component<MMAppProps> { props ->
else -> visual[selected] else -> visual[selected]
} }
if (selectedObject != null) { if (selectedObject != null) {
configEditor(selectedObject, default = selectedObject.allProperties(), key = selected) configEditor(selectedObject, default = selectedObject.properties(), key = selected)
} }
} }
} }

View File

@ -10,7 +10,7 @@
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script> <script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script> <script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
</head> </head>
<body class="testApp"> <body class="application">
<div class="container-fluid" id = "app"> </div> <div class="container-fluid" id = "app"> </div>
</body> </body>
</html> </html>

View File

@ -4,7 +4,7 @@ package hep.dataforge.vis.spatial.demo
import hep.dataforge.meta.int import hep.dataforge.meta.int
import hep.dataforge.meta.number import hep.dataforge.meta.number
import hep.dataforge.meta.setProperty import hep.dataforge.meta.setItem
import hep.dataforge.names.plus import hep.dataforge.names.plus
import hep.dataforge.names.startsWith import hep.dataforge.names.startsWith
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
@ -26,13 +26,13 @@ import kotlin.reflect.KClass
internal var VisualObject3D.variableZSize: Number internal var VisualObject3D.variableZSize: Number
get() = getProperty(Z_SIZE_KEY, false).number ?: 0f get() = getProperty(Z_SIZE_KEY, false).number ?: 0f
set(value) { set(value) {
setProperty(Z_SIZE_KEY, value.asValue()) setItem(Z_SIZE_KEY, value.asValue())
} }
internal var VisualObject3D.value: Int internal var VisualObject3D.value: Int
get() = getProperty("value", false).int ?: 0 get() = getProperty("value", false).int ?: 0
set(value) { set(value) {
setProperty("value", value.asValue()) setItem("value", value.asValue())
val size = value.toFloat() / 255f * 20f val size = value.toFloat() / 255f * 20f
scaleZ = size scaleZ = size
z = -size / 2 z = -size / 2

View File

@ -8,7 +8,7 @@
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
<script type="text/javascript" src="main.bundle.js"></script> <script type="text/javascript" src="main.bundle.js"></script>
</head> </head>
<body class="testApp"> <body class="application">
<div class="container"> <div class="container">
<h1>Demo grid</h1> <h1>Demo grid</h1>
</div> </div>

View File

@ -7,7 +7,7 @@
<link rel="stylesheet" href="css/common.css"> <link rel="stylesheet" href="css/common.css">
<script type="text/javascript" src="playground.js"></script> <script type="text/javascript" src="playground.js"></script>
</head> </head>
<body class="testApp"> <body class="application">
<div class="container"> <div class="container">
<h1>Playground</h1> <h1>Playground</h1>
</div> </div>

View File

@ -1,4 +1,7 @@
pluginManagement { pluginManagement {
val kotlinVersion = "1.3.72"
val toolsVersion = "0.5.2"
repositories { repositories {
mavenLocal() mavenLocal()
jcenter() jcenter()
@ -10,11 +13,18 @@ pluginManagement {
maven("https://dl.bintray.com/mipt-npm/dev") maven("https://dl.bintray.com/mipt-npm/dev")
} }
plugins {
kotlin("jvm") version kotlinVersion
id("scientifik.mpp") version toolsVersion
id("scientifik.jvm") version toolsVersion
id("scientifik.js") version toolsVersion
id("scientifik.publish") version toolsVersion
}
resolutionStrategy { resolutionStrategy {
eachPlugin { eachPlugin {
when (requested.id.id) { when (requested.id.id) {
"scientifik.mpp", "scientifik.publish", "scientifik.jvm", "scientifik.js" -> useModule("scientifik:gradle-tools:${requested.version}") "scientifik.mpp", "scientifik.publish", "scientifik.jvm", "scientifik.js" -> useModule("scientifik:gradle-tools:${toolsVersion}")
"org.openjfx.javafxplugin" -> useModule("org.openjfx:javafx-plugin:${requested.version}")
} }
} }
} }