Documentation and refactoring

This commit is contained in:
Alexander Nozik 2021-02-16 14:49:15 +03:00
parent e82ea7bb94
commit 1da4381a4c
55 changed files with 221 additions and 126 deletions

View File

@ -2,16 +2,16 @@ plugins {
id("ru.mipt.npm.project")
}
val dataforgeVersion by extra("0.3.0-dev-1")
val ktorVersion by extra("1.5.0")
val dataforgeVersion by extra("0.3.0")
val ktorVersion by extra("1.5.1")
val htmlVersion by extra("0.7.2")
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")
val fxVersion by extra("14")
allprojects {
repositories {
mavenLocal()
jcenter()
maven("https://dl.bintray.com/pdvrieze/maven")
maven("http://maven.jzy3d.org/releases")
}

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.gdml.demo
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.values.asValue
import hep.dataforge.vision.gdml.readFile
import hep.dataforge.vision.gdml.toVision

View File

@ -10,7 +10,7 @@ group = "ru.mipt.npm"
val ktorVersion: String by rootProject.extra
kscience {
useSerialization()
// useSerialization()
application()
}

View File

@ -3,7 +3,7 @@ package ru.mipt.npm.muon.monitor.server
import hep.dataforge.context.Context
import hep.dataforge.context.Global
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.solid.SolidManager
import io.ktor.application.Application
import io.ktor.application.call
@ -13,25 +13,24 @@ import io.ktor.features.CallLogging
import io.ktor.features.ContentNegotiation
import io.ktor.features.DefaultHeaders
import io.ktor.http.ContentType
import io.ktor.http.HttpStatusCode
import io.ktor.http.content.resources
import io.ktor.http.content.static
import io.ktor.response.respond
import io.ktor.response.respondText
import io.ktor.routing.Routing
import io.ktor.routing.get
import io.ktor.serialization.json
import io.ktor.server.cio.CIO
import io.ktor.server.engine.embeddedServer
import io.ktor.util.KtorExperimentalAPI
import kotlinx.serialization.json.Json
import org.apache.commons.math3.random.JDKRandomGenerator
import ru.mipt.npm.muon.monitor.Model
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
import ru.mipt.npm.muon.monitor.sim.simulateOne
import io.ktor.response.respondText
import java.awt.Desktop
import java.io.File
import java.net.URI
import io.ktor.http.HttpStatusCode
private val generator = Cos2TrackGenerator(JDKRandomGenerator(223))

View File

@ -5,9 +5,9 @@ plugins {
kscience {
useSerialization {
json()
}
// useSerialization {
// json()
// }
application()
}

View File

@ -13,6 +13,8 @@ kscience {
application()
}
val kotlinWrappersVersion: String by rootProject.extra
kotlin {
jvm {
@ -25,7 +27,7 @@ kotlin {
commonMain {
dependencies {
implementation(project(":visionforge-solid"))
implementation(project(":visionforge-gdml"))
// implementation(project(":visionforge-gdml"))
}
}
jvmMain{
@ -36,7 +38,6 @@ kotlin {
jsMain{
dependencies {
implementation(project(":visionforge-threejs"))
implementation("org.jetbrains:kotlin-css:1.0.0-pre.129-kotlin-1.4.10")
}
}
}

View File

@ -4,10 +4,7 @@ import hep.dataforge.meta.*
import hep.dataforge.names.plus
import hep.dataforge.names.startsWith
import hep.dataforge.values.asValue
import hep.dataforge.vision.getProperty
import hep.dataforge.vision.onPropertyChange
import hep.dataforge.vision.set
import hep.dataforge.vision.setProperty
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
import hep.dataforge.vision.solid.three.*

View File

@ -0,0 +1,22 @@
package hep.dataforge.vision.solid.demo
import javafx.stage.Stage
import tornadofx.*
class FXDemoApp : App(FXDemoGrid::class) {
val view: FXDemoGrid by inject()
override fun start(stage: Stage) {
super.start(stage)
stage.width = 600.0
stage.height = 600.0
view.showcase()
}
}
fun main() {
launch<FXDemoApp>()
}

View File

@ -1,35 +0,0 @@
package hep.dataforge.vision.solid.demo
import hep.dataforge.vision.gdml.gdml
import javafx.stage.Stage
import tornadofx.*
import java.nio.file.NoSuchFileException
import java.nio.file.Paths
class FXDemoApp : App(FXDemoGrid::class) {
val view: FXDemoGrid by inject()
override fun start(stage: Stage) {
super.start(stage)
stage.width = 600.0
stage.height = 600.0
view.showcase()
try {
view.demo("gdml", "gdml-cubes") {
gdml(Paths.get("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.gdml"))
//setProperty(Material3D.MATERIAL_WIREFRAME_KEY, true)
}
}
catch (e: NoSuchFileException) {
println("GDML demo: Please specify the correct file path e.g. " +
"visionforge\\demo\\gdml\\src\\commonMain\\resources\\cubes.gdml")
}
}
}
fun main() {
launch<FXDemoApp>()
}

View File

@ -2,4 +2,6 @@
### DataForge Name
### DataForge Meta
### DataForge Meta
### DataForge Context

View File

@ -11,3 +11,7 @@ When the user or a part of inner program mechanics requests a property, it searc
### Styling
The actual layering scheme is more complicated. All objects support styling. The styles are named `Meta` nodes that could be used to define groups of properties together and use in different `Vision`s. The styles are defined as named `Meta` nodes in a `VisionGroup` `@stylesheet` property (DataForge states that names starting with `@` are reserved for system properties, not visible by default to the user). The style or a list of styles could be applied to a `Vision` by setting the reserved `@style` property to the name of the style being used or by using `Vision::style` extension property. The style name is then resolved to the nearest ancestor that defines it. The key difference from the CSS styling in HTML is that the stylesheets could be added to any node, not only to the hierarchy root. It allows to decouple the whole subtrees together with styles from the main `Vision` graph, or create stand-alone branches. One must note, that the same style could be defined on different levels of the tree, only the nearest ancestor is resolved, meaning that one can override styles for a sub-tree.
### Intermediate representation
### Kotlin DSL for creating vision-graphs

5
docs/features.md Normal file
View File

@ -0,0 +1,5 @@
## Features
### Customization and plugins
### Full-stack development

77
docs/solids.md Normal file
View File

@ -0,0 +1,77 @@
## Solids
The primary initial goal of creating the library was to provide a flexible API and rendering engine to draw solid geometric forms for so-called event display task in particle physics. Event display is used to provide visualization for particle hit events in both accelerator and non-accelerator experiments (see [add links here] for examples). The event display system must have a way to render basic 3D shapes like boxes, tubes and spheres and particle tracks. An additional requirement is to be able to change coloring and transparency of different elements as well as custom attributes specific to the problem.
The `Solid` class inherits the `Vision` and has three additional nullable real vector properties: `position`, `rotation` and `scale`. Those properties are placed on the top level of the class instead of `properties` tree for performance optimization purposes. The `position` and `rotation` properties reflect the position offset in absolute units and rotation in radians relative to the parent and have defaults of `0.0`. Relativity means that if the parent `Vision` (`SolidGroup`) has `position = (1.0, 0.0, 1.0)` and a child has `position = (0.0, 2.0, 0.0)`, then the real offset of rendered object will be `(1.0, 2.0, 1.0)`. The same goes for the rotation. By default, the rotation uses intrinsic Cordan (TaitBryan) angles with `XYZ` order, but order could be changed with an inherited property `rotation.order`. The `scale` property is not inherited and represents local `Solid` scaling factor with default value of `1.0`.
The `SolidGroup` represents the specific kind of `VisionGroup` that has properties of a `Solid` and has one additional special property: the prototype container.
### Solid prototypes
One of the important requirements for event display system is the ability to render a huge number of primitives (tens and hundreds of thousands). This is especially important for accelerator experiments with fine-grained calorimeter detectors ([ref here]). The most memory and CPU-consuming task to render such structures is computing the geometry o equal elements (like calorimeter cells). In order to optimize rendering and model representation for such cases, we introduced so-called prototypes. The idea is that multiple visions could have the same prototype and share the definition and actual rendered geometry. The prototypes are stored in a special container property called `prototypes` in a `SolidGroup` object. In order to access those prototypes there is a special `Solid` object called `SolidReference`. It inherits `Solid` (has properties container, position, rotation and scale), but does not define any geometry. Instead, it has a single `refName` property which stores a fully qualified DataForge `Name` (see [Appendix](appendix.md)) that designates the name of the prototype to be used. During rendering phase, the system searches for appropriate prototype in the nearest parent. If the prototype is not found, the search continues in the next parent in the chain. Like property resolution, the prototype resolution is fine-grained and local, meaning that a part of `Vision` graph could be self-contained together with prototypes.
An important point is that prototypes are resolved in a parent vision container, and the parent vision container for prototypes is the vision group. It means that prototype itself could reference a prototype, or even in corner cases reference itself (such cases should be checked for infinite loops). The prototype relation example is shown in [prototypes.uml](uml/prototypes.puml). Here `Prototype Ref` vision references the `Prototype` vision by first seeking up to `VirionGroup`, the resolving the prototype with appropriate name. In theory, vision groups inside prototypes groups could contain the prototypes of their own, but such constructs should be used with care.
### Solid definitions
Solid models are defined as kotlin classes that also serve as builders for DSL and serialization models. For example, here is the definition for a `Box` class:
```kotlin
@Serializable
@SerialName("solid.box")
class Box(
val xSize: Float,
val ySize: Float,
val zSize: Float
) : SolidBase(), GeometrySolid
```
In general, one does not define how specific solid is rendered, it is done in the rendering back-end. It means that in general, there should be a specific renderer defined for each type of solids defined in the model. Some solids have additional mechanism to avoid providing renderers for each primitive. Classes that inherit `GeometrySolid` interface provide a way to define geometry via polygons like this:
```kotlin
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
val dx = xSize / 2
val dy = ySize / 2
val dz = zSize / 2
val node1 = Point3D(-dx, -dy, -dz)
val node2 = Point3D(dx, -dy, -dz)
val node3 = Point3D(dx, dy, -dz)
val node4 = Point3D(-dx, dy, -dz)
val node5 = Point3D(-dx, -dy, dz)
val node6 = Point3D(dx, -dy, dz)
val node7 = Point3D(dx, dy, dz)
val node8 = Point3D(-dx, dy, dz)
geometryBuilder.face4(node1, node4, node3, node2)
geometryBuilder.face4(node1, node2, node6, node5)
geometryBuilder.face4(node2, node3, node7, node6)
geometryBuilder.face4(node4, node8, node7, node3)
geometryBuilder.face4(node1, node5, node8, node4)
geometryBuilder.face4(node8, node5, node6, node7)
}
```
The `GeometryBuilder` instance is provided by the specific rendering engine, so the polygons are generated for target engine without intermediate steps. If the renderer provides its own implementation for a solid renderer, it takes precedence over generic `GeometrySolid` definition.
An important basic solid is the `Composite`. It is a primitive, that allows combine two (maybe more in future) primitives via [composite solid geometry or CSG](https://en.wikipedia.org/wiki/Constructive_solid_geometry) transformations (union, difference and subtraction). At this moment, the actual transformation is done on the renderer side.
### GDML bindings
VisionForge supports extensible geometry primitive list, but we've started with primitives needed to render BM@N ([ref]) GDML ([ref]) geometry. GDML files are read with [gdml.kt](https://github.com/mipt-npm/gdml.kt) package designed specifically for this purpose. The package uses [https://github.com/pdvrieze/xmlutil](https://github.com/pdvrieze/xmlutil) serialization plugin to parse GDML structure into the convenient object structure and has language definitions for all GDML primitives. The `visionforge-gdml` module contains a converter that transforms Gdml.kt structures into `Solid`.
The GDML file definition contains several sections:
* **defines** - Dimensions and numbers for geometries.
* **materials** - Material definitions.
* **solids** - Primitive definitions and their composition.
* **structure** - Combinations of solids and groups used in geometry.
* **setup** - Metadata and geometry entry point.
GDML materials are currently used only for Solid coloring. The data from material is stored in the `Vision` properties. Solids section and structures are transformed into top level group prototypes, which allows not only to create a compact representation, but also optimize rendering. The gdml structure is not always flexible. For example, it is not possible to add a solid directly into a group, but instead one needs to add a group with a single element. Problems like this could be automatically optimized by the convertor.
Not all GDML solids are currently supported by the converter, they could be added later on-demand. Current support covers all solids used in BM@N geometry.
### ThreeJs renderer
VisionForge is not tied to any single renderer. Right now the primary target is the Browser rendering with [Three.js library](https://threejs.org/). The Three.js supports different renderers including WebGL with hardware support and virtual reality.
The bindings for three-js was implemented in kotlin-js based on a [work by Lars Ivar Hatledal](https://github.com/markaren/three-kt-wrapper). The wrapper allows seamless integration with a lot of different library APIs incliding custom cameras and CSG.

14
docs/uml/prototypes.puml Normal file
View File

@ -0,0 +1,14 @@
@startuml
package "VisionGroup" {
package "Prototypes"{
[Prototype]
package "Prototype group"{
[Prototype Ref] --> [Prototype]
}
}
package "Child group"{
[Ref] --> [Prototype Ref]
}
}
@enduml

View File

@ -1,11 +1,13 @@
package hep.dataforge.vision.examples
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.fragment
import hep.dataforge.vision.plotly.plotly
import hep.dataforge.vision.plotly.withPlotly
import kotlinx.html.hr
import kotlinx.html.p
import kscience.plotly.scatter
@DFExperimental

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.examples
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.ResourceLocation

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.examples
import hep.dataforge.context.Context
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.scriptHeader

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.examples
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionForge
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.html.ResourceLocation

View File

@ -1,6 +1,6 @@
pluginManagement {
val kotlinVersion = "1.4.30-RC"
val toolsVersion = "0.7.3-1.4.30-RC"
val kotlinVersion = "1.4.30"
val toolsVersion = "0.7.6"
repositories {
mavenLocal()
@ -44,9 +44,9 @@ include(
":visionforge-gdml",
":visionforge-server",
":visionforge-plotly",
":demo:spatial-showcase",
":demo:gdml",
":demo:solid-showcase",
// ":demo:gdml",
":demo:muon-monitor",
":demo:sat-demo",
":playground"
":demo:sat-demo"
// ":playground"
)

View File

@ -1,8 +1,8 @@
package hep.dataforge.vision
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.misc.DFExperimental
import kotlin.properties.ReadOnlyProperty
/**

View File

@ -4,6 +4,7 @@ import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.descriptors.defaultItem
import hep.dataforge.meta.descriptors.get
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.names.plus

View File

@ -1,6 +1,7 @@
package hep.dataforge.vision
import hep.dataforge.meta.*
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.Name
import hep.dataforge.names.plus
import hep.dataforge.values.Null
@ -9,7 +10,7 @@ import kotlinx.coroutines.flow.Flow
import kotlinx.coroutines.flow.flow
import kotlinx.coroutines.flow.launchIn
import kotlinx.coroutines.flow.onEach
import kotlinx.serialization.*
import kotlinx.serialization.Serializable
import kotlin.jvm.Synchronized
import kotlin.time.Duration

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.html
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionManager
import kotlinx.html.FlowContent
import kotlinx.html.TagConsumer

View File

@ -1,11 +1,17 @@
package hep.dataforge.vision.html
import hep.dataforge.meta.*
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.MetaSerializer
import hep.dataforge.meta.isEmpty
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionManager
import kotlinx.html.*
import kotlin.collections.set
import kotlin.collections.setOf
/**

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.html
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.set
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionBase
import hep.dataforge.vision.configure
import hep.dataforge.vision.meta

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.html
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionManager
import kotlinx.html.link
import kotlinx.html.script

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision
import hep.dataforge.context.Context
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.html.HtmlFragment
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.Page

View File

@ -9,7 +9,6 @@ val fxVersion: String by rootProject.extra
kscience{
useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion)
useSerialization()
}
dependencies {

View File

@ -7,7 +7,7 @@ kotlin {
val commonMain by getting {
dependencies {
api(project(":visionforge-solid"))
api("kscience.gdml:gdml:0.2.0-dev-3")
api("kscience.gdml:gdml:0.2.0")
}
}
}

View File

@ -234,7 +234,14 @@ private class GDMLTransformer(val settings: GDMLTransformerSettings) {
}
}
else -> error("Renderer for $solid not supported yet")
is GDMLEllipsoid -> TODO("Renderer for $solid not supported yet")
is GDMLElTube -> TODO("Renderer for $solid not supported yet")
is GDMLElCone -> TODO("Renderer for $solid not supported yet")
is GDMLParaboloid -> TODO("Renderer for $solid not supported yet")
is GDMLParallelepiped -> TODO("Renderer for $solid not supported yet")
is GDMLTorus -> TODO("Renderer for $solid not supported yet")
is GDMLTrapezoid -> TODO("Renderer for $solid not supported yet")
is GDMLPolycone -> TODO("Renderer for $solid not supported yet")
}
}

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.gdml
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.itemSequence
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.Vision
import hep.dataforge.vision.meta
import hep.dataforge.vision.solid.*

View File

@ -2,12 +2,12 @@ plugins {
id("ru.mipt.npm.mpp")
}
kscience {
val plotlyVersion = "0.3.1"
kscience{
useSerialization()
}
val plotlyVersion = "0.3.1-dev"
kotlin {
js{
//binaries.library()

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.plotly
import hep.dataforge.meta.Config
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.VisionBase
import hep.dataforge.vision.html.VisionOutput
import kotlinx.serialization.Serializable

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.plotly
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.html.HtmlFragment
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.scriptHeader

View File

@ -2,6 +2,7 @@ package hep.dataforge.vision.three.server
import hep.dataforge.context.Context
import hep.dataforge.meta.*
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.vision.Vision

View File

@ -2,7 +2,7 @@ plugins {
id("ru.mipt.npm.mpp")
}
kscience {
kscience{
useSerialization()
}

View File

@ -3,7 +3,6 @@ package hep.dataforge.vision.solid
import hep.dataforge.vision.VisionBuilder
import hep.dataforge.vision.VisionContainerBuilder
import hep.dataforge.vision.set
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@ -36,25 +35,25 @@ public class Box(
geometryBuilder.face4(node8, node5, node6, node7)
}
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
other as Box
if (xSize != other.xSize) return false
if (ySize != other.ySize) return false
if (zSize != other.zSize) return false
return solidEquals(this, other)
}
override fun hashCode(): Int {
var result = xSize.hashCode()
result = 31 * result + ySize.hashCode()
result = 31 * result + zSize.hashCode()
return 31 * result + Solid.solidHashCode(this)
}
// override fun equals(other: Any?): Boolean {
// if (this === other) return true
// if (other == null || this::class != other::class) return false
//
// other as Box
//
// if (xSize != other.xSize) return false
// if (ySize != other.ySize) return false
// if (zSize != other.zSize) return false
//
// return solidEquals(this, other)
// }
//
// override fun hashCode(): Int {
// var result = xSize.hashCode()
// result = 31 * result + ySize.hashCode()
// result = 31 * result + zSize.hashCode()
// return 31 * result + Solid.solidHashCode(this)
// }
public companion object {

View File

@ -33,7 +33,6 @@ public class SolidGroup(
override val descriptor: NodeDescriptor get() = Solid.descriptor
/**
* Ger a prototype redirecting the request to the parent if prototype is not found
*/
@ -69,7 +68,7 @@ public class SolidGroup(
}
public companion object {
// val PROTOTYPES_KEY = NameToken("@prototypes")
//public val PROTOTYPES_TOKEN = NameToken("@prototypes")
}
}

View File

@ -3,8 +3,8 @@ package hep.dataforge.vision.solid
import hep.dataforge.context.Context
import hep.dataforge.context.PluginFactory
import hep.dataforge.context.PluginTag
import hep.dataforge.meta.DFExperimental
import hep.dataforge.meta.Meta
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.*
import hep.dataforge.vision.html.VisionOutput
import kotlinx.serialization.PolymorphicSerializer

View File

@ -1,7 +1,9 @@
package hep.dataforge.vision.solid
import hep.dataforge.meta.*
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.asMetaItem
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.*
import hep.dataforge.vision.*
import kotlinx.coroutines.flow.Flow
@ -35,15 +37,15 @@ private fun SolidReference.getRefProperty(
@Serializable
@SerialName("solid.ref")
public class SolidReferenceGroup(
public val templateName: Name,
public val refName: Name,
) : SolidBase(), SolidReference, VisionGroup {
/**
* Recursively search for defined template in the parent
*/
override val prototype: Solid
get() = (parent as? SolidGroup)?.getPrototype(templateName)
?: error("Prototype with name $templateName not found in $parent")
get() = (parent as? SolidGroup)?.getPrototype(refName)
?: error("Prototype with name $refName not found in $parent")
override val children: Map<NameToken, Vision>
get() = (prototype as? VisionGroup)?.children

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.solid.transform
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.asName
import hep.dataforge.vision.*
import hep.dataforge.vision.solid.*

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.solid.transform
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.vision.MutableVisionGroup
@ -18,7 +18,7 @@ internal object UnRef : VisualTreeTransform<SolidGroup>() {
reducer[key] = (reducer[key] ?: 0) + value
}
} else if (obj is SolidReferenceGroup) {
reducer[obj.templateName] = (reducer[obj.templateName] ?: 0) + 1
reducer[obj.refName] = (reducer[obj.refName] ?: 0) + 1
}
return reducer
@ -29,7 +29,7 @@ internal object UnRef : VisualTreeTransform<SolidGroup>() {
(this as? SolidGroup)?.prototypes{
set(name, null)
}
children.filter { (it.value as? SolidReferenceGroup)?.templateName == name }.forEach { (key, value) ->
children.filter { (it.value as? SolidReferenceGroup)?.refName == name }.forEach { (key, value) ->
val reference = value as SolidReferenceGroup
val newChild = mergeChild(reference, reference.prototype)
newChild.parent = null

View File

@ -1,7 +1,10 @@
package hep.dataforge.vision.solid
import hep.dataforge.meta.*
import hep.dataforge.meta.MetaItemNode
import hep.dataforge.meta.getIndexed
import hep.dataforge.meta.node
import hep.dataforge.meta.toMetaItem
import hep.dataforge.misc.DFExperimental
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.solid
import hep.dataforge.context.Global
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.get
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@ -2,10 +2,6 @@ plugins {
id("ru.mipt.npm.js")
}
kscience {
useSerialization()
}
kotlin{
js{
binaries.library()

View File

@ -2,13 +2,6 @@ plugins {
id("ru.mipt.npm.mpp")
}
kscience{
useSerialization{
json()
}
}
val ktorVersion: String by rootProject.extra
kotlin {

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.three.server
import hep.dataforge.context.Context
import hep.dataforge.meta.DFExperimental
import hep.dataforge.misc.DFExperimental
import hep.dataforge.vision.html.HtmlVisionFragment
import hep.dataforge.vision.html.ResourceLocation
import hep.dataforge.vision.html.scriptHeader