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
|
||||
build/
|
||||
|
||||
|
||||
!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 scientifik.useSerialization
|
||||
|
||||
val dataforgeVersion by extra("0.1.8")
|
||||
import ru.mipt.npm.gradle.useFx
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp") apply false
|
||||
id("scientifik.jvm") apply false
|
||||
id("scientifik.js") apply false
|
||||
id("scientifik.publish") apply false
|
||||
id("org.jetbrains.changelog") version "0.4.0"
|
||||
id("ru.mipt.npm.project")
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.2.0-dev-3")
|
||||
val ktorVersion by extra("1.4.1")
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
@ -19,7 +15,7 @@ allprojects {
|
||||
}
|
||||
|
||||
group = "hep.dataforge"
|
||||
version = "0.1.5-dev-2"
|
||||
version = "0.2.0-dev-1"
|
||||
}
|
||||
|
||||
val githubProject by extra("visionforge")
|
||||
@ -28,8 +24,17 @@ val fxVersion by extra("14")
|
||||
|
||||
subprojects {
|
||||
if(name.startsWith("visionforge")) {
|
||||
apply(plugin = "scientifik.publish")
|
||||
apply<ru.mipt.npm.gradle.KSciencePublishPlugin>()
|
||||
}
|
||||
afterEvaluate {
|
||||
extensions.findByType<ru.mipt.npm.gradle.KScienceExtension>()?.run {
|
||||
useSerialization()
|
||||
useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion)
|
||||
}
|
||||
}
|
||||
useSerialization()
|
||||
useFx(scientifik.FXModule.CONTROLS, version = fxVersion)
|
||||
}
|
||||
|
||||
apiValidation {
|
||||
validationDisabled = true
|
||||
ignoredPackages.add("info.laht.threekt")
|
||||
}
|
@ -1,19 +1,24 @@
|
||||
import scientifik.DependencyConfiguration
|
||||
import scientifik.FXModule
|
||||
import scientifik.useFx
|
||||
import ru.mipt.npm.gradle.DependencyConfiguration
|
||||
import ru.mipt.npm.gradle.FXModule
|
||||
import ru.mipt.npm.gradle.useFx
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("application")
|
||||
id("ru.mipt.npm.mpp")
|
||||
application
|
||||
}
|
||||
|
||||
val fxVersion: String by rootProject.extra
|
||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||
kscience {
|
||||
val fxVersion: String by rootProject.extra
|
||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||
application()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
jvm {
|
||||
withJava()
|
||||
afterEvaluate {
|
||||
withJava()
|
||||
}
|
||||
}
|
||||
|
||||
js {
|
||||
@ -27,7 +32,7 @@ kotlin {
|
||||
implementation(project(":visionforge-gdml"))
|
||||
}
|
||||
}
|
||||
jsMain{
|
||||
jsMain {
|
||||
dependencies {
|
||||
implementation(project(":ui:bootstrap"))
|
||||
implementation(npm("react-file-drop", "3.0.6"))
|
||||
|
@ -1,6 +1,6 @@
|
||||
package hep.dataforge.vision.gdml.demo
|
||||
|
||||
import scientifik.gdml.*
|
||||
import kscience.gdml.*
|
||||
|
||||
|
||||
fun cubes(): GDML = GDML {
|
||||
|
@ -1,7 +1,6 @@
|
||||
package hep.dataforge.vision.gdml.demo
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
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.ThreeCanvasComponent
|
||||
import hep.dataforge.vision.solid.three.canvasControls
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.css.FlexBasis
|
||||
import kotlinx.css.Overflow
|
||||
import kotlinx.css.flex
|
||||
import kotlinx.css.overflow
|
||||
import kscience.gdml.GDML
|
||||
import kscience.gdml.decodeFromString
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
import react.RProps
|
||||
import react.dom.h1
|
||||
import scientifik.gdml.GDML
|
||||
import scientifik.gdml.parse
|
||||
import styled.css
|
||||
import kotlin.browser.window
|
||||
import kotlin.math.PI
|
||||
|
||||
interface GDMLAppProps : RProps {
|
||||
@ -58,10 +57,10 @@ val GDMLApp = component<GDMLAppProps> { props ->
|
||||
fun loadData(name: String, data: String) {
|
||||
val parsedVision = when {
|
||||
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
||||
val gdml = GDML.parse(data)
|
||||
val gdml = GDML.decodeFromString(data)
|
||||
gdml.toVision()
|
||||
}
|
||||
name.endsWith(".json") -> SolidGroup.parseJson(data)
|
||||
name.endsWith(".json") -> SolidGroup.decodeFromString(data)
|
||||
else -> {
|
||||
window.alert("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.js.Application
|
||||
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.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.css.*
|
||||
import react.child
|
||||
import react.dom.render
|
||||
import styled.injectGlobal
|
||||
import kotlin.browser.document
|
||||
|
||||
|
||||
private class GDMLDemoApp : Application {
|
||||
|
@ -7,7 +7,7 @@
|
||||
<link rel="stylesheet" href="css/bootstrap.min.css">
|
||||
<link rel="stylesheet" href="css/main.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/bootstrap.bundle.min.js"></script>
|
||||
</head>
|
||||
|
@ -3,13 +3,12 @@ package hep.dataforge.vision.gdml.demo
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.setItem
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.gdml.LUnit
|
||||
import hep.dataforge.vision.gdml.readFile
|
||||
import hep.dataforge.vision.gdml.toVision
|
||||
import hep.dataforge.vision.solid.SolidGroup
|
||||
import hep.dataforge.vision.solid.SolidManager
|
||||
import hep.dataforge.vision.solid.SolidMaterial
|
||||
import scientifik.gdml.GDML
|
||||
import kscience.gdml.GDML
|
||||
import java.io.File
|
||||
import java.util.zip.GZIPInputStream
|
||||
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.inputStream().use {
|
||||
val unzip = ZipInputStream(it, Charsets.UTF_8)
|
||||
val text = unzip.readBytes().decodeToString()
|
||||
SolidGroup.parseJson(text)
|
||||
SolidGroup.decodeFromString(text)
|
||||
}
|
||||
}
|
||||
file.name.endsWith("json.gz") -> {
|
||||
file.inputStream().use {
|
||||
val unzip = GZIPInputStream(it)
|
||||
val text = unzip.readBytes().decodeToString()
|
||||
SolidGroup.parseJson(text)
|
||||
SolidGroup.decodeFromString(text)
|
||||
}
|
||||
}
|
||||
else -> error("Unknown extension ${file.extension}")
|
||||
|
@ -1,10 +1,10 @@
|
||||
package hep.dataforge.vision.gdml.demo
|
||||
|
||||
import hep.dataforge.vision.gdml.LUnit
|
||||
import hep.dataforge.vision.gdml.readFile
|
||||
import hep.dataforge.vision.gdml.toVision
|
||||
import hep.dataforge.vision.solid.stringify
|
||||
import scientifik.gdml.GDML
|
||||
import hep.dataforge.vision.solid.encodeToString
|
||||
import kscience.gdml.GDML
|
||||
import kscience.gdml.LUnit
|
||||
import java.io.File
|
||||
import java.nio.file.Paths
|
||||
|
||||
@ -21,7 +21,7 @@ fun main(args: Array<String>) {
|
||||
lUnit = LUnit.CM
|
||||
}
|
||||
|
||||
val json = visual.stringify()
|
||||
val json = visual.encodeToString()
|
||||
println(json)
|
||||
File(outputFileName).writeText(json)
|
||||
//File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
|
||||
|
@ -9,7 +9,7 @@ class FileSerializationTest {
|
||||
@Ignore
|
||||
fun testFileRead(){
|
||||
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
|
||||
val visual = SolidGroup.parseJson(text)
|
||||
val visual = SolidGroup.decodeFromString(text)
|
||||
visual["composite_001".asName()]
|
||||
}
|
||||
}
|
@ -1,43 +1,38 @@
|
||||
import org.jetbrains.kotlin.gradle.plugin.KotlinCompilation.Companion.MAIN_COMPILATION_NAME
|
||||
import scientifik.jsDistDirectory
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("application")
|
||||
id("ru.mipt.npm.mpp")
|
||||
application
|
||||
}
|
||||
|
||||
group = "ru.mipt.npm"
|
||||
|
||||
val ktorVersion = "1.3.2"
|
||||
val ktorVersion: String by rootProject.extra
|
||||
|
||||
kscience {
|
||||
application()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
afterEvaluate {
|
||||
val jsBrowserDistribution by tasks.getting
|
||||
|
||||
val installJS = tasks.getByName("jsBrowserDistribution")
|
||||
|
||||
js {
|
||||
browser {
|
||||
dceTask {
|
||||
dceOptions {
|
||||
keep("ktor-ktor-io.\$\$importsForInline\$\$.ktor-ktor-io.io.ktor.utils.io")
|
||||
jvm {
|
||||
withJava()
|
||||
compilations[MAIN_COMPILATION_NAME]?.apply {
|
||||
tasks.getByName<ProcessResources>(processResourcesTaskName) {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
afterEvaluate {
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
}
|
||||
}
|
||||
webpackTask {
|
||||
mode = org.jetbrains.kotlin.gradle.targets.js.webpack.KotlinWebpackConfig.Mode.PRODUCTION
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
jvm {
|
||||
withJava()
|
||||
compilations[MAIN_COMPILATION_NAME]?.apply {
|
||||
tasks.getByName<ProcessResources>(processResourcesTaskName) {
|
||||
dependsOn(installJS)
|
||||
afterEvaluate {
|
||||
from(project.jsDistDirectory)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
js {
|
||||
useCommonJs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
@ -58,14 +53,6 @@ kotlin {
|
||||
implementation(project(":ui:bootstrap"))
|
||||
implementation("io.ktor:ktor-client-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.NameToken
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.length
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.bootstrap.card
|
||||
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.features.json.JsonFeature
|
||||
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.serialization.json.Json
|
||||
import react.child
|
||||
import react.dom.div
|
||||
import react.dom.render
|
||||
import kotlin.browser.document
|
||||
|
||||
private class MMDemoApp : Application {
|
||||
|
||||
@ -19,7 +19,7 @@ private class MMDemoApp : Application {
|
||||
|
||||
private val connection = HttpClient {
|
||||
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") {
|
||||
child(MMApp) {
|
||||
attrs {
|
||||
model = this@MMDemoApp.model
|
||||
connection = this@MMDemoApp.connection
|
||||
this.model = this@MMDemoApp.model
|
||||
this.connection = this@MMDemoApp.connection
|
||||
this.context = context
|
||||
}
|
||||
}
|
||||
|
@ -6,7 +6,7 @@
|
||||
<title>Three js demo for particle physics</title>
|
||||
<link rel="stylesheet" href="css/bootstrap.min.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/bootstrap.bundle.min.js"></script>
|
||||
</head>
|
||||
|
@ -10,6 +10,7 @@ import io.ktor.application.log
|
||||
import io.ktor.features.CallLogging
|
||||
import io.ktor.features.ContentNegotiation
|
||||
import io.ktor.features.DefaultHeaders
|
||||
import io.ktor.http.ContentType
|
||||
import io.ktor.http.content.resources
|
||||
import io.ktor.http.content.static
|
||||
import io.ktor.response.respond
|
||||
@ -19,6 +20,7 @@ import io.ktor.serialization.json
|
||||
import io.ktor.server.cio.CIO
|
||||
import io.ktor.server.engine.embeddedServer
|
||||
import io.ktor.util.KtorExperimentalAPI
|
||||
import kotlinx.serialization.json.Json
|
||||
import org.apache.commons.math3.random.JDKRandomGenerator
|
||||
import ru.mipt.npm.muon.monitor.Model
|
||||
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
||||
@ -38,7 +40,7 @@ fun Application.module() {
|
||||
install(DefaultHeaders)
|
||||
install(CallLogging)
|
||||
install(ContentNegotiation) {
|
||||
json(module = SolidManager.serialModule)
|
||||
json(Json { serializersModule = SolidManager.serialModule }, ContentType.Application.Json)
|
||||
}
|
||||
install(Routing) {
|
||||
get("/event") {
|
||||
|
@ -1,19 +1,22 @@
|
||||
import scientifik.DependencyConfiguration
|
||||
import scientifik.FXModule
|
||||
import scientifik.useFx
|
||||
import ru.mipt.npm.gradle.*
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("application")
|
||||
id("ru.mipt.npm.mpp")
|
||||
application
|
||||
}
|
||||
|
||||
val fxVersion: String by rootProject.extra
|
||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||
kscience {
|
||||
val fxVersion: String by rootProject.extra
|
||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
||||
application()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
jvm {
|
||||
withJava()
|
||||
afterEvaluate {
|
||||
withJava()
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
@ -8,6 +8,7 @@ import hep.dataforge.vision.Colors
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import hep.dataforge.vision.visible
|
||||
import kotlinx.coroutines.*
|
||||
import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
|
@ -6,7 +6,7 @@
|
||||
<title>Three js demo for particle physics</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css"
|
||||
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>
|
||||
<body class="application">
|
||||
<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
|
||||
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
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -7,12 +7,12 @@ repositories{
|
||||
maven("https://kotlin.bintray.com/kotlinx")
|
||||
maven("https://dl.bintray.com/kotlin/kotlin-eap")
|
||||
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")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
js(IR) {
|
||||
browser {}
|
||||
}
|
||||
|
||||
|
@ -1,32 +1,27 @@
|
||||
pluginManagement {
|
||||
val kotlinVersion = "1.3.72"
|
||||
val toolsVersion = "0.5.2"
|
||||
val kotlinVersion = "1.4.20-M1"
|
||||
val toolsVersion = "0.6.3-dev-1.4.20-M1"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
gradlePluginPortal()
|
||||
maven("https://kotlin.bintray.com/kotlinx")
|
||||
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/scientifik")
|
||||
maven("https://dl.bintray.com/mipt-npm/kscience")
|
||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||
}
|
||||
|
||||
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
|
||||
id("scientifik.mpp") version toolsVersion
|
||||
id("scientifik.jvm") version toolsVersion
|
||||
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}")
|
||||
}
|
||||
}
|
||||
kotlin("js") version kotlinVersion
|
||||
kotlin("multiplatform") version kotlinVersion
|
||||
}
|
||||
}
|
||||
|
||||
@ -34,11 +29,12 @@ pluginManagement {
|
||||
|
||||
rootProject.name = "visionforge"
|
||||
|
||||
|
||||
include(
|
||||
":ui",
|
||||
// ":ui",
|
||||
":ui:react",
|
||||
":ui:ring",
|
||||
":ui:material",
|
||||
// ":ui:material",
|
||||
":ui:bootstrap",
|
||||
":visionforge-core",
|
||||
":visionforge-solid",
|
||||
|
@ -1,15 +1,9 @@
|
||||
plugins {
|
||||
id("scientifik.js")
|
||||
id("ru.mipt.npm.js")
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
useCommonJs()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies{
|
||||
api(project(":ui:react"))
|
||||
}
|
@ -2,6 +2,7 @@ package hep.dataforge.vision.bootstrap
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.length
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.react.ObjectTree
|
||||
import kotlinx.html.*
|
||||
@ -17,7 +18,7 @@ import styled.StyledDOMBuilder
|
||||
import styled.css
|
||||
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-body") {
|
||||
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-body") {
|
||||
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("accordion") {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
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") {
|
||||
div("accordion") {
|
||||
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") {
|
||||
nav {
|
||||
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)
|
||||
}
|
||||
|
||||
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)
|
||||
return accordion(id, list)
|
||||
}
|
||||
|
||||
fun joinStyles(vararg styles: String?) = styles.joinToString(separator = " ") { it ?: "" }
|
||||
|
||||
enum class ContainerSize(val suffix: String) {
|
||||
public enum class ContainerSize(public val suffix: String) {
|
||||
DEFAULT(""),
|
||||
SM("-sm"),
|
||||
MD("-md"),
|
||||
@ -182,7 +181,7 @@ enum class ContainerSize(val suffix: String) {
|
||||
FLUID("-fluid")
|
||||
}
|
||||
|
||||
inline fun RBuilder.container(
|
||||
public inline fun RBuilder.container(
|
||||
size: ContainerSize = ContainerSize.FLUID,
|
||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||
): 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(""),
|
||||
SM("-sm"),
|
||||
MD("-md"),
|
||||
@ -201,7 +200,7 @@ enum class GridMaxSize(val suffix: String) {
|
||||
XL("-xl")
|
||||
}
|
||||
|
||||
inline fun RBuilder.gridColumn(
|
||||
public inline fun RBuilder.gridColumn(
|
||||
weight: Int? = null,
|
||||
maxSize: GridMaxSize = GridMaxSize.NONE,
|
||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||
@ -213,7 +212,7 @@ inline fun RBuilder.gridColumn(
|
||||
block()
|
||||
}
|
||||
|
||||
inline fun RBuilder.gridRow(
|
||||
public inline fun RBuilder.gridRow(
|
||||
block: StyledDOMBuilder<DIV>.() -> Unit
|
||||
): ReactElement = styledDiv{
|
||||
css{
|
||||
@ -222,10 +221,10 @@ inline fun RBuilder.gridRow(
|
||||
block()
|
||||
}
|
||||
|
||||
fun Element.renderObjectTree(
|
||||
public fun Element.renderObjectTree(
|
||||
vision: Vision,
|
||||
clickCallback: (Name) -> Unit = {}
|
||||
) = render(this) {
|
||||
): Unit = render(this) {
|
||||
card("Object tree") {
|
||||
child(ObjectTree) {
|
||||
attrs {
|
||||
|
@ -1,20 +1,14 @@
|
||||
plugins {
|
||||
id("scientifik.js")
|
||||
id("ru.mipt.npm.js")
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
useCommonJs()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies{
|
||||
api(project(":ui:react"))
|
||||
|
||||
api("subroh0508.net.kotlinmaterialui:core:0.4.0")
|
||||
api("subroh0508.net.kotlinmaterialui:lab:0.4.0")
|
||||
api("subroh0508.net.kotlinmaterialui:core:0.4.5")
|
||||
api("subroh0508.net.kotlinmaterialui:lab:0.4.5")
|
||||
api(npm("@material-ui/core","4.9.14"))
|
||||
api(npm("@material-ui/lab","4.0.0-alpha.51"))
|
||||
//api(npm("@material-ui/icons","4.9.1"))
|
||||
|
@ -1,11 +1,5 @@
|
||||
plugins {
|
||||
id("scientifik.js")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
useCommonJs()
|
||||
}
|
||||
id("ru.mipt.npm.js")
|
||||
}
|
||||
|
||||
val reactVersion by extra("16.13.1")
|
||||
@ -14,7 +8,7 @@ dependencies{
|
||||
api(project(":visionforge-core"))
|
||||
|
||||
//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-dom", reactVersion))
|
||||
|
@ -4,6 +4,7 @@ import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.lastOrNull
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.values.Value
|
||||
import kotlinx.html.js.onClickFunction
|
||||
@ -47,7 +48,7 @@ private fun RFBuilder.configEditorItem(props: ConfigEditorItemProps) {
|
||||
val defaultItem = props.default?.get(props.name)
|
||||
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() {
|
||||
item = props.root[props.name]
|
||||
|
@ -9,6 +9,7 @@ import hep.dataforge.meta.descriptors.get
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.lastOrNull
|
||||
import hep.dataforge.names.plus
|
||||
import kotlinx.html.js.onClickFunction
|
||||
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 actualItem = item ?: descriptorItem?.defaultItem()
|
||||
|
||||
val token = props.name.last()?.toString() ?: "Meta"
|
||||
val token = props.name.lastOrNull()?.toString() ?: "Meta"
|
||||
|
||||
val expanderClick: (Event) -> Unit = {
|
||||
expanded = !expanded
|
||||
|
@ -1,6 +1,7 @@
|
||||
package hep.dataforge.vision.react
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.lastOrNull
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.names.startsWith
|
||||
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
|
||||
|
||||
//display as node if any child is visible
|
||||
|
@ -1,22 +1,13 @@
|
||||
plugins {
|
||||
id("scientifik.js")
|
||||
id("ru.mipt.npm.js")
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
target {
|
||||
useCommonJs()
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
dependencies{
|
||||
api(project(":ui:react"))
|
||||
|
||||
implementation(npm("@jetbrains/logos", "1.1.6"))
|
||||
implementation(npm("@jetbrains/ring-ui", "3.0.13"))
|
||||
|
||||
|
||||
implementation(npm("svg-inline-loader", "0.8.0"))
|
||||
}
|
@ -1,13 +1,10 @@
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("ru.mipt.npm.mpp")
|
||||
}
|
||||
|
||||
val dataforgeVersion: String by rootProject.extra
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
useCommonJs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
@ -30,15 +27,15 @@ kotlin {
|
||||
jsMain {
|
||||
dependencies {
|
||||
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-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("inline-style-prefixer", "5.1.0"))
|
||||
api(npm("styled-components", "4.3.2"))
|
||||
api(npm("styled-components", "5.2.0"))
|
||||
//api(project(":ringui-wrapper"))
|
||||
}
|
||||
}
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
|
||||
@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<*>?
|
||||
get() = config[name]
|
||||
set(value) {
|
||||
|
@ -87,13 +87,13 @@ abstract class AbstractVision : Vision {
|
||||
/**
|
||||
* Reset all properties to their default values
|
||||
*/
|
||||
fun resetProperties() {
|
||||
public fun resetProperties() {
|
||||
properties?.removeListener(this)
|
||||
properties = null
|
||||
}
|
||||
|
||||
companion object {
|
||||
val descriptor = NodeDescriptor {
|
||||
public companion object {
|
||||
public val descriptor: NodeDescriptor = NodeDescriptor {
|
||||
value(STYLE_KEY) {
|
||||
type(ValueType.STRING)
|
||||
multiple = true
|
||||
|
@ -1,9 +1,6 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.*
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
|
||||
@ -105,7 +102,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
||||
return when {
|
||||
name.isEmpty() -> error("Should be unreachable")
|
||||
name.length == 1 -> {
|
||||
val token = name.first()!!
|
||||
val token = name.tokens.first()
|
||||
when (val current = children[token]) {
|
||||
null -> createGroup().also { 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 -> 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 -> {
|
||||
val token = name.first()!!
|
||||
val token = name.tokens.first()
|
||||
if (child == null) {
|
||||
removeChild(token)
|
||||
} else {
|
||||
@ -142,7 +139,7 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
|
||||
else -> {
|
||||
//TODO add safety check
|
||||
val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast())
|
||||
parent[name.last()!!.asName()] = child
|
||||
parent[name.tokens.last().asName()] = child
|
||||
}
|
||||
}
|
||||
childrenChanged(name, child)
|
||||
|
@ -8,20 +8,23 @@ import hep.dataforge.names.asName
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
import kotlinx.serialization.builtins.serializer
|
||||
import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
import kotlinx.serialization.encoding.Decoder
|
||||
import kotlinx.serialization.encoding.Encoder
|
||||
|
||||
/**
|
||||
* A container for styles
|
||||
*/
|
||||
@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
|
||||
internal var owner: Vision? = null
|
||||
|
||||
constructor(owner: Vision) : this() {
|
||||
public constructor(owner: Vision) : this() {
|
||||
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?) {
|
||||
@ -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)
|
||||
}
|
||||
|
||||
/**
|
||||
* Define a style without notifying owner
|
||||
*/
|
||||
fun define(key: String, style: Meta?) {
|
||||
public fun define(key: String, style: Meta?) {
|
||||
if (style == null) {
|
||||
styleMap.remove(key)
|
||||
} else {
|
||||
@ -56,7 +59,7 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
|
||||
/**
|
||||
* Set or clear the style
|
||||
*/
|
||||
operator fun set(key: String, style: Meta?) {
|
||||
public operator fun set(key: String, style: Meta?) {
|
||||
val oldStyle = styleMap[key]
|
||||
define(key, 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
|
||||
*/
|
||||
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)
|
||||
set(key, newStyle.seal())
|
||||
}
|
||||
|
||||
@ExperimentalSerializationApi
|
||||
@Serializer(StyleSheet::class)
|
||||
companion object : KSerializer<StyleSheet> {
|
||||
public companion object : KSerializer<StyleSheet> {
|
||||
private val mapSerializer = MapSerializer(String.serializer(), MetaSerializer)
|
||||
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.
|
||||
*/
|
||||
fun Vision.useStyle(name: String) {
|
||||
styles = properties[Vision.STYLE_KEY].stringList + name
|
||||
public fun Vision.useStyle(name: String) {
|
||||
styles = (properties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + name
|
||||
}
|
||||
|
||||
/**
|
||||
* 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 {
|
||||
resolveStyle(it)
|
||||
}.map {
|
||||
@ -109,4 +113,4 @@ fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
||||
/**
|
||||
* 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.toName
|
||||
import hep.dataforge.provider.Type
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.Vision.Companion.TYPE
|
||||
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.Transient
|
||||
|
||||
@ -13,28 +15,28 @@ import kotlinx.serialization.Transient
|
||||
* A root type for display hierarchy
|
||||
*/
|
||||
@Type(TYPE)
|
||||
interface Vision : Configurable {
|
||||
public interface Vision : Configurable {
|
||||
|
||||
/**
|
||||
* The parent object of this one. If null, this one is a root.
|
||||
*/
|
||||
@Transient
|
||||
var parent: VisionGroup?
|
||||
public var parent: VisionGroup?
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
fun getAllProperties(): Laminate
|
||||
public fun getAllProperties(): Laminate
|
||||
|
||||
/**
|
||||
* 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
|
||||
@ -44,46 +46,55 @@ interface Vision : Configurable {
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit
|
||||
public fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
var styles: List<String>
|
||||
get() = properties[STYLE_KEY].stringList
|
||||
public var styles: List<String>
|
||||
get() = properties[STYLE_KEY]?.stringList?: emptyList()
|
||||
set(value) {
|
||||
config[STYLE_KEY] = value
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE = "vision"
|
||||
val STYLE_KEY = "@style".asName()
|
||||
public companion object {
|
||||
public const val TYPE: String = "vision"
|
||||
public val STYLE_KEY: Name = "@style".asName()
|
||||
|
||||
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
|
||||
*/
|
||||
fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
||||
public fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
|
||||
getProperty(key.toName(), inherit)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
|
||||
/**
|
||||
* 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.provider.Provider
|
||||
|
||||
public interface VisionContainer<out V: Vision>{
|
||||
public operator fun get(name: Name): V?
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents a group of [Vision] instances
|
||||
*/
|
||||
interface VisionGroup : Provider, Vision {
|
||||
public interface VisionGroup : Provider, Vision, VisionContainer<Vision> {
|
||||
/**
|
||||
* 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
|
||||
|
||||
@ -18,17 +22,17 @@ interface VisionGroup : Provider, Vision {
|
||||
* A stylesheet for this group and its descendants. Stylesheet is not applied directly,
|
||||
* but instead is just a repository for named configurations.
|
||||
*/
|
||||
val styleSheet: StyleSheet?
|
||||
public val styleSheet: StyleSheet?
|
||||
|
||||
/**
|
||||
* A map of direct children for specific target
|
||||
* (currently "visual" or "style")
|
||||
*/
|
||||
override fun provideTop(target: String): Map<Name, Any> =
|
||||
override fun content(target: String): Map<Name, Any> =
|
||||
when (target) {
|
||||
Vision.TYPE -> children.flatMap { (key, value) ->
|
||||
val res: Map<Name, Any> = if (value is VisionGroup) {
|
||||
value.provideTop(target).mapKeys { key + it.key }
|
||||
value.content(target).mapKeys { key + it.key }
|
||||
} else {
|
||||
mapOf(key.asName() to value)
|
||||
}
|
||||
@ -38,18 +42,18 @@ interface VisionGroup : Provider, Vision {
|
||||
else -> emptyMap()
|
||||
}
|
||||
|
||||
operator fun get(name: Name): Vision? {
|
||||
public override operator fun get(name: Name): Vision? {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
name.length == 1 -> children[name.first()!!]
|
||||
else -> (children[name.first()!!] as? VisionGroup)?.get(name.cutFirst())
|
||||
name.length == 1 -> children[name.tokens.first()]
|
||||
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
|
||||
*/
|
||||
fun attachChildren() {
|
||||
public fun attachChildren() {
|
||||
styleSheet?.owner = this
|
||||
children.values.forEach {
|
||||
it.parent = this
|
||||
@ -57,41 +61,45 @@ interface VisionGroup : Provider, Vision {
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val STYLE_TARGET = "style"
|
||||
public companion object {
|
||||
public const val STYLE_TARGET: String = "style"
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 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]
|
||||
*/
|
||||
interface MutableVisionGroup : VisionGroup {
|
||||
public interface MutableVisionGroup : VisionGroup, VisionContainerBuilder<Vision> {
|
||||
|
||||
/**
|
||||
* Add listener for children structure change.
|
||||
* @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.
|
||||
*/
|
||||
fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit)
|
||||
public fun onChildrenChange(owner: Any?, action: (Name, Vision?) -> Unit)
|
||||
|
||||
/**
|
||||
* 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)
|
||||
operator fun MutableVisionGroup.set(key: String, child: Vision?): Unit = set(key.toName(), child)
|
||||
public operator fun <V: Vision> VisionContainerBuilder<V>.set(token: NameToken, child: V?): Unit = set(token.asName(), 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.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import kotlinx.serialization.ExperimentalSerializationApi
|
||||
import kotlinx.serialization.KSerializer
|
||||
import kotlinx.serialization.UnstableDefault
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonConfiguration
|
||||
import kotlinx.serialization.modules.SerialModule
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import kotlinx.serialization.modules.subclass
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
@DFExperimental
|
||||
interface VisionForm<T : Vision> {
|
||||
val type: KClass<out T>
|
||||
val serializer: KSerializer<T>
|
||||
public interface VisionForm<T : Vision> {
|
||||
public val type: KClass<out 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]
|
||||
*/
|
||||
fun patch(obj: T, meta: Meta)
|
||||
public fun patch(obj: T, meta: Meta)
|
||||
|
||||
companion object {
|
||||
const val TYPE = "visionForm"
|
||||
public companion object {
|
||||
public const val TYPE: String = "visionForm"
|
||||
}
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
object SimpleGroupForm: VisionForm<SimpleVisionGroup>{
|
||||
public object SimpleGroupForm : VisionForm<SimpleVisionGroup> {
|
||||
override val type: KClass<out SimpleVisionGroup> = SimpleVisionGroup::class
|
||||
override val serializer: KSerializer<SimpleVisionGroup> = SimpleVisionGroup.serializer()
|
||||
|
||||
@ -42,86 +44,93 @@ object SimpleGroupForm: VisionForm<SimpleVisionGroup>{
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
fun <T : Vision> VisionForm<T>.visionToMeta(vision: T, module: SerialModule, descriptor: NodeDescriptor? = null): Meta {
|
||||
val engine = Json(VisionManager.jsonConfiguration, module)
|
||||
val json = engine.toJson<T>(serializer, vision)
|
||||
public fun <T : Vision> VisionForm<T>.visionToMeta(
|
||||
vision: T,
|
||||
module: SerializersModule,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
): Meta {
|
||||
val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module }
|
||||
val json = engine.encodeToJsonElement(serializer, vision)
|
||||
return json.toMetaItem(descriptor).node!!
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
fun <T : Vision> VisionForm<T>.buildVision(meta: Meta, module: SerialModule, descriptor: NodeDescriptor? = null): T {
|
||||
val engine = Json(VisionManager.jsonConfiguration, module)
|
||||
public fun <T : Vision> VisionForm<T>.buildVision(
|
||||
meta: Meta,
|
||||
module: SerializersModule,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
): T {
|
||||
val engine = Json(VisionManager.jsonConfiguration) { serializersModule = module }
|
||||
val json = meta.toJson(descriptor)
|
||||
return engine.fromJson(serializer, json)
|
||||
return engine.decodeFromJsonElement(serializer, json)
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
/**
|
||||
* Create a list of factories on first call and cache it
|
||||
*/
|
||||
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 {
|
||||
include(defaultSerialModule)
|
||||
context.content<SerialModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
|
||||
context.gather<SerializersModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
|
||||
include(it)
|
||||
}
|
||||
}
|
||||
|
||||
@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>
|
||||
|
||||
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}")
|
||||
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 form = forms.values.find { it.name.toString() == type } ?: error("Could not resolve a form for type $type")
|
||||
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 engine = Json(VisionManager.jsonConfiguration, visionSerialModule)
|
||||
val json = engine.toJson(form.serializer,vision)
|
||||
val engine = Json(jsonConfiguration) { serializersModule = visionSerialModule }
|
||||
val json = engine.encodeToJsonElement(form.serializer, vision)
|
||||
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")
|
||||
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 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)
|
||||
|
||||
@OptIn(UnstableDefault::class)
|
||||
val jsonConfiguration = JsonConfiguration(
|
||||
prettyPrint = true,
|
||||
useArrayPolymorphism = false,
|
||||
encodeDefaults = false,
|
||||
public val jsonConfiguration: Json = Json {
|
||||
prettyPrint = true
|
||||
useArrayPolymorphism = false
|
||||
encodeDefaults = false
|
||||
ignoreUnknownKeys = true
|
||||
)
|
||||
}
|
||||
|
||||
val defaultSerialModule = SerializersModule {
|
||||
polymorphic(Vision::class, VisionGroup::class) {
|
||||
public val defaultSerialModule: SerializersModule = SerializersModule {
|
||||
polymorphic(Vision::class) {
|
||||
subclass(SimpleVisionGroup.serializer())
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
@ -1,27 +1,27 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||
import hep.dataforge.meta.descriptors.setAttribute
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.node
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.meta.descriptors.attributes
|
||||
|
||||
/**
|
||||
* Extension property to access the "widget" key of [ValueDescriptor]
|
||||
*/
|
||||
var ValueDescriptor.widget: Meta
|
||||
public var ValueDescriptor.widget: Meta
|
||||
get() = attributes["widget"].node ?: Meta.EMPTY
|
||||
set(value) {
|
||||
setAttribute("widget".toName(), value)
|
||||
attributes {
|
||||
set("widget", value)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
||||
*/
|
||||
var ValueDescriptor.widgetType: String?
|
||||
public var ValueDescriptor.widgetType: String?
|
||||
get() = attributes["widget.type"].string
|
||||
set(value) {
|
||||
setAttribute("widget.type".toName(), value)
|
||||
attributes{
|
||||
set("widget.type", value)
|
||||
}
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package hep.dataforge.vision.visitor
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.length
|
||||
import hep.dataforge.vision.Vision
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.Job
|
||||
|
@ -4,10 +4,7 @@ import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.ValueDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.withIndex
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.values.Null
|
||||
import hep.dataforge.values.Value
|
||||
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 parent: FXMetaNode<M>
|
||||
) : FXMeta<M>() {
|
||||
|
||||
val descriptorProperty = parent.descriptorProperty.objectBinding {
|
||||
public val descriptorProperty = parent.descriptorProperty.objectBinding {
|
||||
it?.values?.get(name.body)
|
||||
}
|
||||
|
||||
@ -153,24 +150,24 @@ class FXMetaValue<M : MetaNode<M>>(
|
||||
|
||||
//private val innerValueProperty = SimpleObjectProperty(value)
|
||||
|
||||
val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
||||
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
||||
parent.node[name].value ?: descriptor?.default
|
||||
}
|
||||
|
||||
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 ?: "" }
|
||||
}
|
||||
|
||||
fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
||||
public fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
||||
node?.remove(name.asName())
|
||||
children.invalidate()
|
||||
}
|
||||
|
||||
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 index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||
val newName = name.withIndex(index.toString())
|
||||
|
@ -1,5 +1,5 @@
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("ru.mipt.npm.mpp")
|
||||
}
|
||||
|
||||
kotlin {
|
||||
@ -7,7 +7,7 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
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.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||
import hep.dataforge.vision.useStyle
|
||||
import scientifik.gdml.*
|
||||
import kscience.gdml.*
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
import kotlin.random.Random
|
||||
@ -20,7 +20,7 @@ import kotlin.random.Random
|
||||
private val solidsName = "solids".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 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 nl.adaptivity.xmlutil.StAXReader
|
||||
import scientifik.gdml.GDML
|
||||
import kscience.gdml.GDML
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.util.concurrent.atomic.AtomicInteger
|
||||
|
@ -1,9 +1,9 @@
|
||||
package hep.dataforge.vision.gdml
|
||||
|
||||
import hep.dataforge.vision.solid.stringify
|
||||
import hep.dataforge.vision.solid.encodeToString
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import org.junit.jupiter.api.Test
|
||||
import scientifik.gdml.GDML
|
||||
import kscience.gdml.GDML
|
||||
|
||||
class TestConvertor {
|
||||
|
||||
@ -13,7 +13,7 @@ class TestConvertor {
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||
val vision = xml.toVision()
|
||||
println(vision.stringify())
|
||||
println(vision.encodeToString())
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -33,6 +33,6 @@ class TestConvertor {
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||
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.withContext
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import scientifik.gdml.GDML
|
||||
import kscience.gdml.GDML
|
||||
import java.io.File
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
@ -1,15 +1,14 @@
|
||||
import scientifik.useSerialization
|
||||
import ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion
|
||||
|
||||
plugins {
|
||||
id("scientifik.mpp")
|
||||
id("ru.mipt.npm.mpp")
|
||||
}
|
||||
|
||||
useSerialization()
|
||||
kscience {
|
||||
useSerialization()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js {
|
||||
useCommonJs()
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
@ -22,7 +21,7 @@ kotlin {
|
||||
api("org.fxyz3d:fxyz3d:0.5.2") {
|
||||
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") {
|
||||
exclude(module = "slf4j-simple")
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
|
||||
import kotlinx.serialization.SerialName
|
||||
@ -13,10 +14,10 @@ import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.box")
|
||||
class Box(
|
||||
val xSize: Float,
|
||||
val ySize: Float,
|
||||
val zSize: Float
|
||||
public class Box(
|
||||
public val xSize: Float,
|
||||
public val ySize: Float,
|
||||
public val zSize: Float
|
||||
) : AbstractVision(), GeometrySolid {
|
||||
|
||||
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,
|
||||
ySize: Number,
|
||||
zSize: Number,
|
||||
name: String = "",
|
||||
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.UseSerializers
|
||||
|
||||
enum class CompositeType {
|
||||
public enum class CompositeType {
|
||||
UNION,
|
||||
INTERSECT,
|
||||
SUBTRACT
|
||||
@ -18,10 +18,10 @@ enum class CompositeType {
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.composite")
|
||||
class Composite(
|
||||
val compositeType: CompositeType,
|
||||
val first: Solid,
|
||||
val second: Solid
|
||||
public class Composite(
|
||||
public val compositeType: CompositeType,
|
||||
public val first: Solid,
|
||||
public val second: Solid
|
||||
) : AbstractVision(), Solid, VisionGroup {
|
||||
|
||||
init {
|
||||
@ -42,7 +42,7 @@ class Composite(
|
||||
get() = null
|
||||
}
|
||||
|
||||
inline fun MutableVisionGroup.composite(
|
||||
public inline fun MutableVisionGroup.composite(
|
||||
type: CompositeType,
|
||||
name: String = "",
|
||||
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)
|
||||
|
||||
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)
|
||||
|
||||
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)
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -17,12 +18,12 @@ import kotlin.math.sin
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("solid.cone")
|
||||
class ConeSegment(
|
||||
var radius: Float,
|
||||
var height: Float,
|
||||
var upperRadius: Float,
|
||||
var startAngle: Float = 0f,
|
||||
var angle: Float = PI2
|
||||
public class ConeSegment(
|
||||
public var radius: Float,
|
||||
public var height: Float,
|
||||
public var upperRadius: Float,
|
||||
public var startAngle: Float = 0f,
|
||||
public var angle: Float = PI2
|
||||
) : AbstractVision(), GeometrySolid {
|
||||
|
||||
override var properties: Config? = null
|
||||
@ -75,7 +76,7 @@ class ConeSegment(
|
||||
|
||||
}
|
||||
|
||||
inline fun MutableVisionGroup.cylinder(
|
||||
public inline fun VisionContainerBuilder<Solid>.cylinder(
|
||||
r: Number,
|
||||
height: Number,
|
||||
name: String = "",
|
||||
@ -87,7 +88,7 @@ inline fun MutableVisionGroup.cylinder(
|
||||
).apply(block).also { set(name, it) }
|
||||
|
||||
|
||||
inline fun MutableVisionGroup.cone(
|
||||
public inline fun VisionContainerBuilder<Solid>.cone(
|
||||
bottomRadius: Number,
|
||||
height: Number,
|
||||
upperRadius: Number = 0.0,
|
||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
@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
|
||||
|
||||
@ -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) }
|
||||
|
||||
class ConvexBuilder {
|
||||
public class ConvexBuilder {
|
||||
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))
|
||||
}
|
||||
|
||||
fun build(): Convex {
|
||||
public fun build(): Convex {
|
||||
return Convex(points)
|
||||
}
|
||||
}
|
@ -4,6 +4,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -13,21 +14,21 @@ import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
|
||||
typealias Shape2D = List<Point2D>
|
||||
public typealias Shape2D = List<Point2D>
|
||||
|
||||
@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))
|
||||
}
|
||||
|
||||
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" }
|
||||
val angle = 2 * PI / vertices
|
||||
for (i in 0 until vertices) {
|
||||
@ -36,13 +37,13 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||
}
|
||||
|
||||
@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
|
||||
@SerialName("solid.extrude")
|
||||
class Extruded(
|
||||
var shape: List<Point2D> = ArrayList(),
|
||||
var layers: MutableList<Layer> = ArrayList()
|
||||
public class Extruded(
|
||||
public var shape: List<Point2D> = ArrayList(),
|
||||
public var layers: MutableList<Layer> = ArrayList()
|
||||
) : AbstractVision(), GeometrySolid {
|
||||
|
||||
override var properties: Config? = null
|
||||
@ -51,12 +52,12 @@ class Extruded(
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
this.shape = Shape2DBuilder().apply(block).build()
|
||||
//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()))
|
||||
//TODO send invalidation signal
|
||||
}
|
||||
@ -107,10 +108,10 @@ class Extruded(
|
||||
geometryBuilder.cap(layers.last())
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TYPE = "geometry.3d.extruded"
|
||||
public companion object {
|
||||
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) }
|
@ -5,7 +5,7 @@ import hep.dataforge.meta.Meta
|
||||
/**
|
||||
* @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,
|
||||
* it is added automatically.
|
||||
@ -13,12 +13,12 @@ interface GeometryBuilder<T : Any> {
|
||||
* @param normal optional external normal to the face
|
||||
* @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,
|
||||
vertex2: 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.
|
||||
*/
|
||||
interface GeometrySolid : Solid {
|
||||
fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
|
||||
public interface GeometrySolid : Solid {
|
||||
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
|
||||
val center = Point3D(
|
||||
shape.map { it.x }.average(),
|
||||
|
@ -4,10 +4,12 @@ package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -15,7 +17,7 @@ import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
@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 position: Point3D? = null
|
||||
@ -23,13 +25,13 @@ class PolyLine(var points: List<Point3D>) : AbstractVision(), Solid {
|
||||
override var scale: Point3D? = null
|
||||
|
||||
//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 {
|
||||
val THICKNESS_KEY = "thickness".asName()
|
||||
public companion object {
|
||||
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) }
|
@ -12,8 +12,8 @@ import kotlinx.serialization.Transient
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.collections.set
|
||||
|
||||
abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
||||
abstract val prototype: Vision
|
||||
public abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
||||
public abstract val prototype: Vision
|
||||
|
||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||
return if (inherit) {
|
||||
@ -33,7 +33,7 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
||||
}
|
||||
|
||||
override var styles: List<String>
|
||||
get() = properties[Vision.STYLE_KEY].stringList + prototype.styles
|
||||
get() = (properties[Vision.STYLE_KEY]?.stringList ?: emptyList()) + prototype.styles
|
||||
set(value) {
|
||||
config[Vision.STYLE_KEY] = value
|
||||
}
|
||||
@ -53,11 +53,11 @@ abstract class AbstractProxy : AbstractVision(), VisionGroup {
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("solid.proxy")
|
||||
class Proxy private constructor(
|
||||
val templateName: Name
|
||||
public class Proxy private constructor(
|
||||
public val templateName: Name
|
||||
) : AbstractProxy(), Solid {
|
||||
|
||||
constructor(parent: SolidGroup, templateName: Name) : this(templateName) {
|
||||
public constructor(parent: SolidGroup, templateName: Name) : this(templateName) {
|
||||
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
|
||||
* (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)
|
||||
|
||||
@ -136,12 +136,15 @@ class Proxy private constructor(
|
||||
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val PROXY_CHILD_PROPERTY_PREFIX = "@child"
|
||||
public companion object {
|
||||
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) {
|
||||
is AbstractProxy -> prototype
|
||||
else -> this
|
||||
@ -150,7 +153,7 @@ val Vision.prototype: Vision
|
||||
/**
|
||||
* Create ref for existing prototype
|
||||
*/
|
||||
fun SolidGroup.ref(
|
||||
public fun SolidGroup.ref(
|
||||
templateName: Name,
|
||||
name: String = ""
|
||||
): 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
|
||||
*/
|
||||
fun SolidGroup.proxy(
|
||||
public fun SolidGroup.proxy(
|
||||
name: String,
|
||||
obj: Solid,
|
||||
templateName: Name = name.toName()
|
||||
@ -173,12 +176,3 @@ fun SolidGroup.proxy(
|
||||
}
|
||||
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.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.output.Renderer
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||
import hep.dataforge.vision.enum
|
||||
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.LAYER_KEY
|
||||
import hep.dataforge.vision.solid.Solid.Companion.VISIBLE_KEY
|
||||
import kotlinx.serialization.UseSerializers
|
||||
|
||||
/**
|
||||
* Interface for 3-dimensional [Vision]
|
||||
*/
|
||||
interface Solid : Vision {
|
||||
var position: Point3D?
|
||||
var rotation: Point3D?
|
||||
var scale: Point3D?
|
||||
public interface Solid : Vision {
|
||||
public var position: Point3D?
|
||||
public var rotation: Point3D?
|
||||
public var scale: Point3D?
|
||||
|
||||
override val descriptor: NodeDescriptor? get() = Companion.descriptor
|
||||
|
||||
companion object {
|
||||
|
||||
val VISIBLE_KEY = "visible".asName()
|
||||
|
||||
public companion object {
|
||||
// val SELECTED_KEY = "selected".asName()
|
||||
val DETAIL_KEY = "detail".asName()
|
||||
val LAYER_KEY = "layer".asName()
|
||||
val IGNORE_KEY = "ignore".asName()
|
||||
public val DETAIL_KEY: Name = "detail".asName()
|
||||
public val LAYER_KEY: Name = "layer".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()
|
||||
val Y_KEY = "y".asName()
|
||||
val Z_KEY = "z".asName()
|
||||
public val X_KEY: Name = "x".asName()
|
||||
public val Y_KEY: Name = "y".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
|
||||
val Y_POSITION_KEY = POSITION_KEY + Y_KEY
|
||||
val Z_POSITION_KEY = POSITION_KEY + Z_KEY
|
||||
public val X_POSITION_KEY: Name = POSITION_KEY + X_KEY
|
||||
public val Y_POSITION_KEY: Name = POSITION_KEY + Y_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
|
||||
val Y_ROTATION_KEY = ROTATION + Y_KEY
|
||||
val Z_ROTATION_KEY = ROTATION + Z_KEY
|
||||
public val X_ROTATION_KEY: Name = ROTATION + X_KEY
|
||||
public val Y_ROTATION_KEY: Name = ROTATION + Y_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
|
||||
val Y_SCALE_KEY = SCALE_KEY + Y_KEY
|
||||
val Z_SCALE_KEY = SCALE_KEY + Z_KEY
|
||||
public val X_SCALE_KEY: Name = SCALE_KEY + X_KEY
|
||||
public val Y_SCALE_KEY: Name = SCALE_KEY + Y_KEY
|
||||
public val Z_SCALE_KEY: Name = SCALE_KEY + Z_KEY
|
||||
|
||||
val descriptor by lazy {
|
||||
public val descriptor: NodeDescriptor by lazy {
|
||||
NodeDescriptor {
|
||||
value(VISIBLE_KEY) {
|
||||
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
|
||||
set(value) {
|
||||
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)
|
||||
|
||||
// Common properties
|
||||
|
||||
enum class RotationOrder {
|
||||
public enum class RotationOrder {
|
||||
XYZ,
|
||||
YZX,
|
||||
ZXY,
|
||||
@ -125,7 +123,7 @@ enum class RotationOrder {
|
||||
/**
|
||||
* Rotation order
|
||||
*/
|
||||
var Solid.rotationOrder: RotationOrder
|
||||
public var Solid.rotationOrder: RotationOrder
|
||||
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
|
||||
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
|
||||
*/
|
||||
var Solid.detail: Int?
|
||||
public var Solid.detail: Int?
|
||||
get() = getProperty(DETAIL_KEY, false).int
|
||||
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.
|
||||
* Property is not inherited.
|
||||
*/
|
||||
var Vision.ignore: Boolean?
|
||||
public var Vision.ignore: Boolean?
|
||||
get() = getProperty(IGNORE_KEY, false).boolean
|
||||
set(value) = setItem(IGNORE_KEY, value?.asValue())
|
||||
|
||||
@ -156,21 +150,21 @@ var Vision.ignore: Boolean?
|
||||
private fun Solid.position(): Point3D =
|
||||
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
|
||||
|
||||
var Solid.x: Number
|
||||
public var Solid.x: Number
|
||||
get() = position?.x ?: 0f
|
||||
set(value) {
|
||||
position().x = value.toDouble()
|
||||
propertyChanged(Solid.X_POSITION_KEY)
|
||||
}
|
||||
|
||||
var Solid.y: Number
|
||||
public var Solid.y: Number
|
||||
get() = position?.y ?: 0f
|
||||
set(value) {
|
||||
position().y = value.toDouble()
|
||||
propertyChanged(Solid.Y_POSITION_KEY)
|
||||
}
|
||||
|
||||
var Solid.z: Number
|
||||
public var Solid.z: Number
|
||||
get() = position?.z ?: 0f
|
||||
set(value) {
|
||||
position().z = value.toDouble()
|
||||
@ -180,21 +174,21 @@ var Solid.z: Number
|
||||
private fun Solid.rotation(): Point3D =
|
||||
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
|
||||
|
||||
var Solid.rotationX: Number
|
||||
public var Solid.rotationX: Number
|
||||
get() = rotation?.x ?: 0f
|
||||
set(value) {
|
||||
rotation().x = value.toDouble()
|
||||
propertyChanged(Solid.X_ROTATION_KEY)
|
||||
}
|
||||
|
||||
var Solid.rotationY: Number
|
||||
public var Solid.rotationY: Number
|
||||
get() = rotation?.y ?: 0f
|
||||
set(value) {
|
||||
rotation().y = value.toDouble()
|
||||
propertyChanged(Solid.Y_ROTATION_KEY)
|
||||
}
|
||||
|
||||
var Solid.rotationZ: Number
|
||||
public var Solid.rotationZ: Number
|
||||
get() = rotation?.z ?: 0f
|
||||
set(value) {
|
||||
rotation().z = value.toDouble()
|
||||
@ -204,21 +198,21 @@ var Solid.rotationZ: Number
|
||||
private fun Solid.scale(): Point3D =
|
||||
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
|
||||
|
||||
var Solid.scaleX: Number
|
||||
public var Solid.scaleX: Number
|
||||
get() = scale?.x ?: 1f
|
||||
set(value) {
|
||||
scale().x = value.toDouble()
|
||||
propertyChanged(Solid.X_SCALE_KEY)
|
||||
}
|
||||
|
||||
var Solid.scaleY: Number
|
||||
public var Solid.scaleY: Number
|
||||
get() = scale?.y ?: 1f
|
||||
set(value) {
|
||||
scale().y = value.toDouble()
|
||||
propertyChanged(Solid.Y_SCALE_KEY)
|
||||
}
|
||||
|
||||
var Solid.scaleZ: Number
|
||||
public var Solid.scaleZ: Number
|
||||
get() = scale?.z ?: 1f
|
||||
set(value) {
|
||||
scale().z = value.toDouble()
|
||||
|
@ -15,9 +15,9 @@ import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
import kotlin.collections.set
|
||||
|
||||
interface PrototypeHolder {
|
||||
val parent: VisionGroup?
|
||||
val prototypes: MutableVisionGroup?
|
||||
public interface PrototypeHolder {
|
||||
public val parent: VisionGroup?
|
||||
public val prototypes: MutableVisionGroup?
|
||||
}
|
||||
|
||||
/**
|
||||
@ -25,7 +25,7 @@ interface PrototypeHolder {
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("group.solid")
|
||||
class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||
public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||
|
||||
override var styleSheet: StyleSheet? = null
|
||||
|
||||
@ -39,7 +39,7 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||
/**
|
||||
* 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 = it
|
||||
attach(it)
|
||||
@ -79,33 +79,33 @@ class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
|
||||
override fun createGroup(): SolidGroup = SolidGroup()
|
||||
|
||||
|
||||
companion object {
|
||||
public companion object {
|
||||
// val PROTOTYPES_KEY = NameToken("@prototypes")
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
fun parseJson(json: String): SolidGroup =
|
||||
SolidManager.jsonForSolids.parse(serializer(), json).also { it.attachChildren() }
|
||||
public fun decodeFromString(json: String): SolidGroup =
|
||||
SolidManager.jsonForSolids.decodeFromString(serializer(), json).also { it.attachChildren() }
|
||||
}
|
||||
}
|
||||
|
||||
@Suppress("FunctionName")
|
||||
fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
||||
public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
||||
return SolidGroup().apply(block)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
|
||||
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) }
|
||||
|
||||
/**
|
||||
* 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) }
|
||||
|
||||
/**
|
||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -12,7 +13,7 @@ import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
@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 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,
|
||||
fontSize: Number = 20,
|
||||
fontFamily: String = "Arial",
|
||||
name: String = "",
|
||||
action: SolidLabel.() -> Unit = {}
|
||||
) =
|
||||
SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
|
||||
action: SolidLabel.() -> Unit = {},
|
||||
): SolidLabel = 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.VisionManager
|
||||
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.UnstableDefault
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonConfiguration
|
||||
import kotlinx.serialization.modules.SerialModule
|
||||
import kotlinx.serialization.modules.SerialModuleCollector
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.contextual
|
||||
import kotlinx.serialization.modules.*
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@DFExperimental
|
||||
private class SolidForm<T :Solid>(
|
||||
private class SolidForm<T : Solid>(
|
||||
override val type: KClass<T>,
|
||||
override val serializer: KSerializer<T>
|
||||
override val serializer: KSerializer<T>,
|
||||
) : VisionForm<T> {
|
||||
|
||||
private fun Solid.update(meta: Meta) {
|
||||
@ -46,12 +43,12 @@ private class SolidForm<T :Solid>(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@DFExperimental
|
||||
@OptIn(UnstableDefault::class)
|
||||
private fun SerialModule.extractFactories(): List<SolidForm<*>> {
|
||||
private fun SerializersModule.extractFactories(): List<SolidForm<*>> {
|
||||
val list = ArrayList<SolidForm<*>>()
|
||||
|
||||
val collector = object : SerialModuleCollector {
|
||||
val collector = object : SerializersModuleCollector {
|
||||
override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
|
||||
//Do nothing
|
||||
}
|
||||
@ -59,7 +56,7 @@ private fun SerialModule.extractFactories(): List<SolidForm<*>> {
|
||||
override fun <Base : Any, Sub : Base> polymorphic(
|
||||
baseClass: KClass<Base>,
|
||||
actualClass: KClass<Sub>,
|
||||
actualSerializer: KSerializer<Sub>
|
||||
actualSerializer: KSerializer<Sub>,
|
||||
) {
|
||||
if (baseClass == Vision::class) {
|
||||
@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)
|
||||
return list
|
||||
}
|
||||
|
||||
@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 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 }
|
||||
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 type: KClass<out SolidManager> = SolidManager::class
|
||||
override fun invoke(meta: Meta, context: Context): SolidManager = SolidManager(meta)
|
||||
|
||||
val serialModule = SerializersModule {
|
||||
public val serialModule: SerializersModule = SerializersModule {
|
||||
contextual(Point3DSerializer)
|
||||
contextual(Point2DSerializer)
|
||||
|
||||
polymorphic(Vision::class, Solid::class) {
|
||||
polymorphic(Vision::class) {
|
||||
subclass(SimpleVisionGroup.serializer())
|
||||
subclass(SolidGroup.serializer())
|
||||
subclass(Proxy.serializer())
|
||||
@ -112,15 +116,12 @@ class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(UnstableDefault::class)
|
||||
val jsonForSolids = Json(
|
||||
JsonConfiguration(
|
||||
prettyPrint = true,
|
||||
useArrayPolymorphism = false,
|
||||
encodeDefaults = false,
|
||||
ignoreUnknownKeys = true
|
||||
),
|
||||
context = serialModule
|
||||
)
|
||||
val jsonForSolids = Json {
|
||||
prettyPrint = true
|
||||
useArrayPolymorphism = false
|
||||
encodeDefaults = false
|
||||
ignoreUnknownKeys = true
|
||||
serializersModule = this@Companion.serialModule
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.attributes
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
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.widgetType
|
||||
|
||||
class SolidMaterial : Scheme() {
|
||||
public class SolidMaterial : Scheme() {
|
||||
|
||||
/**
|
||||
* 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
|
||||
*/
|
||||
var specularColor by string(key = SPECULAR_COLOR_KEY)
|
||||
public var specularColor: String? by string(key = SPECULAR_COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Opacity
|
||||
*/
|
||||
var opacity by float(1f, key = OPACITY_KEY)
|
||||
public var opacity: Float by float(1f, key = OPACITY_KEY)
|
||||
|
||||
/**
|
||||
* 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()
|
||||
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()
|
||||
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()
|
||||
val MATERIAL_OPACITY_KEY = MATERIAL_KEY + OPACITY_KEY
|
||||
public val MATERIAL_OPACITY_KEY: Name = MATERIAL_KEY + OPACITY_KEY
|
||||
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
|
||||
NodeDescriptor {
|
||||
value(COLOR_KEY) {
|
||||
@ -77,18 +78,18 @@ class SolidMaterial : Scheme() {
|
||||
/**
|
||||
* Set color as web-color
|
||||
*/
|
||||
fun Solid.color(webColor: String) {
|
||||
public fun Solid.color(webColor: String) {
|
||||
setItem(MATERIAL_COLOR_KEY, webColor.asValue())
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color as integer
|
||||
*/
|
||||
fun Solid.color(rgb: Int) {
|
||||
public fun Solid.color(rgb: Int) {
|
||||
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,
|
||||
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
|
||||
*/
|
||||
var Solid.color: String?
|
||||
public var Solid.color: String?
|
||||
get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
||||
set(value) {
|
||||
setItem(MATERIAL_COLOR_KEY, value?.asValue())
|
||||
}
|
||||
|
||||
val Solid.material: SolidMaterial?
|
||||
public val Solid.material: SolidMaterial?
|
||||
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
|
||||
if (node != null) {
|
||||
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
|
||||
set(value) {
|
||||
setItem(MATERIAL_OPACITY_KEY, value?.asValue())
|
||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -15,12 +16,12 @@ import kotlin.math.sin
|
||||
|
||||
@Serializable
|
||||
@SerialName("solid.sphere")
|
||||
class Sphere(
|
||||
var radius: Float,
|
||||
var phiStart: Float = 0f,
|
||||
var phi: Float = PI2,
|
||||
var thetaStart: Float = 0f,
|
||||
var theta: Float = PI.toFloat()
|
||||
public class Sphere(
|
||||
public var radius: Float,
|
||||
public var phiStart: Float = 0f,
|
||||
public var phi: Float = PI2,
|
||||
public var thetaStart: Float = 0f,
|
||||
public var theta: Float = PI.toFloat()
|
||||
) : AbstractVision(), GeometrySolid {
|
||||
|
||||
override var properties: Config? = null
|
||||
@ -60,13 +61,13 @@ class Sphere(
|
||||
}
|
||||
}
|
||||
|
||||
inline fun MutableVisionGroup.sphere(
|
||||
public inline fun VisionContainerBuilder<Solid>.sphere(
|
||||
radius: Number,
|
||||
phi: Number = 2 * PI,
|
||||
theta: Number = PI,
|
||||
name: String = "",
|
||||
action: Sphere.() -> Unit = {}
|
||||
) = Sphere(
|
||||
): Sphere = Sphere(
|
||||
radius.toFloat(),
|
||||
phi = phi.toFloat(),
|
||||
theta = theta.toFloat()
|
||||
|
@ -5,6 +5,7 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.vision.AbstractVision
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
@ -18,12 +19,12 @@ import kotlin.math.sin
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("solid.tube")
|
||||
class Tube(
|
||||
var radius: Float,
|
||||
var height: Float,
|
||||
var innerRadius: Float = 0f,
|
||||
var startAngle: Float = 0f,
|
||||
var angle: Float = PI2
|
||||
public class Tube(
|
||||
public var radius: Float,
|
||||
public var height: Float,
|
||||
public var innerRadius: Float = 0f,
|
||||
public var startAngle: Float = 0f,
|
||||
public var angle: Float = PI2
|
||||
) : AbstractVision(), GeometrySolid {
|
||||
|
||||
override var position: Point3D? = null
|
||||
@ -129,7 +130,7 @@ class Tube(
|
||||
|
||||
}
|
||||
|
||||
inline fun MutableVisionGroup.tube(
|
||||
public inline fun VisionContainerBuilder<Solid>.tube(
|
||||
r: Number,
|
||||
height: Number,
|
||||
innerRadius: Number = 0f,
|
||||
|
@ -1,47 +1,48 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.number
|
||||
import kotlin.math.PI
|
||||
|
||||
object World {
|
||||
val ZERO = Point3D(0.0, 0.0, 0.0)
|
||||
val ONE = Point3D(1.0, 1.0, 1.0)
|
||||
public object World {
|
||||
public val ZERO: Point3D = Point3D(0.0, 0.0, 0.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) {
|
||||
var x: Double
|
||||
var y: Double
|
||||
public expect class Point2D(x: Number, y: Number) {
|
||||
public var x: Double
|
||||
public var y: Double
|
||||
}
|
||||
|
||||
operator fun Point2D.component1() = x
|
||||
operator fun Point2D.component2() = y
|
||||
public operator fun Point2D.component1(): Double = x
|
||||
public operator fun Point2D.component2(): Double = y
|
||||
|
||||
fun Point2D.toMeta() = Meta {
|
||||
public fun Point2D.toMeta(): Meta = Meta {
|
||||
Solid.X_KEY put x
|
||||
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) {
|
||||
var x: Double
|
||||
var y: Double
|
||||
var z: Double
|
||||
public expect class Point3D(x: Number, y: Number, z: Number) {
|
||||
public var x: Double
|
||||
public var y: 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
|
||||
operator fun Point3D.component2() = y
|
||||
operator fun Point3D.component3() = z
|
||||
public operator fun Point3D.component1(): Double = x
|
||||
public operator fun Point3D.component2(): Double = y
|
||||
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.Y_KEY put y
|
||||
Solid.Z_KEY put z
|
||||
|
@ -2,6 +2,7 @@ package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.double
|
||||
import hep.dataforge.meta.transformations.MetaConverter.Companion.double
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.Vision
|
||||
@ -10,34 +11,19 @@ import kotlinx.serialization.*
|
||||
import kotlinx.serialization.builtins.MapSerializer
|
||||
import kotlinx.serialization.builtins.nullable
|
||||
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)
|
||||
object Point3DSerializer : KSerializer<Point3D> {
|
||||
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
||||
double("x", true)
|
||||
double("y", true)
|
||||
double("z", true)
|
||||
public object Point3DSerializer : KSerializer<Point3D> {
|
||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point3D") {
|
||||
element<Double>("x")
|
||||
element<Double>("y")
|
||||
element<Double>("z")
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): Point3D {
|
||||
@ -47,7 +33,7 @@ object Point3DSerializer : KSerializer<Point3D> {
|
||||
decoder.decodeStructure(descriptor) {
|
||||
loop@ while (true) {
|
||||
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
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, 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)
|
||||
object Point2DSerializer : KSerializer<Point2D> {
|
||||
override val descriptor: SerialDescriptor = SerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
||||
double("x", true)
|
||||
double("y", true)
|
||||
public object Point2DSerializer : KSerializer<Point2D> {
|
||||
override val descriptor: SerialDescriptor = buildClassSerialDescriptor("hep.dataforge.vis.spatial.Point2D") {
|
||||
element<Double>("x")
|
||||
element<Double>("y")
|
||||
}
|
||||
|
||||
override fun deserialize(decoder: Decoder): Point2D {
|
||||
@ -80,7 +67,7 @@ object Point2DSerializer : KSerializer<Point2D> {
|
||||
decoder.decodeStructure(descriptor) {
|
||||
loop@ while (true) {
|
||||
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
|
||||
1 -> y = decodeNullableSerializableElement(descriptor, 1, Double.serializer().nullable) ?: 0.0
|
||||
else -> throw SerializationException("Unknown index $i")
|
||||
@ -98,6 +85,7 @@ object Point2DSerializer : KSerializer<Point2D> {
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalSerializationApi::class)
|
||||
@Serializer(MutableVisionGroup::class)
|
||||
internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
||||
|
||||
@ -120,10 +108,10 @@ internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
|
||||
}
|
||||
|
||||
@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)
|
||||
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){
|
||||
it.attachChildren()
|
||||
}
|
||||
|
@ -2,13 +2,13 @@ package hep.dataforge.vision.solid.specifications
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
|
||||
class Axes : Scheme() {
|
||||
var visible by boolean(!config.isEmpty())
|
||||
var size by double(AXIS_SIZE)
|
||||
var width by double(AXIS_WIDTH)
|
||||
public class Axes : Scheme() {
|
||||
public var visible: Boolean by boolean(!config.isEmpty())
|
||||
public var size: Double by double(AXIS_SIZE)
|
||||
public var width: Double by double(AXIS_WIDTH)
|
||||
|
||||
companion object : SchemeSpec<Axes>(::Axes) {
|
||||
const val AXIS_SIZE = 1000.0
|
||||
const val AXIS_WIDTH = 3.0
|
||||
public companion object : SchemeSpec<Axes>(::Axes) {
|
||||
public const val AXIS_SIZE: Double = 1000.0
|
||||
public const val AXIS_WIDTH: Double = 3.0
|
||||
}
|
||||
}
|
@ -6,24 +6,24 @@ import hep.dataforge.meta.double
|
||||
import hep.dataforge.meta.int
|
||||
import kotlin.math.PI
|
||||
|
||||
class Camera : Scheme() {
|
||||
var fov by int(FIELD_OF_VIEW)
|
||||
public class Camera : Scheme() {
|
||||
public var fov: Int by int(FIELD_OF_VIEW)
|
||||
|
||||
//var aspect by double(1.0)
|
||||
var nearClip by double(NEAR_CLIP)
|
||||
var farClip by double(FAR_CLIP)
|
||||
public var nearClip: Double by double(NEAR_CLIP)
|
||||
public var farClip: Double by double(FAR_CLIP)
|
||||
|
||||
var distance by double(INITIAL_DISTANCE)
|
||||
var azimuth by double(INITIAL_AZIMUTH)
|
||||
var latitude by double(INITIAL_LATITUDE)
|
||||
val zenith: Double get() = PI / 2 - latitude
|
||||
public var distance: Double by double(INITIAL_DISTANCE)
|
||||
public var azimuth: Double by double(INITIAL_AZIMUTH)
|
||||
public var latitude: Double by double(INITIAL_LATITUDE)
|
||||
public val zenith: Double get() = PI / 2 - latitude
|
||||
|
||||
companion object : SchemeSpec<Camera>(::Camera) {
|
||||
const val INITIAL_DISTANCE = 300.0
|
||||
const val INITIAL_AZIMUTH = 0.0
|
||||
const val INITIAL_LATITUDE = PI / 6
|
||||
const val NEAR_CLIP = 0.1
|
||||
const val FAR_CLIP = 10000.0
|
||||
const val FIELD_OF_VIEW = 75
|
||||
public companion object : SchemeSpec<Camera>(::Camera) {
|
||||
public const val INITIAL_DISTANCE: Double = 300.0
|
||||
public const val INITIAL_AZIMUTH: Double = 0.0
|
||||
public const val INITIAL_LATITUDE: Double = PI / 6
|
||||
public const val NEAR_CLIP: Double = 0.1
|
||||
public const val FAR_CLIP: Double = 10000.0
|
||||
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.spec
|
||||
|
||||
class Canvas3DOptions : Scheme() {
|
||||
var axes by spec(Axes, Axes.empty())
|
||||
var camera by spec(Camera, Camera.empty())
|
||||
var controls by spec(Controls, Controls.empty())
|
||||
var minSize by int(300)
|
||||
public class Canvas3DOptions : Scheme() {
|
||||
public var axes: Axes by spec(Axes, Axes.empty())
|
||||
public var camera: Camera by spec(Camera, Camera.empty())
|
||||
public var controls: Controls by spec(Controls, Controls.empty())
|
||||
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
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
@ -7,6 +8,7 @@ import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionGroup
|
||||
import hep.dataforge.vision.solid.*
|
||||
|
||||
@DFExperimental
|
||||
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||
return child.apply {
|
||||
|
||||
@ -32,6 +34,7 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||
}
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
|
||||
|
||||
override fun SolidGroup.transformInPlace() {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid.transform
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
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.SolidGroup
|
||||
|
||||
@DFExperimental
|
||||
object UnRef : VisualTreeTransform<SolidGroup>() {
|
||||
private fun VisionGroup.countRefs(): Map<Name, Int> {
|
||||
return children.values.fold(HashMap()) { reducer, obj ->
|
||||
|
@ -1,6 +1,7 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import kotlinx.serialization.json.toJson
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -24,7 +25,7 @@ class ConvexTest {
|
||||
|
||||
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 points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
||||
|
@ -1,11 +1,26 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.get
|
||||
import kotlin.test.Test
|
||||
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 {
|
||||
@Test
|
||||
fun testCubeSerialization() {
|
||||
@ -14,9 +29,9 @@ class SerializationTest {
|
||||
x = 100
|
||||
z = -100
|
||||
}
|
||||
val string = cube.stringify()
|
||||
val string = cube.encodeToString()
|
||||
println(string)
|
||||
val newCube = Vision.parseJson(string)
|
||||
val newCube = Vision.decodeFromString(string)
|
||||
assertEquals(cube.config, newCube.config)
|
||||
}
|
||||
|
||||
@ -35,9 +50,9 @@ class SerializationTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
val string = group.stringify()
|
||||
val string = group.encodeToString()
|
||||
println(string)
|
||||
val reconstructed = SolidGroup.parseJson(string)
|
||||
val reconstructed = SolidGroup.decodeFromString(string)
|
||||
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.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)
|
||||
}
|
@ -8,6 +8,7 @@ import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
|
||||
import hep.dataforge.vision.visible
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.core.Object3D
|
||||
import info.laht.threekt.objects.Mesh
|
||||
@ -54,7 +55,7 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
||||
) {
|
||||
//update position of mesh using this object
|
||||
updatePosition(source)
|
||||
} else if (propertyName == Solid.VISIBLE_KEY) {
|
||||
} else if (propertyName == Vision.VISIBLE_KEY) {
|
||||
visible = source.visible ?: true
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.visible
|
||||
import info.laht.threekt.core.Object3D
|
||||
import kotlin.collections.set
|
||||
import kotlin.reflect.KClass
|
||||
@ -30,7 +31,7 @@ class ThreePlugin : AbstractPlugin() {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? {
|
||||
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>?
|
||||
}
|
||||
|
||||
@ -63,7 +64,7 @@ class ThreePlugin : AbstractPlugin() {
|
||||
) {
|
||||
//update position of mesh using this object
|
||||
updatePosition(obj)
|
||||
} else if (name == Solid.VISIBLE_KEY) {
|
||||
} else if (name == Vision.VISIBLE_KEY) {
|
||||
visible = obj.visible ?: true
|
||||
}
|
||||
}
|
||||
@ -123,28 +124,28 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
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 ->
|
||||
group.name = token.toString()
|
||||
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) {
|
||||
when (name.length) {
|
||||
0 -> error("Can't set object with an empty name")
|
||||
1 -> set(name.first()!!, obj)
|
||||
else -> getOrCreateGroup(name.cutLast())[name.last()!!] = obj
|
||||
1 -> set(name.tokens.first(), obj)
|
||||
else -> getOrCreateGroup(name.cutLast())[name.tokens.last()] = obj
|
||||
}
|
||||
}
|
||||
|
||||
internal fun Object3D.findChild(name: Name): Object3D? {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
name.length == 1 -> this.children.find { it.name == name.first()!!.toString() }
|
||||
else -> findChild(name.first()!!.asName())?.findChild(name.cutFirst())
|
||||
name.length == 1 -> this.children.find { it.name == name.tokens.first().toString() }
|
||||
else -> findChild(name.tokens.first().asName())?.findChild(name.cutFirst())
|
||||
}
|
||||
}
|
@ -1,5 +1,7 @@
|
||||
package hep.dataforge.vision.solid.three
|
||||
|
||||
import hep.dataforge.names.cutFirst
|
||||
import hep.dataforge.names.firstOrNull
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.solid.Proxy
|
||||
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 ->
|
||||
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
|
||||
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||
if (name.firstOrNull()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
|
||||
val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||
val propertyName = name.cutFirst()
|
||||
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")
|
||||
|
@ -38,7 +38,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
||||
div("row") {
|
||||
div("col-2") {
|
||||
label("checkbox-inline") {
|
||||
input(type = InputType.checkBox){
|
||||
input(type = InputType.checkBox) {
|
||||
attrs {
|
||||
defaultChecked = canvas.axes.visible
|
||||
onChangeFunction = {
|
||||
@ -55,7 +55,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
||||
attrs {
|
||||
onClickFunction = {
|
||||
val json = (canvas.content as? SolidGroup)?.let { group ->
|
||||
SolidManager.jsonForSolids.stringify(
|
||||
SolidManager.jsonForSolids.encodeToString(
|
||||
SolidGroup.serializer(),
|
||||
group
|
||||
)
|
||||
@ -76,7 +76,7 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
|
||||
(0..11).forEach { layer ->
|
||||
div("col-1") {
|
||||
label { +layer.toString() }
|
||||
input(type = InputType.checkBox){
|
||||
input(type = InputType.checkBox) {
|
||||
attrs {
|
||||
if (layer == 0) {
|
||||
defaultChecked = true
|
||||
@ -119,7 +119,7 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
|
||||
+"Export"
|
||||
onClickFunction = {
|
||||
val json = (canvas.content as? SolidGroup)?.let { group ->
|
||||
SolidManager.jsonForSolids.stringify(
|
||||
SolidManager.jsonForSolids.encodeToString(
|
||||
SolidGroup.serializer(),
|
||||
group
|
||||
)
|
||||
|
@ -38,7 +38,7 @@ class FX3DPlugin : AbstractPlugin() {
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
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>?
|
||||
}
|
||||
|
||||
|
@ -1,8 +1,6 @@
|
||||
package hep.dataforge.vision.solid.fx
|
||||
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.solid.Proxy
|
||||
import javafx.scene.Group
|
||||
@ -17,8 +15,8 @@ class FXProxyFactory(val plugin: FX3DPlugin) : FX3DFactory<Proxy> {
|
||||
val node = plugin.buildNode(prototype)
|
||||
|
||||
obj.onPropertyChange(this) { name->
|
||||
if (name.first()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) {
|
||||
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||
if (name.firstOrNull()?.body == Proxy.PROXY_CHILD_PROPERTY_PREFIX) {
|
||||
val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||
val propertyName = name.cutFirst()
|
||||
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")
|
||||
@ -35,7 +33,7 @@ private fun Node.findChild(name: Name): Node? {
|
||||
} else {
|
||||
(this as? Group)
|
||||
?.children
|
||||
?.find { it.properties["name"] as String == name.first()?.toString() }
|
||||
?.find { it.properties["name"] as String == name.firstOrNull()?.toString() }
|
||||
?.findChild(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
@ -1,205 +1,208 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.JSON_PRETTY
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.json.*
|
||||
import kotlinx.serialization.modules.SerialModule
|
||||
import kotlinx.serialization.modules.SerialModuleCollector
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
||||
StructureKind.LIST -> "array"
|
||||
PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||
PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||
PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||
PrimitiveKind.BOOLEAN -> "boolean"
|
||||
else -> "object"
|
||||
}
|
||||
|
||||
private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid")
|
||||
|
||||
private const val definitionNode = "\$defs"
|
||||
|
||||
private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
||||
val list = ArrayList<SerialDescriptor>()
|
||||
fun send(descriptor: SerialDescriptor) = list.add(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>
|
||||
) {
|
||||
if (baseClass == type) {
|
||||
send(actualSerializer.descriptor)
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
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;
|
||||
* `properties` and `required` for objects;
|
||||
* `enum` for enums;
|
||||
* `items` for arrays.
|
||||
*
|
||||
* User can modify this schema to add additional validation keywords
|
||||
* (as per [https://json-schema.org/latest/json-schema-validation.html])
|
||||
* if they want.
|
||||
*/
|
||||
private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
||||
|
||||
if (descriptor.serialName in arrayOf(
|
||||
"hep.dataforge.vision.solid.Point3D",
|
||||
"hep.dataforge.vision.solid.Point3D?",
|
||||
"hep.dataforge.vision.solid.Point2D",
|
||||
"hep.dataforge.vision.solid.Point2D?",
|
||||
"hep.dataforge.meta.Meta",
|
||||
"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
|
||||
|
||||
|
||||
if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
||||
val elementName = descriptor.getElementName(index)
|
||||
|
||||
val elementSchema = when (elementName) {
|
||||
"properties" -> json {
|
||||
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
||||
}
|
||||
"first", "second" -> json {
|
||||
"\$ref" to "#/$definitionNode/children"
|
||||
}
|
||||
"styleSheet" -> json {
|
||||
"type" to "object"
|
||||
"additionalProperties" to json {
|
||||
"\$ref" to "#/$definitionNode/hep.dataforge.meta.Meta"
|
||||
}
|
||||
}
|
||||
in arrayOf("children", "prototypes") -> json {
|
||||
"type" to "object"
|
||||
"additionalProperties" to json {
|
||||
"\$ref" to "#/$definitionNode/children"
|
||||
}
|
||||
}
|
||||
else -> jsonSchema(child, context)
|
||||
}
|
||||
properties[elementName] = elementSchema
|
||||
|
||||
if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
||||
}
|
||||
|
||||
val jsonType = descriptor.getJsonType()
|
||||
val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
||||
"description" to JsonLiteral(descriptor.serialName),
|
||||
"type" to JsonLiteral(jsonType)
|
||||
)
|
||||
if (isEnum) {
|
||||
val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName)
|
||||
objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral))
|
||||
}
|
||||
when (jsonType) {
|
||||
"object" -> {
|
||||
if(descriptor.isVisualObject()) {
|
||||
properties["type"] = json {
|
||||
"const" to descriptor.serialName
|
||||
}
|
||||
}
|
||||
objectData["properties"] = JsonObject(properties)
|
||||
val required = requiredProperties.map { JsonLiteral(it) }
|
||||
if (required.isNotEmpty()) {
|
||||
objectData["required"] = JsonArray(required)
|
||||
}
|
||||
}
|
||||
"array" -> objectData["items"] = properties.values.let {
|
||||
check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" }
|
||||
it.first()
|
||||
}
|
||||
else -> { /* no-op */
|
||||
}
|
||||
}
|
||||
return JsonObject(objectData)
|
||||
}
|
||||
|
||||
fun main() {
|
||||
val context = SolidManager.serialModule
|
||||
val definitions = json {
|
||||
"children" to json {
|
||||
"anyOf" to jsonArray {
|
||||
context.enumerate(Solid::class).forEach {
|
||||
if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") {
|
||||
+json {
|
||||
"\$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 {
|
||||
"type" to "object"
|
||||
"properties" to json {
|
||||
"x" to json {
|
||||
"type" to "number"
|
||||
}
|
||||
"y" to json {
|
||||
"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 {
|
||||
"type" to "number"
|
||||
}
|
||||
"y" to json {
|
||||
"type" to "number"
|
||||
}
|
||||
}
|
||||
}
|
||||
"hep.dataforge.vision.solid.SolidGroup" to jsonSchema(
|
||||
SolidGroup.serializer().descriptor,
|
||||
context
|
||||
)
|
||||
|
||||
}
|
||||
|
||||
println(
|
||||
JSON_PRETTY.stringify(
|
||||
JsonObjectSerializer,
|
||||
json {
|
||||
"\$defs" to definitions
|
||||
"\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup"
|
||||
}
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
//package hep.dataforge.vision.solid
|
||||
//
|
||||
//import hep.dataforge.meta.JSON_PRETTY
|
||||
//import kotlinx.serialization.*
|
||||
//import kotlinx.serialization.descriptors.PrimitiveKind
|
||||
//import kotlinx.serialization.descriptors.SerialDescriptor
|
||||
//import kotlinx.serialization.descriptors.StructureKind
|
||||
//import kotlinx.serialization.descriptors.UnionKind
|
||||
//import kotlinx.serialization.json.*
|
||||
//import kotlinx.serialization.modules.SerialModule
|
||||
//import kotlin.reflect.KClass
|
||||
//
|
||||
//private fun SerialDescriptor.getJsonType() = when (this.kind) {
|
||||
// StructureKind.LIST -> "array"
|
||||
// PrimitiveKind.BYTE, PrimitiveKind.SHORT, PrimitiveKind.INT, PrimitiveKind.LONG,
|
||||
// PrimitiveKind.FLOAT, PrimitiveKind.DOUBLE -> "number"
|
||||
// PrimitiveKind.STRING, PrimitiveKind.CHAR, UnionKind.ENUM_KIND -> "string"
|
||||
// PrimitiveKind.BOOLEAN -> "boolean"
|
||||
// else -> "object"
|
||||
//}
|
||||
//
|
||||
//private fun SerialDescriptor.isVisualObject() = serialName.startsWith("solid")||serialName.startsWith("group.solid")
|
||||
//
|
||||
//private const val definitionNode = "\$defs"
|
||||
//
|
||||
//private fun SerialModule.enumerate(type: KClass<*>): Sequence<SerialDescriptor> {
|
||||
// val list = ArrayList<SerialDescriptor>()
|
||||
// fun send(descriptor: SerialDescriptor) = list.add(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>
|
||||
// ) {
|
||||
// if (baseClass == type) {
|
||||
// send(actualSerializer.descriptor)
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// }
|
||||
// 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;
|
||||
// * `properties` and `required` for objects;
|
||||
// * `enum` for enums;
|
||||
// * `items` for arrays.
|
||||
// *
|
||||
// * User can modify this schema to add additional validation keywords
|
||||
// * (as per [https://json-schema.org/latest/json-schema-validation.html])
|
||||
// * if they want.
|
||||
// */
|
||||
//private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): JsonObject {
|
||||
//
|
||||
// if (descriptor.serialName in arrayOf(
|
||||
// "hep.dataforge.vision.solid.Point3D",
|
||||
// "hep.dataforge.vision.solid.Point3D?",
|
||||
// "hep.dataforge.vision.solid.Point2D",
|
||||
// "hep.dataforge.vision.solid.Point2D?",
|
||||
// "hep.dataforge.meta.Meta",
|
||||
// "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
|
||||
//
|
||||
//
|
||||
// if (!isEnum && !isPolymorphic) descriptor.elementDescriptors().forEachIndexed { index, child ->
|
||||
// val elementName = descriptor.getElementName(index)
|
||||
//
|
||||
// val elementSchema = when (elementName) {
|
||||
// "properties" -> buildJsonObject {
|
||||
// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta")
|
||||
// }
|
||||
// "first", "second" -> buildJsonObject {
|
||||
// put("\$ref", "#/$definitionNode/children")
|
||||
// }
|
||||
// "styleSheet" -> buildJsonObject {
|
||||
// put("type", "object")
|
||||
// put("additionalProperties", buildJsonObject {
|
||||
// put("\$ref", "#/$definitionNode/hep.dataforge.meta.Meta")
|
||||
// })
|
||||
// }
|
||||
// in arrayOf("children", "prototypes") -> buildJsonObject {
|
||||
// put("type", "object")
|
||||
// put("additionalProperties", buildJsonObject {
|
||||
// put("\$ref", "#/$definitionNode/children")
|
||||
// })
|
||||
// }
|
||||
// else -> jsonSchema(child, context)
|
||||
// }
|
||||
// properties[elementName] = elementSchema
|
||||
//
|
||||
// if (!descriptor.isElementOptional(index)) requiredProperties.add(elementName)
|
||||
// }
|
||||
//
|
||||
// val jsonType = descriptor.getJsonType()
|
||||
// val objectData: MutableMap<String, JsonElement> = mutableMapOf(
|
||||
// "description" to JsonLiteral(descriptor.serialName),
|
||||
// "type" to JsonLiteral(jsonType)
|
||||
// )
|
||||
// if (isEnum) {
|
||||
// val allElementNames = (0 until descriptor.elementsCount).map(descriptor::getElementName)
|
||||
// objectData += "enum" to JsonArray(allElementNames.map(::JsonLiteral))
|
||||
// }
|
||||
// when (jsonType) {
|
||||
// "object" -> {
|
||||
// if(descriptor.isVisualObject()) {
|
||||
// properties["type"] = json {
|
||||
// "const" to descriptor.serialName
|
||||
// }
|
||||
// }
|
||||
// objectData["properties"] = JsonObject(properties)
|
||||
// val required = requiredProperties.map { JsonLiteral(it) }
|
||||
// if (required.isNotEmpty()) {
|
||||
// objectData["required"] = JsonArray(required)
|
||||
// }
|
||||
// }
|
||||
// "array" -> objectData["items"] = properties.values.let {
|
||||
// check(it.size == 1) { "Array descriptor has returned inconsistent number of elements: expected 1, found ${it.size}" }
|
||||
// it.first()
|
||||
// }
|
||||
// else -> { /* no-op */
|
||||
// }
|
||||
// }
|
||||
// return JsonObject(objectData)
|
||||
//}
|
||||
//
|
||||
//fun main() {
|
||||
// val context = SolidManager.serialModule
|
||||
// val definitions = json {
|
||||
// "children" to json {
|
||||
// "anyOf" to jsonArray {
|
||||
// context.enumerate(Solid::class).forEach {
|
||||
// if (it.serialName == "hep.dataforge.vis.spatial.SolidGroup") {
|
||||
// +json {
|
||||
// "\$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 {
|
||||
// "type" to "object"
|
||||
// "properties" to json {
|
||||
// "x" to json {
|
||||
// "type" to "number"
|
||||
// }
|
||||
// "y" to json {
|
||||
// "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 {
|
||||
// "type" to "number"
|
||||
// }
|
||||
// "y" to json {
|
||||
// "type" to "number"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// "hep.dataforge.vision.solid.SolidGroup" to jsonSchema(
|
||||
// SolidGroup.serializer().descriptor,
|
||||
// context
|
||||
// )
|
||||
//
|
||||
// }
|
||||
//
|
||||
// println(
|
||||
// JSON_PRETTY.stringify(
|
||||
// JsonObjectSerializer,
|
||||
// json {
|
||||
// "\$defs" to definitions
|
||||
// "\$ref" to "#/$definitionNode/hep.dataforge.vision.solid.SolidGroup"
|
||||
// }
|
||||
// )
|
||||
// )
|
||||
//}
|
||||
//
|
||||
|
@ -1,11 +1,11 @@
|
||||
package hep.dataforge.vision.solid
|
||||
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 class Point3D(val point: FXPoint3D) {
|
||||
public actual class Point3D(val point: FXPoint3D) {
|
||||
actual constructor(x: Number, y: Number, z: Number) : this(
|
||||
FXPoint3D(
|
||||
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 set(value) {
|
||||
point.x = value.toFloat()
|
||||
}
|
||||
|
||||
actual var y: Double
|
||||
public actual var y: Double
|
||||
inline get() = point.y.toDouble()
|
||||
inline set(value) {
|
||||
point.y = value.toFloat()
|
||||
}
|
||||
|
||||
actual var z: Double
|
||||
public actual var z: Double
|
||||
inline get() = point.z.toDouble()
|
||||
inline set(value) {
|
||||
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))
|
||||
}
|
Loading…
Reference in New Issue
Block a user