Major build update and refactoring
This commit is contained in:
parent
9361145197
commit
6116523091
2
.gitignore
vendored
2
.gitignore
vendored
@ -5,6 +5,4 @@ out/
|
|||||||
.gradle
|
.gradle
|
||||||
build/
|
build/
|
||||||
|
|
||||||
|
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
gradle.properties
|
|
14
CHANGELOG.md
14
CHANGELOG.md
@ -0,0 +1,14 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
### Added
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
### Deprecated
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
### Security
|
@ -1,16 +1,12 @@
|
|||||||
import scientifik.useFx
|
import ru.mipt.npm.gradle.useFx
|
||||||
import scientifik.useSerialization
|
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.1.8")
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp") apply false
|
id("ru.mipt.npm.project")
|
||||||
id("scientifik.jvm") apply false
|
|
||||||
id("scientifik.js") apply false
|
|
||||||
id("scientifik.publish") apply false
|
|
||||||
id("org.jetbrains.changelog") version "0.4.0"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val dataforgeVersion by extra("0.2.0-dev-3")
|
||||||
|
val ktorVersion by extra("1.4.1")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
@ -19,7 +15,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "hep.dataforge"
|
group = "hep.dataforge"
|
||||||
version = "0.1.5-dev-2"
|
version = "0.2.0-dev-1"
|
||||||
}
|
}
|
||||||
|
|
||||||
val githubProject by extra("visionforge")
|
val githubProject by extra("visionforge")
|
||||||
@ -28,8 +24,17 @@ val fxVersion by extra("14")
|
|||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
if(name.startsWith("visionforge")) {
|
if(name.startsWith("visionforge")) {
|
||||||
apply(plugin = "scientifik.publish")
|
apply<ru.mipt.npm.gradle.KSciencePublishPlugin>()
|
||||||
}
|
}
|
||||||
|
afterEvaluate {
|
||||||
|
extensions.findByType<ru.mipt.npm.gradle.KScienceExtension>()?.run {
|
||||||
useSerialization()
|
useSerialization()
|
||||||
useFx(scientifik.FXModule.CONTROLS, version = fxVersion)
|
useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
apiValidation {
|
||||||
|
validationDisabled = true
|
||||||
|
ignoredPackages.add("info.laht.threekt")
|
||||||
}
|
}
|
@ -1,20 +1,25 @@
|
|||||||
import scientifik.DependencyConfiguration
|
import ru.mipt.npm.gradle.DependencyConfiguration
|
||||||
import scientifik.FXModule
|
import ru.mipt.npm.gradle.FXModule
|
||||||
import scientifik.useFx
|
import ru.mipt.npm.gradle.useFx
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
id("application")
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
val fxVersion: String by rootProject.extra
|
kscience {
|
||||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
val fxVersion: String by rootProject.extra
|
||||||
|
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||||
|
application()
|
||||||
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
|
afterEvaluate {
|
||||||
withJava()
|
withJava()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
js {
|
js {
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
@ -27,7 +32,7 @@ kotlin {
|
|||||||
implementation(project(":visionforge-gdml"))
|
implementation(project(":visionforge-gdml"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain{
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":ui:bootstrap"))
|
implementation(project(":ui:bootstrap"))
|
||||||
implementation(npm("react-file-drop", "3.0.6"))
|
implementation(npm("react-file-drop", "3.0.6"))
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
package hep.dataforge.vision.gdml.demo
|
package hep.dataforge.vision.gdml.demo
|
||||||
|
|
||||||
import scientifik.gdml.*
|
import kscience.gdml.*
|
||||||
|
|
||||||
|
|
||||||
fun cubes(): GDML = GDML {
|
fun cubes(): GDML = GDML {
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package hep.dataforge.vision.gdml.demo
|
package hep.dataforge.vision.gdml.demo
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.meta.set
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
@ -18,18 +17,18 @@ import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
|||||||
import hep.dataforge.vision.solid.three.ThreeCanvas
|
import hep.dataforge.vision.solid.three.ThreeCanvas
|
||||||
import hep.dataforge.vision.solid.three.ThreeCanvasComponent
|
import hep.dataforge.vision.solid.three.ThreeCanvasComponent
|
||||||
import hep.dataforge.vision.solid.three.canvasControls
|
import hep.dataforge.vision.solid.three.canvasControls
|
||||||
|
import kotlinx.browser.window
|
||||||
import kotlinx.css.FlexBasis
|
import kotlinx.css.FlexBasis
|
||||||
import kotlinx.css.Overflow
|
import kotlinx.css.Overflow
|
||||||
import kotlinx.css.flex
|
import kotlinx.css.flex
|
||||||
import kotlinx.css.overflow
|
import kotlinx.css.overflow
|
||||||
|
import kscience.gdml.GDML
|
||||||
|
import kscience.gdml.decodeFromString
|
||||||
import org.w3c.files.FileReader
|
import org.w3c.files.FileReader
|
||||||
import org.w3c.files.get
|
import org.w3c.files.get
|
||||||
import react.RProps
|
import react.RProps
|
||||||
import react.dom.h1
|
import react.dom.h1
|
||||||
import scientifik.gdml.GDML
|
|
||||||
import scientifik.gdml.parse
|
|
||||||
import styled.css
|
import styled.css
|
||||||
import kotlin.browser.window
|
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
interface GDMLAppProps : RProps {
|
interface GDMLAppProps : RProps {
|
||||||
@ -58,10 +57,10 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
|||||||
fun loadData(name: String, data: String) {
|
fun loadData(name: String, data: String) {
|
||||||
val parsedVision = when {
|
val parsedVision = when {
|
||||||
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
||||||
val gdml = GDML.parse(data)
|
val gdml = GDML.decodeFromString(data)
|
||||||
gdml.toVision()
|
gdml.toVision()
|
||||||
}
|
}
|
||||||
name.endsWith(".json") -> SolidGroup.parseJson(data)
|
name.endsWith(".json") -> SolidGroup.decodeFromString(data)
|
||||||
else -> {
|
else -> {
|
||||||
window.alert("File extension is not recognized: $name")
|
window.alert("File extension is not recognized: $name")
|
||||||
error("File extension is not recognized: $name")
|
error("File extension is not recognized: $name")
|
||||||
|
@ -3,15 +3,12 @@ package hep.dataforge.vision.gdml.demo
|
|||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.js.Application
|
import hep.dataforge.js.Application
|
||||||
import hep.dataforge.js.startApplication
|
import hep.dataforge.js.startApplication
|
||||||
import hep.dataforge.vision.gdml.GDMLTransformer
|
|
||||||
import hep.dataforge.vision.gdml.LUnit
|
|
||||||
import hep.dataforge.vision.gdml.toVision
|
import hep.dataforge.vision.gdml.toVision
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
import kotlinx.browser.document
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import react.child
|
import react.child
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import styled.injectGlobal
|
import styled.injectGlobal
|
||||||
import kotlin.browser.document
|
|
||||||
|
|
||||||
|
|
||||||
private class GDMLDemoApp : Application {
|
private class GDMLDemoApp : Application {
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="css/main.css">
|
<link rel="stylesheet" href="css/main.css">
|
||||||
<link rel="stylesheet" href="css/fileDrop.css">
|
<link rel="stylesheet" href="css/fileDrop.css">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="gdml.js"></script>
|
||||||
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
|
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
|
||||||
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
|
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -3,13 +3,12 @@ package hep.dataforge.vision.gdml.demo
|
|||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.setItem
|
import hep.dataforge.meta.setItem
|
||||||
import hep.dataforge.values.asValue
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vision.gdml.LUnit
|
|
||||||
import hep.dataforge.vision.gdml.readFile
|
import hep.dataforge.vision.gdml.readFile
|
||||||
import hep.dataforge.vision.gdml.toVision
|
import hep.dataforge.vision.gdml.toVision
|
||||||
import hep.dataforge.vision.solid.SolidGroup
|
import hep.dataforge.vision.solid.SolidGroup
|
||||||
import hep.dataforge.vision.solid.SolidManager
|
import hep.dataforge.vision.solid.SolidManager
|
||||||
import hep.dataforge.vision.solid.SolidMaterial
|
import hep.dataforge.vision.solid.SolidMaterial
|
||||||
import scientifik.gdml.GDML
|
import kscience.gdml.GDML
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.util.zip.GZIPInputStream
|
import java.util.zip.GZIPInputStream
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
@ -32,19 +31,19 @@ fun SolidManager.Companion.readFile(file: File): SolidGroup = when {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.extension == "json" -> SolidGroup.parseJson(file.readText())
|
file.extension == "json" -> SolidGroup.decodeFromString(file.readText())
|
||||||
file.name.endsWith("json.zip") -> {
|
file.name.endsWith("json.zip") -> {
|
||||||
file.inputStream().use {
|
file.inputStream().use {
|
||||||
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
||||||
val text = unzip.readBytes().decodeToString()
|
val text = unzip.readBytes().decodeToString()
|
||||||
SolidGroup.parseJson(text)
|
SolidGroup.decodeFromString(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
file.name.endsWith("json.gz") -> {
|
file.name.endsWith("json.gz") -> {
|
||||||
file.inputStream().use {
|
file.inputStream().use {
|
||||||
val unzip = GZIPInputStream(it)
|
val unzip = GZIPInputStream(it)
|
||||||
val text = unzip.readBytes().decodeToString()
|
val text = unzip.readBytes().decodeToString()
|
||||||
SolidGroup.parseJson(text)
|
SolidGroup.decodeFromString(text)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> error("Unknown extension ${file.extension}")
|
else -> error("Unknown extension ${file.extension}")
|
||||||
|
@ -1,10 +1,10 @@
|
|||||||
package hep.dataforge.vision.gdml.demo
|
package hep.dataforge.vision.gdml.demo
|
||||||
|
|
||||||
import hep.dataforge.vision.gdml.LUnit
|
|
||||||
import hep.dataforge.vision.gdml.readFile
|
import hep.dataforge.vision.gdml.readFile
|
||||||
import hep.dataforge.vision.gdml.toVision
|
import hep.dataforge.vision.gdml.toVision
|
||||||
import hep.dataforge.vision.solid.stringify
|
import hep.dataforge.vision.solid.encodeToString
|
||||||
import scientifik.gdml.GDML
|
import kscience.gdml.GDML
|
||||||
|
import kscience.gdml.LUnit
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
|
|
||||||
@ -21,7 +21,7 @@ fun main(args: Array<String>) {
|
|||||||
lUnit = LUnit.CM
|
lUnit = LUnit.CM
|
||||||
}
|
}
|
||||||
|
|
||||||
val json = visual.stringify()
|
val json = visual.encodeToString()
|
||||||
println(json)
|
println(json)
|
||||||
File(outputFileName).writeText(json)
|
File(outputFileName).writeText(json)
|
||||||
//File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
|
//File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
|
||||||
|
@ -9,7 +9,7 @@ class FileSerializationTest {
|
|||||||
@Ignore
|
@Ignore
|
||||||
fun testFileRead(){
|
fun testFileRead(){
|
||||||
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
|
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
|
||||||
val visual = SolidGroup.parseJson(text)
|
val visual = SolidGroup.decodeFromString(text)
|
||||||
visual["composite_001".asName()]
|
visual["composite_001".asName()]
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,44 +1,39 @@
|
|||||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||||
import scientifik.jsDistDirectory
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
id("application")
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.mipt.npm"
|
group = "ru.mipt.npm"
|
||||||
|
|
||||||
val ktorVersion = "1.3.2"
|
val ktorVersion: String by rootProject.extra
|
||||||
|
|
||||||
|
kscience {
|
||||||
|
application()
|
||||||
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
afterEvaluate {
|
||||||
val installJS = tasks.getByName("jsBrowserDistribution")
|
val jsBrowserDistribution by tasks.getting
|
||||||
|
|
||||||
js {
|
|
||||||
browser {
|
|
||||||
dceTask {
|
|
||||||
dceOptions {
|
|
||||||
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
webpackTask {
|
|
||||||
mode = org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode.PRODUCTION
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
withJava()
|
withJava()
|
||||||
compilations[MAIN_COMPILATION_NAME]?.apply {
|
compilations[MAIN_COMPILATION_NAME]?.apply {
|
||||||
tasks.getByName<ProcessResources>(processResourcesTaskName) {
|
tasks.getByName<ProcessResources>(processResourcesTaskName) {
|
||||||
dependsOn(installJS)
|
dependsOn(jsBrowserDistribution)
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
from(project.jsDistDirectory)
|
from(jsBrowserDistribution)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
js {
|
||||||
|
useCommonJs()
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
@ -58,14 +53,6 @@ kotlin {
|
|||||||
implementation(project(":ui:bootstrap"))
|
implementation(project(":ui:bootstrap"))
|
||||||
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
implementation("io.ktor:ktor-client-js:$ktorVersion")
|
||||||
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
|
implementation("io.ktor:ktor-client-serialization-js:$ktorVersion")
|
||||||
implementation(npm("text-encoding"))
|
|
||||||
implementation(npm("abort-controller"))
|
|
||||||
implementation(npm("bufferutil"))
|
|
||||||
implementation(npm("utf-8-validate"))
|
|
||||||
implementation(npm("fs"))
|
|
||||||
// implementation(npm("jquery"))
|
|
||||||
// implementation(npm("popper.js"))
|
|
||||||
// implementation(npm("react-is"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import hep.dataforge.context.Context
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.names.isEmpty
|
import hep.dataforge.names.isEmpty
|
||||||
|
import hep.dataforge.names.length
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.bootstrap.card
|
import hep.dataforge.vision.bootstrap.card
|
||||||
import hep.dataforge.vision.react.component
|
import hep.dataforge.vision.react.component
|
||||||
|
@ -7,11 +7,11 @@ import hep.dataforge.vision.solid.SolidManager
|
|||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.features.json.JsonFeature
|
import io.ktor.client.features.json.JsonFeature
|
||||||
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
||||||
|
import kotlinx.browser.document
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import react.child
|
import react.child
|
||||||
import react.dom.div
|
import react.dom.div
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import kotlin.browser.document
|
|
||||||
|
|
||||||
private class MMDemoApp : Application {
|
private class MMDemoApp : Application {
|
||||||
|
|
||||||
@ -19,7 +19,7 @@ private class MMDemoApp : Application {
|
|||||||
|
|
||||||
private val connection = HttpClient {
|
private val connection = HttpClient {
|
||||||
install(JsonFeature) {
|
install(JsonFeature) {
|
||||||
serializer = KotlinxSerializer(Json(context = SolidManager.serialModule))
|
serializer = KotlinxSerializer(Json { serializersModule = SolidManager.serialModule })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,8 +34,8 @@ private class MMDemoApp : Application {
|
|||||||
div("container-fluid h-100") {
|
div("container-fluid h-100") {
|
||||||
child(MMApp) {
|
child(MMApp) {
|
||||||
attrs {
|
attrs {
|
||||||
model = this@MMDemoApp.model
|
this.model = this@MMDemoApp.model
|
||||||
connection = this@MMDemoApp.connection
|
this.connection = this@MMDemoApp.connection
|
||||||
this.context = context
|
this.context = context
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<title>Three js demo for particle physics</title>
|
<title>Three js demo for particle physics</title>
|
||||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||||
<link rel="stylesheet" href="css/main.css">
|
<link rel="stylesheet" href="css/main.css">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="muon-monitor.js"></script>
|
||||||
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
|
<script type="text/javascript" src ="js/jquery-3.4.1.min.js"></script>
|
||||||
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
|
<script type="text/javascript" src ="js/bootstrap.bundle.min.js"></script>
|
||||||
</head>
|
</head>
|
||||||
|
@ -10,6 +10,7 @@ import io.ktor.application.log
|
|||||||
import io.ktor.features.CallLogging
|
import io.ktor.features.CallLogging
|
||||||
import io.ktor.features.ContentNegotiation
|
import io.ktor.features.ContentNegotiation
|
||||||
import io.ktor.features.DefaultHeaders
|
import io.ktor.features.DefaultHeaders
|
||||||
|
import io.ktor.http.ContentType
|
||||||
import io.ktor.http.content.resources
|
import io.ktor.http.content.resources
|
||||||
import io.ktor.http.content.static
|
import io.ktor.http.content.static
|
||||||
import io.ktor.response.respond
|
import io.ktor.response.respond
|
||||||
@ -19,6 +20,7 @@ import io.ktor.serialization.json
|
|||||||
import io.ktor.server.cio.CIO
|
import io.ktor.server.cio.CIO
|
||||||
import io.ktor.server.engine.embeddedServer
|
import io.ktor.server.engine.embeddedServer
|
||||||
import io.ktor.util.KtorExperimentalAPI
|
import io.ktor.util.KtorExperimentalAPI
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
import org.apache.commons.math3.random.JDKRandomGenerator
|
import org.apache.commons.math3.random.JDKRandomGenerator
|
||||||
import ru.mipt.npm.muon.monitor.Model
|
import ru.mipt.npm.muon.monitor.Model
|
||||||
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
||||||
@ -38,7 +40,7 @@ fun Application.module() {
|
|||||||
install(DefaultHeaders)
|
install(DefaultHeaders)
|
||||||
install(CallLogging)
|
install(CallLogging)
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json(module = SolidManager.serialModule)
|
json(Json { serializersModule = SolidManager.serialModule }, ContentType.Application.Json)
|
||||||
}
|
}
|
||||||
install(Routing) {
|
install(Routing) {
|
||||||
get("/event") {
|
get("/event") {
|
||||||
|
@ -1,20 +1,23 @@
|
|||||||
import scientifik.DependencyConfiguration
|
import ru.mipt.npm.gradle.*
|
||||||
import scientifik.FXModule
|
|
||||||
import scientifik.useFx
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
id("application")
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
val fxVersion: String by rootProject.extra
|
kscience {
|
||||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
val fxVersion: String by rootProject.extra
|
||||||
|
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||||
|
application()
|
||||||
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
|
afterEvaluate {
|
||||||
withJava()
|
withJava()
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
|
@ -8,6 +8,7 @@ import hep.dataforge.vision.Colors
|
|||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||||
|
import hep.dataforge.vision.visible
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.*
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
<title>Three js demo for particle physics</title>
|
<title>Three js demo for particle physics</title>
|
||||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||||
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous">
|
||||||
<script type="text/javascript" src="main.bundle.js"></script>
|
<script type="text/javascript" src="spatial-showcase.js"></script>
|
||||||
</head>
|
</head>
|
||||||
<body class="application">
|
<body class="application">
|
||||||
<div class="container">
|
<div class="container">
|
||||||
|
9
gradle.properties
Normal file
9
gradle.properties
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
kotlin.code.style=official
|
||||||
|
kotlin.parallel.tasks.in.project=true
|
||||||
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
|
kotlin.native.enableDependencyPropagation=false
|
||||||
|
kotlin.mpp.stability.nowarn=true
|
||||||
|
|
||||||
|
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
|
||||||
|
org.gradle.parallel=true
|
||||||
|
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -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-6.6-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -7,12 +7,12 @@ repositories{
|
|||||||
maven("https://kotlin.bintray.com/kotlinx")
|
maven("https://kotlin.bintray.com/kotlinx")
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
maven("https://dl.bintray.com/mipt-npm/dataforge")
|
maven("https://dl.bintray.com/mipt-npm/dataforge")
|
||||||
maven("https://dl.bintray.com/mipt-npm/scientifik")
|
maven("https://dl.bintray.com/mipt-npm/kscience")
|
||||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
js {
|
js(IR) {
|
||||||
browser {}
|
browser {}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,32 +1,27 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
val kotlinVersion = "1.3.72"
|
val kotlinVersion = "1.4.20-M1"
|
||||||
val toolsVersion = "0.5.2"
|
val toolsVersion = "0.6.3-dev-1.4.20-M1"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
jcenter()
|
jcenter()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
maven("https://kotlin.bintray.com/kotlinx")
|
|
||||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||||
|
maven("https://dl.bintray.com/kotlin/kotlinx")
|
||||||
maven("https://dl.bintray.com/mipt-npm/dataforge")
|
maven("https://dl.bintray.com/mipt-npm/dataforge")
|
||||||
maven("https://dl.bintray.com/mipt-npm/scientifik")
|
maven("https://dl.bintray.com/mipt-npm/kscience")
|
||||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
|
id("ru.mipt.npm.project") version toolsVersion
|
||||||
|
id("ru.mipt.npm.mpp") version toolsVersion
|
||||||
|
id("ru.mipt.npm.jvm") version toolsVersion
|
||||||
|
id("ru.mipt.npm.js") version toolsVersion
|
||||||
|
id("ru.mipt.npm.publish") version toolsVersion
|
||||||
kotlin("jvm") version kotlinVersion
|
kotlin("jvm") version kotlinVersion
|
||||||
id("scientifik.mpp") version toolsVersion
|
kotlin("js") version kotlinVersion
|
||||||
id("scientifik.jvm") version toolsVersion
|
kotlin("multiplatform") version kotlinVersion
|
||||||
id("scientifik.js") version toolsVersion
|
|
||||||
id("scientifik.publish") version toolsVersion
|
|
||||||
}
|
|
||||||
|
|
||||||
resolutionStrategy {
|
|
||||||
eachPlugin {
|
|
||||||
when (requested.id.id) {
|
|
||||||
"scientifik.mpp", "scientifik.publish", "scientifik.jvm", "scientifik.js" -> useModule("scientifik:gradle-tools:${toolsVersion}")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -34,11 +29,12 @@ pluginManagement {
|
|||||||
|
|
||||||
rootProject.name = "visionforge"
|
rootProject.name = "visionforge"
|
||||||
|
|
||||||
|
|
||||||
include(
|
include(
|
||||||
":ui",
|
// ":ui",
|
||||||
":ui:react",
|
":ui:react",
|
||||||
":ui:ring",
|
":ui:ring",
|
||||||
":ui:material",
|
// ":ui:material",
|
||||||
":ui:bootstrap",
|
":ui:bootstrap",
|
||||||
":visionforge-core",
|
":visionforge-core",
|
||||||
":visionforge-solid",
|
":visionforge-solid",
|
||||||
|
@ -1,15 +1,9 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.js")
|
id("ru.mipt.npm.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
kotlin {
|
|
||||||
target {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":ui:react"))
|
api(project(":ui:react"))
|
||||||
}
|
}
|
@ -2,6 +2,7 @@ package hep.dataforge.vision.bootstrap
|
|||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
|
import hep.dataforge.names.length
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.react.ObjectTree
|
import hep.dataforge.vision.react.ObjectTree
|
||||||
import kotlinx.html.*
|
import kotlinx.html.*
|
||||||
@ -17,7 +18,7 @@ import styled.StyledDOMBuilder
|
|||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
|
|
||||||
inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
public inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
||||||
div("card w-100") {
|
div("card w-100") {
|
||||||
div("card-body") {
|
div("card-body") {
|
||||||
h3(classes = "card-title") { +title }
|
h3(classes = "card-title") { +title }
|
||||||
@ -26,7 +27,7 @@ inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagCo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun RBuilder.card(title: String, classes: String? = null, crossinline block: RBuilder.() -> Unit) {
|
public inline fun RBuilder.card(title: String, classes: String? = null, crossinline block: RBuilder.() -> Unit) {
|
||||||
div("card w-100 $classes") {
|
div("card w-100 $classes") {
|
||||||
div("card-body") {
|
div("card-body") {
|
||||||
h3(classes = "card-title") {
|
h3(classes = "card-title") {
|
||||||
@ -37,7 +38,7 @@ inline fun RBuilder.card(title: String, classes: String? = null, crossinline blo
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TagConsumer<HTMLElement>.accordion(id: String, elements: List<Pair<String, DIV.() -> Unit>>) {
|
public fun TagConsumer<HTMLElement>.accordion(id: String, elements: List<Pair<String, DIV.() -> Unit>>) {
|
||||||
div("container-fluid") {
|
div("container-fluid") {
|
||||||
div("accordion") {
|
div("accordion") {
|
||||||
this.id = id
|
this.id = id
|
||||||
@ -69,18 +70,18 @@ fun TagConsumer<HTMLElement>.accordion(id: String, elements: List<Pair<String, D
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias AccordionBuilder = MutableList<Pair<String, DIV.() -> Unit>>
|
public typealias AccordionBuilder = MutableList<Pair<String, DIV.() -> Unit>>
|
||||||
|
|
||||||
fun AccordionBuilder.entry(title: String, builder: DIV.() -> Unit) {
|
public fun AccordionBuilder.entry(title: String, builder: DIV.() -> Unit) {
|
||||||
add(title to builder)
|
add(title to builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun TagConsumer<HTMLElement>.accordion(id: String, builder: AccordionBuilder.() -> Unit) {
|
public fun TagConsumer<HTMLElement>.accordion(id: String, builder: AccordionBuilder.() -> Unit) {
|
||||||
val list = ArrayList<Pair<String, DIV.() -> Unit>>().apply(builder)
|
val list = ArrayList<Pair<String, DIV.() -> Unit>>().apply(builder)
|
||||||
accordion(id, list)
|
accordion(id, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RBuilder.accordion(id: String, elements: List<Pair<String, RDOMBuilder<DIV>.() -> Unit>>): ReactElement {
|
public fun RBuilder.accordion(id: String, elements: List<Pair<String, RDOMBuilder<DIV>.() -> Unit>>): ReactElement {
|
||||||
return div("container-fluid") {
|
return div("container-fluid") {
|
||||||
div("accordion") {
|
div("accordion") {
|
||||||
attrs {
|
attrs {
|
||||||
@ -120,7 +121,7 @@ fun RBuilder.accordion(id: String, elements: List<Pair<String, RDOMBuilder<DIV>.
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) {
|
public fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) {
|
||||||
div("container-fluid p-0") {
|
div("container-fluid p-0") {
|
||||||
nav {
|
nav {
|
||||||
attrs {
|
attrs {
|
||||||
@ -160,20 +161,18 @@ fun RBuilder.namecrumbs(name: Name?, rootTitle: String, link: (Name) -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
typealias RAccordionBuilder = MutableList<Pair<String, RDOMBuilder<DIV>.() -> Unit>>
|
public typealias RAccordionBuilder = MutableList<Pair<String, RDOMBuilder<DIV>.() -> Unit>>
|
||||||
|
|
||||||
fun RAccordionBuilder.entry(title: String, builder: RDOMBuilder<DIV>.() -> Unit) {
|
public fun RAccordionBuilder.entry(title: String, builder: RDOMBuilder<DIV>.() -> Unit) {
|
||||||
add(title to builder)
|
add(title to builder)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun RBuilder.accordion(id: String, builder: RAccordionBuilder.() -> Unit): ReactElement {
|
public fun RBuilder.accordion(id: String, builder: RAccordionBuilder.() -> Unit): ReactElement {
|
||||||
val list = ArrayList<Pair<String, RDOMBuilder<DIV>.() -> Unit>>().apply(builder)
|
val list = ArrayList<Pair<String, RDOMBuilder<DIV>.() -> Unit>>().apply(builder)
|
||||||
return accordion(id, list)
|
return accordion(id, list)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun joinStyles(vararg styles: String?) = styles.joinToString(separator = " ") { it ?: "" }
|
public enum class ContainerSize(public val suffix: String) {
|
||||||
|
|
||||||
enum class ContainerSize(val suffix: String) {
|
|
||||||
DEFAULT(""),
|
DEFAULT(""),
|
||||||
SM("-sm"),
|
SM("-sm"),
|
||||||
MD("-md"),
|
MD("-md"),
|
||||||
@ -182,7 +181,7 @@ enum class ContainerSize(val suffix: String) {
|
|||||||
FLUID("-fluid")
|
FLUID("-fluid")
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun RBuilder.container(
|
public inline fun RBuilder.container(
|
||||||
size: ContainerSize = ContainerSize.FLUID,
|
size: ContainerSize = ContainerSize.FLUID,
|
||||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||||
): ReactElement = styledDiv{
|
): ReactElement = styledDiv{
|
||||||
@ -193,7 +192,7 @@ inline fun RBuilder.container(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
enum class GridMaxSize(val suffix: String) {
|
public enum class GridMaxSize(public val suffix: String) {
|
||||||
NONE(""),
|
NONE(""),
|
||||||
SM("-sm"),
|
SM("-sm"),
|
||||||
MD("-md"),
|
MD("-md"),
|
||||||
@ -201,7 +200,7 @@ enum class GridMaxSize(val suffix: String) {
|
|||||||
XL("-xl")
|
XL("-xl")
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun RBuilder.gridColumn(
|
public inline fun RBuilder.gridColumn(
|
||||||
weight: Int? = null,
|
weight: Int? = null,
|
||||||
maxSize: GridMaxSize = GridMaxSize.NONE,
|
maxSize: GridMaxSize = GridMaxSize.NONE,
|
||||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||||
@ -213,7 +212,7 @@ inline fun RBuilder.gridColumn(
|
|||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun RBuilder.gridRow(
|
public inline fun RBuilder.gridRow(
|
||||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||||
): ReactElement = styledDiv{
|
): ReactElement = styledDiv{
|
||||||
css{
|
css{
|
||||||
@ -222,10 +221,10 @@ inline fun RBuilder.gridRow(
|
|||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Element.renderObjectTree(
|
public fun Element.renderObjectTree(
|
||||||
vision: Vision,
|
vision: Vision,
|
||||||
clickCallback: (Name) -> Unit = {}
|
clickCallback: (Name) -> Unit = {}
|
||||||
) = render(this) {
|
): Unit = render(this) {
|
||||||
card("Object tree") {
|
card("Object tree") {
|
||||||
child(ObjectTree) {
|
child(ObjectTree) {
|
||||||
attrs {
|
attrs {
|
||||||
|
@ -1,20 +1,14 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.js")
|
id("ru.mipt.npm.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
kotlin {
|
|
||||||
target {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":ui:react"))
|
api(project(":ui:react"))
|
||||||
|
|
||||||
api("subroh0508.net.kotlinmaterialui:core:0.4.0")
|
api("subroh0508.net.kotlinmaterialui:core:0.4.5")
|
||||||
api("subroh0508.net.kotlinmaterialui:lab:0.4.0")
|
api("subroh0508.net.kotlinmaterialui:lab:0.4.5")
|
||||||
api(npm("@material-ui/core","4.9.14"))
|
api(npm("@material-ui/core","4.9.14"))
|
||||||
api(npm("@material-ui/lab","4.0.0-alpha.51"))
|
api(npm("@material-ui/lab","4.0.0-alpha.51"))
|
||||||
//api(npm("@material-ui/icons","4.9.1"))
|
//api(npm("@material-ui/icons","4.9.1"))
|
||||||
|
@ -1,11 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.js")
|
id("ru.mipt.npm.js")
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
target {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val reactVersion by extra("16.13.1")
|
val reactVersion by extra("16.13.1")
|
||||||
@ -14,7 +8,7 @@ dependencies{
|
|||||||
api(project(":visionforge-core"))
|
api(project(":visionforge-core"))
|
||||||
|
|
||||||
//api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72")
|
//api("org.jetbrains:kotlin-react:16.13.1-pre.104-kotlin-1.3.72")
|
||||||
api("org.jetbrains:kotlin-react-dom:$reactVersion-pre.104-kotlin-1.3.72")
|
api("org.jetbrains:kotlin-react-dom:$reactVersion-pre.123-kotlin-1.4.10")
|
||||||
|
|
||||||
api(npm("react", reactVersion))
|
api(npm("react", reactVersion))
|
||||||
api(npm("react-dom", reactVersion))
|
api(npm("react-dom", reactVersion))
|
||||||
|
@ -4,6 +4,7 @@ import hep.dataforge.meta.*
|
|||||||
import hep.dataforge.meta.descriptors.*
|
import hep.dataforge.meta.descriptors.*
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
|
import hep.dataforge.names.lastOrNull
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
@ -47,7 +48,7 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
|||||||
val defaultItem = props.default?.get(props.name)
|
val defaultItem = props.default?.get(props.name)
|
||||||
var actualItem: MetaItem<Meta>? by state { item ?: defaultItem ?: descriptorItem?.defaultItem() }
|
var actualItem: MetaItem<Meta>? by state { item ?: defaultItem ?: descriptorItem?.defaultItem() }
|
||||||
|
|
||||||
val token = props.name.last()?.toString() ?: "Properties"
|
val token = props.name.lastOrNull()?.toString() ?: "Properties"
|
||||||
|
|
||||||
fun update() {
|
fun update() {
|
||||||
item = props.root[props.name]
|
item = props.root[props.name]
|
||||||
|
@ -9,6 +9,7 @@ import hep.dataforge.meta.descriptors.get
|
|||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
|
import hep.dataforge.names.lastOrNull
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
@ -43,7 +44,7 @@ private fun RFBuilder.metaViewerItem(props: MetaViewerProps) {
|
|||||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
||||||
val actualItem = item ?: descriptorItem?.defaultItem()
|
val actualItem = item ?: descriptorItem?.defaultItem()
|
||||||
|
|
||||||
val token = props.name.last()?.toString() ?: "Meta"
|
val token = props.name.lastOrNull()?.toString() ?: "Meta"
|
||||||
|
|
||||||
val expanderClick: (Event) -> Unit = {
|
val expanderClick: (Event) -> Unit = {
|
||||||
expanded = !expanded
|
expanded = !expanded
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.vision.react
|
package hep.dataforge.vision.react
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.lastOrNull
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.startsWith
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
@ -42,7 +43,7 @@ private fun RFBuilder.objectTree(props: ObjectTreeProps): Unit {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val token = props.name.last()?.toString() ?: "World"
|
val token = props.name.lastOrNull()?.toString() ?: "World"
|
||||||
val obj = props.obj
|
val obj = props.obj
|
||||||
|
|
||||||
//display as node if any child is visible
|
//display as node if any child is visible
|
||||||
|
@ -1,22 +1,13 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.js")
|
id("ru.mipt.npm.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
kotlin {
|
|
||||||
target {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":ui:react"))
|
api(project(":ui:react"))
|
||||||
|
|
||||||
implementation(npm("@jetbrains/logos", "1.1.6"))
|
implementation(npm("@jetbrains/logos", "1.1.6"))
|
||||||
implementation(npm("@jetbrains/ring-ui", "3.0.13"))
|
implementation(npm("@jetbrains/ring-ui", "3.0.13"))
|
||||||
|
|
||||||
|
|
||||||
implementation(npm("svg-inline-loader", "0.8.0"))
|
implementation(npm("svg-inline-loader", "0.8.0"))
|
||||||
}
|
}
|
@ -1,13 +1,10 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
js {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
@ -30,15 +27,15 @@ kotlin {
|
|||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
api("hep.dataforge:dataforge-output-html:$dataforgeVersion")
|
||||||
api("org.jetbrains.kotlinx:kotlinx-html:0.6.12")
|
api("org.jetbrains.kotlinx:kotlinx-html:0.7.2")
|
||||||
|
|
||||||
//api("org.jetbrains:kotlin-extensions:1.0.1-pre.105-kotlin-1.3.72")
|
//api("org.jetbrains:kotlin-extensions:1.0.1-pre.105-kotlin-1.3.72")
|
||||||
//api("org.jetbrains:kotlin-css-js:1.0.0-pre.105-kotlin-1.3.72")
|
//api("org.jetbrains:kotlin-css-js:1.0.0-pre.105-kotlin-1.3.72")
|
||||||
api("org.jetbrains:kotlin-styled:1.0.0-pre.104-kotlin-1.3.72")
|
api("org.jetbrains:kotlin-styled:5.2.0-pre.123-kotlin-1.4.10")
|
||||||
|
|
||||||
api(npm("core-js", "2.6.5"))
|
api(npm("core-js", "2.6.5"))
|
||||||
api(npm("inline-style-prefixer", "5.1.0"))
|
api(npm("inline-style-prefixer", "5.1.0"))
|
||||||
api(npm("styled-components", "4.3.2"))
|
api(npm("styled-components", "5.2.0"))
|
||||||
//api(project(":ringui-wrapper"))
|
//api(project(":ringui-wrapper"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.*
|
|||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
class ConfigProperty(val config: Config, val name: Name) : Property<MetaItem<*>?> {
|
internal class ConfigProperty(val config: Config, val name: Name) : Property<MetaItem<*>?> {
|
||||||
override var value: MetaItem<*>?
|
override var value: MetaItem<*>?
|
||||||
get() = config[name]
|
get() = config[name]
|
||||||
set(value) {
|
set(value) {
|
||||||
|
@ -87,13 +87,13 @@ abstract class AbstractVision : Vision {
|
|||||||
/**
|
/**
|
||||||
* Reset all properties to their default values
|
* Reset all properties to their default values
|
||||||
*/
|
*/
|
||||||
fun resetProperties() {
|
public fun resetProperties() {
|
||||||
properties?.removeListener(this)
|
properties?.removeListener(this)
|
||||||
properties = null
|
properties = null
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
val descriptor = NodeDescriptor {
|
public val descriptor: NodeDescriptor = NodeDescriptor {
|
||||||
value(STYLE_KEY) {
|
value(STYLE_KEY) {
|
||||||
type(ValueType.STRING)
|
type(ValueType.STRING)
|
||||||
multiple = true
|
multiple = true
|
||||||
|
@ -1,9 +1,6 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.names.isEmpty
|
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
|
|
||||||
@ -105,7 +102,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
|||||||
return when {
|
return when {
|
||||||
name.isEmpty() -> error("Should be unreachable")
|
name.isEmpty() -> error("Should be unreachable")
|
||||||
name.length == 1 -> {
|
name.length == 1 -> {
|
||||||
val token = name.first()!!
|
val token = name.tokens.first()
|
||||||
when (val current = children[token]) {
|
when (val current = children[token]) {
|
||||||
null -> createGroup().also { child ->
|
null -> createGroup().also { child ->
|
||||||
attach(child)
|
attach(child)
|
||||||
@ -115,7 +112,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
|||||||
else -> error("Can't create group with name $name because it exists and not a group")
|
else -> error("Can't create group with name $name because it exists and not a group")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> createGroups(name.first()!!.asName()).createGroups(name.cutFirst())
|
else -> createGroups(name.tokens.first().asName()).createGroups(name.cutFirst())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -131,7 +128,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
name.length == 1 -> {
|
name.length == 1 -> {
|
||||||
val token = name.first()!!
|
val token = name.tokens.first()
|
||||||
if (child == null) {
|
if (child == null) {
|
||||||
removeChild(token)
|
removeChild(token)
|
||||||
} else {
|
} else {
|
||||||
@ -142,7 +139,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
|||||||
else -> {
|
else -> {
|
||||||
//TODO add safety check
|
//TODO add safety check
|
||||||
val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast())
|
val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast())
|
||||||
parent[name.last()!!.asName()] = child
|
parent[name.tokens.last().asName()] = child
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
childrenChanged(name, child)
|
childrenChanged(name, child)
|
||||||
|
@ -8,20 +8,23 @@ import hep.dataforge.names.asName
|
|||||||
import kotlinx.serialization.*
|
import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.encoding.Decoder
|
||||||
|
import kotlinx.serialization.encoding.Encoder
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for styles
|
* A container for styles
|
||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta> = LinkedHashMap()) {
|
public class StyleSheet private constructor(private val styleMap: MutableMap<String, Meta> = LinkedHashMap()) {
|
||||||
@Transient
|
@Transient
|
||||||
internal var owner: Vision? = null
|
internal var owner: Vision? = null
|
||||||
|
|
||||||
constructor(owner: Vision) : this() {
|
public constructor(owner: Vision) : this() {
|
||||||
this.owner = owner
|
this.owner = owner
|
||||||
}
|
}
|
||||||
|
|
||||||
val items: Map<String, Meta> get() = styleMap
|
public val items: Map<String, Meta> get() = styleMap
|
||||||
|
|
||||||
|
|
||||||
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
|
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
|
||||||
@ -38,14 +41,14 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(key: String): Meta? {
|
public operator fun get(key: String): Meta? {
|
||||||
return styleMap[key] ?: owner?.parent?.styleSheet?.get(key)
|
return styleMap[key] ?: owner?.parent?.styleSheet?.get(key)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a style without notifying owner
|
* Define a style without notifying owner
|
||||||
*/
|
*/
|
||||||
fun define(key: String, style: Meta?) {
|
public fun define(key: String, style: Meta?) {
|
||||||
if (style == null) {
|
if (style == null) {
|
||||||
styleMap.remove(key)
|
styleMap.remove(key)
|
||||||
} else {
|
} else {
|
||||||
@ -56,7 +59,7 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
|
|||||||
/**
|
/**
|
||||||
* Set or clear the style
|
* Set or clear the style
|
||||||
*/
|
*/
|
||||||
operator fun set(key: String, style: Meta?) {
|
public operator fun set(key: String, style: Meta?) {
|
||||||
val oldStyle = styleMap[key]
|
val oldStyle = styleMap[key]
|
||||||
define(key, style)
|
define(key, style)
|
||||||
owner?.styleChanged(key, oldStyle, style)
|
owner?.styleChanged(key, oldStyle, style)
|
||||||
@ -65,13 +68,14 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
|
|||||||
/**
|
/**
|
||||||
* Create and set a style
|
* Create and set a style
|
||||||
*/
|
*/
|
||||||
operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
public operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
||||||
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
||||||
set(key, newStyle.seal())
|
set(key, newStyle.seal())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ExperimentalSerializationApi
|
||||||
@Serializer(StyleSheet::class)
|
@Serializer(StyleSheet::class)
|
||||||
companion object : KSerializer<StyleSheet> {
|
public companion object : KSerializer<StyleSheet> {
|
||||||
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
||||||
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
override val descriptor: SerialDescriptor get() = mapSerializer.descriptor
|
||||||
|
|
||||||
@ -91,14 +95,14 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
|
|||||||
/**
|
/**
|
||||||
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
|
||||||
*/
|
*/
|
||||||
fun Vision.useStyle(name: String) {
|
public fun Vision.useStyle(name: String) {
|
||||||
styles = properties[Vision.STYLE_KEY].stringList + name
|
styles = (properties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + name
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Resolve an item in all style layers
|
* Resolve an item in all style layers
|
||||||
*/
|
*/
|
||||||
fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
||||||
return styles.asSequence().map {
|
return styles.asSequence().map {
|
||||||
resolveStyle(it)
|
resolveStyle(it)
|
||||||
}.map {
|
}.map {
|
||||||
@ -109,4 +113,4 @@ fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
|||||||
/**
|
/**
|
||||||
* Collect all styles for this object in a single laminate
|
* Collect all styles for this object in a single laminate
|
||||||
*/
|
*/
|
||||||
val Vision.allStyles: Laminate get() = Laminate(styles.mapNotNull(::resolveStyle))
|
public val Vision.allStyles: Laminate get() = Laminate(styles.mapNotNull(::resolveStyle))
|
@ -5,7 +5,9 @@ import hep.dataforge.names.Name
|
|||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vision.Vision.Companion.TYPE
|
import hep.dataforge.vision.Vision.Companion.TYPE
|
||||||
|
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||||
import kotlinx.serialization.PolymorphicSerializer
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
|
|
||||||
@ -13,28 +15,28 @@ import kotlinx.serialization.Transient
|
|||||||
* A root type for display hierarchy
|
* A root type for display hierarchy
|
||||||
*/
|
*/
|
||||||
@Type(TYPE)
|
@Type(TYPE)
|
||||||
interface Vision : Configurable {
|
public interface Vision : Configurable {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* 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.
|
||||||
*/
|
*/
|
||||||
@Transient
|
@Transient
|
||||||
var parent: VisionGroup?
|
public var parent: VisionGroup?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Nullable version of [config] used to check if this [Vision] has custom properties
|
* Nullable version of [config] used to check if this [Vision] has custom properties
|
||||||
*/
|
*/
|
||||||
val properties: Config?
|
public val properties: Config?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* All properties including styles and prototypes if present, including inherited ones
|
* All properties including styles and prototypes if present, including inherited ones
|
||||||
*/
|
*/
|
||||||
fun getAllProperties(): Laminate
|
public fun getAllProperties(): Laminate
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get property (including styles). [inherit] toggles parent node property lookup
|
* Get property (including styles). [inherit] toggles parent node property lookup
|
||||||
*/
|
*/
|
||||||
fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
|
public fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ger a property including inherited values
|
* Ger a property including inherited values
|
||||||
@ -44,46 +46,55 @@ interface Vision : Configurable {
|
|||||||
/**
|
/**
|
||||||
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
|
||||||
*/
|
*/
|
||||||
fun propertyChanged(name: Name): Unit
|
public fun propertyChanged(name: Name): Unit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add listener triggering on property change
|
* Add listener triggering on property change
|
||||||
*/
|
*/
|
||||||
fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit
|
public fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove change listeners with given owner.
|
* Remove change listeners with given owner.
|
||||||
*/
|
*/
|
||||||
fun removeChangeListener(owner: Any?)
|
public fun removeChangeListener(owner: Any?)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* List of names of styles applied to this object. Order matters. Not inherited.
|
* List of names of styles applied to this object. Order matters. Not inherited.
|
||||||
*/
|
*/
|
||||||
var styles: List<String>
|
public var styles: List<String>
|
||||||
get() = properties[STYLE_KEY].stringList
|
get() = properties[STYLE_KEY]?.stringList?: emptyList()
|
||||||
set(value) {
|
set(value) {
|
||||||
config[STYLE_KEY] = value
|
config[STYLE_KEY] = value
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val TYPE = "vision"
|
public const val TYPE: String = "vision"
|
||||||
val STYLE_KEY = "@style".asName()
|
public val STYLE_KEY: Name = "@style".asName()
|
||||||
|
|
||||||
private val VISION_SERIALIZER = PolymorphicSerializer(Vision::class)
|
private val VISION_SERIALIZER = PolymorphicSerializer(Vision::class)
|
||||||
|
|
||||||
fun serializer() = VISION_SERIALIZER
|
public fun serializer(): PolymorphicSerializer<Vision> = VISION_SERIALIZER
|
||||||
|
|
||||||
|
public val VISIBLE_KEY: Name = "visible".asName()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get [Vision] property using key as a String
|
* Get [Vision] property using key as a String
|
||||||
*/
|
*/
|
||||||
fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
public fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
||||||
getProperty(key.toName(), inherit)
|
getProperty(key.toName(), inherit)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision].
|
* Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision].
|
||||||
*/
|
*/
|
||||||
tailrec fun Vision.resolveStyle(name: String): Meta? =
|
public tailrec fun Vision.resolveStyle(name: String): Meta? =
|
||||||
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name)
|
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name)
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Control visibility of the element
|
||||||
|
*/
|
||||||
|
public var Vision.visible: Boolean?
|
||||||
|
get() = getItem(VISIBLE_KEY).boolean
|
||||||
|
set(value) = setItem(VISIBLE_KEY, value?.asValue())
|
||||||
|
@ -3,14 +3,18 @@ package hep.dataforge.vision
|
|||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.provider.Provider
|
import hep.dataforge.provider.Provider
|
||||||
|
|
||||||
|
public interface VisionContainer<out V: Vision>{
|
||||||
|
public operator fun get(name: Name): V?
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents a group of [Vision] instances
|
* Represents a group of [Vision] instances
|
||||||
*/
|
*/
|
||||||
interface VisionGroup : Provider, Vision {
|
public interface VisionGroup : Provider, Vision, VisionContainer<Vision> {
|
||||||
/**
|
/**
|
||||||
* A map of top level named children
|
* A map of top level named children
|
||||||
*/
|
*/
|
||||||
val children: Map<NameToken, Vision>
|
public val children: Map<NameToken, Vision>
|
||||||
|
|
||||||
override val defaultTarget: String get() = Vision.TYPE
|
override val defaultTarget: String get() = Vision.TYPE
|
||||||
|
|
||||||
@ -18,17 +22,17 @@ interface VisionGroup : Provider, Vision {
|
|||||||
* A stylesheet for this group and its descendants. Stylesheet is not applied directly,
|
* A stylesheet for this group and its descendants. Stylesheet is not applied directly,
|
||||||
* but instead is just a repository for named configurations.
|
* but instead is just a repository for named configurations.
|
||||||
*/
|
*/
|
||||||
val styleSheet: StyleSheet?
|
public val styleSheet: StyleSheet?
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A map of direct children for specific target
|
* A map of direct children for specific target
|
||||||
* (currently "visual" or "style")
|
* (currently "visual" or "style")
|
||||||
*/
|
*/
|
||||||
override fun provideTop(target: String): Map<Name, Any> =
|
override fun content(target: String): Map<Name, Any> =
|
||||||
when (target) {
|
when (target) {
|
||||||
Vision.TYPE -> children.flatMap { (key, value) ->
|
Vision.TYPE -> children.flatMap { (key, value) ->
|
||||||
val res: Map<Name, Any> = if (value is VisionGroup) {
|
val res: Map<Name, Any> = if (value is VisionGroup) {
|
||||||
value.provideTop(target).mapKeys { key + it.key }
|
value.content(target).mapKeys { key + it.key }
|
||||||
} else {
|
} else {
|
||||||
mapOf(key.asName() to value)
|
mapOf(key.asName() to value)
|
||||||
}
|
}
|
||||||
@ -38,18 +42,18 @@ interface VisionGroup : Provider, Vision {
|
|||||||
else -> emptyMap()
|
else -> emptyMap()
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun get(name: Name): Vision? {
|
public override operator fun get(name: Name): Vision? {
|
||||||
return when {
|
return when {
|
||||||
name.isEmpty() -> this
|
name.isEmpty() -> this
|
||||||
name.length == 1 -> children[name.first()!!]
|
name.length == 1 -> children[name.tokens.first()]
|
||||||
else -> (children[name.first()!!] as? VisionGroup)?.get(name.cutFirst())
|
else -> (children[name.tokens.first()] as? VisionGroup)?.get(name.cutFirst())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A fix for serialization bug that writes all proper parents inside the tree after deserialization
|
* A fix for serialization bug that writes all proper parents inside the tree after deserialization
|
||||||
*/
|
*/
|
||||||
fun attachChildren() {
|
public fun attachChildren() {
|
||||||
styleSheet?.owner = this
|
styleSheet?.owner = this
|
||||||
children.values.forEach {
|
children.values.forEach {
|
||||||
it.parent = this
|
it.parent = this
|
||||||
@ -57,41 +61,45 @@ interface VisionGroup : Provider, Vision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val STYLE_TARGET = "style"
|
public const val STYLE_TARGET: String = "style"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over children of this group
|
* Iterate over children of this group
|
||||||
*/
|
*/
|
||||||
operator fun VisionGroup.iterator(): Iterator<Vision> = children.values.iterator()
|
public operator fun VisionGroup.iterator(): Iterator<Vision> = children.values.iterator()
|
||||||
|
|
||||||
val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty()
|
public val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty()
|
||||||
|
|
||||||
|
public interface VisionContainerBuilder<in V: Vision>{
|
||||||
|
public operator fun set(name: Name, child: V?)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Mutable version of [VisionGroup]
|
* Mutable version of [VisionGroup]
|
||||||
*/
|
*/
|
||||||
interface MutableVisionGroup : VisionGroup {
|
public interface MutableVisionGroup : VisionGroup, VisionContainerBuilder<Vision> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add listener for children structure change.
|
* Add listener for children structure change.
|
||||||
* @param owner the handler to properly remove listeners
|
* @param owner the handler to properly remove listeners
|
||||||
* @param action First argument of the action is the name of changed child. Second argument is the new value of the object.
|
* @param action First argument of the action is the name of changed child. Second argument is the new value of the object.
|
||||||
*/
|
*/
|
||||||
fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit)
|
public fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Remove children change listener
|
* Remove children change listener
|
||||||
*/
|
*/
|
||||||
fun removeChildrenChangeListener(owner: Any?)
|
public fun removeChildrenChangeListener(owner: Any?)
|
||||||
|
|
||||||
operator fun set(name: Name, child: Vision?)
|
// public operator fun set(name: Name, child: Vision?)
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun VisionGroup.get(str: String?): Vision? = get(str?.toName() ?: Name.EMPTY)
|
public operator fun <V: Vision> VisionContainer<V>.get(str: String?): V? = get(str?.toName() ?: Name.EMPTY)
|
||||||
|
|
||||||
operator fun MutableVisionGroup.set(token: NameToken, child: Vision?): Unit = set(token.asName(), child)
|
public operator fun <V: Vision> VisionContainerBuilder<V>.set(token: NameToken, child: V?): Unit = set(token.asName(), child)
|
||||||
operator fun MutableVisionGroup.set(key: String, child: Vision?): Unit = set(key.toName(), child)
|
public operator fun <V: Vision> VisionContainerBuilder<V>.set(key: String, child: V?): Unit = set(key.toName(), child)
|
||||||
|
|
||||||
fun MutableVisionGroup.removeAll() = children.keys.map { it.asName() }.forEach { this[it] = null }
|
public fun MutableVisionGroup.removeAll(): Unit = children.keys.map { it.asName() }.forEach { this[it] = null }
|
@ -3,35 +3,37 @@ package hep.dataforge.vision
|
|||||||
import hep.dataforge.context.*
|
import hep.dataforge.context.*
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.UnstableDefault
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
|
||||||
import kotlinx.serialization.modules.SerialModule
|
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
import kotlinx.serialization.modules.SerializersModule
|
||||||
|
import kotlinx.serialization.modules.polymorphic
|
||||||
|
import kotlinx.serialization.modules.subclass
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
interface VisionForm<T : Vision> {
|
public interface VisionForm<T : Vision> {
|
||||||
val type: KClass<out T>
|
public val type: KClass<out T>
|
||||||
val serializer: KSerializer<T>
|
public val serializer: KSerializer<T>
|
||||||
|
|
||||||
val name get() = serializer.descriptor.serialName.toName()
|
public val name: Name
|
||||||
|
get() = serializer.descriptor.serialName.toName()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Apply a patch to given [Vision]
|
* Apply a patch to given [Vision]
|
||||||
*/
|
*/
|
||||||
fun patch(obj: T, meta: Meta)
|
public fun patch(obj: T, meta: Meta)
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val TYPE = "visionForm"
|
public const val TYPE: String = "visionForm"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
object SimpleGroupForm: VisionForm<SimpleVisionGroup>{
|
public object SimpleGroupForm : VisionForm<SimpleVisionGroup> {
|
||||||
override val type: KClass<out SimpleVisionGroup> = SimpleVisionGroup::class
|
override val type: KClass<out SimpleVisionGroup> = SimpleVisionGroup::class
|
||||||
override val serializer: KSerializer<SimpleVisionGroup> = SimpleVisionGroup.serializer()
|
override val serializer: KSerializer<SimpleVisionGroup> = SimpleVisionGroup.serializer()
|
||||||
|
|
||||||
@ -42,86 +44,93 @@ object SimpleGroupForm: VisionForm<SimpleVisionGroup>{
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <T : Vision> VisionForm<T>.visionToMeta(vision: T, module: SerialModule, descriptor: NodeDescriptor? = null): Meta {
|
public fun <T : Vision> VisionForm<T>.visionToMeta(
|
||||||
val engine = Json(VisionManager.jsonConfiguration, module)
|
vision: T,
|
||||||
val json = engine.toJson<T>(serializer, vision)
|
module: SerializersModule,
|
||||||
|
descriptor: NodeDescriptor? = null,
|
||||||
|
): Meta {
|
||||||
|
val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module }
|
||||||
|
val json = engine.encodeToJsonElement(serializer, vision)
|
||||||
return json.toMetaItem(descriptor).node!!
|
return json.toMetaItem(descriptor).node!!
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun <T : Vision> VisionForm<T>.buildVision(meta: Meta, module: SerialModule, descriptor: NodeDescriptor? = null): T {
|
public fun <T : Vision> VisionForm<T>.buildVision(
|
||||||
val engine = Json(VisionManager.jsonConfiguration, module)
|
meta: Meta,
|
||||||
|
module: SerializersModule,
|
||||||
|
descriptor: NodeDescriptor? = null,
|
||||||
|
): T {
|
||||||
|
val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module }
|
||||||
val json = meta.toJson(descriptor)
|
val json = meta.toJson(descriptor)
|
||||||
return engine.fromJson(serializer, json)
|
return engine.decodeFromJsonElement(serializer, json)
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a list of factories on first call and cache it
|
* Create a list of factories on first call and cache it
|
||||||
*/
|
*/
|
||||||
private val forms by lazy {
|
private val forms by lazy {
|
||||||
context.content<VisionForm<*>>(VisionForm.TYPE).mapKeys { it.value.type }
|
context.gather<VisionForm<*>>(VisionForm.TYPE).mapKeys { it.value.type }
|
||||||
}
|
}
|
||||||
|
|
||||||
val visionSerialModule
|
public val visionSerialModule: SerializersModule
|
||||||
get() = SerializersModule {
|
get() = SerializersModule {
|
||||||
include(defaultSerialModule)
|
include(defaultSerialModule)
|
||||||
context.content<SerialModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
|
context.gather<SerializersModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
|
||||||
include(it)
|
include(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T : Vision> resolveVisionForm(type: KClass<out T>): VisionForm<T>? =
|
public fun <T : Vision> resolveVisionForm(type: KClass<out T>): VisionForm<T> =
|
||||||
forms[type] as VisionForm<T>
|
forms[type] as VisionForm<T>
|
||||||
|
|
||||||
inline fun <reified T : Vision> buildSpecificVision(meta: Meta): T {
|
public inline fun <reified T : Vision> buildSpecificVision(meta: Meta): T {
|
||||||
val factory = resolveVisionForm(T::class) ?: error("Could not resolve a form for ${meta["type"].string}")
|
val factory = resolveVisionForm(T::class) ?: error("Could not resolve a form for ${meta["type"].string}")
|
||||||
return factory.buildVision(meta, visionSerialModule)
|
return factory.buildVision(meta, visionSerialModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildVision(meta: Meta): Vision {
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
|
public fun buildVision(meta: Meta): Vision {
|
||||||
val type = meta["type"].string ?: Vision.serializer().descriptor.serialName
|
val type = meta["type"].string ?: Vision.serializer().descriptor.serialName
|
||||||
val form = forms.values.find { it.name.toString() == type } ?: error("Could not resolve a form for type $type")
|
val form = forms.values.find { it.name.toString() == type } ?: error("Could not resolve a form for type $type")
|
||||||
return form.buildVision(meta, visionSerialModule)
|
return form.buildVision(meta, visionSerialModule)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Vision> writeVisionToMeta(vision: T): Meta {
|
public fun <T : Vision> writeVisionToMeta(vision: T): Meta {
|
||||||
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
|
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
|
||||||
val engine = Json(VisionManager.jsonConfiguration, visionSerialModule)
|
val engine = Json(jsonConfiguration) { serializersModule = visionSerialModule }
|
||||||
val json = engine.toJson(form.serializer,vision)
|
val json = engine.encodeToJsonElement(form.serializer, vision)
|
||||||
return json.toMetaItem().node!!
|
return json.toMetaItem().node!!
|
||||||
}
|
}
|
||||||
|
|
||||||
fun patchVision(vision: Vision, meta: Meta) {
|
public fun patchVision(vision: Vision, meta: Meta) {
|
||||||
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
|
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
|
||||||
form.patch(vision, meta)
|
form.patch(vision, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : PluginFactory<VisionManager> {
|
public companion object : PluginFactory<VisionManager> {
|
||||||
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
||||||
override val type: KClass<out VisionManager> = VisionManager::class
|
override val type: KClass<out VisionManager> = VisionManager::class
|
||||||
|
|
||||||
const val VISION_SERIAL_MODULE_TARGET = "visionSerialModule"
|
public const val VISION_SERIAL_MODULE_TARGET: String = "visionSerialModule"
|
||||||
|
|
||||||
override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta)
|
override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta)
|
||||||
|
|
||||||
@OptIn(UnstableDefault::class)
|
public val jsonConfiguration: Json = Json {
|
||||||
val jsonConfiguration = JsonConfiguration(
|
prettyPrint = true
|
||||||
prettyPrint = true,
|
useArrayPolymorphism = false
|
||||||
useArrayPolymorphism = false,
|
encodeDefaults = false
|
||||||
encodeDefaults = false,
|
|
||||||
ignoreUnknownKeys = true
|
ignoreUnknownKeys = true
|
||||||
)
|
}
|
||||||
|
|
||||||
val defaultSerialModule = SerializersModule {
|
public val defaultSerialModule: SerializersModule = SerializersModule {
|
||||||
polymorphic(Vision::class, VisionGroup::class) {
|
polymorphic(Vision::class) {
|
||||||
subclass(SimpleVisionGroup.serializer())
|
subclass(SimpleVisionGroup.serializer())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,27 +1,27 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
import hep.dataforge.meta.descriptors.setAttribute
|
import hep.dataforge.meta.descriptors.attributes
|
||||||
import hep.dataforge.meta.get
|
|
||||||
import hep.dataforge.meta.node
|
|
||||||
import hep.dataforge.meta.string
|
|
||||||
import hep.dataforge.names.toName
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension property to access the "widget" key of [ValueDescriptor]
|
* Extension property to access the "widget" key of [ValueDescriptor]
|
||||||
*/
|
*/
|
||||||
var ValueDescriptor.widget: Meta
|
public var ValueDescriptor.widget: Meta
|
||||||
get() = attributes["widget"].node ?: Meta.EMPTY
|
get() = attributes["widget"].node ?: Meta.EMPTY
|
||||||
set(value) {
|
set(value) {
|
||||||
setAttribute("widget".toName(), value)
|
attributes {
|
||||||
|
set("widget", value)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
||||||
*/
|
*/
|
||||||
var ValueDescriptor.widgetType: String?
|
public var ValueDescriptor.widgetType: String?
|
||||||
get() = attributes["widget.type"].string
|
get() = attributes["widget.type"].string
|
||||||
set(value) {
|
set(value) {
|
||||||
setAttribute("widget.type".toName(), value)
|
attributes{
|
||||||
|
set("widget.type", value)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.vision.visitor
|
package hep.dataforge.vision.visitor
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.length
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||||
import kotlinx.coroutines.Job
|
import kotlinx.coroutines.Job
|
||||||
|
@ -4,10 +4,7 @@ import hep.dataforge.meta.*
|
|||||||
import hep.dataforge.meta.descriptors.ItemDescriptor
|
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.names.NameToken
|
|
||||||
import hep.dataforge.names.asName
|
|
||||||
import hep.dataforge.names.withIndex
|
|
||||||
import hep.dataforge.values.Null
|
import hep.dataforge.values.Null
|
||||||
import hep.dataforge.values.Value
|
import hep.dataforge.values.Value
|
||||||
import javafx.beans.binding.ListBinding
|
import javafx.beans.binding.ListBinding
|
||||||
@ -137,12 +134,12 @@ class FXMetaNode<M : MetaNode<M>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class FXMetaValue<M : MetaNode<M>>(
|
public class FXMetaValue<M : MetaNode<M>>(
|
||||||
override val name: NameToken,
|
override val name: NameToken,
|
||||||
override val parent: FXMetaNode<M>
|
override val parent: FXMetaNode<M>
|
||||||
) : FXMeta<M>() {
|
) : FXMeta<M>() {
|
||||||
|
|
||||||
val descriptorProperty = parent.descriptorProperty.objectBinding {
|
public val descriptorProperty = parent.descriptorProperty.objectBinding {
|
||||||
it?.values?.get(name.body)
|
it?.values?.get(name.body)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -153,24 +150,24 @@ class FXMetaValue<M : MetaNode<M>>(
|
|||||||
|
|
||||||
//private val innerValueProperty = SimpleObjectProperty(value)
|
//private val innerValueProperty = SimpleObjectProperty(value)
|
||||||
|
|
||||||
val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
||||||
parent.node[name].value ?: descriptor?.default
|
parent.node[name].value ?: descriptor?.default
|
||||||
}
|
}
|
||||||
|
|
||||||
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null }
|
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null }
|
||||||
|
|
||||||
val value by valueProperty
|
public val value by valueProperty
|
||||||
|
|
||||||
override val descriptionProperty = descriptorProperty.stringBinding { it?.info ?: "" }
|
override val descriptionProperty = descriptorProperty.stringBinding { it?.info ?: "" }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
public fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
||||||
node?.remove(name.asName())
|
node?.remove(name.asName())
|
||||||
children.invalidate()
|
children.invalidate()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
||||||
return if (append && token.index.isNotEmpty()) {
|
return if (append && token.hasIndex()) {
|
||||||
val name = token.asName()
|
val name = token.asName()
|
||||||
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||||
val newName = name.withIndex(index.toString())
|
val newName = name.withIndex(index.toString())
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
@ -7,7 +7,7 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":visionforge-solid"))
|
api(project(":visionforge-solid"))
|
||||||
api("scientifik:gdml:0.1.8")
|
api("kscience.gdml:gdml:0.2.0-dev-2")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -12,7 +12,7 @@ import hep.dataforge.vision.set
|
|||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||||
import hep.dataforge.vision.useStyle
|
import hep.dataforge.vision.useStyle
|
||||||
import scientifik.gdml.*
|
import kscience.gdml.*
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
@ -20,7 +20,7 @@ import kotlin.random.Random
|
|||||||
private val solidsName = "solids".asName()
|
private val solidsName = "solids".asName()
|
||||||
private val volumesName = "volumes".asName()
|
private val volumesName = "volumes".asName()
|
||||||
|
|
||||||
class GDMLTransformer internal constructor(val root: GDML) {
|
public class GDMLTransformer internal constructor(val root: GDML) {
|
||||||
//private val materialCache = HashMap<GDMLMaterial, Meta>()
|
//private val materialCache = HashMap<GDMLMaterial, Meta>()
|
||||||
private val random = Random(222)
|
private val random = Random(222)
|
||||||
|
|
||||||
|
@ -1,70 +0,0 @@
|
|||||||
package hep.dataforge.vision.gdml
|
|
||||||
|
|
||||||
import scientifik.gdml.AUnit
|
|
||||||
import scientifik.gdml.GDMLPosition
|
|
||||||
import scientifik.gdml.GDMLRotation
|
|
||||||
import scientifik.gdml.GDMLSolid
|
|
||||||
|
|
||||||
enum class LUnit(val value: Float) {
|
|
||||||
MM(1f),
|
|
||||||
CM(10f),
|
|
||||||
M(1000f)
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLPosition.unit(): LUnit = LUnit.valueOf(unit.toUpperCase())
|
|
||||||
|
|
||||||
fun GDMLPosition.x(unit: LUnit): Float = if (unit.name == this.unit) {
|
|
||||||
x.toFloat()
|
|
||||||
} else {
|
|
||||||
x.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLPosition.y(unit: LUnit): Float = if (unit.name == this.unit) {
|
|
||||||
y.toFloat()
|
|
||||||
} else {
|
|
||||||
y.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLPosition.z(unit: LUnit): Float = if (unit.name == this.unit) {
|
|
||||||
z.toFloat()
|
|
||||||
} else {
|
|
||||||
z.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLRotation.unit(): AUnit = AUnit.valueOf(unit.toUpperCase())
|
|
||||||
|
|
||||||
fun GDMLRotation.x(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) {
|
|
||||||
x.toFloat()
|
|
||||||
} else {
|
|
||||||
x.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLRotation.y(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) {
|
|
||||||
y.toFloat()
|
|
||||||
} else {
|
|
||||||
y.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLRotation.z(unit: AUnit = AUnit.RAD): Float = if (unit.name == this.unit) {
|
|
||||||
z.toFloat()
|
|
||||||
} else {
|
|
||||||
z.toFloat() / unit.value * unit().value
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLSolid.lscale(unit: LUnit): Float {
|
|
||||||
val solidUnit = lunit?.let { LUnit.valueOf(it.toUpperCase()) } ?: return 1f
|
|
||||||
return if (solidUnit == unit) {
|
|
||||||
1f
|
|
||||||
} else {
|
|
||||||
solidUnit.value / unit.value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun GDMLSolid.ascale(unit: AUnit = AUnit.RAD): Float {
|
|
||||||
val solidUnit = aunit?.let { AUnit.valueOf(it.toUpperCase()) } ?: return 1f
|
|
||||||
return if (solidUnit == unit) {
|
|
||||||
1f
|
|
||||||
} else {
|
|
||||||
solidUnit.value / unit.value
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ package hep.dataforge.vision.gdml
|
|||||||
|
|
||||||
import hep.dataforge.vision.solid.SolidGroup
|
import hep.dataforge.vision.solid.SolidGroup
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
import nl.adaptivity.xmlutil.StAXReader
|
||||||
import scientifik.gdml.GDML
|
import kscience.gdml.GDML
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package hep.dataforge.vision.gdml
|
package hep.dataforge.vision.gdml
|
||||||
|
|
||||||
import hep.dataforge.vision.solid.stringify
|
import hep.dataforge.vision.solid.encodeToString
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
import nl.adaptivity.xmlutil.StAXReader
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
import scientifik.gdml.GDML
|
import kscience.gdml.GDML
|
||||||
|
|
||||||
class TestConvertor {
|
class TestConvertor {
|
||||||
|
|
||||||
@ -13,7 +13,7 @@ class TestConvertor {
|
|||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val xmlReader = StAXReader(stream, "UTF-8")
|
||||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||||
val vision = xml.toVision()
|
val vision = xml.toVision()
|
||||||
println(vision.stringify())
|
println(vision.encodeToString())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -33,6 +33,6 @@ class TestConvertor {
|
|||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val xmlReader = StAXReader(stream, "UTF-8")
|
||||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||||
val visual = xml.toVision()
|
val visual = xml.toVision()
|
||||||
println(visual.stringify())
|
println(visual.encodeToString())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -8,7 +8,7 @@ import hep.dataforge.vision.visitor.flowStatistics
|
|||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
import nl.adaptivity.xmlutil.StAXReader
|
||||||
import scientifik.gdml.GDML
|
import kscience.gdml.GDML
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
@ -1,15 +1,14 @@
|
|||||||
import scientifik.useSerialization
|
import ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("scientifik.mpp")
|
id("ru.mipt.npm.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
useSerialization()
|
kscience {
|
||||||
|
useSerialization()
|
||||||
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
js {
|
|
||||||
useCommonJs()
|
|
||||||
}
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
commonMain {
|
||||||
@ -22,7 +21,7 @@ kotlin {
|
|||||||
api("org.fxyz3d:fxyz3d:0.5.2") {
|
api("org.fxyz3d:fxyz3d:0.5.2") {
|
||||||
exclude(module = "slf4j-simple")
|
exclude(module = "slf4j-simple")
|
||||||
}
|
}
|
||||||
api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${Scientifik.coroutinesVersion}")
|
api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${coroutinesVersion}")
|
||||||
implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") {
|
implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") {
|
||||||
exclude(module = "slf4j-simple")
|
exclude(module = "slf4j-simple")
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
|
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
@ -13,10 +14,10 @@ import kotlinx.serialization.UseSerializers
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.box")
|
@SerialName("solid.box")
|
||||||
class Box(
|
public class Box(
|
||||||
val xSize: Float,
|
public val xSize: Float,
|
||||||
val ySize: Float,
|
public val ySize: Float,
|
||||||
val zSize: Float
|
public val zSize: Float
|
||||||
) : AbstractVision(), GeometrySolid {
|
) : AbstractVision(), GeometrySolid {
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -67,15 +68,15 @@ class Box(
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.box(
|
public inline fun VisionContainerBuilder<Solid>.box(
|
||||||
xSize: Number,
|
xSize: Number,
|
||||||
ySize: Number,
|
ySize: Number,
|
||||||
zSize: Number,
|
zSize: Number,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
action: Box.() -> Unit = {}
|
action: Box.() -> Unit = {}
|
||||||
) = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) }
|
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) }
|
@ -10,7 +10,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
|
|
||||||
enum class CompositeType {
|
public enum class CompositeType {
|
||||||
UNION,
|
UNION,
|
||||||
INTERSECT,
|
INTERSECT,
|
||||||
SUBTRACT
|
SUBTRACT
|
||||||
@ -18,10 +18,10 @@ enum class CompositeType {
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.composite")
|
@SerialName("solid.composite")
|
||||||
class Composite(
|
public class Composite(
|
||||||
val compositeType: CompositeType,
|
public val compositeType: CompositeType,
|
||||||
val first: Solid,
|
public val first: Solid,
|
||||||
val second: Solid
|
public val second: Solid
|
||||||
) : AbstractVision(), Solid, VisionGroup {
|
) : AbstractVision(), Solid, VisionGroup {
|
||||||
|
|
||||||
init {
|
init {
|
||||||
@ -42,7 +42,7 @@ class Composite(
|
|||||||
get() = null
|
get() = null
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.composite(
|
public inline fun MutableVisionGroup.composite(
|
||||||
type: CompositeType,
|
type: CompositeType,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
builder: SolidGroup.() -> Unit
|
builder: SolidGroup.() -> Unit
|
||||||
@ -67,11 +67,11 @@ inline fun MutableVisionGroup.composite(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.union(name: String = "", builder: SolidGroup.() -> Unit) =
|
public inline fun MutableVisionGroup.union(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||||
composite(CompositeType.UNION, name, builder = builder)
|
composite(CompositeType.UNION, name, builder = builder)
|
||||||
|
|
||||||
inline fun MutableVisionGroup.subtract(name: String = "", builder: SolidGroup.() -> Unit) =
|
public inline fun MutableVisionGroup.subtract(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||||
composite(CompositeType.SUBTRACT, name, builder = builder)
|
composite(CompositeType.SUBTRACT, name, builder = builder)
|
||||||
|
|
||||||
inline fun MutableVisionGroup.intersect(name: String = "", builder: SolidGroup.() -> Unit) =
|
public inline fun MutableVisionGroup.intersect(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||||
composite(CompositeType.INTERSECT, name, builder = builder)
|
composite(CompositeType.INTERSECT, name, builder = builder)
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -17,12 +18,12 @@ import kotlin.math.sin
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.cone")
|
@SerialName("solid.cone")
|
||||||
class ConeSegment(
|
public class ConeSegment(
|
||||||
var radius: Float,
|
public var radius: Float,
|
||||||
var height: Float,
|
public var height: Float,
|
||||||
var upperRadius: Float,
|
public var upperRadius: Float,
|
||||||
var startAngle: Float = 0f,
|
public var startAngle: Float = 0f,
|
||||||
var angle: Float = PI2
|
public var angle: Float = PI2
|
||||||
) : AbstractVision(), GeometrySolid {
|
) : AbstractVision(), GeometrySolid {
|
||||||
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
@ -75,7 +76,7 @@ class ConeSegment(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.cylinder(
|
public inline fun VisionContainerBuilder<Solid>.cylinder(
|
||||||
r: Number,
|
r: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
@ -87,7 +88,7 @@ inline fun MutableVisionGroup.cylinder(
|
|||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { set(name, it) }
|
||||||
|
|
||||||
|
|
||||||
inline fun MutableVisionGroup.cone(
|
public inline fun VisionContainerBuilder<Solid>.cone(
|
||||||
bottomRadius: Number,
|
bottomRadius: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
upperRadius: Number = 0.0,
|
upperRadius: Number = 0.0,
|
||||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.convex")
|
@SerialName("solid.convex")
|
||||||
class Convex(val points: List<Point3D>) : AbstractVision(), Solid {
|
public class Convex(public val points: List<Point3D>) : AbstractVision(), Solid {
|
||||||
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
@ -23,17 +24,17 @@ class Convex(val points: List<Point3D>) : AbstractVision(), Solid {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}) =
|
public inline fun VisionContainerBuilder<Solid>.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}): Convex =
|
||||||
ConvexBuilder().apply(action).build().also { set(name, it) }
|
ConvexBuilder().apply(action).build().also { set(name, it) }
|
||||||
|
|
||||||
class ConvexBuilder {
|
public class ConvexBuilder {
|
||||||
private val points = ArrayList<Point3D>()
|
private val points = ArrayList<Point3D>()
|
||||||
|
|
||||||
fun point(x: Number, y: Number, z: Number) {
|
public fun point(x: Number, y: Number, z: Number) {
|
||||||
points.add(Point3D(x, y, z))
|
points.add(Point3D(x, y, z))
|
||||||
}
|
}
|
||||||
|
|
||||||
fun build(): Convex {
|
public fun build(): Convex {
|
||||||
return Convex(points)
|
return Convex(points)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,6 +4,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -13,21 +14,21 @@ import kotlin.math.cos
|
|||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
|
||||||
typealias Shape2D = List<Point2D>
|
public typealias Shape2D = List<Point2D>
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
class Shape2DBuilder(private val points: MutableList<Point2D> = ArrayList()) {
|
public class Shape2DBuilder(private val points: MutableList<Point2D> = ArrayList()) {
|
||||||
|
|
||||||
fun point(x: Number, y: Number) {
|
public fun point(x: Number, y: Number) {
|
||||||
points.add(Point2D(x, y))
|
points.add(Point2D(x, y))
|
||||||
}
|
}
|
||||||
|
|
||||||
infix fun Number.to(y: Number) = point(this, y)
|
public infix fun Number.to(y: Number): Unit = point(this, y)
|
||||||
|
|
||||||
fun build(): Shape2D = points
|
public fun build(): Shape2D = points
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||||
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
require(vertices > 2) { "Polygon must have more than 2 vertices" }
|
||||||
val angle = 2 * PI / vertices
|
val angle = 2 * PI / vertices
|
||||||
for (i in 0 until vertices) {
|
for (i in 0 until vertices) {
|
||||||
@ -36,13 +37,13 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.extrude")
|
@SerialName("solid.extrude")
|
||||||
class Extruded(
|
public class Extruded(
|
||||||
var shape: List<Point2D> = ArrayList(),
|
public var shape: List<Point2D> = ArrayList(),
|
||||||
var layers: MutableList<Layer> = ArrayList()
|
public var layers: MutableList<Layer> = ArrayList()
|
||||||
) : AbstractVision(), GeometrySolid {
|
) : AbstractVision(), GeometrySolid {
|
||||||
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
@ -51,12 +52,12 @@ class Extruded(
|
|||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
fun shape(block: Shape2DBuilder.() -> Unit) {
|
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||||
this.shape = Shape2DBuilder().apply(block).build()
|
this.shape = Shape2DBuilder().apply(block).build()
|
||||||
//TODO send invalidation signal
|
//TODO send invalidation signal
|
||||||
}
|
}
|
||||||
|
|
||||||
fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
|
public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) {
|
||||||
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
|
layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat()))
|
||||||
//TODO send invalidation signal
|
//TODO send invalidation signal
|
||||||
}
|
}
|
||||||
@ -107,10 +108,10 @@ class Extruded(
|
|||||||
geometryBuilder.cap(layers.last())
|
geometryBuilder.cap(layers.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val TYPE = "geometry.3d.extruded"
|
public const val TYPE: String = "solid.extruded"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableVisionGroup.extrude(name: String = "", action: Extruded.() -> Unit = {}) =
|
public fun VisionContainerBuilder<Solid>.extrude(name: String = "", action: Extruded.() -> Unit = {}): Extruded =
|
||||||
Extruded().apply(action).also { set(name, it) }
|
Extruded().apply(action).also { set(name, it) }
|
@ -5,7 +5,7 @@ import hep.dataforge.meta.Meta
|
|||||||
/**
|
/**
|
||||||
* @param T the type of resulting geometry
|
* @param T the type of resulting geometry
|
||||||
*/
|
*/
|
||||||
interface GeometryBuilder<T : Any> {
|
public interface GeometryBuilder<T : Any> {
|
||||||
/**
|
/**
|
||||||
* Add a face to 3D model. If one of the vertices is not present in the current geometry model list of vertices,
|
* Add a face to 3D model. If one of the vertices is not present in the current geometry model list of vertices,
|
||||||
* it is added automatically.
|
* it is added automatically.
|
||||||
@ -13,12 +13,12 @@ interface GeometryBuilder<T : Any> {
|
|||||||
* @param normal optional external normal to the face
|
* @param normal optional external normal to the face
|
||||||
* @param meta optional additional platform-specific parameters like color or texture index
|
* @param meta optional additional platform-specific parameters like color or texture index
|
||||||
*/
|
*/
|
||||||
fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY)
|
public fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY)
|
||||||
|
|
||||||
fun build(): T
|
public fun build(): T
|
||||||
}
|
}
|
||||||
|
|
||||||
fun GeometryBuilder<*>.face4(
|
public fun GeometryBuilder<*>.face4(
|
||||||
vertex1: Point3D,
|
vertex1: Point3D,
|
||||||
vertex2: Point3D,
|
vertex2: Point3D,
|
||||||
vertex3: Point3D,
|
vertex3: Point3D,
|
||||||
@ -33,11 +33,11 @@ fun GeometryBuilder<*>.face4(
|
|||||||
/**
|
/**
|
||||||
* [GeometrySolid] is a [Solid] that can represent its own geometry as a set of polygons.
|
* [GeometrySolid] is a [Solid] that can represent its own geometry as a set of polygons.
|
||||||
*/
|
*/
|
||||||
interface GeometrySolid : Solid {
|
public interface GeometrySolid : Solid {
|
||||||
fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
|
public fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <T : Any> GeometryBuilder<T>.cap(shape: List<Point3D>, normal: Point3D? = null) {
|
public fun <T : Any> GeometryBuilder<T>.cap(shape: List<Point3D>, normal: Point3D? = null) {
|
||||||
//FIXME won't work for non-convex shapes
|
//FIXME won't work for non-convex shapes
|
||||||
val center = Point3D(
|
val center = Point3D(
|
||||||
shape.map { it.x }.average(),
|
shape.map { it.x }.average(),
|
||||||
|
@ -4,10 +4,12 @@ package hep.dataforge.vision.solid
|
|||||||
|
|
||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -15,7 +17,7 @@ import kotlinx.serialization.UseSerializers
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.line")
|
@SerialName("solid.line")
|
||||||
class PolyLine(var points: List<Point3D>) : AbstractVision(), Solid {
|
public class PolyLine(public var points: List<Point3D>) : AbstractVision(), Solid {
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -23,13 +25,13 @@ class PolyLine(var points: List<Point3D>) : AbstractVision(), Solid {
|
|||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
|
||||||
//var lineType by string()
|
//var lineType by string()
|
||||||
var thickness by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
|
public var thickness: Number by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
val THICKNESS_KEY = "thickness".asName()
|
public val THICKNESS_KEY: Name = "thickness".asName()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableVisionGroup.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}) =
|
public fun VisionContainerBuilder<Solid>.polyline(vararg points: Point3D, name: String = "", action: PolyLine.() -> Unit = {}): PolyLine =
|
||||||
PolyLine(points.toList()).apply(action).also { set(name, it) }
|
PolyLine(points.toList()).apply(action).also { set(name, it) }
|
@ -12,8 +12,8 @@ import kotlinx.serialization.Transient
|
|||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
public abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
||||||
abstract val prototype: Vision
|
public abstract val prototype: Vision
|
||||||
|
|
||||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||||
return if (inherit) {
|
return if (inherit) {
|
||||||
@ -33,7 +33,7 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override var styles: List<String>
|
override var styles: List<String>
|
||||||
get() = properties[Vision.STYLE_KEY].stringList + prototype.styles
|
get() = (properties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + prototype.styles
|
||||||
set(value) {
|
set(value) {
|
||||||
config[Vision.STYLE_KEY] = value
|
config[Vision.STYLE_KEY] = value
|
||||||
}
|
}
|
||||||
@ -53,11 +53,11 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.proxy")
|
@SerialName("solid.proxy")
|
||||||
class Proxy private constructor(
|
public class Proxy private constructor(
|
||||||
val templateName: Name
|
public val templateName: Name
|
||||||
) : AbstractProxy(), Solid {
|
) : AbstractProxy(), Solid {
|
||||||
|
|
||||||
constructor(parent: SolidGroup, templateName: Name) : this(templateName) {
|
public constructor(parent: SolidGroup, templateName: Name) : this(templateName) {
|
||||||
this.parent = parent
|
this.parent = parent
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -104,7 +104,7 @@ class Proxy private constructor(
|
|||||||
* A ProxyChild is created temporarily only to interact with properties, it does not store any values
|
* A ProxyChild is created temporarily only to interact with properties, it does not store any values
|
||||||
* (properties are stored in external cache) and created and destroyed on-demand).
|
* (properties are stored in external cache) and created and destroyed on-demand).
|
||||||
*/
|
*/
|
||||||
inner class ProxyChild(val name: Name) : AbstractProxy() {
|
public inner class ProxyChild(public val name: Name) : AbstractProxy() {
|
||||||
|
|
||||||
override val prototype: Vision get() = prototypeFor(name)
|
override val prototype: Vision get() = prototypeFor(name)
|
||||||
|
|
||||||
@ -136,12 +136,15 @@ class Proxy private constructor(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
const val PROXY_CHILD_PROPERTY_PREFIX = "@child"
|
public const val PROXY_CHILD_PROPERTY_PREFIX: String = "@child"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val Vision.prototype: Vision
|
/**
|
||||||
|
* Get a vision prototype if it is a [Proxy] or vision itself if it is not
|
||||||
|
*/
|
||||||
|
public val Vision.prototype: Vision
|
||||||
get() = when (this) {
|
get() = when (this) {
|
||||||
is AbstractProxy -> prototype
|
is AbstractProxy -> prototype
|
||||||
else -> this
|
else -> this
|
||||||
@ -150,7 +153,7 @@ val Vision.prototype: Vision
|
|||||||
/**
|
/**
|
||||||
* Create ref for existing prototype
|
* Create ref for existing prototype
|
||||||
*/
|
*/
|
||||||
fun SolidGroup.ref(
|
public fun SolidGroup.ref(
|
||||||
templateName: Name,
|
templateName: Name,
|
||||||
name: String = ""
|
name: String = ""
|
||||||
): Proxy = Proxy(this, templateName).also { set(name, it) }
|
): Proxy = Proxy(this, templateName).also { set(name, it) }
|
||||||
@ -158,7 +161,7 @@ fun SolidGroup.ref(
|
|||||||
/**
|
/**
|
||||||
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
* Add new proxy wrapping given object and automatically adding it to the prototypes
|
||||||
*/
|
*/
|
||||||
fun SolidGroup.proxy(
|
public fun SolidGroup.proxy(
|
||||||
name: String,
|
name: String,
|
||||||
obj: Solid,
|
obj: Solid,
|
||||||
templateName: Name = name.toName()
|
templateName: Name = name.toName()
|
||||||
@ -173,12 +176,3 @@ fun SolidGroup.proxy(
|
|||||||
}
|
}
|
||||||
return ref(templateName, name)
|
return ref(templateName, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
fun SolidGroup.proxyGroup(
|
|
||||||
name: String,
|
|
||||||
templateName: Name = name.toName(),
|
|
||||||
block: MutableVisionGroup.() -> Unit
|
|
||||||
): Proxy {
|
|
||||||
val group = SolidGroup().apply(block)
|
|
||||||
return proxy(name, group, templateName)
|
|
||||||
}
|
|
||||||
|
@ -4,65 +4,63 @@ package hep.dataforge.vision.solid
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.output.Renderer
|
import hep.dataforge.output.Renderer
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
import hep.dataforge.values.asValue
|
import hep.dataforge.values.asValue
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
|
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||||
import hep.dataforge.vision.enum
|
import hep.dataforge.vision.enum
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
|
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
|
||||||
import hep.dataforge.vision.solid.Solid.Companion.VISIBLE_KEY
|
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Interface for 3-dimensional [Vision]
|
* Interface for 3-dimensional [Vision]
|
||||||
*/
|
*/
|
||||||
interface Solid : Vision {
|
public interface Solid : Vision {
|
||||||
var position: Point3D?
|
public var position: Point3D?
|
||||||
var rotation: Point3D?
|
public var rotation: Point3D?
|
||||||
var scale: Point3D?
|
public var scale: Point3D?
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor? get() = Companion.descriptor
|
override val descriptor: NodeDescriptor? get() = Companion.descriptor
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
|
|
||||||
val VISIBLE_KEY = "visible".asName()
|
|
||||||
|
|
||||||
// val SELECTED_KEY = "selected".asName()
|
// val SELECTED_KEY = "selected".asName()
|
||||||
val DETAIL_KEY = "detail".asName()
|
public val DETAIL_KEY: Name = "detail".asName()
|
||||||
val LAYER_KEY = "layer".asName()
|
public val LAYER_KEY: Name = "layer".asName()
|
||||||
val IGNORE_KEY = "ignore".asName()
|
public val IGNORE_KEY: Name = "ignore".asName()
|
||||||
|
|
||||||
val GEOMETRY_KEY = "geometry".asName()
|
public val GEOMETRY_KEY: Name = "geometry".asName()
|
||||||
|
|
||||||
val X_KEY = "x".asName()
|
public val X_KEY: Name = "x".asName()
|
||||||
val Y_KEY = "y".asName()
|
public val Y_KEY: Name = "y".asName()
|
||||||
val Z_KEY = "z".asName()
|
public val Z_KEY: Name = "z".asName()
|
||||||
|
|
||||||
val POSITION_KEY = "pos".asName()
|
public val POSITION_KEY: Name = "pos".asName()
|
||||||
|
|
||||||
val X_POSITION_KEY = POSITION_KEY + X_KEY
|
public val X_POSITION_KEY: Name = POSITION_KEY + X_KEY
|
||||||
val Y_POSITION_KEY = POSITION_KEY + Y_KEY
|
public val Y_POSITION_KEY: Name = POSITION_KEY + Y_KEY
|
||||||
val Z_POSITION_KEY = POSITION_KEY + Z_KEY
|
public val Z_POSITION_KEY: Name = POSITION_KEY + Z_KEY
|
||||||
|
|
||||||
val ROTATION = "rotation".asName()
|
public val ROTATION: Name = "rotation".asName()
|
||||||
|
|
||||||
val X_ROTATION_KEY = ROTATION + X_KEY
|
public val X_ROTATION_KEY: Name = ROTATION + X_KEY
|
||||||
val Y_ROTATION_KEY = ROTATION + Y_KEY
|
public val Y_ROTATION_KEY: Name = ROTATION + Y_KEY
|
||||||
val Z_ROTATION_KEY = ROTATION + Z_KEY
|
public val Z_ROTATION_KEY: Name = ROTATION + Z_KEY
|
||||||
|
|
||||||
val ROTATION_ORDER_KEY = ROTATION + "order"
|
public val ROTATION_ORDER_KEY: Name = ROTATION + "order"
|
||||||
|
|
||||||
val SCALE_KEY = "scale".asName()
|
public val SCALE_KEY: Name = "scale".asName()
|
||||||
|
|
||||||
val X_SCALE_KEY = SCALE_KEY + X_KEY
|
public val X_SCALE_KEY: Name = SCALE_KEY + X_KEY
|
||||||
val Y_SCALE_KEY = SCALE_KEY + Y_KEY
|
public val Y_SCALE_KEY: Name = SCALE_KEY + Y_KEY
|
||||||
val Z_SCALE_KEY = SCALE_KEY + Z_KEY
|
public val Z_SCALE_KEY: Name = SCALE_KEY + Z_KEY
|
||||||
|
|
||||||
val descriptor by lazy {
|
public val descriptor: NodeDescriptor by lazy {
|
||||||
NodeDescriptor {
|
NodeDescriptor {
|
||||||
value(VISIBLE_KEY) {
|
value(VISIBLE_KEY) {
|
||||||
type(ValueType.BOOLEAN)
|
type(ValueType.BOOLEAN)
|
||||||
@ -100,20 +98,20 @@ interface Solid : Vision {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Count number of layers to the top object. Return 1 if this is top layer
|
* Get the layer number this solid belongs to. Return 0 if layer is not defined.
|
||||||
*/
|
*/
|
||||||
var Solid.layer: Int
|
public var Solid.layer: Int
|
||||||
get() = properties?.getItem(LAYER_KEY).int ?: 0
|
get() = properties?.getItem(LAYER_KEY).int ?: 0
|
||||||
set(value) {
|
set(value) {
|
||||||
config[LAYER_KEY] = value.asValue()
|
config[LAYER_KEY] = value.asValue()
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Renderer<Solid>.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit) =
|
public fun Renderer<Solid>.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit): Unit =
|
||||||
render(SolidGroup().apply(action), meta)
|
render(SolidGroup().apply(action), meta)
|
||||||
|
|
||||||
// Common properties
|
// Common properties
|
||||||
|
|
||||||
enum class RotationOrder {
|
public enum class RotationOrder {
|
||||||
XYZ,
|
XYZ,
|
||||||
YZX,
|
YZX,
|
||||||
ZXY,
|
ZXY,
|
||||||
@ -125,7 +123,7 @@ enum class RotationOrder {
|
|||||||
/**
|
/**
|
||||||
* Rotation order
|
* Rotation order
|
||||||
*/
|
*/
|
||||||
var Solid.rotationOrder: RotationOrder
|
public var Solid.rotationOrder: RotationOrder
|
||||||
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||||
set(value) = setItem(Solid.ROTATION_ORDER_KEY, value.name.asValue())
|
set(value) = setItem(Solid.ROTATION_ORDER_KEY, value.name.asValue())
|
||||||
|
|
||||||
@ -133,19 +131,15 @@ var Solid.rotationOrder: RotationOrder
|
|||||||
/**
|
/**
|
||||||
* Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited
|
* Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited
|
||||||
*/
|
*/
|
||||||
var Solid.detail: Int?
|
public var Solid.detail: Int?
|
||||||
get() = getProperty(DETAIL_KEY, false).int
|
get() = getProperty(DETAIL_KEY, false).int
|
||||||
set(value) = setItem(DETAIL_KEY, value?.asValue())
|
set(value) = setItem(DETAIL_KEY, value?.asValue())
|
||||||
|
|
||||||
var Vision.visible: Boolean?
|
|
||||||
get() = getItem(VISIBLE_KEY).boolean
|
|
||||||
set(value) = setItem(VISIBLE_KEY, value?.asValue())
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If this property is true, the object will be ignored on render.
|
* If this property is true, the object will be ignored on render.
|
||||||
* Property is not inherited.
|
* Property is not inherited.
|
||||||
*/
|
*/
|
||||||
var Vision.ignore: Boolean?
|
public var Vision.ignore: Boolean?
|
||||||
get() = getProperty(IGNORE_KEY, false).boolean
|
get() = getProperty(IGNORE_KEY, false).boolean
|
||||||
set(value) = setItem(IGNORE_KEY, value?.asValue())
|
set(value) = setItem(IGNORE_KEY, value?.asValue())
|
||||||
|
|
||||||
@ -156,21 +150,21 @@ var Vision.ignore: Boolean?
|
|||||||
private fun Solid.position(): Point3D =
|
private fun Solid.position(): Point3D =
|
||||||
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
|
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
|
||||||
|
|
||||||
var Solid.x: Number
|
public var Solid.x: Number
|
||||||
get() = position?.x ?: 0f
|
get() = position?.x ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().x = value.toDouble()
|
position().x = value.toDouble()
|
||||||
propertyChanged(Solid.X_POSITION_KEY)
|
propertyChanged(Solid.X_POSITION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.y: Number
|
public var Solid.y: Number
|
||||||
get() = position?.y ?: 0f
|
get() = position?.y ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().y = value.toDouble()
|
position().y = value.toDouble()
|
||||||
propertyChanged(Solid.Y_POSITION_KEY)
|
propertyChanged(Solid.Y_POSITION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.z: Number
|
public var Solid.z: Number
|
||||||
get() = position?.z ?: 0f
|
get() = position?.z ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
position().z = value.toDouble()
|
position().z = value.toDouble()
|
||||||
@ -180,21 +174,21 @@ var Solid.z: Number
|
|||||||
private fun Solid.rotation(): Point3D =
|
private fun Solid.rotation(): Point3D =
|
||||||
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
|
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
|
||||||
|
|
||||||
var Solid.rotationX: Number
|
public var Solid.rotationX: Number
|
||||||
get() = rotation?.x ?: 0f
|
get() = rotation?.x ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().x = value.toDouble()
|
rotation().x = value.toDouble()
|
||||||
propertyChanged(Solid.X_ROTATION_KEY)
|
propertyChanged(Solid.X_ROTATION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.rotationY: Number
|
public var Solid.rotationY: Number
|
||||||
get() = rotation?.y ?: 0f
|
get() = rotation?.y ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().y = value.toDouble()
|
rotation().y = value.toDouble()
|
||||||
propertyChanged(Solid.Y_ROTATION_KEY)
|
propertyChanged(Solid.Y_ROTATION_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.rotationZ: Number
|
public var Solid.rotationZ: Number
|
||||||
get() = rotation?.z ?: 0f
|
get() = rotation?.z ?: 0f
|
||||||
set(value) {
|
set(value) {
|
||||||
rotation().z = value.toDouble()
|
rotation().z = value.toDouble()
|
||||||
@ -204,21 +198,21 @@ var Solid.rotationZ: Number
|
|||||||
private fun Solid.scale(): Point3D =
|
private fun Solid.scale(): Point3D =
|
||||||
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
|
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
|
||||||
|
|
||||||
var Solid.scaleX: Number
|
public var Solid.scaleX: Number
|
||||||
get() = scale?.x ?: 1f
|
get() = scale?.x ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().x = value.toDouble()
|
scale().x = value.toDouble()
|
||||||
propertyChanged(Solid.X_SCALE_KEY)
|
propertyChanged(Solid.X_SCALE_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.scaleY: Number
|
public var Solid.scaleY: Number
|
||||||
get() = scale?.y ?: 1f
|
get() = scale?.y ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().y = value.toDouble()
|
scale().y = value.toDouble()
|
||||||
propertyChanged(Solid.Y_SCALE_KEY)
|
propertyChanged(Solid.Y_SCALE_KEY)
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.scaleZ: Number
|
public var Solid.scaleZ: Number
|
||||||
get() = scale?.z ?: 1f
|
get() = scale?.z ?: 1f
|
||||||
set(value) {
|
set(value) {
|
||||||
scale().z = value.toDouble()
|
scale().z = value.toDouble()
|
||||||
|
@ -15,9 +15,9 @@ import kotlinx.serialization.Serializable
|
|||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
interface PrototypeHolder {
|
public interface PrototypeHolder {
|
||||||
val parent: VisionGroup?
|
public val parent: VisionGroup?
|
||||||
val prototypes: MutableVisionGroup?
|
public val prototypes: MutableVisionGroup?
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -25,7 +25,7 @@ interface PrototypeHolder {
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("group.solid")
|
@SerialName("group.solid")
|
||||||
class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||||
|
|
||||||
override var styleSheet: StyleSheet? = null
|
override var styleSheet: StyleSheet? = null
|
||||||
|
|
||||||
@ -39,7 +39,7 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
|||||||
/**
|
/**
|
||||||
* Create or edit prototype node as a group
|
* Create or edit prototype node as a group
|
||||||
*/
|
*/
|
||||||
fun prototypes(builder: MutableVisionGroup.() -> Unit): Unit {
|
public fun prototypes(builder: MutableVisionGroup.() -> Unit): Unit {
|
||||||
(prototypes ?: Prototypes().also {
|
(prototypes ?: Prototypes().also {
|
||||||
prototypes = it
|
prototypes = it
|
||||||
attach(it)
|
attach(it)
|
||||||
@ -79,33 +79,33 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
|||||||
override fun createGroup(): SolidGroup = SolidGroup()
|
override fun createGroup(): SolidGroup = SolidGroup()
|
||||||
|
|
||||||
|
|
||||||
companion object {
|
public companion object {
|
||||||
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
fun parseJson(json: String): SolidGroup =
|
public fun decodeFromString(json: String): SolidGroup =
|
||||||
SolidManager.jsonForSolids.parse(serializer(), json).also { it.attachChildren() }
|
SolidManager.jsonForSolids.decodeFromString(serializer(), json).also { it.attachChildren() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("FunctionName")
|
@Suppress("FunctionName")
|
||||||
fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
||||||
return SolidGroup().apply(block)
|
return SolidGroup().apply(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Ger a prototype redirecting the request to the parent if prototype is not found
|
* Ger a prototype redirecting the request to the parent if prototype is not found
|
||||||
*/
|
*/
|
||||||
tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? =
|
public tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? =
|
||||||
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
|
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
|
||||||
|
|
||||||
fun MutableVisionGroup.group(name: Name = Name.EMPTY, action: SolidGroup.() -> Unit = {}): SolidGroup =
|
public fun MutableVisionGroup.group(name: Name = Name.EMPTY, action: SolidGroup.() -> Unit = {}): SolidGroup =
|
||||||
SolidGroup().apply(action).also { set(name, it) }
|
SolidGroup().apply(action).also { set(name, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a group with given [name], attach it to this parent and return it.
|
* Define a group with given [name], attach it to this parent and return it.
|
||||||
*/
|
*/
|
||||||
fun MutableVisionGroup.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup =
|
public fun MutableVisionGroup.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup =
|
||||||
SolidGroup().apply(action).also { set(name, it) }
|
SolidGroup().apply(action).also { set(name, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.label")
|
@SerialName("solid.label")
|
||||||
class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Solid {
|
public class SolidLabel(public var text: String, public var fontSize: Double, public var fontFamily: String) : AbstractVision(), Solid {
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -21,11 +22,10 @@ class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String)
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fun MutableVisionGroup.label(
|
public fun VisionContainerBuilder<Solid>.label(
|
||||||
text: String,
|
text: String,
|
||||||
fontSize: Number = 20,
|
fontSize: Number = 20,
|
||||||
fontFamily: String = "Arial",
|
fontFamily: String = "Arial",
|
||||||
name: String = "",
|
name: String = "",
|
||||||
action: SolidLabel.() -> Unit = {}
|
action: SolidLabel.() -> Unit = {},
|
||||||
) =
|
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
|
||||||
SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
|
|
@ -12,20 +12,17 @@ import hep.dataforge.vision.Vision
|
|||||||
import hep.dataforge.vision.VisionForm
|
import hep.dataforge.vision.VisionForm
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIAL_MODULE_TARGET
|
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIAL_MODULE_TARGET
|
||||||
|
import kotlinx.serialization.DeserializationStrategy
|
||||||
|
import kotlinx.serialization.ExperimentalSerializationApi
|
||||||
import kotlinx.serialization.KSerializer
|
import kotlinx.serialization.KSerializer
|
||||||
import kotlinx.serialization.UnstableDefault
|
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.json.JsonConfiguration
|
import kotlinx.serialization.modules.*
|
||||||
import kotlinx.serialization.modules.SerialModule
|
|
||||||
import kotlinx.serialization.modules.SerialModuleCollector
|
|
||||||
import kotlinx.serialization.modules.SerializersModule
|
|
||||||
import kotlinx.serialization.modules.contextual
|
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
private class SolidForm<T :Solid>(
|
private class SolidForm<T : Solid>(
|
||||||
override val type: KClass<T>,
|
override val type: KClass<T>,
|
||||||
override val serializer: KSerializer<T>
|
override val serializer: KSerializer<T>,
|
||||||
) : VisionForm<T> {
|
) : VisionForm<T> {
|
||||||
|
|
||||||
private fun Solid.update(meta: Meta) {
|
private fun Solid.update(meta: Meta) {
|
||||||
@ -46,12 +43,12 @@ private class SolidForm<T :Solid>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
@OptIn(UnstableDefault::class)
|
private fun SerializersModule.extractFactories(): List<SolidForm<*>> {
|
||||||
private fun SerialModule.extractFactories(): List<SolidForm<*>> {
|
|
||||||
val list = ArrayList<SolidForm<*>>()
|
val list = ArrayList<SolidForm<*>>()
|
||||||
|
|
||||||
val collector = object : SerialModuleCollector {
|
val collector = object : SerializersModuleCollector {
|
||||||
override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
|
override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
|
||||||
//Do nothing
|
//Do nothing
|
||||||
}
|
}
|
||||||
@ -59,7 +56,7 @@ private fun SerialModule.extractFactories(): List<SolidForm<*>> {
|
|||||||
override fun <Base : Any, Sub : Base> polymorphic(
|
override fun <Base : Any, Sub : Base> polymorphic(
|
||||||
baseClass: KClass<Base>,
|
baseClass: KClass<Base>,
|
||||||
actualClass: KClass<Sub>,
|
actualClass: KClass<Sub>,
|
||||||
actualSerializer: KSerializer<Sub>
|
actualSerializer: KSerializer<Sub>,
|
||||||
) {
|
) {
|
||||||
if (baseClass == Vision::class) {
|
if (baseClass == Vision::class) {
|
||||||
@Suppress("UNCHECKED_CAST") val factory = SolidForm<Solid>(
|
@Suppress("UNCHECKED_CAST") val factory = SolidForm<Solid>(
|
||||||
@ -70,34 +67,41 @@ private fun SerialModule.extractFactories(): List<SolidForm<*>> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
override fun <Base : Any> polymorphicDefault(
|
||||||
|
baseClass: KClass<Base>,
|
||||||
|
defaultSerializerProvider: (className: String?) -> DeserializationStrategy<out Base>?,
|
||||||
|
) {
|
||||||
|
TODO("Not yet implemented")
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
dumpTo(collector)
|
dumpTo(collector)
|
||||||
return list
|
return list
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
public class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
||||||
|
|
||||||
val visionManager by require(VisionManager)
|
public val visionManager: VisionManager by require(VisionManager)
|
||||||
|
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override fun provideTop(target: String): Map<Name, Any> = when (target) {
|
override fun content(target: String): Map<Name, Any> = when (target) {
|
||||||
VisionForm.TYPE -> serialModule.extractFactories().associateBy { it.name }
|
VisionForm.TYPE -> serialModule.extractFactories().associateBy { it.name }
|
||||||
VISION_SERIAL_MODULE_TARGET -> mapOf(tag.name.toName() to serialModule)
|
VISION_SERIAL_MODULE_TARGET -> mapOf(tag.name.toName() to serialModule)
|
||||||
else -> super.provideTop(target)
|
else -> super.content(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object : PluginFactory<SolidManager> {
|
public companion object : PluginFactory<SolidManager> {
|
||||||
override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP)
|
||||||
override val type: KClass<out SolidManager> = SolidManager::class
|
override val type: KClass<out SolidManager> = SolidManager::class
|
||||||
override fun invoke(meta: Meta, context: Context): SolidManager = SolidManager(meta)
|
override fun invoke(meta: Meta, context: Context): SolidManager = SolidManager(meta)
|
||||||
|
|
||||||
val serialModule = SerializersModule {
|
public val serialModule: SerializersModule = SerializersModule {
|
||||||
contextual(Point3DSerializer)
|
contextual(Point3DSerializer)
|
||||||
contextual(Point2DSerializer)
|
contextual(Point2DSerializer)
|
||||||
|
|
||||||
polymorphic(Vision::class, Solid::class) {
|
polymorphic(Vision::class) {
|
||||||
subclass(SimpleVisionGroup.serializer())
|
subclass(SimpleVisionGroup.serializer())
|
||||||
subclass(SolidGroup.serializer())
|
subclass(SolidGroup.serializer())
|
||||||
subclass(Proxy.serializer())
|
subclass(Proxy.serializer())
|
||||||
@ -112,15 +116,12 @@ class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(UnstableDefault::class)
|
val jsonForSolids = Json {
|
||||||
val jsonForSolids = Json(
|
prettyPrint = true
|
||||||
JsonConfiguration(
|
useArrayPolymorphism = false
|
||||||
prettyPrint = true,
|
encodeDefaults = false
|
||||||
useArrayPolymorphism = false,
|
|
||||||
encodeDefaults = false,
|
|
||||||
ignoreUnknownKeys = true
|
ignoreUnknownKeys = true
|
||||||
),
|
serializersModule = this@Companion.serialModule
|
||||||
context = serialModule
|
}
|
||||||
)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import hep.dataforge.meta.descriptors.attributes
|
import hep.dataforge.meta.descriptors.attributes
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.values.ValueType
|
import hep.dataforge.values.ValueType
|
||||||
@ -13,41 +14,41 @@ import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
|||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
||||||
import hep.dataforge.vision.widgetType
|
import hep.dataforge.vision.widgetType
|
||||||
|
|
||||||
class SolidMaterial : Scheme() {
|
public class SolidMaterial : Scheme() {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Primary web-color for the material
|
* Primary web-color for the material
|
||||||
*/
|
*/
|
||||||
var color by string(key = COLOR_KEY)
|
public var color: String? by string(key = COLOR_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specular color for phong material
|
* Specular color for phong material
|
||||||
*/
|
*/
|
||||||
var specularColor by string(key = SPECULAR_COLOR_KEY)
|
public var specularColor: String? by string(key = SPECULAR_COLOR_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opacity
|
* Opacity
|
||||||
*/
|
*/
|
||||||
var opacity by float(1f, key = OPACITY_KEY)
|
public var opacity: Float by float(1f, key = OPACITY_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Replace material by wire frame
|
* Replace material by wire frame
|
||||||
*/
|
*/
|
||||||
var wireframe by boolean(false, WIREFRAME_KEY)
|
public var wireframe: Boolean by boolean(false, WIREFRAME_KEY)
|
||||||
|
|
||||||
companion object : SchemeSpec<SolidMaterial>(::SolidMaterial) {
|
public companion object : SchemeSpec<SolidMaterial>(::SolidMaterial) {
|
||||||
|
|
||||||
val MATERIAL_KEY = "material".asName()
|
public val MATERIAL_KEY: Name = "material".asName()
|
||||||
internal val COLOR_KEY = "color".asName()
|
internal val COLOR_KEY = "color".asName()
|
||||||
val MATERIAL_COLOR_KEY = MATERIAL_KEY + COLOR_KEY
|
public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY
|
||||||
internal val SPECULAR_COLOR_KEY = "specularColor".asName()
|
internal val SPECULAR_COLOR_KEY = "specularColor".asName()
|
||||||
val MATERIAL_SPECULAR_COLOR_KEY = MATERIAL_KEY + SPECULAR_COLOR_KEY
|
public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY
|
||||||
internal val OPACITY_KEY = "opacity".asName()
|
internal val OPACITY_KEY = "opacity".asName()
|
||||||
val MATERIAL_OPACITY_KEY = MATERIAL_KEY + OPACITY_KEY
|
public val MATERIAL_OPACITY_KEY: Name = MATERIAL_KEY + OPACITY_KEY
|
||||||
internal val WIREFRAME_KEY = "wireframe".asName()
|
internal val WIREFRAME_KEY = "wireframe".asName()
|
||||||
val MATERIAL_WIREFRAME_KEY = MATERIAL_KEY + WIREFRAME_KEY
|
public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY
|
||||||
|
|
||||||
val descriptor by lazy {
|
public val descriptor: NodeDescriptor by lazy {
|
||||||
//must be lazy to avoid initialization bug
|
//must be lazy to avoid initialization bug
|
||||||
NodeDescriptor {
|
NodeDescriptor {
|
||||||
value(COLOR_KEY) {
|
value(COLOR_KEY) {
|
||||||
@ -77,18 +78,18 @@ class SolidMaterial : Scheme() {
|
|||||||
/**
|
/**
|
||||||
* Set color as web-color
|
* Set color as web-color
|
||||||
*/
|
*/
|
||||||
fun Solid.color(webColor: String) {
|
public fun Solid.color(webColor: String) {
|
||||||
setItem(MATERIAL_COLOR_KEY, webColor.asValue())
|
setItem(MATERIAL_COLOR_KEY, webColor.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set color as integer
|
* Set color as integer
|
||||||
*/
|
*/
|
||||||
fun Solid.color(rgb: Int) {
|
public fun Solid.color(rgb: Int) {
|
||||||
setItem(MATERIAL_COLOR_KEY, rgb.asValue())
|
setItem(MATERIAL_COLOR_KEY, rgb.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Solid.color(r: UByte, g: UByte, b: UByte) = setItem(
|
public fun Solid.color(r: UByte, g: UByte, b: UByte): Unit = setItem(
|
||||||
MATERIAL_COLOR_KEY,
|
MATERIAL_COLOR_KEY,
|
||||||
Colors.rgbToMeta(r, g, b)
|
Colors.rgbToMeta(r, g, b)
|
||||||
)
|
)
|
||||||
@ -96,16 +97,16 @@ fun Solid.color(r: UByte, g: UByte, b: UByte) = setItem(
|
|||||||
/**
|
/**
|
||||||
* Web colors representation of the color in `#rrggbb` format or HTML name
|
* Web colors representation of the color in `#rrggbb` format or HTML name
|
||||||
*/
|
*/
|
||||||
var Solid.color: String?
|
public var Solid.color: String?
|
||||||
get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
||||||
set(value) {
|
set(value) {
|
||||||
setItem(MATERIAL_COLOR_KEY, value?.asValue())
|
setItem(MATERIAL_COLOR_KEY, value?.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
val Solid.material: SolidMaterial?
|
public val Solid.material: SolidMaterial?
|
||||||
get() = getItem(MATERIAL_KEY).node?.let { SolidMaterial.wrap(it) }
|
get() = getItem(MATERIAL_KEY).node?.let { SolidMaterial.wrap(it) }
|
||||||
|
|
||||||
fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
||||||
val node = config[MATERIAL_KEY].node
|
val node = config[MATERIAL_KEY].node
|
||||||
if (node != null) {
|
if (node != null) {
|
||||||
SolidMaterial.update(node, builder)
|
SolidMaterial.update(node, builder)
|
||||||
@ -114,7 +115,7 @@ fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var Solid.opacity: Double?
|
public var Solid.opacity: Double?
|
||||||
get() = getItem(MATERIAL_OPACITY_KEY).double
|
get() = getItem(MATERIAL_OPACITY_KEY).double
|
||||||
set(value) {
|
set(value) {
|
||||||
setItem(MATERIAL_OPACITY_KEY, value?.asValue())
|
setItem(MATERIAL_OPACITY_KEY, value?.asValue())
|
||||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -15,12 +16,12 @@ import kotlin.math.sin
|
|||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.sphere")
|
@SerialName("solid.sphere")
|
||||||
class Sphere(
|
public class Sphere(
|
||||||
var radius: Float,
|
public var radius: Float,
|
||||||
var phiStart: Float = 0f,
|
public var phiStart: Float = 0f,
|
||||||
var phi: Float = PI2,
|
public var phi: Float = PI2,
|
||||||
var thetaStart: Float = 0f,
|
public var thetaStart: Float = 0f,
|
||||||
var theta: Float = PI.toFloat()
|
public var theta: Float = PI.toFloat()
|
||||||
) : AbstractVision(), GeometrySolid {
|
) : AbstractVision(), GeometrySolid {
|
||||||
|
|
||||||
override var properties: Config? = null
|
override var properties: Config? = null
|
||||||
@ -60,13 +61,13 @@ class Sphere(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.sphere(
|
public inline fun VisionContainerBuilder<Solid>.sphere(
|
||||||
radius: Number,
|
radius: Number,
|
||||||
phi: Number = 2 * PI,
|
phi: Number = 2 * PI,
|
||||||
theta: Number = PI,
|
theta: Number = PI,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
action: Sphere.() -> Unit = {}
|
action: Sphere.() -> Unit = {}
|
||||||
) = Sphere(
|
): Sphere = Sphere(
|
||||||
radius.toFloat(),
|
radius.toFloat(),
|
||||||
phi = phi.toFloat(),
|
phi = phi.toFloat(),
|
||||||
theta = theta.toFloat()
|
theta = theta.toFloat()
|
||||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
|||||||
import hep.dataforge.meta.Config
|
import hep.dataforge.meta.Config
|
||||||
import hep.dataforge.vision.AbstractVision
|
import hep.dataforge.vision.AbstractVision
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
|
import hep.dataforge.vision.VisionContainerBuilder
|
||||||
import hep.dataforge.vision.set
|
import hep.dataforge.vision.set
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
@ -18,12 +19,12 @@ import kotlin.math.sin
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.tube")
|
@SerialName("solid.tube")
|
||||||
class Tube(
|
public class Tube(
|
||||||
var radius: Float,
|
public var radius: Float,
|
||||||
var height: Float,
|
public var height: Float,
|
||||||
var innerRadius: Float = 0f,
|
public var innerRadius: Float = 0f,
|
||||||
var startAngle: Float = 0f,
|
public var startAngle: Float = 0f,
|
||||||
var angle: Float = PI2
|
public var angle: Float = PI2
|
||||||
) : AbstractVision(), GeometrySolid {
|
) : AbstractVision(), GeometrySolid {
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
@ -129,7 +130,7 @@ class Tube(
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
inline fun MutableVisionGroup.tube(
|
public inline fun VisionContainerBuilder<Solid>.tube(
|
||||||
r: Number,
|
r: Number,
|
||||||
height: Number,
|
height: Number,
|
||||||
innerRadius: Number = 0f,
|
innerRadius: Number = 0f,
|
||||||
|
@ -1,47 +1,48 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.meta.MetaBuilder
|
||||||
import hep.dataforge.meta.get
|
import hep.dataforge.meta.get
|
||||||
import hep.dataforge.meta.number
|
import hep.dataforge.meta.number
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
object World {
|
public object World {
|
||||||
val ZERO = Point3D(0.0, 0.0, 0.0)
|
public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0)
|
||||||
val ONE = Point3D(1.0, 1.0, 1.0)
|
public val ONE: Point3D = Point3D(1.0, 1.0, 1.0)
|
||||||
}
|
}
|
||||||
|
|
||||||
const val PI2: Float = 2 * PI.toFloat()
|
public const val PI2: Float = 2 * PI.toFloat()
|
||||||
|
|
||||||
expect class Point2D(x: Number, y: Number) {
|
public expect class Point2D(x: Number, y: Number) {
|
||||||
var x: Double
|
public var x: Double
|
||||||
var y: Double
|
public var y: Double
|
||||||
}
|
}
|
||||||
|
|
||||||
operator fun Point2D.component1() = x
|
public operator fun Point2D.component1(): Double = x
|
||||||
operator fun Point2D.component2() = y
|
public operator fun Point2D.component2(): Double = y
|
||||||
|
|
||||||
fun Point2D.toMeta() = Meta {
|
public fun Point2D.toMeta(): Meta = Meta {
|
||||||
Solid.X_KEY put x
|
Solid.X_KEY put x
|
||||||
Solid.Y_KEY put y
|
Solid.Y_KEY put y
|
||||||
}
|
}
|
||||||
|
|
||||||
fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0)
|
internal fun Meta.point2D(): Point2D = Point2D(this["x"].number ?: 0, this["y"].number ?: 0)
|
||||||
|
|
||||||
expect class Point3D(x: Number, y: Number, z: Number) {
|
public expect class Point3D(x: Number, y: Number, z: Number) {
|
||||||
var x: Double
|
public var x: Double
|
||||||
var y: Double
|
public var y: Double
|
||||||
var z: Double
|
public var z: Double
|
||||||
}
|
}
|
||||||
|
|
||||||
expect operator fun Point3D.plus(other: Point3D): Point3D
|
public expect operator fun Point3D.plus(other: Point3D): Point3D
|
||||||
|
|
||||||
operator fun Point3D.component1() = x
|
public operator fun Point3D.component1(): Double = x
|
||||||
operator fun Point3D.component2() = y
|
public operator fun Point3D.component2(): Double = y
|
||||||
operator fun Point3D.component3() = z
|
public operator fun Point3D.component3(): Double = z
|
||||||
|
|
||||||
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
internal fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
|
||||||
|
|
||||||
fun Point3D.toMeta() = Meta {
|
public fun Point3D.toMeta(): MetaBuilder = Meta {
|
||||||
Solid.X_KEY put x
|
Solid.X_KEY put x
|
||||||
Solid.Y_KEY put y
|
Solid.Y_KEY put y
|
||||||
Solid.Z_KEY put z
|
Solid.Z_KEY put z
|
||||||
|
@ -2,6 +2,7 @@ package hep.dataforge.vision.solid
|
|||||||
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.double
|
import hep.dataforge.meta.double
|
||||||
|
import hep.dataforge.meta.transformations.MetaConverter.Companion.double
|
||||||
import hep.dataforge.names.NameToken
|
import hep.dataforge.names.NameToken
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
@ -10,34 +11,19 @@ import kotlinx.serialization.*
|
|||||||
import kotlinx.serialization.builtins.MapSerializer
|
import kotlinx.serialization.builtins.MapSerializer
|
||||||
import kotlinx.serialization.builtins.nullable
|
import kotlinx.serialization.builtins.nullable
|
||||||
import kotlinx.serialization.builtins.serializer
|
import kotlinx.serialization.builtins.serializer
|
||||||
|
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
|
import kotlinx.serialization.descriptors.buildClassSerialDescriptor
|
||||||
|
import kotlinx.serialization.descriptors.element
|
||||||
|
import kotlinx.serialization.encoding.*
|
||||||
|
|
||||||
inline fun <R> Decoder.decodeStructure(
|
|
||||||
desc: SerialDescriptor,
|
|
||||||
vararg typeParams: KSerializer<*> = emptyArray(),
|
|
||||||
crossinline block: CompositeDecoder.() -> R
|
|
||||||
): R {
|
|
||||||
val decoder = beginStructure(desc, *typeParams)
|
|
||||||
val res = decoder.block()
|
|
||||||
decoder.endStructure(desc)
|
|
||||||
return res
|
|
||||||
}
|
|
||||||
|
|
||||||
inline fun Encoder.encodeStructure(
|
|
||||||
desc: SerialDescriptor,
|
|
||||||
vararg typeParams: KSerializer<*> = emptyArray(),
|
|
||||||
block: CompositeEncoder.() -> Unit
|
|
||||||
) {
|
|
||||||
val encoder = beginStructure(desc, *typeParams)
|
|
||||||
encoder.block()
|
|
||||||
encoder.endStructure(desc)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Serializer(Point3D::class)
|
@Serializer(Point3D::class)
|
||||||
object Point3DSerializer : KSerializer<Point3D> {
|
public object Point3DSerializer : KSerializer<Point3D> {
|
||||||
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
||||||
double("x", true)
|
element<Double>("x")
|
||||||
double("y", true)
|
element<Double>("y")
|
||||||
double("z", true)
|
element<Double>("z")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): Point3D {
|
override fun deserialize(decoder: Decoder): Point3D {
|
||||||
@ -47,7 +33,7 @@ object Point3DSerializer : KSerializer<Point3D> {
|
|||||||
decoder.decodeStructure(descriptor) {
|
decoder.decodeStructure(descriptor) {
|
||||||
loop@ while (true) {
|
loop@ while (true) {
|
||||||
when (val i = decodeElementIndex(descriptor)) {
|
when (val i = decodeElementIndex(descriptor)) {
|
||||||
CompositeDecoder.READ_DONE -> break@loop
|
CompositeDecoder.DECODE_DONE -> break@loop
|
||||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||||
2 -> z = decodeNullableSerializableElement(descriptor, 2, Double.serializer().nullable) ?: 0.0
|
2 -> z = decodeNullableSerializableElement(descriptor, 2, Double.serializer().nullable) ?: 0.0
|
||||||
@ -67,11 +53,12 @@ object Point3DSerializer : KSerializer<Point3D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Serializer(Point2D::class)
|
@Serializer(Point2D::class)
|
||||||
object Point2DSerializer : KSerializer<Point2D> {
|
public object Point2DSerializer : KSerializer<Point2D> {
|
||||||
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
||||||
double("x", true)
|
element<Double>("x")
|
||||||
double("y", true)
|
element<Double>("y")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun deserialize(decoder: Decoder): Point2D {
|
override fun deserialize(decoder: Decoder): Point2D {
|
||||||
@ -80,7 +67,7 @@ object Point2DSerializer : KSerializer<Point2D> {
|
|||||||
decoder.decodeStructure(descriptor) {
|
decoder.decodeStructure(descriptor) {
|
||||||
loop@ while (true) {
|
loop@ while (true) {
|
||||||
when (val i = decodeElementIndex(descriptor)) {
|
when (val i = decodeElementIndex(descriptor)) {
|
||||||
CompositeDecoder.READ_DONE -> break@loop
|
CompositeDecoder.DECODE_DONE -> break@loop
|
||||||
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
0 -> x = decodeNullableSerializableElement(descriptor, 0, Double.serializer().nullable) ?: 0.0
|
||||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||||
else -> throw SerializationException("Unknown index $i")
|
else -> throw SerializationException("Unknown index $i")
|
||||||
@ -98,6 +85,7 @@ object Point2DSerializer : KSerializer<Point2D> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Serializer(MutableVisionGroup::class)
|
@Serializer(MutableVisionGroup::class)
|
||||||
internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
||||||
|
|
||||||
@ -120,10 +108,10 @@ internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
fun Vision.stringify(): String = SolidManager.jsonForSolids.stringify(Vision.serializer(), this)
|
public fun Vision.encodeToString(): String = SolidManager.jsonForSolids.encodeToString(Vision.serializer(), this)
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
fun Vision.Companion.parseJson(str: String) = SolidManager.jsonForSolids.parse(serializer(), str).also {
|
public fun Vision.Companion.decodeFromString(str: String): Vision = SolidManager.jsonForSolids.decodeFromString(serializer(), str).also {
|
||||||
if(it is VisionGroup){
|
if(it is VisionGroup){
|
||||||
it.attachChildren()
|
it.attachChildren()
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,13 @@ package hep.dataforge.vision.solid.specifications
|
|||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
|
||||||
class Axes : Scheme() {
|
public class Axes : Scheme() {
|
||||||
var visible by boolean(!config.isEmpty())
|
public var visible: Boolean by boolean(!config.isEmpty())
|
||||||
var size by double(AXIS_SIZE)
|
public var size: Double by double(AXIS_SIZE)
|
||||||
var width by double(AXIS_WIDTH)
|
public var width: Double by double(AXIS_WIDTH)
|
||||||
|
|
||||||
companion object : SchemeSpec<Axes>(::Axes) {
|
public companion object : SchemeSpec<Axes>(::Axes) {
|
||||||
const val AXIS_SIZE = 1000.0
|
public const val AXIS_SIZE: Double = 1000.0
|
||||||
const val AXIS_WIDTH = 3.0
|
public const val AXIS_WIDTH: Double = 3.0
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,24 +6,24 @@ import hep.dataforge.meta.double
|
|||||||
import hep.dataforge.meta.int
|
import hep.dataforge.meta.int
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
class Camera : Scheme() {
|
public class Camera : Scheme() {
|
||||||
var fov by int(FIELD_OF_VIEW)
|
public var fov: Int by int(FIELD_OF_VIEW)
|
||||||
|
|
||||||
//var aspect by double(1.0)
|
//var aspect by double(1.0)
|
||||||
var nearClip by double(NEAR_CLIP)
|
public var nearClip: Double by double(NEAR_CLIP)
|
||||||
var farClip by double(FAR_CLIP)
|
public var farClip: Double by double(FAR_CLIP)
|
||||||
|
|
||||||
var distance by double(INITIAL_DISTANCE)
|
public var distance: Double by double(INITIAL_DISTANCE)
|
||||||
var azimuth by double(INITIAL_AZIMUTH)
|
public var azimuth: Double by double(INITIAL_AZIMUTH)
|
||||||
var latitude by double(INITIAL_LATITUDE)
|
public var latitude: Double by double(INITIAL_LATITUDE)
|
||||||
val zenith: Double get() = PI / 2 - latitude
|
public val zenith: Double get() = PI / 2 - latitude
|
||||||
|
|
||||||
companion object : SchemeSpec<Camera>(::Camera) {
|
public companion object : SchemeSpec<Camera>(::Camera) {
|
||||||
const val INITIAL_DISTANCE = 300.0
|
public const val INITIAL_DISTANCE: Double = 300.0
|
||||||
const val INITIAL_AZIMUTH = 0.0
|
public const val INITIAL_AZIMUTH: Double = 0.0
|
||||||
const val INITIAL_LATITUDE = PI / 6
|
public const val INITIAL_LATITUDE: Double = PI / 6
|
||||||
const val NEAR_CLIP = 0.1
|
public const val NEAR_CLIP: Double = 0.1
|
||||||
const val FAR_CLIP = 10000.0
|
public const val FAR_CLIP: Double = 10000.0
|
||||||
const val FIELD_OF_VIEW = 75
|
public const val FIELD_OF_VIEW: Int = 75
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -5,11 +5,11 @@ import hep.dataforge.meta.SchemeSpec
|
|||||||
import hep.dataforge.meta.int
|
import hep.dataforge.meta.int
|
||||||
import hep.dataforge.meta.spec
|
import hep.dataforge.meta.spec
|
||||||
|
|
||||||
class Canvas3DOptions : Scheme() {
|
public class Canvas3DOptions : Scheme() {
|
||||||
var axes by spec(Axes, Axes.empty())
|
public var axes: Axes by spec(Axes, Axes.empty())
|
||||||
var camera by spec(Camera, Camera.empty())
|
public var camera: Camera by spec(Camera, Camera.empty())
|
||||||
var controls by spec(Controls, Controls.empty())
|
public var controls: Controls by spec(Controls, Controls.empty())
|
||||||
var minSize by int(300)
|
public var minSize: Int by int(300)
|
||||||
|
|
||||||
companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions)
|
public companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions)
|
||||||
}
|
}
|
@ -1,5 +1,6 @@
|
|||||||
package hep.dataforge.vision.solid.transform
|
package hep.dataforge.vision.solid.transform
|
||||||
|
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.update
|
import hep.dataforge.meta.update
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
@ -7,6 +8,7 @@ import hep.dataforge.vision.Vision
|
|||||||
import hep.dataforge.vision.VisionGroup
|
import hep.dataforge.vision.VisionGroup
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||||
return child.apply {
|
return child.apply {
|
||||||
|
|
||||||
@ -32,6 +34,7 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
|
object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
|
||||||
|
|
||||||
override fun SolidGroup.transformInPlace() {
|
override fun SolidGroup.transformInPlace() {
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package hep.dataforge.vision.solid.transform
|
package hep.dataforge.vision.solid.transform
|
||||||
|
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vision.MutableVisionGroup
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
@ -7,6 +8,7 @@ import hep.dataforge.vision.VisionGroup
|
|||||||
import hep.dataforge.vision.solid.Proxy
|
import hep.dataforge.vision.solid.Proxy
|
||||||
import hep.dataforge.vision.solid.SolidGroup
|
import hep.dataforge.vision.solid.SolidGroup
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
object UnRef : VisualTreeTransform<SolidGroup>() {
|
object UnRef : VisualTreeTransform<SolidGroup>() {
|
||||||
private fun VisionGroup.countRefs(): Map<Name, Int> {
|
private fun VisionGroup.countRefs(): Map<Name, Int> {
|
||||||
return children.values.fold(HashMap()) { reducer, obj ->
|
return children.values.fold(HashMap()) { reducer, obj ->
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
import hep.dataforge.meta.*
|
import hep.dataforge.meta.*
|
||||||
|
import kotlinx.serialization.json.toJson
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -24,7 +25,7 @@ class ConvexTest {
|
|||||||
|
|
||||||
val convex = group.children.values.first() as Convex
|
val convex = group.children.values.first() as Convex
|
||||||
|
|
||||||
val json = SolidManager.jsonForSolids.toJson(Convex.serializer(), convex)
|
val json = SolidManager.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex)
|
||||||
val meta = json.toMetaItem().node!!
|
val meta = json.toMetaItem().node!!
|
||||||
|
|
||||||
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
||||||
|
@ -1,11 +1,26 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
|
import hep.dataforge.vision.MutableVisionGroup
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.get
|
import hep.dataforge.vision.get
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create and attach new proxied group
|
||||||
|
*/
|
||||||
|
fun SolidGroup.proxyGroup(
|
||||||
|
name: String,
|
||||||
|
templateName: Name = name.toName(),
|
||||||
|
block: MutableVisionGroup.() -> Unit
|
||||||
|
): Proxy {
|
||||||
|
val group = SolidGroup().apply(block)
|
||||||
|
return proxy(name, group, templateName)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
class SerializationTest {
|
class SerializationTest {
|
||||||
@Test
|
@Test
|
||||||
fun testCubeSerialization() {
|
fun testCubeSerialization() {
|
||||||
@ -14,9 +29,9 @@ class SerializationTest {
|
|||||||
x = 100
|
x = 100
|
||||||
z = -100
|
z = -100
|
||||||
}
|
}
|
||||||
val string = cube.stringify()
|
val string = cube.encodeToString()
|
||||||
println(string)
|
println(string)
|
||||||
val newCube = Vision.parseJson(string)
|
val newCube = Vision.decodeFromString(string)
|
||||||
assertEquals(cube.config, newCube.config)
|
assertEquals(cube.config, newCube.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -35,9 +50,9 @@ class SerializationTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val string = group.stringify()
|
val string = group.encodeToString()
|
||||||
println(string)
|
println(string)
|
||||||
val reconstructed = SolidGroup.parseJson(string)
|
val reconstructed = SolidGroup.decodeFromString(string)
|
||||||
assertEquals(group["cube"]?.config, reconstructed["cube"]?.config)
|
assertEquals(group["cube"]?.config, reconstructed["cube"]?.config)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,10 +5,10 @@ import info.laht.threekt.math.Vector2
|
|||||||
import info.laht.threekt.math.Vector3
|
import info.laht.threekt.math.Vector3
|
||||||
import info.laht.threekt.math.plus
|
import info.laht.threekt.math.plus
|
||||||
|
|
||||||
actual typealias Point2D = Vector2
|
public actual typealias Point2D = Vector2
|
||||||
|
|
||||||
actual typealias Point3D = Vector3
|
public actual typealias Point3D = Vector3
|
||||||
|
|
||||||
actual operator fun Point3D.plus(other: Point3D): Point3D {
|
public actual operator fun Point3D.plus(other: Point3D): Point3D {
|
||||||
return this.plus(other)
|
return this.plus(other)
|
||||||
}
|
}
|
@ -8,6 +8,7 @@ import hep.dataforge.vision.solid.*
|
|||||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||||
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
||||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
||||||
|
import hep.dataforge.vision.visible
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
@ -54,7 +55,7 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
|||||||
) {
|
) {
|
||||||
//update position of mesh using this object
|
//update position of mesh using this object
|
||||||
updatePosition(source)
|
updatePosition(source)
|
||||||
} else if (propertyName == Solid.VISIBLE_KEY) {
|
} else if (propertyName == Vision.VISIBLE_KEY) {
|
||||||
visible = source.visible ?: true
|
visible = source.visible ?: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ import hep.dataforge.meta.Meta
|
|||||||
import hep.dataforge.names.*
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.solid.*
|
||||||
|
import hep.dataforge.vision.visible
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
@ -30,7 +31,7 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? {
|
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? {
|
||||||
return (objectFactories[type]
|
return (objectFactories[type]
|
||||||
?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type })
|
?: context.gather<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type })
|
||||||
as ThreeFactory<Solid>?
|
as ThreeFactory<Solid>?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,7 +64,7 @@ class ThreePlugin : AbstractPlugin() {
|
|||||||
) {
|
) {
|
||||||
//update position of mesh using this object
|
//update position of mesh using this object
|
||||||
updatePosition(obj)
|
updatePosition(obj)
|
||||||
} else if (name == Solid.VISIBLE_KEY) {
|
} else if (name == Vision.VISIBLE_KEY) {
|
||||||
visible = obj.visible ?: true
|
visible = obj.visible ?: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -123,28 +124,28 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D {
|
|||||||
return when {
|
return when {
|
||||||
name.isEmpty() -> this
|
name.isEmpty() -> this
|
||||||
name.length == 1 -> {
|
name.length == 1 -> {
|
||||||
val token = name.first()!!
|
val token = name.tokens.first()
|
||||||
children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group ->
|
children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group ->
|
||||||
group.name = token.toString()
|
group.name = token.toString()
|
||||||
this.add(group)
|
this.add(group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else -> getOrCreateGroup(name.first()!!.asName()).getOrCreateGroup(name.cutFirst())
|
else -> getOrCreateGroup(name.tokens.first().asName()).getOrCreateGroup(name.cutFirst())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal operator fun Object3D.set(name: Name, obj: Object3D) {
|
internal operator fun Object3D.set(name: Name, obj: Object3D) {
|
||||||
when (name.length) {
|
when (name.length) {
|
||||||
0 -> error("Can't set object with an empty name")
|
0 -> error("Can't set object with an empty name")
|
||||||
1 -> set(name.first()!!, obj)
|
1 -> set(name.tokens.first(), obj)
|
||||||
else -> getOrCreateGroup(name.cutLast())[name.last()!!] = obj
|
else -> getOrCreateGroup(name.cutLast())[name.tokens.last()] = obj
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal fun Object3D.findChild(name: Name): Object3D? {
|
internal fun Object3D.findChild(name: Name): Object3D? {
|
||||||
return when {
|
return when {
|
||||||
name.isEmpty() -> this
|
name.isEmpty() -> this
|
||||||
name.length == 1 -> this.children.find { it.name == name.first()!!.toString() }
|
name.length == 1 -> this.children.find { it.name == name.tokens.first().toString() }
|
||||||
else -> findChild(name.first()!!.asName())?.findChild(name.cutFirst())
|
else -> findChild(name.tokens.first().asName())?.findChild(name.cutFirst())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,5 +1,7 @@
|
|||||||
package hep.dataforge.vision.solid.three
|
package hep.dataforge.vision.solid.three
|
||||||
|
|
||||||
|
import hep.dataforge.names.cutFirst
|
||||||
|
import hep.dataforge.names.firstOrNull
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.solid.Proxy
|
import hep.dataforge.vision.solid.Proxy
|
||||||
import hep.dataforge.vision.solid.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
|
import hep.dataforge.vision.solid.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
|
||||||
@ -42,8 +44,8 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
obj.onPropertyChange(this) { name ->
|
obj.onPropertyChange(this) { name ->
|
||||||
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
|
if (name.firstOrNull()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
|
||||||
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||||
val propertyName = name.cutFirst()
|
val propertyName = name.cutFirst()
|
||||||
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
|
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
|
||||||
val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found")
|
val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||||
|
@ -38,7 +38,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
|||||||
div("row") {
|
div("row") {
|
||||||
div("col-2") {
|
div("col-2") {
|
||||||
label("checkbox-inline") {
|
label("checkbox-inline") {
|
||||||
input(type = InputType.checkBox){
|
input(type = InputType.checkBox) {
|
||||||
attrs {
|
attrs {
|
||||||
defaultChecked = canvas.axes.visible
|
defaultChecked = canvas.axes.visible
|
||||||
onChangeFunction = {
|
onChangeFunction = {
|
||||||
@ -55,7 +55,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
|||||||
attrs {
|
attrs {
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
val json = (canvas.content as? SolidGroup)?.let { group ->
|
val json = (canvas.content as? SolidGroup)?.let { group ->
|
||||||
SolidManager.jsonForSolids.stringify(
|
SolidManager.jsonForSolids.encodeToString(
|
||||||
SolidGroup.serializer(),
|
SolidGroup.serializer(),
|
||||||
group
|
group
|
||||||
)
|
)
|
||||||
@ -76,7 +76,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
|||||||
(0..11).forEach { layer ->
|
(0..11).forEach { layer ->
|
||||||
div("col-1") {
|
div("col-1") {
|
||||||
label { +layer.toString() }
|
label { +layer.toString() }
|
||||||
input(type = InputType.checkBox){
|
input(type = InputType.checkBox) {
|
||||||
attrs {
|
attrs {
|
||||||
if (layer == 0) {
|
if (layer == 0) {
|
||||||
defaultChecked = true
|
defaultChecked = true
|
||||||
@ -119,7 +119,7 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
|
|||||||
+"Export"
|
+"Export"
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
val json = (canvas.content as? SolidGroup)?.let { group ->
|
val json = (canvas.content as? SolidGroup)?.let { group ->
|
||||||
SolidManager.jsonForSolids.stringify(
|
SolidManager.jsonForSolids.encodeToString(
|
||||||
SolidGroup.serializer(),
|
SolidGroup.serializer(),
|
||||||
group
|
group
|
||||||
)
|
)
|
||||||
|
@ -38,7 +38,7 @@ class FX3DPlugin : AbstractPlugin() {
|
|||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
private fun findObjectFactory(type: KClass<out Solid>): FX3DFactory<Solid>? {
|
private fun findObjectFactory(type: KClass<out Solid>): FX3DFactory<Solid>? {
|
||||||
return (objectFactories[type] ?: context.content<FX3DFactory<*>>(TYPE).values.find { it.type == type })
|
return (objectFactories[type] ?: context.gather<FX3DFactory<*>>(TYPE).values.find { it.type == type })
|
||||||
as FX3DFactory<Solid>?
|
as FX3DFactory<Solid>?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
package hep.dataforge.vision.solid.fx
|
package hep.dataforge.vision.solid.fx
|
||||||
|
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.*
|
||||||
import hep.dataforge.names.isEmpty
|
|
||||||
import hep.dataforge.names.toName
|
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.solid.Proxy
|
import hep.dataforge.vision.solid.Proxy
|
||||||
import javafx.scene.Group
|
import javafx.scene.Group
|
||||||
@ -17,8 +15,8 @@ class FXProxyFactory(val plugin: FX3DPlugin) : FX3DFactory<Proxy> {
|
|||||||
val node = plugin.buildNode(prototype)
|
val node = plugin.buildNode(prototype)
|
||||||
|
|
||||||
obj.onPropertyChange(this) { name->
|
obj.onPropertyChange(this) { name->
|
||||||
if (name.first()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) {
|
if (name.firstOrNull()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) {
|
||||||
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||||
val propertyName = name.cutFirst()
|
val propertyName = name.cutFirst()
|
||||||
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
|
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
|
||||||
val child = node.findChild(childName) ?: error("Object child with name '$childName' not found")
|
val child = node.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||||
@ -35,7 +33,7 @@ private fun Node.findChild(name: Name): Node? {
|
|||||||
} else {
|
} else {
|
||||||
(this as? Group)
|
(this as? Group)
|
||||||
?.children
|
?.children
|
||||||
?.find { it.properties["name"] as String == name.first()?.toString() }
|
?.find { it.properties["name"] as String == name.firstOrNull()?.toString() }
|
||||||
?.findChild(name.cutFirst())
|
?.findChild(name.cutFirst())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,205 +1,208 @@
|
|||||||
package hep.dataforge.vision.solid
|
//package hep.dataforge.vision.solid
|
||||||
|
//
|
||||||
import hep.dataforge.meta.JSON_PRETTY
|
//import hep.dataforge.meta.JSON_PRETTY
|
||||||
import kotlinx.serialization.*
|
//import kotlinx.serialization.*
|
||||||
import kotlinx.serialization.json.*
|
//import kotlinx.serialization.descriptors.PrimitiveKind
|
||||||
import kotlinx.serialization.modules.SerialModule
|
//import kotlinx.serialization.descriptors.SerialDescriptor
|
||||||
import kotlinx.serialization.modules.SerialModuleCollector
|
//import kotlinx.serialization.descriptors.StructureKind
|
||||||
import kotlin.reflect.KClass
|
//import kotlinx.serialization.descriptors.UnionKind
|
||||||
|
//import kotlinx.serialization.json.*
|
||||||
private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
//import kotlinx.serialization.modules.SerialModule
|
||||||
StructureKind.LIST -> "array"
|
//import kotlin.reflect.KClass
|
||||||
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
//
|
||||||
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
//private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
||||||
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
// StructureKind.LIST -> "array"
|
||||||
PrimitiveKind.BOOLEAN -> "boolean"
|
// PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||||
else -> "object"
|
// PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||||
}
|
// PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||||
|
// PrimitiveKind.BOOLEAN -> "boolean"
|
||||||
private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid")
|
// else -> "object"
|
||||||
|
//}
|
||||||
private const val definitionNode = "\$defs"
|
//
|
||||||
|
//private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid")
|
||||||
private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
//
|
||||||
val list = ArrayList<SerialDescriptor>()
|
//private const val definitionNode = "\$defs"
|
||||||
fun send(descriptor: SerialDescriptor) = list.add(descriptor)
|
//
|
||||||
|
//private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
||||||
val enumerator = object : SerialModuleCollector {
|
// val list = ArrayList<SerialDescriptor>()
|
||||||
override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
|
// fun send(descriptor: SerialDescriptor) = list.add(descriptor)
|
||||||
if (kClass == type) {
|
//
|
||||||
send(serializer.descriptor)
|
// val enumerator = object : SerialModuleCollector {
|
||||||
}
|
// override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
|
||||||
}
|
// if (kClass == type) {
|
||||||
|
// send(serializer.descriptor)
|
||||||
override fun <Base : Any, Sub : Base> polymorphic(
|
// }
|
||||||
baseClass: KClass<Base>,
|
// }
|
||||||
actualClass: KClass<Sub>,
|
//
|
||||||
actualSerializer: KSerializer<Sub>
|
// override fun <Base : Any, Sub : Base> polymorphic(
|
||||||
) {
|
// baseClass: KClass<Base>,
|
||||||
if (baseClass == type) {
|
// actualClass: KClass<Sub>,
|
||||||
send(actualSerializer.descriptor)
|
// actualSerializer: KSerializer<Sub>
|
||||||
}
|
// ) {
|
||||||
}
|
// if (baseClass == type) {
|
||||||
|
// send(actualSerializer.descriptor)
|
||||||
}
|
// }
|
||||||
dumpTo(enumerator)
|
// }
|
||||||
return list.asSequence()
|
//
|
||||||
}
|
// }
|
||||||
|
// dumpTo(enumerator)
|
||||||
/**
|
// return list.asSequence()
|
||||||
* Creates an [JsonObject] which contains Json Schema of given [descriptor].
|
//}
|
||||||
*
|
//
|
||||||
* Schema can contain following fields:
|
///**
|
||||||
* `description`, `type` for all descriptors;
|
// * Creates an [JsonObject] which contains Json Schema of given [descriptor].
|
||||||
* `properties` and `required` for objects;
|
// *
|
||||||
* `enum` for enums;
|
// * Schema can contain following fields:
|
||||||
* `items` for arrays.
|
// * `description`, `type` for all descriptors;
|
||||||
*
|
// * `properties` and `required` for objects;
|
||||||
* User can modify this schema to add additional validation keywords
|
// * `enum` for enums;
|
||||||
* (as per [https://json-schema.org/latest/json-schema-validation.html])
|
// * `items` for arrays.
|
||||||
* if they want.
|
// *
|
||||||
*/
|
// * User can modify this schema to add additional validation keywords
|
||||||
private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
// * (as per [https://json-schema.org/latest/json-schema-validation.html])
|
||||||
|
// * if they want.
|
||||||
if (descriptor.serialName in arrayOf(
|
// */
|
||||||
"hep.dataforge.vision.solid.Point3D",
|
//private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
||||||
"hep.dataforge.vision.solid.Point3D?",
|
//
|
||||||
"hep.dataforge.vision.solid.Point2D",
|
// if (descriptor.serialName in arrayOf(
|
||||||
"hep.dataforge.vision.solid.Point2D?",
|
// "hep.dataforge.vision.solid.Point3D",
|
||||||
"hep.dataforge.meta.Meta",
|
// "hep.dataforge.vision.solid.Point3D?",
|
||||||
"hep.dataforge.meta.Meta?"
|
// "hep.dataforge.vision.solid.Point2D",
|
||||||
)
|
// "hep.dataforge.vision.solid.Point2D?",
|
||||||
) return json {
|
// "hep.dataforge.meta.Meta",
|
||||||
"\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}"
|
// "hep.dataforge.meta.Meta?"
|
||||||
}
|
// )
|
||||||
|
// ) return json {
|
||||||
|
// "\$ref" to "#/$definitionNode/${descriptor.serialName.replace("?", "")}"
|
||||||
val properties: MutableMap<String, JsonObject> = mutableMapOf()
|
// }
|
||||||
val requiredProperties: MutableSet<String> = mutableSetOf()
|
//
|
||||||
val isEnum = descriptor.kind == UnionKind.ENUM_KIND
|
//
|
||||||
val isPolymorphic = descriptor.kind is PolymorphicKind
|
// val properties: MutableMap<String, JsonObject> = mutableMapOf()
|
||||||
|
// val requiredProperties: MutableSet<String> = mutableSetOf()
|
||||||
|
// val isEnum = descriptor.kind == UnionKind.ENUM_KIND
|
||||||
if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
// val isPolymorphic = descriptor.kind is PolymorphicKind
|
||||||
val elementName = descriptor.getElementName(index)
|
//
|
||||||
|
//
|
||||||
val elementSchema = when (elementName) {
|
// if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
||||||
"properties" -> json {
|
// val elementName = descriptor.getElementName(index)
|
||||||
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
//
|
||||||
}
|
// val elementSchema = when (elementName) {
|
||||||
"first", "second" -> json {
|
// "properties" -> buildJsonObject {
|
||||||
"\$ref" to "#/$definitionNode/children"
|
// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta")
|
||||||
}
|
// }
|
||||||
"styleSheet" -> json {
|
// "first", "second" -> buildJsonObject {
|
||||||
"type" to "object"
|
// put("\$ref", "#/$definitionNode/children")
|
||||||
"additionalProperties" to json {
|
// }
|
||||||
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
// "styleSheet" -> buildJsonObject {
|
||||||
}
|
// put("type", "object")
|
||||||
}
|
// put("additionalProperties", buildJsonObject {
|
||||||
in arrayOf("children", "prototypes") -> json {
|
// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta")
|
||||||
"type" to "object"
|
// })
|
||||||
"additionalProperties" to json {
|
// }
|
||||||
"\$ref" to "#/$definitionNode/children"
|
// in arrayOf("children", "prototypes") -> buildJsonObject {
|
||||||
}
|
// put("type", "object")
|
||||||
}
|
// put("additionalProperties", buildJsonObject {
|
||||||
else -> jsonSchema(child, context)
|
// put("\$ref", "#/$definitionNode/children")
|
||||||
}
|
// })
|
||||||
properties[elementName] = elementSchema
|
// }
|
||||||
|
// else -> jsonSchema(child, context)
|
||||||
if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
// }
|
||||||
}
|
// properties[elementName] = elementSchema
|
||||||
|
//
|
||||||
val jsonType = descriptor.getJsonType()
|
// if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
||||||
val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
// }
|
||||||
"description" to JsonLiteral(descriptor.serialName),
|
//
|
||||||
"type" to JsonLiteral(jsonType)
|
// val jsonType = descriptor.getJsonType()
|
||||||
)
|
// val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
||||||
if (isEnum) {
|
// "description" to JsonLiteral(descriptor.serialName),
|
||||||
val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName)
|
// "type" to JsonLiteral(jsonType)
|
||||||
objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral))
|
// )
|
||||||
}
|
// if (isEnum) {
|
||||||
when (jsonType) {
|
// val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName)
|
||||||
"object" -> {
|
// objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral))
|
||||||
if(descriptor.isVisualObject()) {
|
// }
|
||||||
properties["type"] = json {
|
// when (jsonType) {
|
||||||
"const" to descriptor.serialName
|
// "object" -> {
|
||||||
}
|
// if(descriptor.isVisualObject()) {
|
||||||
}
|
// properties["type"] = json {
|
||||||
objectData["properties"] = JsonObject(properties)
|
// "const" to descriptor.serialName
|
||||||
val required = requiredProperties.map { JsonLiteral(it) }
|
// }
|
||||||
if (required.isNotEmpty()) {
|
// }
|
||||||
objectData["required"] = JsonArray(required)
|
// objectData["properties"] = JsonObject(properties)
|
||||||
}
|
// val required = requiredProperties.map { JsonLiteral(it) }
|
||||||
}
|
// if (required.isNotEmpty()) {
|
||||||
"array" -> objectData["items"] = properties.values.let {
|
// objectData["required"] = JsonArray(required)
|
||||||
check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" }
|
// }
|
||||||
it.first()
|
// }
|
||||||
}
|
// "array" -> objectData["items"] = properties.values.let {
|
||||||
else -> { /* no-op */
|
// check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" }
|
||||||
}
|
// it.first()
|
||||||
}
|
// }
|
||||||
return JsonObject(objectData)
|
// else -> { /* no-op */
|
||||||
}
|
// }
|
||||||
|
// }
|
||||||
fun main() {
|
// return JsonObject(objectData)
|
||||||
val context = SolidManager.serialModule
|
//}
|
||||||
val definitions = json {
|
//
|
||||||
"children" to json {
|
//fun main() {
|
||||||
"anyOf" to jsonArray {
|
// val context = SolidManager.serialModule
|
||||||
context.enumerate(Solid::class).forEach {
|
// val definitions = json {
|
||||||
if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") {
|
// "children" to json {
|
||||||
+json {
|
// "anyOf" to jsonArray {
|
||||||
"\$ref" to "#/$definitionNode/${it.serialName}"
|
// context.enumerate(Solid::class).forEach {
|
||||||
}
|
// if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") {
|
||||||
} else {
|
// +json {
|
||||||
+jsonSchema(it, context)
|
// "\$ref" to "#/$definitionNode/${it.serialName}"
|
||||||
}
|
// }
|
||||||
}
|
// } else {
|
||||||
}
|
// +jsonSchema(it, context)
|
||||||
}
|
// }
|
||||||
"hep.dataforge.meta.Meta" to json {
|
// }
|
||||||
"type" to "object"
|
// }
|
||||||
}
|
// }
|
||||||
"hep.dataforge.vision.solid.Point3D" to json {
|
// "hep.dataforge.meta.Meta" to json {
|
||||||
"type" to "object"
|
// "type" to "object"
|
||||||
"properties" to json {
|
// }
|
||||||
"x" to json {
|
// "hep.dataforge.vision.solid.Point3D" to json {
|
||||||
"type" to "number"
|
// "type" to "object"
|
||||||
}
|
// "properties" to json {
|
||||||
"y" to json {
|
// "x" to json {
|
||||||
"type" to "number"
|
// "type" to "number"
|
||||||
}
|
// }
|
||||||
"z" to json {
|
// "y" to json {
|
||||||
"type" to "number"
|
// "type" to "number"
|
||||||
}
|
// }
|
||||||
}
|
// "z" to json {
|
||||||
}
|
// "type" to "number"
|
||||||
"hep.dataforge.vision.solid.Point2D" to json {
|
// }
|
||||||
"type" to "object"
|
// }
|
||||||
"properties" to json {
|
// }
|
||||||
"x" to json {
|
// "hep.dataforge.vision.solid.Point2D" to json {
|
||||||
"type" to "number"
|
// "type" to "object"
|
||||||
}
|
// "properties" to json {
|
||||||
"y" to json {
|
// "x" to json {
|
||||||
"type" to "number"
|
// "type" to "number"
|
||||||
}
|
// }
|
||||||
}
|
// "y" to json {
|
||||||
}
|
// "type" to "number"
|
||||||
"hep.dataforge.vision.solid.SolidGroup" to jsonSchema(
|
// }
|
||||||
SolidGroup.serializer().descriptor,
|
// }
|
||||||
context
|
// }
|
||||||
)
|
// "hep.dataforge.vision.solid.SolidGroup" to jsonSchema(
|
||||||
|
// SolidGroup.serializer().descriptor,
|
||||||
}
|
// context
|
||||||
|
// )
|
||||||
println(
|
//
|
||||||
JSON_PRETTY.stringify(
|
// }
|
||||||
JsonObjectSerializer,
|
//
|
||||||
json {
|
// println(
|
||||||
"\$defs" to definitions
|
// JSON_PRETTY.stringify(
|
||||||
"\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup"
|
// JsonObjectSerializer,
|
||||||
}
|
// json {
|
||||||
)
|
// "\$defs" to definitions
|
||||||
)
|
// "\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup"
|
||||||
}
|
// }
|
||||||
|
// )
|
||||||
|
// )
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
package hep.dataforge.vision.solid
|
package hep.dataforge.vision.solid
|
||||||
import org.fxyz3d.geometry.Point3D as FXPoint3D
|
import org.fxyz3d.geometry.Point3D as FXPoint3D
|
||||||
|
|
||||||
actual data class Point2D(actual var x: Double, actual var y: Double) {
|
public actual data class Point2D(public actual var x: Double, public actual var y: Double) {
|
||||||
actual constructor(x: Number, y: Number) : this(x.toDouble(), y.toDouble())
|
actual constructor(x: Number, y: Number) : this(x.toDouble(), y.toDouble())
|
||||||
}
|
}
|
||||||
|
|
||||||
actual class Point3D(val point: FXPoint3D) {
|
public actual class Point3D(val point: FXPoint3D) {
|
||||||
actual constructor(x: Number, y: Number, z: Number) : this(
|
actual constructor(x: Number, y: Number, z: Number) : this(
|
||||||
FXPoint3D(
|
FXPoint3D(
|
||||||
x.toFloat(),
|
x.toFloat(),
|
||||||
@ -14,19 +14,19 @@ actual class Point3D(val point: FXPoint3D) {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
actual var x: Double
|
public actual var x: Double
|
||||||
inline get() = point.x.toDouble()
|
inline get() = point.x.toDouble()
|
||||||
inline set(value) {
|
inline set(value) {
|
||||||
point.x = value.toFloat()
|
point.x = value.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual var y: Double
|
public actual var y: Double
|
||||||
inline get() = point.y.toDouble()
|
inline get() = point.y.toDouble()
|
||||||
inline set(value) {
|
inline set(value) {
|
||||||
point.y = value.toFloat()
|
point.y = value.toFloat()
|
||||||
}
|
}
|
||||||
|
|
||||||
actual var z: Double
|
public actual var z: Double
|
||||||
inline get() = point.z.toDouble()
|
inline get() = point.z.toDouble()
|
||||||
inline set(value) {
|
inline set(value) {
|
||||||
point.z = value.toFloat()
|
point.z = value.toFloat()
|
||||||
@ -45,6 +45,6 @@ actual class Point3D(val point: FXPoint3D) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
actual operator fun Point3D.plus(other: Point3D): Point3D {
|
public actual operator fun Point3D.plus(other: Point3D): Point3D {
|
||||||
return Point3D(point.add(other.point))
|
return Point3D(point.add(other.point))
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user