Separate modules for jsroot and gdml

This commit is contained in:
Alexander Nozik 2019-07-08 22:11:15 +03:00
parent 67def6cdb5
commit f4221d66cc
47 changed files with 631 additions and 548 deletions

View File

@ -1,5 +1,10 @@
package hep.dataforge.vis.common 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 * Taken from https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt
*/ */
@ -175,3 +180,22 @@ object Colors {
const val yellow = 0xFFFF00 const val yellow = 0xFFFF00
const val yellowgreen = 0x9ACD32 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
}

View File

@ -10,33 +10,33 @@ import hep.dataforge.provider.Provider
/** /**
* A display group which allows both named and unnamed children * A display group which allows both named and unnamed children
*/ */
class DisplayGroup( class VisualGroup(
override val parent: DisplayObject? = null, meta: Meta = EmptyMeta override val parent: VisualObject? = null, meta: Meta = EmptyMeta
) : DisplayObject, Iterable<DisplayObject>, Provider { ) : VisualObject, Iterable<VisualObject>, Provider {
private val namedChildren = HashMap<Name, DisplayObject>() private val namedChildren = HashMap<Name, VisualObject>()
private val unnamedChildren = ArrayList<DisplayObject>() 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 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> { override fun provideTop(target: String): Map<Name, Any> {
return when(target){ return when(target){
DisplayObject.TYPE -> namedChildren VisualObject.TYPE -> namedChildren
else -> emptyMap() 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>() private val listeners = HashSet<Listener>()
/** /**
* Add listener for children change * 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)) 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){ if(key == null){
} else { } else {
@ -68,7 +68,7 @@ class DisplayGroup(
/** /**
* Append unnamed child * Append unnamed child
*/ */
fun add(child: DisplayObject) { fun add(child: VisualObject) {
unnamedChildren.add(child) unnamedChildren.add(child)
listeners.forEach { it.callback(null, child) } listeners.forEach { it.callback(null, child) }
} }
@ -76,7 +76,7 @@ class DisplayGroup(
/** /**
* remove unnamed child * remove unnamed child
*/ */
fun remove(child: DisplayObject) { fun remove(child: VisualObject) {
unnamedChildren.remove(child) unnamedChildren.remove(child)
listeners.forEach { it.callback(null, null) } listeners.forEach { it.callback(null, null) }
} }

View File

@ -4,20 +4,20 @@ import hep.dataforge.meta.*
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.provider.Type import hep.dataforge.provider.Type
import hep.dataforge.vis.common.DisplayObject.Companion.META_KEY import hep.dataforge.vis.common.VisualObject.Companion.META_KEY
import hep.dataforge.vis.common.DisplayObject.Companion.TAGS_KEY import hep.dataforge.vis.common.VisualObject.Companion.TAGS_KEY
import hep.dataforge.vis.common.DisplayObject.Companion.TYPE import hep.dataforge.vis.common.VisualObject.Companion.TYPE
/** /**
* A root type for display hierarchy * A root type for display hierarchy
*/ */
@Type(TYPE) @Type(TYPE)
interface DisplayObject : MetaRepr { interface VisualObject : MetaRepr {
/** /**
* The parent object of this one. If null, this one is a root. * The parent object of this one. If null, this one is a root.
*/ */
val parent: DisplayObject? val parent: VisualObject?
val properties: Styled val properties: Styled
@ -26,7 +26,7 @@ interface DisplayObject : MetaRepr {
} }
companion object { companion object {
const val TYPE = "display" const val TYPE = "visual"
const val DEFAULT_TYPE = "" const val DEFAULT_TYPE = ""
//const val TYPE_KEY = "@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 * 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) properties.onChange(owner, action)
parent?.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 * Remove all meta listeners with matching owners
*/ */
fun DisplayObject.removeChangeListener(owner: Any?) { fun VisualObject.removeChangeListener(owner: Any?) {
properties.removeListener(owner) properties.removeListener(owner)
parent?.removeChangeListener(owner) parent?.removeChangeListener(owner)
} }
@ -63,24 +63,24 @@ fun DisplayObject.removeChangeListener(owner: Any?) {
/** /**
* Additional meta not relevant to display * 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( open class DisplayLeaf(
override val parent: DisplayObject?, override val parent: VisualObject?,
meta: Meta = EmptyMeta meta: Meta = EmptyMeta
) : DisplayObject { ) : VisualObject {
final override val properties = Styled(meta) final override val properties = Styled(meta)
} }
///** ///**
// * A group that could contain both named and unnamed children. Unnamed children could be accessed only via // * 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 // override val defaultTarget: String get() = DisplayObject.TARGET
// //
// val children // val children

View File

@ -16,8 +16,8 @@ class DisplayObjectDelegate(
val key: Name?, val key: Name?,
val default: MetaItem<*>?, val default: MetaItem<*>?,
val inherited: Boolean val inherited: Boolean
) : ReadWriteProperty<DisplayObject, MetaItem<*>?> { ) : ReadWriteProperty<VisualObject, MetaItem<*>?> {
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): MetaItem<*>? { override fun getValue(thisRef: VisualObject, property: KProperty<*>): MetaItem<*>? {
val name = key ?: property.name.toName() val name = key ?: property.name.toName()
return if (inherited) { return if (inherited) {
thisRef.getProperty(name) thisRef.getProperty(name)
@ -26,7 +26,7 @@ class DisplayObjectDelegate(
} ?: default } ?: 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() val name = key ?: property.name.toName()
thisRef.properties[name] = value thisRef.properties[name] = value
} }
@ -38,8 +38,8 @@ class DisplayObjectDelegateWrapper<T>(
val inherited: Boolean, val inherited: Boolean,
val write: Config.(name: Name, value: T) -> Unit = { name, value -> set(name, value) }, val write: Config.(name: Name, value: T) -> Unit = { name, value -> set(name, value) },
val read: (MetaItem<*>?) -> T? val read: (MetaItem<*>?) -> T?
) : ReadWriteProperty<DisplayObject, T> { ) : ReadWriteProperty<VisualObject, T> {
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): T { override fun getValue(thisRef: VisualObject, property: KProperty<*>): T {
val name = key ?: property.name.toName() val name = key ?: property.name.toName()
return if (inherited) { return if (inherited) {
read(thisRef.getProperty(name)) read(thisRef.getProperty(name))
@ -48,74 +48,74 @@ class DisplayObjectDelegateWrapper<T>(
} ?: default } ?: 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() val name = key ?: property.name.toName()
thisRef.properties[name] = value 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 } 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 } 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 } 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 } 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 } 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 } 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 } 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 } DisplayObjectDelegateWrapper(key?.toName(), null, inherited) { it }
//fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) } //fun <T : Configurable> Configurable.spec(spec: Specification<T>, key: String? = null) = ChildConfigDelegate<T>(key) { spec.wrap(this) }
@JvmName("safeString") @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 } DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.string }
@JvmName("safeBoolean") @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 } DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.boolean }
@JvmName("safeNumber") @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 } DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.number }
@JvmName("safeDouble") @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 } DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { it.double }
@JvmName("safeInt") @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 } 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) } } DisplayObjectDelegateWrapper(key?.toName(), default, inherited) { item -> item.string?.let { enumValueOf<E>(it) } }
//merge properties //merge properties
fun <T> DisplayObject.merge( fun <T> VisualObject.merge(
key: String? = null, key: String? = null,
transformer: (Sequence<MetaItem<*>>) -> T transformer: (Sequence<MetaItem<*>>) -> T
): ReadOnlyProperty<DisplayObject, T> { ): ReadOnlyProperty<VisualObject, T> {
return object : ReadOnlyProperty<DisplayObject, T> { return object : ReadOnlyProperty<VisualObject, T> {
override fun getValue(thisRef: DisplayObject, property: KProperty<*>): T { override fun getValue(thisRef: VisualObject, property: KProperty<*>): T {
val name = key?.toName() ?: property.name.toName() val name = key?.toName() ?: property.name.toName()
val sequence = sequence<MetaItem<*>> { val sequence = sequence<MetaItem<*>> {
var thisObj: DisplayObject? = thisRef var thisObj: VisualObject? = thisRef
while (thisObj != null) { while (thisObj != null) {
thisObj.properties[name]?.let { yield(it) } thisObj.properties[name]?.let { yield(it) }
thisObj = thisObj.parent thisObj = thisObj.parent

View 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"
}
}
}

View File

@ -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

View File

@ -8,7 +8,7 @@ import hep.dataforge.vis.common.*
import hep.dataforge.vis.spatial.three.MeshThreeFactory import hep.dataforge.vis.spatial.three.MeshThreeFactory
import info.laht.threekt.core.BufferGeometry 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() 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) } JSRootGeometry(this, meta).apply(action).also { add(it) }
//fun Meta.toDynamic(): dynamic { //fun Meta.toDynamic(): dynamic {

View File

@ -3,14 +3,14 @@ package hep.dataforge.vis.spatial.jsroot
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.toDynamic 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.DisplayLeaf
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.node import hep.dataforge.vis.common.node
import hep.dataforge.vis.spatial.three.ThreeFactory import hep.dataforge.vis.spatial.three.ThreeFactory
import info.laht.threekt.core.Object3D 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() 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) val json = JSON.parse<Any>(str)
JSRootObject(this, EmptyMeta, json).also { add(it) } JSRootObject(this, EmptyMeta, json).also { add(it) }
} }

View File

@ -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
}
}

View File

@ -1,6 +1,6 @@
import * as JSROOT from "JSRootUtils" import * as JSROOT from "src/main/resources/JSRootUtils"
import * as THREE from "three" 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 // Holder of all TGeo-related functions and classes
const GradPerSegm = 6; // grad per segment in cylinder/spherical symmetry shapes const GradPerSegm = 6; // grad per segment in cylinder/spherical symmetry shapes

View 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>

View File

@ -3,16 +3,16 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.getProperty import hep.dataforge.vis.common.getProperty
import hep.dataforge.vis.common.onChange import hep.dataforge.vis.common.onChange
import javafx.beans.binding.ObjectBinding import javafx.beans.binding.ObjectBinding
import tornadofx.* 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<*>?>>() private val binndings = HashMap<Name, ObjectBinding<MetaItem<*>?>>()
init { init {

View File

@ -3,8 +3,8 @@ package hep.dataforge.vis.spatial
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import javafx.scene.Group import javafx.scene.Group
import javafx.scene.Node import javafx.scene.Node
import org.fxyz3d.shapes.primitives.CuboidMesh import org.fxyz3d.shapes.primitives.CuboidMesh
@ -14,11 +14,11 @@ import tornadofx.*
* https://github.com/miho/JCSG for operations * 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() } val canvas by lazy { Canvas3D() }
private fun buildNode(obj: DisplayObject): Node? { private fun buildNode(obj: VisualObject): Node? {
val listener = DisplayObjectFXListener(obj) val listener = DisplayObjectFXListener(obj)
val x = listener["pos.x"].float() val x = listener["pos.x"].float()
val y = listener["pos.y"].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) org.fxyz3d.geometry.Point3D(x.value ?: 0f, y.value ?: 0f, z.value ?: 0f)
} }
return when (obj) { return when (obj) {
is DisplayGroup -> Group(obj.map { buildNode(it) }).apply { is VisualGroup -> Group(obj.map { buildNode(it) }).apply {
this.translateXProperty().bind(x) this.translateXProperty().bind(x)
this.translateYProperty().bind(y) this.translateYProperty().bind(y)
this.translateZProperty().bind(z) 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) } buildNode(obj)?.let { canvas.world.children.add(it) }
} }
} }

View File

@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.meta.number import hep.dataforge.meta.number
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import javafx.scene.Parent import javafx.scene.Parent
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
@ -21,7 +21,7 @@ class RendererDemoView : View() {
center = renderer.canvas.root center = renderer.canvas.root
} }
lateinit var group: DisplayGroup lateinit var group: VisualGroup
init { init {

View 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")
}
}
}
}

View File

@ -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()
// }
//}

View File

@ -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)
// }
//
//
// }
// }
//}

View File

@ -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()} }
}

View File

@ -4,8 +4,6 @@ import hep.dataforge.context.ContextBuilder
import hep.dataforge.meta.number import hep.dataforge.meta.number
import hep.dataforge.vis.common.Colors import hep.dataforge.vis.common.Colors
import hep.dataforge.vis.spatial.* 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.GlobalScope
import kotlinx.coroutines.delay import kotlinx.coroutines.delay
import kotlinx.coroutines.isActive import kotlinx.coroutines.isActive
@ -21,12 +19,9 @@ class ThreeDemoApp : ApplicationBase() {
override val stateKeys: List<String> = emptyList() override val stateKeys: List<String> = emptyList()
override fun start(state: Map<String, Any>) { override fun start(state: Map<String, Any>) {
require("JSRootGeoBase.js")
//TODO replace by optimized builder after dataforge 0.1.3-dev-8 //TODO replace by optimized builder after dataforge 0.1.3-dev-8
val context = ContextBuilder("three-demo").apply { val context = ContextBuilder("three-demo").build()
plugin(JSRootPlugin())
}.build()
context.plugins.load(ThreeDemoGrid()).run { context.plugins.load(ThreeDemoGrid()).run {
demo("shapes", "Basic shapes") { demo("shapes", "Basic shapes") {
@ -76,15 +71,15 @@ class ThreeDemoApp : ApplicationBase() {
} }
} }
demo("jsroot", "JSROOT cube") { // demo("jsroot", "JSROOT cube") {
jsRootGeometry { // jsRootGeometry {
y = 110.0 // y = 110.0
shape = box(50, 50, 50) // shape = box(50, 50, 50)
color(Colors.lightcoral) // color(Colors.lightcoral)
rotationX = PI / 4 // rotationX = PI / 4
rotationY = PI / 4 // rotationY = PI / 4
} // }
} // }
demo("extrude", "extruded shape") { demo("extrude", "extruded shape") {
extrude { extrude {

View File

@ -12,8 +12,8 @@ import hep.dataforge.names.Name
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.output.OutputManager import hep.dataforge.output.OutputManager
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.render import hep.dataforge.vis.spatial.render
import hep.dataforge.vis.spatial.three.ThreeOutput import hep.dataforge.vis.spatial.three.ThreeOutput
import hep.dataforge.vis.spatial.three.ThreePlugin import hep.dataforge.vis.spatial.three.ThreePlugin
@ -49,7 +49,7 @@ class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager {
val three = context.plugins.get<ThreePlugin>()!! val three = context.plugins.get<ThreePlugin>()!!
return outputs.getOrPut(name) { 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) { val output = three.output(meta) {
"axis" to { "axis" to {
"size" to 500 "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 { val meta = buildMeta {
"title" to title "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) output.render(action = block)
} }

View File

@ -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}
}
}

View File

@ -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)
}
}

View File

@ -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()
}
}

View File

@ -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)
}
}
}
}

View File

@ -4,7 +4,7 @@ import hep.dataforge.meta.boolean
import hep.dataforge.names.startsWith import hep.dataforge.names.startsWith
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.provider.Type import hep.dataforge.provider.Type
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.getProperty import hep.dataforge.vis.common.getProperty
import hep.dataforge.vis.common.onChange import hep.dataforge.vis.common.onChange
import hep.dataforge.vis.spatial.* import hep.dataforge.vis.spatial.*
@ -19,13 +19,13 @@ import info.laht.threekt.objects.LineSegments
import info.laht.threekt.objects.Mesh import info.laht.threekt.objects.Mesh
import kotlin.reflect.KClass 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 * Builder and updater for three.js object
*/ */
@Type(TYPE) @Type(TYPE)
interface ThreeFactory<T : DisplayObject> { interface ThreeFactory<T : VisualObject> {
val type: KClass<out T> val type: KClass<out T>
@ -34,7 +34,7 @@ interface ThreeFactory<T : DisplayObject> {
companion object { companion object {
const val TYPE = "threeFactory" 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) val geometry = geometryBuilder(obj)
//JS sometimes tries to pass Geometry as BufferGeometry //JS sometimes tries to pass Geometry as BufferGeometry
@ -84,7 +84,7 @@ interface ThreeFactory<T : DisplayObject> {
/** /**
* Update position, rotation and visibility * 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) position.set(obj.x, obj.y, obj.z)
setRotationFromEuler(obj.euler) setRotationFromEuler(obj.euler)
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
@ -94,7 +94,7 @@ internal fun Object3D.updatePosition(obj: DisplayObject) {
/** /**
* Unsafe invocation of a factory * 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)) { if (type.isInstance(obj)) {
return invoke(obj as T) return invoke(obj as T)
} else { } else {
@ -105,7 +105,7 @@ operator fun <T : DisplayObject> ThreeFactory<T>.invoke(obj: Any): Object3D {
/** /**
* Basic geometry-based factory * 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> { ThreeFactory<T> {
/** /**
* Build a geometry for an object * Build a geometry for an object

View File

@ -4,7 +4,7 @@ import hep.dataforge.context.Context
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.vis.common.Colors 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 hep.dataforge.vis.spatial.demo.require
import info.laht.threekt.WebGLRenderer import info.laht.threekt.WebGLRenderer
import info.laht.threekt.helpers.AxesHelper import info.laht.threekt.helpers.AxesHelper
@ -15,7 +15,7 @@ import kotlin.browser.window
private val elementResizeEvent = require("element-resize-event") 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 override val context: Context get() = three.context
@ -58,7 +58,7 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<D
animate() animate()
} }
override fun render(obj: DisplayObject, meta: Meta) { override fun render(obj: VisualObject, meta: Meta) {
scene.add(three.buildObject3D(obj)) scene.add(three.buildObject3D(obj))
} }
} }

View File

@ -5,8 +5,8 @@ import hep.dataforge.context.PluginFactory
import hep.dataforge.context.PluginTag import hep.dataforge.context.PluginTag
import hep.dataforge.context.content import hep.dataforge.context.content
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.* import hep.dataforge.vis.spatial.*
import info.laht.threekt.cameras.Camera import info.laht.threekt.cameras.Camera
import info.laht.threekt.cameras.PerspectiveCamera import info.laht.threekt.cameras.PerspectiveCamera
@ -20,7 +20,7 @@ import kotlin.reflect.KClass
class ThreePlugin : AbstractPlugin() { class ThreePlugin : AbstractPlugin() {
override val tag: PluginTag get() = Companion.tag 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) private val compositeFactory = ThreeCompositeFactory(this)
init { init {
@ -30,14 +30,14 @@ class ThreePlugin : AbstractPlugin() {
objectFactories[Sphere::class] = ThreeSphereFactory objectFactories[Sphere::class] = ThreeSphereFactory
} }
private fun findObjectFactory(type: KClass<out DisplayObject>): ThreeFactory<*>? { private fun findObjectFactory(type: KClass<out VisualObject>): ThreeFactory<*>? {
return objectFactories[type] return objectFactories[type]
?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type } ?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type }
} }
fun buildObject3D(obj: DisplayObject): Object3D { fun buildObject3D(obj: VisualObject): Object3D {
return when (obj) { return when (obj) {
is DisplayGroup -> Group(obj.map { buildObject3D(it) }).apply { is VisualGroup -> Group(obj.map { buildObject3D(it) }).apply {
updatePosition(obj) updatePosition(obj)
} }
is Composite -> compositeFactory(obj) is Composite -> compositeFactory(obj)

View File

@ -4,7 +4,7 @@ import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.float import hep.dataforge.meta.float
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.node 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.rotationOrder
import hep.dataforge.vis.spatial.rotationX import hep.dataforge.vis.spatial.rotationX
import hep.dataforge.vis.spatial.rotationY 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) } 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) val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)

View File

@ -2,12 +2,12 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta 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.DisplayLeaf
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.double 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 xSize by double(100.0)
var ySize by double(100.0) var ySize by double(100.0)
var zSize 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 { companion object {
const val TYPE = "geometry.3d.box" 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) } 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{ Box(this, meta).apply(action).apply{
this.xSize = xSize.toDouble() this.xSize = xSize.toDouble()
this.ySize = ySize.toDouble() this.ySize = ySize.toDouble()

View File

@ -3,9 +3,9 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.seal 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.DisplayLeaf
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
enum class CompositeType { enum class CompositeType {
UNION, UNION,
@ -14,25 +14,25 @@ enum class CompositeType {
} }
class Composite( class Composite(
parent: DisplayObject?, parent: VisualObject?,
val first: DisplayObject, val first: VisualObject,
val second: DisplayObject, val second: VisualObject,
val type: CompositeType = CompositeType.UNION, val type: CompositeType = CompositeType.UNION,
meta: Meta = EmptyMeta meta: Meta = EmptyMeta
) : DisplayLeaf(parent, meta) ) : DisplayLeaf(parent, meta)
fun DisplayGroup.composite(type: CompositeType, builder: DisplayGroup.() -> Unit): Composite { fun VisualGroup.composite(type: CompositeType, builder: VisualGroup.() -> Unit): Composite {
val group = DisplayGroup().apply(builder) val group = VisualGroup().apply(builder)
val children = group.toList() val children = group.toList()
if (children.size != 2) error("Composite requires exactly two children") if (children.size != 2) error("Composite requires exactly two children")
return Composite(this, children[0], children[1], type, group.properties.seal()).also { add(it) } 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) composite(CompositeType.UNION,builder)
fun DisplayGroup.subtract(builder: DisplayGroup.() -> Unit) = fun VisualGroup.subtract(builder: VisualGroup.() -> Unit) =
composite(CompositeType.SUBTRACT,builder) composite(CompositeType.SUBTRACT,builder)
fun DisplayGroup.intersect(builder: DisplayGroup.() -> Unit) = fun VisualGroup.intersect(builder: VisualGroup.() -> Unit) =
composite(CompositeType.INTERSECT,builder) composite(CompositeType.INTERSECT,builder)

View File

@ -1,11 +1,11 @@
package hep.dataforge.vis.spatial package hep.dataforge.vis.spatial
import hep.dataforge.meta.* 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.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")) 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) } ConvexBuilder().apply(action).build(this, meta).also { add(it) }
class ConvexBuilder { class ConvexBuilder {
@ -30,7 +30,7 @@ class ConvexBuilder {
points.add(Point3D(x, y, z)) points.add(Point3D(x, y, z))
} }
fun build(parent: DisplayObject?, meta: Meta): Convex { fun build(parent: VisualObject?, meta: Meta): Convex {
val points = buildMeta { val points = buildMeta {
points.forEachIndexed { index, value -> points.forEachIndexed { index, value ->
"points.point[$index]" to value.toMeta() "points.point[$index]" to value.toMeta()

View File

@ -1,9 +1,9 @@
package hep.dataforge.vis.spatial package hep.dataforge.vis.spatial
import hep.dataforge.meta.* 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.DisplayLeaf
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.sin 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 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 val shape
get() = properties.getAll("shape.point").map { (_, value) -> 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) } Extruded(this, meta).apply(action).also { add(it) }

View File

@ -1,7 +1,7 @@
package hep.dataforge.vis.spatial package hep.dataforge.vis.spatial
import hep.dataforge.meta.* 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 { data class Point2D(val x: Number, val y: Number) : MetaRepr {
override fun toMeta(): Meta = buildMeta { override fun toMeta(): Meta = buildMeta {
@ -60,6 +60,6 @@ fun GeometryBuilder<*>.face4(
face(vertex1, vertex3, vertex4, normal, meta) face(vertex1, vertex3, vertex4, normal, meta)
} }
interface Shape : DisplayObject { interface Shape : VisualObject {
fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
} }

View File

@ -2,13 +2,13 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta 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.DisplayLeaf
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.double import hep.dataforge.vis.common.double
import kotlin.math.PI 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 radius by double(50.0)
var phiStart by double(0.0) var phiStart by double(0.0)
var phi by double(2 * PI) var phi by double(2 * PI)
@ -16,10 +16,10 @@ class Sphere(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, meta) {
var theta by double(PI) 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) } Sphere(this, meta).apply(action).also { add(it) }
fun DisplayGroup.sphere( fun VisualGroup.sphere(
radius: Number, radius: Number,
phi: Number = 2 * PI, phi: Number = 2 * PI,
theta: Number = PI, theta: Number = PI,

View File

@ -2,16 +2,16 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.DisplayObject import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.getProperty import hep.dataforge.vis.common.getProperty
fun DisplayGroup.group(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit = {}): DisplayGroup = fun VisualGroup.group(meta: Meta = EmptyMeta, action: VisualGroup.() -> Unit = {}): VisualGroup =
DisplayGroup(this, meta).apply(action).also { add(it) } VisualGroup(this, meta).apply(action).also { add(it) }
fun Output<DisplayObject>.render(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit) = fun Output<VisualObject>.render(meta: Meta = EmptyMeta, action: VisualGroup.() -> Unit) =
render(DisplayGroup(null, EmptyMeta).apply(action), meta) render(VisualGroup(null, EmptyMeta).apply(action), meta)
//TODO replace properties by containers? //TODO replace properties by containers?
@ -20,7 +20,7 @@ fun Output<DisplayObject>.render(meta: Meta = EmptyMeta, action: DisplayGroup.()
/** /**
* Visibility property. Inherited from parent * Visibility property. Inherited from parent
*/ */
var DisplayObject.visible var VisualObject.visible
get() = getProperty("visible").boolean ?: true get() = getProperty("visible").boolean ?: true
set(value) { set(value) {
properties["visible"] = value properties["visible"] = value
@ -31,7 +31,7 @@ var DisplayObject.visible
/** /**
* x position property relative to parent. Not inherited * x position property relative to parent. Not inherited
*/ */
var DisplayObject.x var VisualObject.x
get() = properties["pos.x"].number ?: 0.0 get() = properties["pos.x"].number ?: 0.0
set(value) { set(value) {
properties["pos.x"] = value properties["pos.x"] = value
@ -40,7 +40,7 @@ var DisplayObject.x
/** /**
* y position property. Not inherited * y position property. Not inherited
*/ */
var DisplayObject.y var VisualObject.y
get() = properties["pos.y"].number ?: 0.0 get() = properties["pos.y"].number ?: 0.0
set(value) { set(value) {
properties["pos.y"] = value properties["pos.y"] = value
@ -49,7 +49,7 @@ var DisplayObject.y
/** /**
* z position property. Not inherited * z position property. Not inherited
*/ */
var DisplayObject.z var VisualObject.z
get() = properties["pos.z"].number ?: 0.0 get() = properties["pos.z"].number ?: 0.0
set(value) { set(value) {
properties["pos.z"] = value properties["pos.z"] = value
@ -60,7 +60,7 @@ var DisplayObject.z
/** /**
* x rotation relative to parent. Not inherited * x rotation relative to parent. Not inherited
*/ */
var DisplayObject.rotationX var VisualObject.rotationX
get() = properties["rotation.x"].number ?: 0.0 get() = properties["rotation.x"].number ?: 0.0
set(value) { set(value) {
properties["rotation.x"] = value properties["rotation.x"] = value
@ -69,7 +69,7 @@ var DisplayObject.rotationX
/** /**
* y rotation relative to parent. Not inherited * y rotation relative to parent. Not inherited
*/ */
var DisplayObject.rotationY var VisualObject.rotationY
get() = properties["rotation.y"].number ?: 0.0 get() = properties["rotation.y"].number ?: 0.0
set(value) { set(value) {
properties["rotation.y"] = value properties["rotation.y"] = value
@ -78,7 +78,7 @@ var DisplayObject.rotationY
/** /**
* z rotation relative to parent. Not inherited * z rotation relative to parent. Not inherited
*/ */
var DisplayObject.rotationZ var VisualObject.rotationZ
get() = properties["rotation.z"].number ?: 0.0 get() = properties["rotation.z"].number ?: 0.0
set(value) { set(value) {
properties["rotation.z"] = value properties["rotation.z"] = value
@ -96,7 +96,7 @@ enum class RotationOrder {
/** /**
* Rotation order. Not inherited * Rotation order. Not inherited
*/ */
var DisplayObject.rotationOrder: RotationOrder var VisualObject.rotationOrder: RotationOrder
get() = getProperty("rotation.order").enum<RotationOrder>() ?: RotationOrder.XYZ get() = getProperty("rotation.order").enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) { set(value) {
properties["rotation.order"] = value properties["rotation.order"] = value
@ -107,7 +107,7 @@ var DisplayObject.rotationOrder: RotationOrder
/** /**
* X scale. Not inherited * X scale. Not inherited
*/ */
var DisplayObject.scaleX var VisualObject.scaleX
get() = properties["scale.x"].number ?: 1.0 get() = properties["scale.x"].number ?: 1.0
set(value) { set(value) {
properties["scale.x"] = value properties["scale.x"] = value
@ -116,7 +116,7 @@ var DisplayObject.scaleX
/** /**
* Y scale. Not inherited * Y scale. Not inherited
*/ */
var DisplayObject.scaleY var VisualObject.scaleY
get() = properties["scale.y"].number ?: 1.0 get() = properties["scale.y"].number ?: 1.0
set(value) { set(value) {
properties["scale.y"] = value properties["scale.y"] = value
@ -125,36 +125,18 @@ var DisplayObject.scaleY
/** /**
* Z scale. Not inherited * Z scale. Not inherited
*/ */
var DisplayObject.scaleZ var VisualObject.scaleZ
get() = properties["scale.z"].number ?: 1.0 get() = properties["scale.z"].number ?: 1.0
set(value) { set(value) {
properties["scale.z"] = 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 //TODO add inherited scale
/** /**
* Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default * 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 get() = properties["detail"]?.int
set(value) { set(value) {
properties["detail"] = value properties["detail"] = value

View File

@ -4,14 +4,14 @@ import hep.dataforge.meta.get
import hep.dataforge.meta.getAll import hep.dataforge.meta.getAll
import hep.dataforge.meta.node import hep.dataforge.meta.node
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.vis.common.DisplayGroup import hep.dataforge.vis.common.VisualGroup
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
class ConvexTest { class ConvexTest {
@Test @Test
fun testConvexBuilder() { fun testConvexBuilder() {
val group = DisplayGroup().apply { val group = VisualGroup().apply {
convex { convex {
point(50, 50, -50) point(50, 50, -50)
point(50, -50, -50) point(50, -50, -50)

Binary file not shown.

View File

@ -1,5 +1,5 @@
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists 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 zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists

18
gradlew vendored
View File

@ -1,5 +1,21 @@
#!/usr/bin/env sh #!/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 ## Gradle start up script for UN*X
@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` 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. # 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. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"

18
gradlew.bat vendored
View File

@ -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 @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@ -14,7 +30,7 @@ set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% 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. @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 @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome

View File

@ -33,7 +33,9 @@ include(
":dataforge-vis-fx", ":dataforge-vis-fx",
":dataforge-vis-spatial", ":dataforge-vis-spatial",
":dataforge-vis-spatial-fx", ":dataforge-vis-spatial-fx",
":dataforge-vis-spatial-js" ":dataforge-vis-spatial-js",
":dataforge-vis-jsroot",
":dataforge-vis-spatial-gdml"
) )
//if(file("../dataforge-core").exists()) { //if(file("../dataforge-core").exists()) {