Merge remote-tracking branch 'origin/dev' into dev

# Conflicts:
#	dataforge-vis-common/src/commonMain/kotlin/hep/dataforge/vis/common/VisualGroup.kt
This commit is contained in:
Alexander Nozik 2020-01-03 22:12:59 +03:00
commit 65a73ad869
11 changed files with 112 additions and 12 deletions

View File

@ -1,13 +1,73 @@
[![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub) [![JetBrains Research](https://jb.gg/badges/research.svg)](https://confluence.jetbrains.com/display/ALL/JetBrains+on+GitHub)
# DataForge plugins for visualisation # DataForge Visualisation Platform
## Common visualisation objects This repository contains [DataForge](http://npm.mipt.ru/dataforge/)
(also [here](https://github.com/mipt-npm/dataforge-core)) components useful for visualization in
various scientific applications. Currently, the main application is 3D visualization for particle
physics experiments.
## JavaFX utilities for meta manipulations The project is developed as a Kotlin multiplatform application, currently
targeting browser JavaScript and JVM.
## 3D visualisation Main features:
- 3D visualization of complex experimental set-ups
- Event display such as particle tracks, etc.
- Scales up to few hundred thousands of elements
- Camera move, rotate, zoom-in and zoom-out
- Object tree with property editor
- Settings export and import
- Multiple platform support
Includes common discription and serializers, JavaFX and Three.js implementations.
## GDML bindings for 3D visualisation (to be moved to gdml project) ## Modules contained in this repository:
### dataforge-vis-common
Common visualisation objects such as VisualObject and VisualGroup.
### dataforge-vis-spatial
Includes common description and serializers for 3D visualisation, JavaFX and Three.js implementations.
### dataforge-vis-spatial-gdml
GDML bindings for 3D visualisation (to be moved to gdml project).
### dataforge-vis-jsroot
Some JSROOT bindings.
Note: Currently, this part is experimental and put here for completeness. This module may not build.
### demo
Several demonstrations of using the dataforge-vis framework:
##### spatial-showcase
Contains a simple demonstration (grid with a few shapes that you can rotate, move camera, etc.).
To see the demo: run `demo/spatial-showcase/distribution/installJsDist` Gradle task, then open
`build/distribuions/spatial-showcase-js-0.1.0-dev/index.html` file in your browser.
Other demos can be built similarly.
##### muon-monitor
A full-stack application example, showing the
[Muon Monitor](http://npm.mipt.ru/projects/physics.html#mounMonitor) experiment set-up.
Includes server back-end generating events, as well as visualization front-end.
To run full-stack app (both server and browser front-end), run
`demo/muon-monitor/application/run` task.
##### gdml
Visualization example for geometry defined as GDML file.

View File

@ -6,7 +6,7 @@ import kotlinx.serialization.Transient
/** /**
* Abstract implementation of group of [VisualObject] * Abstract implementation of mutable group of [VisualObject]
*/ */
abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup { abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup {
@ -24,6 +24,7 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), MutableVisualGroup
} }
} }
// TODO Consider renaming to `StructureChangeListener` (singular)
private data class StructureChangeListeners(val owner: Any?, val callback: (Name, VisualObject?) -> Unit) private data class StructureChangeListeners(val owner: Any?, val callback: (Name, VisualObject?) -> Unit)
@Transient @Transient

View File

@ -6,7 +6,8 @@ import hep.dataforge.values.int
import kotlin.math.max import kotlin.math.max
/** /**
* Taken from https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt * Definitions of common colors. Taken from
* https://github.com/markaren/three.kt/blob/master/threejs-wrapper/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt
*/ */
object Colors { object Colors {
const val aliceblue = 0xF0F8FF const val aliceblue = 0xF0F8FF
@ -184,6 +185,9 @@ object Colors {
const val GREEN_KEY = "green" const val GREEN_KEY = "green"
const val BLUE_KEY = "blue" const val BLUE_KEY = "blue"
/**
* Convert color represented as Meta to string of format #rrggbb
*/
fun fromMeta(item: MetaItem<*>): String { fun fromMeta(item: MetaItem<*>): String {
return when (item) { return when (item) {
is MetaItem.NodeItem<*> -> { is MetaItem.NodeItem<*> -> {
@ -204,11 +208,17 @@ object Colors {
} }
} }
/**
* Convert Int color to string of format #rrggbb
*/
fun rgbToString(rgb: Int): String { fun rgbToString(rgb: Int): String {
val string = rgb.toString(16).padStart(6, '0') val string = rgb.toString(16).padStart(6, '0')
return "#" + string.substring(max(0, string.length - 6)) return "#" + string.substring(max(0, string.length - 6))
} }
/**
* Convert three bytes representing color to string of format #rrggbb
*/
fun rgbToString(red: UByte, green: UByte, blue: UByte): String { fun rgbToString(red: UByte, green: UByte, blue: UByte): String {
fun colorToString(color: UByte): String { fun colorToString(color: UByte): String {
return color.toString(16).padStart(2, '0') return color.toString(16).padStart(2, '0')
@ -221,6 +231,9 @@ object Colors {
} }
} }
/**
* Convert three bytes representing color to Meta
*/
fun rgbToMeta(r: UByte, g: UByte, b: UByte): Meta = buildMeta { fun rgbToMeta(r: UByte, g: UByte, b: UByte): Meta = buildMeta {
RED_KEY put r.toInt() RED_KEY put r.toInt()
GREEN_KEY put g.toInt() GREEN_KEY put g.toInt()

View File

@ -3,6 +3,9 @@ package hep.dataforge.vis.common
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.provider.Provider import hep.dataforge.provider.Provider
/**
* Represents a group of [VisualObject] instances
*/
interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject { interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
/** /**
* A map of top level named children * A map of top level named children
@ -61,7 +64,9 @@ data class StyleRef(val group: VisualGroup, val styleName: Name)
val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty() val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty()
/**
* Mutable version of [VisualGroup]
*/
interface MutableVisualGroup : VisualGroup { interface MutableVisualGroup : VisualGroup {
/** /**

View File

@ -69,11 +69,17 @@ interface VisualObject : Configurable {
//const val META_KEY = "@meta" //const val META_KEY = "@meta"
//const val TAGS_KEY = "@tags" //const val TAGS_KEY = "@tags"
} }
} }
/**
* Get [VisualObject] property using key as a String
*/
fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit) fun VisualObject.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? = getProperty(key.toName(), inherit)
/**
* Set [VisualObject] property using key as a String
*/
fun VisualObject.setProperty(key: String, value: Any?) = setProperty(key.toName(), value) fun VisualObject.setProperty(key: String, value: Any?) = setProperty(key.toName(), value)
/** /**

View File

@ -3,12 +3,18 @@ package hep.dataforge.vis.common
import hep.dataforge.descriptors.ValueDescriptor import hep.dataforge.descriptors.ValueDescriptor
import hep.dataforge.meta.* import hep.dataforge.meta.*
/**
* Extension property to access the "widget" key of [ValueDescriptor]
*/
var ValueDescriptor.widget: Meta var ValueDescriptor.widget: Meta
get() = this.config["widget"].node?: EmptyMeta get() = this.config["widget"].node?: EmptyMeta
set(value) { set(value) {
this.config["widget"] = value this.config["widget"] = value
} }
/**
* Extension property to access the "widget.type" key of [ValueDescriptor]
*/
var ValueDescriptor.widgetType: String? var ValueDescriptor.widgetType: String?
get() = this["widget.type"].string get() = this["widget.type"].string
set(value) { set(value) {

View File

@ -62,7 +62,7 @@ class Extruded(
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) { override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
val shape: Shape2D = shape val shape: Shape2D = shape
if (shape.size < 3) error("Extruded shape requires more than points per layer") if (shape.size < 3) error("Extruded shape requires more than 2 points per layer")
/** /**
* Expand the shape for specific layers * Expand the shape for specific layers

View File

@ -24,6 +24,9 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlin.collections.set import kotlin.collections.set
/**
* Represents 3-dimensional Visual Group
*/
@Serializable @Serializable
@SerialName("group.3d") @SerialName("group.3d")
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D { class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {

View File

@ -14,6 +14,9 @@ import hep.dataforge.vis.spatial.VisualObject3D.Companion.LAYER_KEY
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
/**
* Interface for 3-dimensional [VisualObject]
*/
interface VisualObject3D : VisualObject { interface VisualObject3D : VisualObject {
var position: Point3D? var position: Point3D?
var rotation: Point3D? var rotation: Point3D?

View File

@ -6,7 +6,7 @@ import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.objects.Mesh import info.laht.threekt.objects.Mesh
/** /**
* This should be inner, becaulse it uses object builder * This should be inner, because it uses object builder
*/ */
class ThreeCompositeFactory(val three: ThreePlugin) : MeshThreeFactory<Composite>(Composite::class) { class ThreeCompositeFactory(val three: ThreePlugin) : MeshThreeFactory<Composite>(Composite::class) {

View File

@ -16,6 +16,9 @@ import info.laht.threekt.math.Matrix4
import info.laht.threekt.math.Vector3 import info.laht.threekt.math.Vector3
import info.laht.threekt.objects.Mesh import info.laht.threekt.objects.Mesh
/**
* Constructive Solid Geometry
*/
open external class CSG { open external class CSG {
open var polygons: Array<Polygon> open var polygons: Array<Polygon>
open fun clone(): CSG open fun clone(): CSG