Separate modules for jsroot and gdml
This commit is contained in:
parent
67def6cdb5
commit
f4221d66cc
@ -1,5 +1,10 @@
|
||||
package hep.dataforge.vis.common
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.meta.set
|
||||
|
||||
/**
|
||||
* Taken from https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt
|
||||
*/
|
||||
@ -174,4 +179,23 @@ object Colors {
|
||||
const val whitesmoke = 0xF5F5F5
|
||||
const val yellow = 0xFFFF00
|
||||
const val yellowgreen = 0x9ACD32
|
||||
}
|
||||
|
||||
|
||||
fun VisualObject.color(rgb: Int) {
|
||||
this.properties["material"] = rgb
|
||||
}
|
||||
|
||||
fun VisualObject.color(meta: Meta) {
|
||||
this.properties["material"] = meta
|
||||
}
|
||||
|
||||
fun VisualObject.color(builder: MetaBuilder.() -> Unit) {
|
||||
color(buildMeta(builder))
|
||||
}
|
||||
|
||||
fun VisualObject.color(r: Int, g: Int, b: Int) = color {
|
||||
"red" to r
|
||||
"green" to g
|
||||
"blue" to b
|
||||
}
|
@ -10,33 +10,33 @@ import hep.dataforge.provider.Provider
|
||||
/**
|
||||
* A display group which allows both named and unnamed children
|
||||
*/
|
||||
class DisplayGroup(
|
||||
override val parent: DisplayObject? = null, meta: Meta = EmptyMeta
|
||||
) : DisplayObject, Iterable<DisplayObject>, Provider {
|
||||
class VisualGroup(
|
||||
override val parent: VisualObject? = null, meta: Meta = EmptyMeta
|
||||
) : VisualObject, Iterable<VisualObject>, Provider {
|
||||
|
||||
private val namedChildren = HashMap<Name, DisplayObject>()
|
||||
private val unnamedChildren = ArrayList<DisplayObject>()
|
||||
private val namedChildren = HashMap<Name, VisualObject>()
|
||||
private val unnamedChildren = ArrayList<VisualObject>()
|
||||
|
||||
override val defaultTarget: String get() = DisplayObject.TYPE
|
||||
override val defaultTarget: String get() = VisualObject.TYPE
|
||||
override val properties: Styled = Styled(meta)
|
||||
|
||||
override fun iterator(): Iterator<DisplayObject> = (namedChildren.values + unnamedChildren).iterator()
|
||||
override fun iterator(): Iterator<VisualObject> = (namedChildren.values + unnamedChildren).iterator()
|
||||
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when(target){
|
||||
DisplayObject.TYPE -> namedChildren
|
||||
VisualObject.TYPE -> namedChildren
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
private data class Listener(val owner: Any?, val callback: (Name?, DisplayObject?) -> Unit)
|
||||
private data class Listener(val owner: Any?, val callback: (Name?, VisualObject?) -> Unit)
|
||||
|
||||
private val listeners = HashSet<Listener>()
|
||||
|
||||
/**
|
||||
* Add listener for children change
|
||||
*/
|
||||
fun onChildrenChange(owner: Any?, action: (Name?, DisplayObject?) -> Unit) {
|
||||
fun onChildrenChange(owner: Any?, action: (Name?, VisualObject?) -> Unit) {
|
||||
listeners.add(Listener(owner, action))
|
||||
}
|
||||
|
||||
@ -51,7 +51,7 @@ class DisplayGroup(
|
||||
/**
|
||||
*
|
||||
*/
|
||||
operator fun set(key: String?, child: DisplayObject?) {
|
||||
operator fun set(key: String?, child: VisualObject?) {
|
||||
if(key == null){
|
||||
|
||||
} else {
|
||||
@ -68,7 +68,7 @@ class DisplayGroup(
|
||||
/**
|
||||
* Append unnamed child
|
||||
*/
|
||||
fun add(child: DisplayObject) {
|
||||
fun add(child: VisualObject) {
|
||||
unnamedChildren.add(child)
|
||||
listeners.forEach { it.callback(null, child) }
|
||||
}
|
||||
@ -76,7 +76,7 @@ class DisplayGroup(
|
||||
/**
|
||||
* remove unnamed child
|
||||
*/
|
||||
fun remove(child: DisplayObject) {
|
||||
fun remove(child: VisualObject) {
|
||||
unnamedChildren.remove(child)
|
||||
listeners.forEach { it.callback(null, null) }
|
||||
}
|
@ -4,20 +4,20 @@ import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.vis.common.DisplayObject.Companion.META_KEY
|
||||
import hep.dataforge.vis.common.DisplayObject.Companion.TAGS_KEY
|
||||
import hep.dataforge.vis.common.DisplayObject.Companion.TYPE
|
||||
import hep.dataforge.vis.common.VisualObject.Companion.META_KEY
|
||||
import hep.dataforge.vis.common.VisualObject.Companion.TAGS_KEY
|
||||
import hep.dataforge.vis.common.VisualObject.Companion.TYPE
|
||||
|
||||
/**
|
||||
* A root type for display hierarchy
|
||||
*/
|
||||
@Type(TYPE)
|
||||
interface DisplayObject : MetaRepr {
|
||||
interface VisualObject : MetaRepr {
|
||||
|
||||
/**
|
||||
* The parent object of this one. If null, this one is a root.
|
||||
*/
|
||||
val parent: DisplayObject?
|
||||
val parent: VisualObject?
|
||||
|
||||
val properties: Styled
|
||||
|
||||
@ -26,7 +26,7 @@ interface DisplayObject : MetaRepr {
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE = "display"
|
||||
const val TYPE = "visual"
|
||||
|
||||
const val DEFAULT_TYPE = ""
|
||||
//const val TYPE_KEY = "@type"
|
||||
@ -39,14 +39,14 @@ interface DisplayObject : MetaRepr {
|
||||
/**
|
||||
* Get the property of this display object of parent's if not found
|
||||
*/
|
||||
tailrec fun DisplayObject.getProperty(name: Name): MetaItem<*>? = properties[name] ?: parent?.getProperty(name)
|
||||
tailrec fun VisualObject.getProperty(name: Name): MetaItem<*>? = properties[name] ?: parent?.getProperty(name)
|
||||
|
||||
fun DisplayObject.getProperty(name: String): MetaItem<*>? = getProperty(name.toName())
|
||||
fun VisualObject.getProperty(name: String): MetaItem<*>? = getProperty(name.toName())
|
||||
|
||||
/**
|
||||
* A change listener for [DisplayObject] configuration.
|
||||
* A change listener for [VisualObject] configuration.
|
||||
*/
|
||||
fun DisplayObject.onChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit) {
|
||||
fun VisualObject.onChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit) {
|
||||
properties.onChange(owner, action)
|
||||
parent?.onChange(owner, action)
|
||||
}
|
||||
@ -54,7 +54,7 @@ fun DisplayObject.onChange(owner: Any?, action: (Name, before: MetaItem<*>?, aft
|
||||
/**
|
||||
* Remove all meta listeners with matching owners
|
||||
*/
|
||||
fun DisplayObject.removeChangeListener(owner: Any?) {
|
||||
fun VisualObject.removeChangeListener(owner: Any?) {
|
||||
properties.removeListener(owner)
|
||||
parent?.removeChangeListener(owner)
|
||||
}
|
||||
@ -63,24 +63,24 @@ fun DisplayObject.removeChangeListener(owner: Any?) {
|
||||
/**
|
||||
* Additional meta not relevant to display
|
||||
*/
|
||||
val DisplayObject.meta: Meta get() = properties[META_KEY]?.node ?: EmptyMeta
|
||||
val VisualObject.meta: Meta get() = properties[META_KEY]?.node ?: EmptyMeta
|
||||
|
||||
val DisplayObject.tags: List<String> get() = properties[TAGS_KEY].stringList
|
||||
val VisualObject.tags: List<String> get() = properties[TAGS_KEY].stringList
|
||||
|
||||
/**
|
||||
* Basic [DisplayObject] leaf element
|
||||
* Basic [VisualObject] leaf element
|
||||
*/
|
||||
open class DisplayLeaf(
|
||||
override val parent: DisplayObject?,
|
||||
override val parent: VisualObject?,
|
||||
meta: Meta = EmptyMeta
|
||||
) : DisplayObject {
|
||||
) : VisualObject {
|
||||
final override val properties = Styled(meta)
|
||||
}
|
||||
|
||||
///**
|
||||
// * A group that could contain both named and unnamed children. Unnamed children could be accessed only via
|
||||
// */
|
||||
//interface DisplayGroup : DisplayObject, Iterable<DisplayObject>, Provider {
|
||||
//interface VisualGroup : DisplayObject, Iterable<DisplayObject>, Provider {
|
||||
// override val defaultTarget: String get() = DisplayObject.TARGET
|
||||
//
|
||||
// val children
|
@ -16,8 +16,8 @@ class DisplayObjectDelegate(
|
||||
val key: Name?,
|
||||
val default: MetaItem<*>?,
|
||||
val inherited: Boolean
|
||||
) : ReadWriteProperty<DisplayObject, MetaItem<*>?> {
|
||||
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): MetaItem<*>? {
|
||||
) : ReadWriteProperty<VisualObject, MetaItem<*>?> {
|
||||
override fun getValue(thisRef: VisualObject, property: KProperty<*>): MetaItem<*>? {
|
||||
val name = key ?: property.name.toName()
|
||||
return if (inherited) {
|
||||
thisRef.getProperty(name)
|
||||
@ -26,7 +26,7 @@ class DisplayObjectDelegate(
|
||||
} ?: default
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: DisplayObject, property: KProperty<*>, value: MetaItem<*>?) {
|
||||
override fun setValue(thisRef: VisualObject, property: KProperty<*>, value: MetaItem<*>?) {
|
||||
val name = key ?: property.name.toName()
|
||||
thisRef.properties[name] = value
|
||||
}
|
||||
@ -38,8 +38,8 @@ class DisplayObjectDelegateWrapper<T>(
|
||||
val inherited: Boolean,
|
||||
val write: Config.(name: Name, value: T) -> Unit = { name, value -> set(name, value) },
|
||||
val read: (MetaItem<*>?) -> T?
|
||||
) : ReadWriteProperty<DisplayObject, T> {
|
||||
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): T {
|
||||
) : ReadWriteProperty<VisualObject, T> {
|
||||
override fun getValue(thisRef: VisualObject, property: KProperty<*>): T {
|
||||
val name = key ?: property.name.toName()
|
||||
return if (inherited) {
|
||||
read(thisRef.getProperty(name))
|
||||
@ -48,74 +48,74 @@ class DisplayObjectDelegateWrapper<T>(
|
||||
} ?: default
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: DisplayObject, property: KProperty<*>, value: T) {
|
||||
override fun setValue(thisRef: VisualObject, property: KProperty<*>, value: T) {
|
||||
val name = key ?: property.name.toName()
|
||||
thisRef.properties[name] = value
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
fun DisplayObject.value(default: Value? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.value(default: Value? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.value }
|
||||
|
||||
fun DisplayObject.string(default: String? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.string(default: String? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.string }
|
||||
|
||||
fun DisplayObject.boolean(default: Boolean? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.boolean(default: Boolean? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.boolean }
|
||||
|
||||
fun DisplayObject.number(default: Number? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.number(default: Number? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.number }
|
||||
|
||||
fun DisplayObject.double(default: Double? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.double(default: Double? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.double }
|
||||
|
||||
fun DisplayObject.int(default: Int? = null, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.int(default: Int? = null, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.int }
|
||||
|
||||
|
||||
fun DisplayObject.node(key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.node(key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), null, inherited) { it.node }
|
||||
|
||||
fun DisplayObject.item(key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.item(key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), null, inherited) { it }
|
||||
|
||||
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
|
||||
|
||||
@JvmName("safeString")
|
||||
fun DisplayObject.string(default: String, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.string(default: String, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.string }
|
||||
|
||||
@JvmName("safeBoolean")
|
||||
fun DisplayObject.boolean(default: Boolean, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.boolean(default: Boolean, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.boolean }
|
||||
|
||||
@JvmName("safeNumber")
|
||||
fun DisplayObject.number(default: Number, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.number(default: Number, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.number }
|
||||
|
||||
@JvmName("safeDouble")
|
||||
fun DisplayObject.double(default: Double, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.double(default: Double, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.double }
|
||||
|
||||
@JvmName("safeInt")
|
||||
fun DisplayObject.int(default: Int, key: String? = null, inherited: Boolean = true) =
|
||||
fun VisualObject.int(default: Int, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.int }
|
||||
|
||||
inline fun <reified E : Enum<E>> DisplayObject.enum(default: E, key: String? = null, inherited: Boolean = true) =
|
||||
inline fun <reified E : Enum<E>> VisualObject.enum(default: E, key: String? = null, inherited: Boolean = true) =
|
||||
DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { item -> item.string?.let { enumValueOf<E>(it) } }
|
||||
|
||||
//merge properties
|
||||
|
||||
fun <T> DisplayObject.merge(
|
||||
fun <T> VisualObject.merge(
|
||||
key: String? = null,
|
||||
transformer: (Sequence<MetaItem<*>>) -> T
|
||||
): ReadOnlyProperty<DisplayObject, T> {
|
||||
return object : ReadOnlyProperty<DisplayObject, T> {
|
||||
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): T {
|
||||
): ReadOnlyProperty<VisualObject, T> {
|
||||
return object : ReadOnlyProperty<VisualObject, T> {
|
||||
override fun getValue(thisRef: VisualObject, property: KProperty<*>): T {
|
||||
val name = key?.toName() ?: property.name.toName()
|
||||
val sequence = sequence<MetaItem<*>> {
|
||||
var thisObj: DisplayObject? = thisRef
|
||||
var thisObj: VisualObject? = thisRef
|
||||
while (thisObj != null) {
|
||||
thisObj.properties[name]?.let { yield(it) }
|
||||
thisObj = thisObj.parent
|
61
dataforge-vis-jsroot/build.gradle.kts
Normal file
61
dataforge-vis-jsroot/build.gradle.kts
Normal file
@ -0,0 +1,61 @@
|
||||
import org.jetbrains.kotlin.gradle.frontend.KotlinFrontendExtension
|
||||
import org.jetbrains.kotlin.gradle.frontend.npm.NpmExtension
|
||||
import org.jetbrains.kotlin.gradle.frontend.webpack.WebPackExtension
|
||||
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
|
||||
|
||||
plugins {
|
||||
id("kotlin2js")
|
||||
id("kotlin-dce-js")
|
||||
id("org.jetbrains.kotlin.frontend")
|
||||
}
|
||||
|
||||
val kotlinVersion: String by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
implementation(project(":dataforge-vis-spatial-js"))
|
||||
implementation("info.laht.threekt:threejs-wrapper:0.106-npm-2")
|
||||
testCompile(kotlin("test-js"))
|
||||
}
|
||||
|
||||
configure<KotlinFrontendExtension> {
|
||||
downloadNodeJsVersion = "latest"
|
||||
|
||||
configure<NpmExtension> {
|
||||
dependency("three","0.106.2")
|
||||
devDependency("karma")
|
||||
}
|
||||
|
||||
sourceMaps = true
|
||||
|
||||
bundle<WebPackExtension>("webpack") {
|
||||
this as WebPackExtension
|
||||
bundleName = "main"
|
||||
contentPath = file("src/main/web")
|
||||
sourceMapEnabled = true
|
||||
//mode = "production"
|
||||
mode = "development"
|
||||
}
|
||||
}
|
||||
|
||||
tasks {
|
||||
"compileKotlin2Js"(Kotlin2JsCompile::class) {
|
||||
kotlinOptions {
|
||||
metaInfo = true
|
||||
outputFile = "${project.buildDir.path}/js/${project.name}.js"
|
||||
sourceMap = true
|
||||
moduleKind = "commonjs"
|
||||
main = "call"
|
||||
kotlinOptions.sourceMapEmbedSources = "always"
|
||||
}
|
||||
}
|
||||
|
||||
"compileTestKotlin2Js"(Kotlin2JsCompile::class) {
|
||||
kotlinOptions {
|
||||
metaInfo = true
|
||||
outputFile = "${project.buildDir.path}/js/${project.name}-test.js"
|
||||
sourceMap = true
|
||||
moduleKind = "commonjs"
|
||||
kotlinOptions.sourceMapEmbedSources = "always"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,19 @@
|
||||
package hep.dataforge.vis.spatial.demo
|
||||
|
||||
external val module: Module
|
||||
|
||||
external interface Module {
|
||||
val hot: Hot?
|
||||
}
|
||||
|
||||
external interface Hot {
|
||||
val data: dynamic
|
||||
|
||||
fun accept()
|
||||
fun accept(dependency: String, callback: () -> Unit)
|
||||
fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit)
|
||||
|
||||
fun dispose(callback: (data: dynamic) -> Unit)
|
||||
}
|
||||
|
||||
external fun require(name: String): dynamic
|
@ -8,7 +8,7 @@ import hep.dataforge.vis.common.*
|
||||
import hep.dataforge.vis.spatial.three.MeshThreeFactory
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
|
||||
class JSRootGeometry(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
class JSRootGeometry(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
|
||||
var shape by node()
|
||||
|
||||
@ -53,7 +53,7 @@ class JSRootGeometry(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, m
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayGroup.jsRootGeometry(meta: Meta = EmptyMeta, action: JSRootGeometry.() -> Unit = {}) =
|
||||
fun VisualGroup.jsRootGeometry(meta: Meta = EmptyMeta, action: JSRootGeometry.() -> Unit = {}) =
|
||||
JSRootGeometry(this, meta).apply(action).also { add(it) }
|
||||
|
||||
//fun Meta.toDynamic(): dynamic {
|
@ -3,14 +3,14 @@ package hep.dataforge.vis.spatial.jsroot
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.toDynamic
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.node
|
||||
import hep.dataforge.vis.spatial.three.ThreeFactory
|
||||
import info.laht.threekt.core.Object3D
|
||||
|
||||
class JSRootObject(parent: DisplayObject?, meta: Meta, val data: dynamic) : DisplayLeaf(parent, meta) {
|
||||
class JSRootObject(parent: VisualObject?, meta: Meta, val data: dynamic) : DisplayLeaf(parent, meta) {
|
||||
|
||||
var options by node()
|
||||
|
||||
@ -28,7 +28,7 @@ object ThreeJSRootObjectFactory : ThreeFactory<JSRootObject> {
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayGroup.jsRootObject(str: String) {
|
||||
fun VisualGroup.jsRootObject(str: String) {
|
||||
val json = JSON.parse<Any>(str)
|
||||
JSRootObject(this, EmptyMeta, json).also { add(it) }
|
||||
}
|
@ -0,0 +1,49 @@
|
||||
package hep.dataforge.vis.spatial.demo
|
||||
|
||||
import hep.dataforge.vis.spatial.jsroot.JSRootDemoApp
|
||||
import kotlin.browser.document
|
||||
import kotlin.dom.hasClass
|
||||
|
||||
|
||||
abstract class ApplicationBase {
|
||||
abstract val stateKeys: List<String>
|
||||
|
||||
abstract fun start(state: Map<String, Any>)
|
||||
abstract fun dispose(): Map<String, Any>
|
||||
}
|
||||
|
||||
|
||||
fun main() {
|
||||
var application: ApplicationBase? = null
|
||||
|
||||
val state: dynamic = module.hot?.let { hot ->
|
||||
hot.accept()
|
||||
|
||||
hot.dispose { data ->
|
||||
data.appState = application?.dispose()
|
||||
application = null
|
||||
}
|
||||
|
||||
hot.data
|
||||
}
|
||||
|
||||
if (document.body != null) {
|
||||
application = start(state)
|
||||
} else {
|
||||
application = null
|
||||
document.addEventListener("DOMContentLoaded", { application = start(state) })
|
||||
}
|
||||
}
|
||||
|
||||
fun start(state: dynamic): ApplicationBase? {
|
||||
return if (document.body?.hasClass("testApp") == true) {
|
||||
val application = JSRootDemoApp()
|
||||
|
||||
@Suppress("UnsafeCastFromDynamic")
|
||||
application.start(state?.appState ?: emptyMap<String, Any>())
|
||||
|
||||
application
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
import * as JSROOT from "JSRootUtils"
|
||||
import * as JSROOT from "src/main/resources/JSRootUtils"
|
||||
import * as THREE from "three"
|
||||
import * as ThreeBSP from "ThreeCSG"
|
||||
import * as ThreeBSP from "src/main/resources/ThreeCSG"
|
||||
|
||||
// Holder of all TGeo-related functions and classes
|
||||
const GradPerSegm = 6; // grad per segment in cylinder/spherical symmetry shapes
|
33
dataforge-vis-jsroot/src/main/web/index.html
Normal file
33
dataforge-vis-jsroot/src/main/web/index.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Three js demo for particle physics</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<script type="text/javascript" src="main.bundle.js"></script>
|
||||
</head>
|
||||
<body class="testApp">
|
||||
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
|
||||
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
|
||||
Загрузить данные
|
||||
<br/>
|
||||
(перетащить файл сюда)
|
||||
</div>
|
||||
<div class="container">
|
||||
<h1>Demo grid</h1>
|
||||
</div>
|
||||
<div class="container" id="canvas"></div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
||||
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
||||
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
||||
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
@ -3,16 +3,16 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.getProperty
|
||||
import hep.dataforge.vis.common.onChange
|
||||
import javafx.beans.binding.ObjectBinding
|
||||
import tornadofx.*
|
||||
|
||||
/**
|
||||
* A caching binding collection for [DisplayObject] properties
|
||||
* A caching binding collection for [VisualObject] properties
|
||||
*/
|
||||
class DisplayObjectFXListener(val obj: DisplayObject) {
|
||||
class DisplayObjectFXListener(val obj: VisualObject) {
|
||||
private val binndings = HashMap<Name, ObjectBinding<MetaItem<*>?>>()
|
||||
|
||||
init {
|
||||
|
@ -3,8 +3,8 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import javafx.scene.Group
|
||||
import javafx.scene.Node
|
||||
import org.fxyz3d.shapes.primitives.CuboidMesh
|
||||
@ -14,11 +14,11 @@ import tornadofx.*
|
||||
* https://github.com/miho/JCSG for operations
|
||||
*
|
||||
*/
|
||||
class FX3DOutput(override val context: Context) : Output<DisplayObject> {
|
||||
class FX3DOutput(override val context: Context) : Output<VisualObject> {
|
||||
val canvas by lazy { Canvas3D() }
|
||||
|
||||
|
||||
private fun buildNode(obj: DisplayObject): Node? {
|
||||
private fun buildNode(obj: VisualObject): Node? {
|
||||
val listener = DisplayObjectFXListener(obj)
|
||||
val x = listener["pos.x"].float()
|
||||
val y = listener["pos.y"].float()
|
||||
@ -27,7 +27,7 @@ class FX3DOutput(override val context: Context) : Output<DisplayObject> {
|
||||
org.fxyz3d.geometry.Point3D(x.value ?: 0f, y.value ?: 0f, z.value ?: 0f)
|
||||
}
|
||||
return when (obj) {
|
||||
is DisplayGroup -> Group(obj.map { buildNode(it) }).apply {
|
||||
is VisualGroup -> Group(obj.map { buildNode(it) }).apply {
|
||||
this.translateXProperty().bind(x)
|
||||
this.translateYProperty().bind(y)
|
||||
this.translateZProperty().bind(z)
|
||||
@ -43,7 +43,7 @@ class FX3DOutput(override val context: Context) : Output<DisplayObject> {
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(obj: DisplayObject, meta: Meta) {
|
||||
override fun render(obj: VisualObject, meta: Meta) {
|
||||
buildNode(obj)?.let { canvas.world.children.add(it) }
|
||||
}
|
||||
}
|
@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import javafx.scene.Parent
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -21,7 +21,7 @@ class RendererDemoView : View() {
|
||||
center = renderer.canvas.root
|
||||
}
|
||||
|
||||
lateinit var group: DisplayGroup
|
||||
lateinit var group: VisualGroup
|
||||
|
||||
init {
|
||||
|
||||
|
18
dataforge-vis-spatial-gdml/build.gradle.kts
Normal file
18
dataforge-vis-spatial-gdml/build.gradle.kts
Normal file
@ -0,0 +1,18 @@
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
}
|
||||
|
||||
repositories{
|
||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
sourceSets {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
api(project(":dataforge-vis-spatial"))
|
||||
api("scientifik:gdml:0.1.1")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,31 @@
|
||||
//package hep.dataforge.vis.spatial.gdml
|
||||
//
|
||||
//import hep.dataforge.context.AbstractPlugin
|
||||
//import hep.dataforge.context.Context
|
||||
//import hep.dataforge.context.PluginFactory
|
||||
//import hep.dataforge.context.PluginTag
|
||||
//import hep.dataforge.meta.Meta
|
||||
//import hep.dataforge.names.Name
|
||||
//import hep.dataforge.names.toName
|
||||
//import hep.dataforge.vis.spatial.three.ThreeFactory
|
||||
//import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||
//import kotlin.reflect.KClass
|
||||
//
|
||||
//class GDMLPlugin : AbstractPlugin() {
|
||||
// override val tag: PluginTag get() = GDMLPlugin.tag
|
||||
//
|
||||
// override fun dependsOn() = listOf(ThreePlugin)
|
||||
//
|
||||
// override fun provideTop(target: String): Map<Name, Any> {
|
||||
// return when(target){
|
||||
// ThreeFactory.TYPE-> mapOf("gdml".toName() to ThreeGDMLFactory)
|
||||
// else -> emptyMap()
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// companion object : PluginFactory<GDMLPlugin> {
|
||||
// override val tag = PluginTag("vis.gdml", "hep.dataforge")
|
||||
// override val type: KClass<GDMLPlugin> = GDMLPlugin::class
|
||||
// override fun invoke(meta: Meta) = GDMLPlugin()
|
||||
// }
|
||||
//}
|
@ -0,0 +1,92 @@
|
||||
//package hep.dataforge.vis.spatial.gdml
|
||||
//
|
||||
//import hep.dataforge.meta.Meta
|
||||
//import hep.dataforge.meta.buildMeta
|
||||
//import hep.dataforge.meta.toDynamic
|
||||
//import hep.dataforge.meta.values
|
||||
//import hep.dataforge.vis.common.DisplayLeaf
|
||||
//import hep.dataforge.vis.common.VisualObject
|
||||
//import hep.dataforge.vis.common.int
|
||||
//import hep.dataforge.vis.spatial.three.MeshThreeFactory
|
||||
////import hep.dataforge.vis.spatial.jsroot.createCubeBuffer
|
||||
////import hep.dataforge.vis.spatial.jsroot.createGeometry
|
||||
////import hep.dataforge.vis.spatial.jsroot.createTubeBuffer
|
||||
////import hep.dataforge.vis.spatial.jsroot.createXtruBuffer
|
||||
//import info.laht.threekt.core.BufferGeometry
|
||||
//
|
||||
//
|
||||
//class GDMLShape(parent: VisualObject?, meta: Meta, val shape: GDMLSolid) :
|
||||
// DisplayLeaf(parent, meta) {
|
||||
//
|
||||
// var facesLimit by int(0)
|
||||
//
|
||||
// companion object {
|
||||
// const val TYPE = "geometry.3d.gdml"
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//
|
||||
//object ThreeGDMLFactory : MeshThreeFactory<GDMLShape>(GDMLShape::class) {
|
||||
// //TODO fix ineffective conversion
|
||||
// private fun Meta?.toJsRoot() = this?.let {
|
||||
// buildMeta {
|
||||
// values().forEach { (name, value) ->
|
||||
// name.toString().replaceFirst("p", "f") to value
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// override fun buildGeometry(obj: GDMLShape): BufferGeometry {
|
||||
// return when (obj.shape) {
|
||||
// is GDMLBox -> createCubeBuffer(
|
||||
// obj.shape.config.toJsRoot()?.toDynamic(),
|
||||
// obj.facesLimit
|
||||
// )
|
||||
// is GDMLTube -> createTubeBuffer(
|
||||
// obj.shape.config.toJsRoot()?.toDynamic(),
|
||||
// obj.facesLimit
|
||||
// )
|
||||
// is GDMLXtru -> {
|
||||
// val meta = buildMeta {
|
||||
// val vertices = obj.shape.vertices
|
||||
// val zs = obj.shape.sections.sortedBy { it.zOrder!! }
|
||||
// "fNz" to zs.size
|
||||
// "fNvert" to vertices.size
|
||||
// "fX" to vertices.map { it.x }
|
||||
// "fY" to vertices.map { it.y }
|
||||
// "fX0" to zs.map { it.xOffsset }
|
||||
// "fY0" to zs.map { it.yOffset }
|
||||
// "fZ" to zs.map { it.zPosition!! }
|
||||
// "fScale" to zs.map { it.scalingFactor }
|
||||
// }
|
||||
// createXtruBuffer(meta.toDynamic(), obj.facesLimit)
|
||||
// }
|
||||
// is GDMLUnion -> {
|
||||
// val meta = buildMeta {
|
||||
// "fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
// "fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
// "fNode._typename" to "TGeoUnion"
|
||||
// }
|
||||
// createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
// }
|
||||
// is GDMLSubtraction -> {
|
||||
// val meta = buildMeta {
|
||||
// "fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
// "fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
// "fNode._typename" to "TGeoSubtraction"
|
||||
// }
|
||||
// createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
// }
|
||||
// is GDMLIntersection -> {
|
||||
// val meta = buildMeta {
|
||||
// "fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
// "fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
// "fNode._typename" to "TGeoIntersection"
|
||||
// }
|
||||
// createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
// }
|
||||
//
|
||||
//
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -0,0 +1,103 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.color
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import scientifik.gdml.*
|
||||
|
||||
|
||||
private fun VisualObject.applyPosition(pos: GDMLPosition): VisualObject = apply {
|
||||
x = pos.x
|
||||
y = pos.y
|
||||
z = pos.z
|
||||
//TODO convert units if needed
|
||||
}
|
||||
|
||||
private fun VisualObject.applyRotation(rotation: GDMLRotation): VisualObject = apply {
|
||||
rotationX = rotation.x
|
||||
rotationY = rotation.y
|
||||
rotationZ = rotation.z
|
||||
//TODO convert units if needed
|
||||
}
|
||||
|
||||
private fun VisualGroup.addSolid(root: GDML, solid: GDMLSolid, block: VisualObject.() -> Unit = {}): VisualObject {
|
||||
return when (solid) {
|
||||
is GDMLBox -> box(solid.x, solid.y, solid.z)
|
||||
is GDMLTube -> TODO()
|
||||
is GDMLXtru -> extrude {
|
||||
TODO()
|
||||
}
|
||||
is GDMLScaledSolid -> {
|
||||
//Add solid with modified scale
|
||||
val innerSolid = solid.solidref.resolve(root)
|
||||
?: error("Solid with tag ${solid.solidref.ref} for scaled solid ${solid.name} not defined")
|
||||
addSolid(root, innerSolid) {
|
||||
block()
|
||||
scaleX = scaleX.toDouble() * solid.scale.value.toDouble()
|
||||
scaleY = scaleY.toDouble() * solid.scale.value.toDouble()
|
||||
scaleZ = scaleZ.toDouble() * solid.scale.value.toDouble()
|
||||
}
|
||||
}
|
||||
is GDMLSphere -> sphere(solid.rmax, solid.deltaphi, solid.deltatheta) {
|
||||
phiStart = solid.startphi.toDouble()
|
||||
thetaStart = solid.starttheta.toDouble()
|
||||
}
|
||||
is GDMLOrb -> sphere(solid.r)
|
||||
is GDMLPolyhedra -> TODO()
|
||||
is GDMLBoolSolid -> {
|
||||
val first = solid.first.resolve(root) ?: error("")
|
||||
val second = solid.second.resolve(root) ?: error("")
|
||||
val type: CompositeType = when (solid) {
|
||||
is GDMLUnion -> CompositeType.UNION
|
||||
is GDMLSubtraction -> CompositeType.SUBTRACT
|
||||
is GDMLIntersection -> CompositeType.INTERSECT
|
||||
}
|
||||
return composite(type) {
|
||||
addSolid(root, first) {
|
||||
solid.resolveFirstPosition(root)?.let { applyPosition(it) }
|
||||
solid.resolveFirstRotation(root)?.let { applyRotation(it) }
|
||||
}
|
||||
addSolid(root, second) {}
|
||||
solid.resolvePosition(root)?.let { applyPosition(it) }
|
||||
solid.resolveRotation(root)?.let { applyRotation(it) }
|
||||
}
|
||||
}
|
||||
}.apply(block)
|
||||
}
|
||||
|
||||
private fun VisualGroup.addVolume(
|
||||
root: GDML,
|
||||
gdmlVolume: GDMLVolume,
|
||||
resolveColor: GDMLMaterialBase.() -> Meta
|
||||
): VisualGroup {
|
||||
val solid =
|
||||
gdmlVolume.solidref.resolve(root)
|
||||
?: error("Solid with tag ${gdmlVolume.solidref.ref} for volume ${gdmlVolume.name} not defined")
|
||||
val material =
|
||||
gdmlVolume.materialref.resolve(root)
|
||||
?: error("Material with tag ${gdmlVolume.materialref.ref} for volume ${gdmlVolume.name} not defined")
|
||||
|
||||
addSolid(root, solid) {
|
||||
color(material.resolveColor())
|
||||
}
|
||||
|
||||
gdmlVolume.physVolumes.forEach {
|
||||
val volume = it.volumeref.resolve(root)?: error("Volume with ref ${it.volumeref.ref} could not be resolved")
|
||||
addVolume(root,volume,resolveColor).apply {
|
||||
it.resolvePosition(root)?.let { pos -> applyPosition(pos) }
|
||||
it.resolveRotation(root)?.let { rot -> applyRotation(rot) }
|
||||
}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
|
||||
fun GDML.toVisual(): VisualGroup {
|
||||
//TODO add materials cache
|
||||
fun GDMLMaterialBase.color(): Meta = EmptyMeta
|
||||
return VisualGroup().also { it.addVolume(this, world){color()} }
|
||||
}
|
@ -4,8 +4,6 @@ import hep.dataforge.context.ContextBuilder
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import hep.dataforge.vis.spatial.jsroot.JSRootPlugin
|
||||
import hep.dataforge.vis.spatial.jsroot.jsRootGeometry
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
@ -21,19 +19,16 @@ class ThreeDemoApp : ApplicationBase() {
|
||||
override val stateKeys: List<String> = emptyList()
|
||||
|
||||
override fun start(state: Map<String, Any>) {
|
||||
require("JSRootGeoBase.js")
|
||||
|
||||
//TODO replace by optimized builder after dataforge 0.1.3-dev-8
|
||||
val context = ContextBuilder("three-demo").apply {
|
||||
plugin(JSRootPlugin())
|
||||
}.build()
|
||||
val context = ContextBuilder("three-demo").build()
|
||||
|
||||
context.plugins.load(ThreeDemoGrid()).run {
|
||||
demo("shapes", "Basic shapes"){
|
||||
box(100.0,100.0,100.0) {
|
||||
demo("shapes", "Basic shapes") {
|
||||
box(100.0, 100.0, 100.0) {
|
||||
z = 110.0
|
||||
}
|
||||
sphere(50.0){
|
||||
sphere(50.0) {
|
||||
x = 110
|
||||
detail = 200
|
||||
}
|
||||
@ -76,15 +71,15 @@ class ThreeDemoApp : ApplicationBase() {
|
||||
}
|
||||
}
|
||||
|
||||
demo("jsroot", "JSROOT cube") {
|
||||
jsRootGeometry {
|
||||
y = 110.0
|
||||
shape = box(50, 50, 50)
|
||||
color(Colors.lightcoral)
|
||||
rotationX = PI / 4
|
||||
rotationY = PI / 4
|
||||
}
|
||||
}
|
||||
// demo("jsroot", "JSROOT cube") {
|
||||
// jsRootGeometry {
|
||||
// y = 110.0
|
||||
// shape = box(50, 50, 50)
|
||||
// color(Colors.lightcoral)
|
||||
// rotationX = PI / 4
|
||||
// rotationY = PI / 4
|
||||
// }
|
||||
// }
|
||||
|
||||
demo("extrude", "extruded shape") {
|
||||
extrude {
|
||||
@ -107,7 +102,7 @@ class ThreeDemoApp : ApplicationBase() {
|
||||
rotationY = PI / 4
|
||||
}
|
||||
box(100, 100, 100)
|
||||
color{
|
||||
color {
|
||||
"color" to Colors.lightgreen
|
||||
"opacity" to 0.3
|
||||
}
|
||||
|
@ -12,8 +12,8 @@ import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.output.OutputManager
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.render
|
||||
import hep.dataforge.vis.spatial.three.ThreeOutput
|
||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||
@ -49,7 +49,7 @@ class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager {
|
||||
val three = context.plugins.get<ThreePlugin>()!!
|
||||
|
||||
return outputs.getOrPut(name) {
|
||||
if (type != DisplayObject::class) error("Supports only DisplayObject")
|
||||
if (type != VisualObject::class) error("Supports only DisplayObject")
|
||||
val output = three.output(meta) {
|
||||
"axis" to {
|
||||
"size" to 500
|
||||
@ -79,10 +79,10 @@ class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager {
|
||||
}
|
||||
}
|
||||
|
||||
fun ThreeDemoGrid.demo(name: String, title: String = name, block: DisplayGroup.() -> Unit) {
|
||||
fun ThreeDemoGrid.demo(name: String, title: String = name, block: VisualGroup.() -> Unit) {
|
||||
val meta = buildMeta {
|
||||
"title" to title
|
||||
}
|
||||
val output = get<DisplayObject>(DisplayObject::class, name.toName(), meta = meta)
|
||||
val output = get<VisualObject>(VisualObject::class, name.toName(), meta = meta)
|
||||
output.render(action = block)
|
||||
}
|
@ -1,54 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
|
||||
@DslMarker
|
||||
annotation class GDMLApi
|
||||
|
||||
@GDMLApi
|
||||
class GDML {
|
||||
private val defines = GDMLDefineContainer()
|
||||
private var solids = GDMLSolidContainer()
|
||||
|
||||
fun define(block: GDMLDefineContainer.() -> Unit) {
|
||||
defines.apply(block).map
|
||||
}
|
||||
|
||||
fun solids(block: GDMLSolidContainer.() -> Unit) {
|
||||
solids.apply(block).map
|
||||
}
|
||||
|
||||
fun getPosition(ref: String) = defines.map[ref] as? GDMLPosition
|
||||
fun getRotation(ref: String) = defines.map[ref] as? GDMLRotation
|
||||
fun getSolid(ref:String) = solids.map[ref]
|
||||
}
|
||||
|
||||
@GDMLApi
|
||||
class GDMLDefineContainer {
|
||||
internal val map = HashMap<String, GDMLDefine>()
|
||||
|
||||
fun position(name: String, block: GDMLPosition.() -> Unit) {
|
||||
map[name] = GDMLPosition(Config()).apply(block).apply { this.pName = name }
|
||||
}
|
||||
|
||||
fun rotation(name: String, block: GDMLRotation.() -> Unit) {
|
||||
map[name] = GDMLRotation(Config()).apply(block).apply { this.pName = name }
|
||||
}
|
||||
}
|
||||
|
||||
@GDMLApi
|
||||
class GDMLSolidContainer {
|
||||
internal val map = HashMap<String, GDMLSolid>()
|
||||
|
||||
operator fun get(ref: String) = map[ref]
|
||||
|
||||
fun box(name: String, block: GDMLBox.() -> Unit) {
|
||||
map[name] = GDMLBox.build(block).apply{this.pName = name}
|
||||
}
|
||||
fun tube(name: String, block: GDMLTube.() -> Unit){
|
||||
map[name] = GDMLTube.build(block).apply{this.pName = name}
|
||||
}
|
||||
fun xtru(name: String, block: GDMLXtru.() -> Unit) {
|
||||
map[name] = GDMLXtru.build(block).apply{this.pName = name}
|
||||
}
|
||||
}
|
@ -1,182 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import kotlin.properties.ReadWriteProperty
|
||||
import kotlin.reflect.KProperty
|
||||
|
||||
sealed class GDMLNode(override val config: Config) : Specific {
|
||||
var pName by string()
|
||||
}
|
||||
|
||||
sealed class GDMLDefine(config: Config) : GDMLNode(config)
|
||||
|
||||
class GDMLPosition(config: Config) : GDMLDefine(config) {
|
||||
var x by number(0f).float
|
||||
var y by number(0f).float
|
||||
var z by number(0f).float
|
||||
var unit by string("cm")
|
||||
|
||||
companion object : Specification<GDMLPosition> {
|
||||
override fun wrap(config: Config) = GDMLPosition(config)
|
||||
}
|
||||
}
|
||||
|
||||
class GDMLRotation(config: Config) : GDMLDefine(config) {
|
||||
var x by number(0f).float
|
||||
var y by number(0f).float
|
||||
var z by number(0f).float
|
||||
var unit by string("deg")
|
||||
|
||||
companion object : Specification<GDMLRotation> {
|
||||
override fun wrap(config: Config) = GDMLRotation(config)
|
||||
}
|
||||
}
|
||||
|
||||
sealed class GDMLSolid(config: Config) : GDMLNode(config) {
|
||||
abstract val type: String
|
||||
}
|
||||
|
||||
class GDMLBox(config: Config) : GDMLSolid(config) {
|
||||
override val type: String = "box"
|
||||
|
||||
var pDx by number().double
|
||||
var pDy by number().double
|
||||
var pDz by number().double
|
||||
|
||||
companion object : Specification<GDMLBox> {
|
||||
override fun wrap(config: Config): GDMLBox = GDMLBox(config)
|
||||
}
|
||||
}
|
||||
|
||||
class GDMLTube(config: Config) : GDMLSolid(config) {
|
||||
override val type: String = "tube"
|
||||
|
||||
var pRMin by number().double
|
||||
var pRMax by number().double
|
||||
var pDz by number().double
|
||||
var pSPhi by number().double
|
||||
var pDPhi by number().double
|
||||
|
||||
companion object : Specification<GDMLTube> {
|
||||
override fun wrap(config: Config): GDMLTube = GDMLTube(config)
|
||||
}
|
||||
}
|
||||
|
||||
class GDMLXtru(config: Config) : GDMLSolid(config) {
|
||||
override val type: String = "xtru"
|
||||
|
||||
class TwoDimVertex(val x: Double, val y: Double)
|
||||
|
||||
class Section(override val config: Config) : Specific {
|
||||
var zOrder by number().int
|
||||
var zPosition by number().double
|
||||
var xOffsset by number(0.0).double
|
||||
var yOffset by number(0.0).double
|
||||
var scalingFactor by number(1.0).double
|
||||
|
||||
companion object : Specification<Section> {
|
||||
override fun wrap(config: Config): Section = Section(config)
|
||||
}
|
||||
}
|
||||
|
||||
val verteces
|
||||
get() = config.getAll("twoDimVertex").values.map {
|
||||
val x = it.node["x"].double!!
|
||||
val y = it.node["y"].double!!
|
||||
TwoDimVertex(x, y)
|
||||
}
|
||||
|
||||
val sections get() = config.getAll("section").values.map { Section(it.node!!) }
|
||||
|
||||
fun vertex(x: Double, y: Double) {
|
||||
config.append("twoDimVertex", TwoDimVertex(x, y))
|
||||
}
|
||||
|
||||
fun section(index: Int, z: Double, block: Section.() -> Unit) {
|
||||
config["section[$index]"] = Section.build(block).apply { zOrder = index; zPosition = z }
|
||||
}
|
||||
|
||||
companion object : Specification<GDMLXtru> {
|
||||
override fun wrap(config: Config): GDMLXtru = GDMLXtru(config)
|
||||
}
|
||||
}
|
||||
|
||||
internal class GDMLRefDelegate(val key: String?) : ReadWriteProperty<GDMLNode, String?> {
|
||||
override fun getValue(thisRef: GDMLNode, property: KProperty<*>): String? {
|
||||
val realKey = key ?: property.name
|
||||
return thisRef.config["$realKey.ref"].string
|
||||
}
|
||||
|
||||
override fun setValue(thisRef: GDMLNode, property: KProperty<*>, value: String?) {
|
||||
val realKey = key ?: property.name
|
||||
if (value == null) {
|
||||
thisRef.config.remove(realKey)
|
||||
} else {
|
||||
thisRef.config["$realKey.ref"] = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
internal fun GDMLNode.ref(key: String? = null) = GDMLRefDelegate(key)
|
||||
|
||||
|
||||
sealed class GDMLBoolSolid(config: Config, var root: GDML? = null) : GDMLSolid(config) {
|
||||
var first by ref()
|
||||
|
||||
@JsName("resolveFirst")
|
||||
fun first() = first?.let{ref -> root?.getSolid(ref)}
|
||||
|
||||
var second by ref()
|
||||
|
||||
@JsName("resolveSecond")
|
||||
fun second() = second?.let{ref -> root?.getSolid(ref)}
|
||||
|
||||
var position by spec(GDMLPosition)
|
||||
|
||||
var positionref by ref()
|
||||
|
||||
/**
|
||||
* Get the position from either position block or reference (if root is provided)
|
||||
*/
|
||||
@JsName("resolvePosition")
|
||||
fun position() = position ?: positionref?.let{ref -> root?.getPosition(ref)}
|
||||
|
||||
var rotation by spec(GDMLRotation)
|
||||
|
||||
var rotationref by ref()
|
||||
|
||||
/**
|
||||
* Get the rotation from either position block or reference (if root is provided)
|
||||
*/
|
||||
@JsName("resolveRotation")
|
||||
fun rotation() = rotation ?: rotationref?.let{ref -> root?.getRotation(ref)}
|
||||
|
||||
var firstposition by spec(GDMLPosition)
|
||||
|
||||
var firstrotation by spec(GDMLRotation)
|
||||
}
|
||||
|
||||
|
||||
class GDMLUnion(config: Config) : GDMLBoolSolid(config) {
|
||||
override val type: String = "union"
|
||||
|
||||
companion object : Specification<GDMLUnion> {
|
||||
override fun wrap(config: Config): GDMLUnion = GDMLUnion(config)
|
||||
}
|
||||
}
|
||||
|
||||
class GDMLSubtraction(config: Config) : GDMLBoolSolid(config) {
|
||||
override val type: String = "subtraction"
|
||||
|
||||
companion object : Specification<GDMLUnion> {
|
||||
override fun wrap(config: Config) = GDMLUnion(config)
|
||||
}
|
||||
}
|
||||
|
||||
class GDMLIntersection(config: Config) : GDMLBoolSolid(config) {
|
||||
override val type: String = "intersection"
|
||||
|
||||
companion object : Specification<GDMLIntersection> {
|
||||
override fun wrap(config: Config) = GDMLIntersection(config)
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.context.AbstractPlugin
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.spatial.three.ThreeFactory
|
||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
class GDMLPlugin : AbstractPlugin() {
|
||||
override val tag: PluginTag get() = GDMLPlugin.tag
|
||||
|
||||
override fun dependsOn() = listOf(ThreePlugin)
|
||||
|
||||
override fun provideTop(target: String): Map<Name, Any> {
|
||||
return when(target){
|
||||
ThreeFactory.TYPE-> mapOf("gdml".toName() to ThreeGDMLFactory)
|
||||
else -> emptyMap()
|
||||
}
|
||||
}
|
||||
|
||||
companion object : PluginFactory<GDMLPlugin> {
|
||||
override val tag = PluginTag("vis.gdml", "hep.dataforge")
|
||||
override val type: KClass<GDMLPlugin> = GDMLPlugin::class
|
||||
override fun invoke(meta: Meta) = GDMLPlugin()
|
||||
}
|
||||
}
|
@ -1,92 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.buildMeta
|
||||
import hep.dataforge.meta.toDynamic
|
||||
import hep.dataforge.meta.values
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.int
|
||||
import hep.dataforge.vis.spatial.three.MeshThreeFactory
|
||||
import hep.dataforge.vis.spatial.jsroot.createCubeBuffer
|
||||
import hep.dataforge.vis.spatial.jsroot.createGeometry
|
||||
import hep.dataforge.vis.spatial.jsroot.createTubeBuffer
|
||||
import hep.dataforge.vis.spatial.jsroot.createXtruBuffer
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
|
||||
|
||||
class GDMLShape(parent: DisplayObject?, meta: Meta, val shape: GDMLSolid) :
|
||||
DisplayLeaf(parent, meta) {
|
||||
|
||||
var facesLimit by int(0)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "geometry.3d.gdml"
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
object ThreeGDMLFactory : MeshThreeFactory<GDMLShape>(GDMLShape::class) {
|
||||
//TODO fix ineffective conversion
|
||||
private fun Meta?.toJsRoot() = this?.let {
|
||||
buildMeta {
|
||||
values().forEach { (name, value) ->
|
||||
name.toString().replaceFirst("p", "f") to value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun buildGeometry(obj: GDMLShape): BufferGeometry {
|
||||
return when (obj.shape) {
|
||||
is GDMLBox -> createCubeBuffer(
|
||||
obj.shape.config.toJsRoot()?.toDynamic(),
|
||||
obj.facesLimit
|
||||
)
|
||||
is GDMLTube -> createTubeBuffer(
|
||||
obj.shape.config.toJsRoot()?.toDynamic(),
|
||||
obj.facesLimit
|
||||
)
|
||||
is GDMLXtru -> {
|
||||
val meta = buildMeta {
|
||||
val vertices = obj.shape.verteces
|
||||
val zs = obj.shape.sections.sortedBy { it.zOrder!! }
|
||||
"fNz" to zs.size
|
||||
"fNvert" to vertices.size
|
||||
"fX" to vertices.map { it.x }
|
||||
"fY" to vertices.map { it.y }
|
||||
"fX0" to zs.map { it.xOffsset }
|
||||
"fY0" to zs.map { it.yOffset }
|
||||
"fZ" to zs.map { it.zPosition!! }
|
||||
"fScale" to zs.map { it.scalingFactor }
|
||||
}
|
||||
createXtruBuffer(meta.toDynamic(), obj.facesLimit)
|
||||
}
|
||||
is GDMLUnion -> {
|
||||
val meta = buildMeta {
|
||||
"fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
"fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
"fNode._typename" to "TGeoUnion"
|
||||
}
|
||||
createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
}
|
||||
is GDMLSubtraction -> {
|
||||
val meta = buildMeta {
|
||||
"fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
"fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
"fNode._typename" to "TGeoSubtraction"
|
||||
}
|
||||
createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
}
|
||||
is GDMLIntersection -> {
|
||||
val meta = buildMeta {
|
||||
"fNode.fLeft" to obj.shape.first()?.config.toJsRoot()
|
||||
"fNode.fRight" to obj.shape.second()?.config.toJsRoot()
|
||||
"fNode._typename" to "TGeoIntersection"
|
||||
}
|
||||
createGeometry(meta.toDynamic(), obj.facesLimit)
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
}
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.boolean
|
||||
import hep.dataforge.names.startsWith
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.getProperty
|
||||
import hep.dataforge.vis.common.onChange
|
||||
import hep.dataforge.vis.spatial.*
|
||||
@ -19,13 +19,13 @@ import info.laht.threekt.objects.LineSegments
|
||||
import info.laht.threekt.objects.Mesh
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
internal val DisplayObject.material get() = getProperty("material").material()
|
||||
internal val VisualObject.material get() = getProperty("material").material()
|
||||
|
||||
/**
|
||||
* Builder and updater for three.js object
|
||||
*/
|
||||
@Type(TYPE)
|
||||
interface ThreeFactory<T : DisplayObject> {
|
||||
interface ThreeFactory<T : VisualObject> {
|
||||
|
||||
val type: KClass<out T>
|
||||
|
||||
@ -34,7 +34,7 @@ interface ThreeFactory<T : DisplayObject> {
|
||||
companion object {
|
||||
const val TYPE = "threeFactory"
|
||||
|
||||
fun <T : DisplayObject> buildMesh(obj: T, geometryBuilder: (T) -> BufferGeometry): Mesh {
|
||||
fun <T : VisualObject> buildMesh(obj: T, geometryBuilder: (T) -> BufferGeometry): Mesh {
|
||||
val geometry = geometryBuilder(obj)
|
||||
|
||||
//JS sometimes tries to pass Geometry as BufferGeometry
|
||||
@ -84,7 +84,7 @@ interface ThreeFactory<T : DisplayObject> {
|
||||
/**
|
||||
* Update position, rotation and visibility
|
||||
*/
|
||||
internal fun Object3D.updatePosition(obj: DisplayObject) {
|
||||
internal fun Object3D.updatePosition(obj: VisualObject) {
|
||||
position.set(obj.x, obj.y, obj.z)
|
||||
setRotationFromEuler(obj.euler)
|
||||
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
|
||||
@ -94,7 +94,7 @@ internal fun Object3D.updatePosition(obj: DisplayObject) {
|
||||
/**
|
||||
* Unsafe invocation of a factory
|
||||
*/
|
||||
operator fun <T : DisplayObject> ThreeFactory<T>.invoke(obj: Any): Object3D {
|
||||
operator fun <T : VisualObject> ThreeFactory<T>.invoke(obj: Any): Object3D {
|
||||
if (type.isInstance(obj)) {
|
||||
return invoke(obj as T)
|
||||
} else {
|
||||
@ -105,7 +105,7 @@ operator fun <T : DisplayObject> ThreeFactory<T>.invoke(obj: Any): Object3D {
|
||||
/**
|
||||
* Basic geometry-based factory
|
||||
*/
|
||||
abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out T>) :
|
||||
abstract class MeshThreeFactory<T : VisualObject>(override val type: KClass<out T>) :
|
||||
ThreeFactory<T> {
|
||||
/**
|
||||
* Build a geometry for an object
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.demo.require
|
||||
import info.laht.threekt.WebGLRenderer
|
||||
import info.laht.threekt.helpers.AxesHelper
|
||||
@ -15,7 +15,7 @@ import kotlin.browser.window
|
||||
|
||||
private val elementResizeEvent = require("element-resize-event")
|
||||
|
||||
class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<DisplayObject> {
|
||||
class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<VisualObject> {
|
||||
|
||||
override val context: Context get() = three.context
|
||||
|
||||
@ -58,7 +58,7 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<D
|
||||
animate()
|
||||
}
|
||||
|
||||
override fun render(obj: DisplayObject, meta: Meta) {
|
||||
override fun render(obj: VisualObject, meta: Meta) {
|
||||
scene.add(three.buildObject3D(obj))
|
||||
}
|
||||
}
|
||||
|
@ -5,8 +5,8 @@ import hep.dataforge.context.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.context.content
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import info.laht.threekt.cameras.Camera
|
||||
import info.laht.threekt.cameras.PerspectiveCamera
|
||||
@ -20,7 +20,7 @@ import kotlin.reflect.KClass
|
||||
class ThreePlugin : AbstractPlugin() {
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
private val objectFactories = HashMap<KClass<out DisplayObject>, ThreeFactory<*>>()
|
||||
private val objectFactories = HashMap<KClass<out VisualObject>, ThreeFactory<*>>()
|
||||
private val compositeFactory = ThreeCompositeFactory(this)
|
||||
|
||||
init {
|
||||
@ -30,14 +30,14 @@ class ThreePlugin : AbstractPlugin() {
|
||||
objectFactories[Sphere::class] = ThreeSphereFactory
|
||||
}
|
||||
|
||||
private fun findObjectFactory(type: KClass<out DisplayObject>): ThreeFactory<*>? {
|
||||
private fun findObjectFactory(type: KClass<out VisualObject>): ThreeFactory<*>? {
|
||||
return objectFactories[type]
|
||||
?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type }
|
||||
}
|
||||
|
||||
fun buildObject3D(obj: DisplayObject): Object3D {
|
||||
fun buildObject3D(obj: VisualObject): Object3D {
|
||||
return when (obj) {
|
||||
is DisplayGroup -> Group(obj.map { buildObject3D(it) }).apply {
|
||||
is VisualGroup -> Group(obj.map { buildObject3D(it) }).apply {
|
||||
updatePosition(obj)
|
||||
}
|
||||
is Composite -> compositeFactory(obj)
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.float
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.node
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.rotationOrder
|
||||
import hep.dataforge.vis.spatial.rotationX
|
||||
import hep.dataforge.vis.spatial.rotationY
|
||||
@ -25,7 +25,7 @@ fun Group(children: Collection<Object3D>) = info.laht.threekt.objects.Group().ap
|
||||
children.forEach { this.add(it) }
|
||||
}
|
||||
|
||||
val DisplayObject.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
|
||||
val VisualObject.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
|
||||
|
||||
val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
|
||||
|
||||
|
@ -2,12 +2,12 @@ package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.double
|
||||
|
||||
class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape {
|
||||
class Box(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape {
|
||||
var xSize by double(100.0)
|
||||
var ySize by double(100.0)
|
||||
var zSize by double(100.0)
|
||||
@ -36,13 +36,14 @@ class Box(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape
|
||||
|
||||
companion object {
|
||||
const val TYPE = "geometry.3d.box"
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayGroup.box(meta: Meta = EmptyMeta, action: Box.() -> Unit = {}) =
|
||||
fun VisualGroup.box(meta: Meta = EmptyMeta, action: Box.() -> Unit = {}) =
|
||||
Box(this, meta).apply(action).also { add(it) }
|
||||
|
||||
fun DisplayGroup.box(xSize: Number, ySize: Number, zSize: Number, meta: Meta = EmptyMeta, action: Box.() -> Unit = {}) =
|
||||
fun VisualGroup.box(xSize: Number, ySize: Number, zSize: Number, meta: Meta = EmptyMeta, action: Box.() -> Unit = {}) =
|
||||
Box(this, meta).apply(action).apply{
|
||||
this.xSize = xSize.toDouble()
|
||||
this.ySize = ySize.toDouble()
|
||||
|
@ -3,9 +3,9 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.seal
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
|
||||
enum class CompositeType {
|
||||
UNION,
|
||||
@ -14,25 +14,25 @@ enum class CompositeType {
|
||||
}
|
||||
|
||||
class Composite(
|
||||
parent: DisplayObject?,
|
||||
val first: DisplayObject,
|
||||
val second: DisplayObject,
|
||||
parent: VisualObject?,
|
||||
val first: VisualObject,
|
||||
val second: VisualObject,
|
||||
val type: CompositeType = CompositeType.UNION,
|
||||
meta: Meta = EmptyMeta
|
||||
) : DisplayLeaf(parent, meta)
|
||||
|
||||
fun DisplayGroup.composite(type: CompositeType, builder: DisplayGroup.() -> Unit): Composite {
|
||||
val group = DisplayGroup().apply(builder)
|
||||
fun VisualGroup.composite(type: CompositeType, builder: VisualGroup.() -> Unit): Composite {
|
||||
val group = VisualGroup().apply(builder)
|
||||
val children = group.toList()
|
||||
if (children.size != 2) error("Composite requires exactly two children")
|
||||
return Composite(this, children[0], children[1], type, group.properties.seal()).also { add(it) }
|
||||
}
|
||||
|
||||
fun DisplayGroup.union(builder: DisplayGroup.() -> Unit) =
|
||||
fun VisualGroup.union(builder: VisualGroup.() -> Unit) =
|
||||
composite(CompositeType.UNION,builder)
|
||||
|
||||
fun DisplayGroup.subtract(builder: DisplayGroup.() -> Unit) =
|
||||
fun VisualGroup.subtract(builder: VisualGroup.() -> Unit) =
|
||||
composite(CompositeType.SUBTRACT,builder)
|
||||
|
||||
fun DisplayGroup.intersect(builder: DisplayGroup.() -> Unit) =
|
||||
fun VisualGroup.intersect(builder: VisualGroup.() -> Unit) =
|
||||
composite(CompositeType.INTERSECT,builder)
|
@ -1,11 +1,11 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
|
||||
class Convex(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
class Convex(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
|
||||
val points = points(properties["points"] ?: error("Vertices not defined"))
|
||||
|
||||
@ -20,7 +20,7 @@ class Convex(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayGroup.convex(meta: Meta = EmptyMeta, action: ConvexBuilder.() -> Unit = {}) =
|
||||
fun VisualGroup.convex(meta: Meta = EmptyMeta, action: ConvexBuilder.() -> Unit = {}) =
|
||||
ConvexBuilder().apply(action).build(this, meta).also { add(it) }
|
||||
|
||||
class ConvexBuilder {
|
||||
@ -30,7 +30,7 @@ class ConvexBuilder {
|
||||
points.add(Point3D(x, y, z))
|
||||
}
|
||||
|
||||
fun build(parent: DisplayObject?, meta: Meta): Convex {
|
||||
fun build(parent: VisualObject?, meta: Meta): Convex {
|
||||
val points = buildMeta {
|
||||
points.forEachIndexed { index, value ->
|
||||
"points.point[$index]" to value.toMeta()
|
||||
|
@ -1,9 +1,9 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
@ -42,7 +42,7 @@ class Layer(override val config: Config) : Specific {
|
||||
|
||||
//class Layer(val z: Number, val x: Number = 0.0, val y: Number = 0.0, val scale: Number = 1.0)
|
||||
|
||||
class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape {
|
||||
class Extruded(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta), Shape {
|
||||
|
||||
val shape
|
||||
get() = properties.getAll("shape.point").map { (_, value) ->
|
||||
@ -119,5 +119,5 @@ class Extruded(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta),
|
||||
}
|
||||
}
|
||||
|
||||
fun DisplayGroup.extrude(meta: Meta = EmptyMeta, action: Extruded.() -> Unit = {}) =
|
||||
fun VisualGroup.extrude(meta: Meta = EmptyMeta, action: Extruded.() -> Unit = {}) =
|
||||
Extruded(this, meta).apply(action).also { add(it) }
|
@ -1,7 +1,7 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
|
||||
data class Point2D(val x: Number, val y: Number) : MetaRepr {
|
||||
override fun toMeta(): Meta = buildMeta {
|
||||
@ -60,6 +60,6 @@ fun GeometryBuilder<*>.face4(
|
||||
face(vertex1, vertex3, vertex4, normal, meta)
|
||||
}
|
||||
|
||||
interface Shape : DisplayObject {
|
||||
interface Shape : VisualObject {
|
||||
fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
|
||||
}
|
@ -2,13 +2,13 @@ package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.EmptyMeta
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.DisplayLeaf
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.double
|
||||
import kotlin.math.PI
|
||||
|
||||
class Sphere(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
class Sphere(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
var radius by double(50.0)
|
||||
var phiStart by double(0.0)
|
||||
var phi by double(2 * PI)
|
||||
@ -16,10 +16,10 @@ class Sphere(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
var theta by double(PI)
|
||||
}
|
||||
|
||||
fun DisplayGroup.sphere(meta: Meta = EmptyMeta, action: Sphere.() -> Unit = {}) =
|
||||
fun VisualGroup.sphere(meta: Meta = EmptyMeta, action: Sphere.() -> Unit = {}) =
|
||||
Sphere(this, meta).apply(action).also { add(it) }
|
||||
|
||||
fun DisplayGroup.sphere(
|
||||
fun VisualGroup.sphere(
|
||||
radius: Number,
|
||||
phi: Number = 2 * PI,
|
||||
theta: Number = PI,
|
||||
|
@ -2,16 +2,16 @@ package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.DisplayObject
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.getProperty
|
||||
|
||||
fun DisplayGroup.group(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit = {}): DisplayGroup =
|
||||
DisplayGroup(this, meta).apply(action).also { add(it) }
|
||||
fun VisualGroup.group(meta: Meta = EmptyMeta, action: VisualGroup.() -> Unit = {}): VisualGroup =
|
||||
VisualGroup(this, meta).apply(action).also { add(it) }
|
||||
|
||||
|
||||
fun Output<DisplayObject>.render(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit) =
|
||||
render(DisplayGroup(null, EmptyMeta).apply(action), meta)
|
||||
fun Output<VisualObject>.render(meta: Meta = EmptyMeta, action: VisualGroup.() -> Unit) =
|
||||
render(VisualGroup(null, EmptyMeta).apply(action), meta)
|
||||
|
||||
//TODO replace properties by containers?
|
||||
|
||||
@ -20,7 +20,7 @@ fun Output<DisplayObject>.render(meta: Meta = EmptyMeta, action: DisplayGroup.()
|
||||
/**
|
||||
* Visibility property. Inherited from parent
|
||||
*/
|
||||
var DisplayObject.visible
|
||||
var VisualObject.visible
|
||||
get() = getProperty("visible").boolean ?: true
|
||||
set(value) {
|
||||
properties["visible"] = value
|
||||
@ -31,7 +31,7 @@ var DisplayObject.visible
|
||||
/**
|
||||
* x position property relative to parent. Not inherited
|
||||
*/
|
||||
var DisplayObject.x
|
||||
var VisualObject.x
|
||||
get() = properties["pos.x"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.x"] = value
|
||||
@ -40,7 +40,7 @@ var DisplayObject.x
|
||||
/**
|
||||
* y position property. Not inherited
|
||||
*/
|
||||
var DisplayObject.y
|
||||
var VisualObject.y
|
||||
get() = properties["pos.y"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.y"] = value
|
||||
@ -49,7 +49,7 @@ var DisplayObject.y
|
||||
/**
|
||||
* z position property. Not inherited
|
||||
*/
|
||||
var DisplayObject.z
|
||||
var VisualObject.z
|
||||
get() = properties["pos.z"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.z"] = value
|
||||
@ -60,7 +60,7 @@ var DisplayObject.z
|
||||
/**
|
||||
* x rotation relative to parent. Not inherited
|
||||
*/
|
||||
var DisplayObject.rotationX
|
||||
var VisualObject.rotationX
|
||||
get() = properties["rotation.x"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.x"] = value
|
||||
@ -69,7 +69,7 @@ var DisplayObject.rotationX
|
||||
/**
|
||||
* y rotation relative to parent. Not inherited
|
||||
*/
|
||||
var DisplayObject.rotationY
|
||||
var VisualObject.rotationY
|
||||
get() = properties["rotation.y"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.y"] = value
|
||||
@ -78,7 +78,7 @@ var DisplayObject.rotationY
|
||||
/**
|
||||
* z rotation relative to parent. Not inherited
|
||||
*/
|
||||
var DisplayObject.rotationZ
|
||||
var VisualObject.rotationZ
|
||||
get() = properties["rotation.z"].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.z"] = value
|
||||
@ -96,7 +96,7 @@ enum class RotationOrder {
|
||||
/**
|
||||
* Rotation order. Not inherited
|
||||
*/
|
||||
var DisplayObject.rotationOrder: RotationOrder
|
||||
var VisualObject.rotationOrder: RotationOrder
|
||||
get() = getProperty("rotation.order").enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||
set(value) {
|
||||
properties["rotation.order"] = value
|
||||
@ -107,7 +107,7 @@ var DisplayObject.rotationOrder: RotationOrder
|
||||
/**
|
||||
* X scale. Not inherited
|
||||
*/
|
||||
var DisplayObject.scaleX
|
||||
var VisualObject.scaleX
|
||||
get() = properties["scale.x"].number ?: 1.0
|
||||
set(value) {
|
||||
properties["scale.x"] = value
|
||||
@ -116,7 +116,7 @@ var DisplayObject.scaleX
|
||||
/**
|
||||
* Y scale. Not inherited
|
||||
*/
|
||||
var DisplayObject.scaleY
|
||||
var VisualObject.scaleY
|
||||
get() = properties["scale.y"].number ?: 1.0
|
||||
set(value) {
|
||||
properties["scale.y"] = value
|
||||
@ -125,36 +125,18 @@ var DisplayObject.scaleY
|
||||
/**
|
||||
* Z scale. Not inherited
|
||||
*/
|
||||
var DisplayObject.scaleZ
|
||||
var VisualObject.scaleZ
|
||||
get() = properties["scale.z"].number ?: 1.0
|
||||
set(value) {
|
||||
properties["scale.z"] = value
|
||||
}
|
||||
|
||||
fun DisplayObject.color(rgb: Int) {
|
||||
this.properties["material"] = rgb
|
||||
}
|
||||
|
||||
fun DisplayObject.color(meta: Meta) {
|
||||
this.properties["material"] = meta
|
||||
}
|
||||
|
||||
fun DisplayObject.color(builder: MetaBuilder.()->Unit) {
|
||||
color(buildMeta(builder))
|
||||
}
|
||||
|
||||
fun DisplayObject.color(r: Int, g: Int, b: Int) = color{
|
||||
"red" to r
|
||||
"green" to g
|
||||
"blue" to b
|
||||
}
|
||||
|
||||
//TODO add inherited scale
|
||||
|
||||
/**
|
||||
* Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default
|
||||
*/
|
||||
var DisplayObject.detail: Int?
|
||||
var VisualObject.detail: Int?
|
||||
get() = properties["detail"]?.int
|
||||
set(value) {
|
||||
properties["detail"] = value
|
||||
|
@ -4,14 +4,14 @@ import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.getAll
|
||||
import hep.dataforge.meta.node
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vis.common.DisplayGroup
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
class ConvexTest {
|
||||
@Test
|
||||
fun testConvexBuilder() {
|
||||
val group = DisplayGroup().apply {
|
||||
val group = VisualGroup().apply {
|
||||
convex {
|
||||
point(50, 50, -50)
|
||||
point(50, -50, -50)
|
||||
|
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.1.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.5-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
18
gradlew
vendored
18
gradlew
vendored
@ -1,5 +1,21 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
#
|
||||
# Copyright 2015 the original author or authors.
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# https://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
##############################################################################
|
||||
##
|
||||
## Gradle start up script for UN*X
|
||||
@ -28,7 +44,7 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m"'
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
|
18
gradlew.bat
vendored
18
gradlew.bat
vendored
@ -1,3 +1,19 @@
|
||||
@rem
|
||||
@rem Copyright 2015 the original author or authors.
|
||||
@rem
|
||||
@rem Licensed under the Apache License, Version 2.0 (the "License");
|
||||
@rem you may not use this file except in compliance with the License.
|
||||
@rem You may obtain a copy of the License at
|
||||
@rem
|
||||
@rem https://www.apache.org/licenses/LICENSE-2.0
|
||||
@rem
|
||||
@rem Unless required by applicable law or agreed to in writing, software
|
||||
@rem distributed under the License is distributed on an "AS IS" BASIS,
|
||||
@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
@rem See the License for the specific language governing permissions and
|
||||
@rem limitations under the License.
|
||||
@rem
|
||||
|
||||
@if "%DEBUG%" == "" @echo off
|
||||
@rem ##########################################################################
|
||||
@rem
|
||||
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m"
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
@ -33,7 +33,9 @@ include(
|
||||
":dataforge-vis-fx",
|
||||
":dataforge-vis-spatial",
|
||||
":dataforge-vis-spatial-fx",
|
||||
":dataforge-vis-spatial-js"
|
||||
":dataforge-vis-spatial-js",
|
||||
":dataforge-vis-jsroot",
|
||||
":dataforge-vis-spatial-gdml"
|
||||
)
|
||||
|
||||
//if(file("../dataforge-core").exists()) {
|
||||
|
Loading…
Reference in New Issue
Block a user