Remove global VisionForge object
This commit is contained in:
parent
97b988d419
commit
0961ae90b7
@ -1,27 +1,29 @@
|
||||
plugins {
|
||||
id("ru.mipt.npm.gradle.project")
|
||||
kotlin("multiplatform") apply false
|
||||
kotlin("jvm") apply false
|
||||
kotlin("js") apply false
|
||||
kotlin("jupyter.api") apply false
|
||||
id("ru.mipt.npm.gradle.js") apply false
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.4.0-dev-2")
|
||||
val kotlinWrappersVersion by extra("pre.148-kotlin-1.4.30")
|
||||
val fxVersion by extra("14")
|
||||
val dataforgeVersion by extra("0.4.0")
|
||||
val kotlinWrappersVersion by extra("pre.152-kotlin-1.4.32")
|
||||
val fxVersion by extra("11")
|
||||
|
||||
allprojects {
|
||||
repositories {
|
||||
mavenLocal()
|
||||
mavenCentral()
|
||||
jcenter()
|
||||
maven("https://repo.kotlin.link")
|
||||
maven("https://kotlin.bintray.com/kotlin-js-wrappers")
|
||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
||||
maven("http://maven.jzy3d.org/releases")
|
||||
maven("https://maven.jzy3d.org/releases")
|
||||
maven("https://maven.pkg.jetbrains.space/kotlin/p/kotlin/kotlin-js-wrappers")
|
||||
maven("https://maven.pkg.jetbrains.space/public/p/kotlinx-html/maven")
|
||||
}
|
||||
|
||||
group = "space.kscience"
|
||||
version = "0.2.0-dev-13"
|
||||
version = "0.2.0-dev-15"
|
||||
}
|
||||
|
||||
subprojects {
|
||||
|
@ -2,8 +2,7 @@ import ru.mipt.npm.gradle.DependencyConfiguration
|
||||
import ru.mipt.npm.gradle.FXModule
|
||||
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.common")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
application
|
||||
}
|
||||
|
||||
|
@ -3,12 +3,12 @@ package space.kscience.visionforge.gdml
|
||||
import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.names.toName
|
||||
import space.kscience.dataforge.values.asValue
|
||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.setProperty
|
||||
import space.kscience.visionforge.solid.SolidMaterial
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
import kotlin.test.assertTrue
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class GDMLVisualTest {
|
||||
|
||||
@ -23,10 +23,10 @@ class GDMLVisualTest {
|
||||
|
||||
@Test
|
||||
fun testPrototypeProperty() {
|
||||
val visual = cubes.toVision()
|
||||
val child = visual["composite[0,0,0].segment[0]".toName()]
|
||||
assertTrue { child!= null }
|
||||
child?.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
||||
assertEquals("red", child?.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string)
|
||||
val vision = GdmlShowCase.cubes().toVision()
|
||||
val child = vision["composite-000.segment-0".toName()]
|
||||
assertNotNull(child)
|
||||
child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
||||
assertEquals("red", child.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string)
|
||||
}
|
||||
}
|
@ -4,9 +4,9 @@ import kotlinx.browser.document
|
||||
import react.child
|
||||
import react.dom.render
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.Application
|
||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||
import space.kscience.visionforge.gdml.GdmlShowcase
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
import space.kscience.visionforge.startApplication
|
||||
@ -19,13 +19,13 @@ private class GDMLDemoApp : Application {
|
||||
|
||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||
|
||||
val context = Global.context("demo") .apply{
|
||||
plugins.fetch(ThreePlugin)
|
||||
val context = Global.buildContext("demo"){
|
||||
plugin(ThreePlugin)
|
||||
}
|
||||
|
||||
render(element) {
|
||||
child(GDMLApp) {
|
||||
val vision = GdmlShowcase.cubes.toVision()
|
||||
val vision = GdmlShowCase.cubes().toVision()
|
||||
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
||||
attrs {
|
||||
this.context = context
|
||||
|
@ -3,12 +3,13 @@ package space.kscience.visionforge.gdml.demo
|
||||
import javafx.geometry.Orientation
|
||||
import javafx.scene.Parent
|
||||
import javafx.stage.FileChooser
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.VisionManager
|
||||
import space.kscience.visionforge.describedProperties
|
||||
import space.kscience.visionforge.editor.VisualObjectEditorFragment
|
||||
import space.kscience.visionforge.editor.VisualObjectTreeFragment
|
||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.solid.FX3DPlugin
|
||||
import space.kscience.visionforge.solid.FXCanvas3D
|
||||
@ -19,8 +20,13 @@ import tornadofx.*
|
||||
class GDMLDemoApp : App(GDMLView::class)
|
||||
|
||||
class GDMLView : View() {
|
||||
private val fx3d = Global.plugins.fetch(FX3DPlugin)
|
||||
private val visionManager = Global.plugins.fetch(VisionManager)
|
||||
private val context = Context {
|
||||
plugin(FX3DPlugin)
|
||||
plugin(VisionManager)
|
||||
}
|
||||
|
||||
private val fx3d = context.fetch(FX3DPlugin)
|
||||
private val visionManager = context.fetch(VisionManager)
|
||||
private val canvas = FXCanvas3D(fx3d)
|
||||
|
||||
private val treeFragment = VisualObjectTreeFragment().apply {
|
||||
@ -61,7 +67,7 @@ class GDMLView : View() {
|
||||
|
||||
init {
|
||||
runAsync {
|
||||
cubes.toVision()
|
||||
GdmlShowCase.cubes().toVision()
|
||||
} ui {
|
||||
canvas.render(it)
|
||||
}
|
||||
|
@ -7,9 +7,6 @@ plugins {
|
||||
repositories {
|
||||
mavenCentral()
|
||||
maven("https://repo.kotlin.link")
|
||||
maven("https://dl.bintray.com/mipt-npm/dataforge")
|
||||
maven("https://dl.bintray.com/mipt-npm/kscience")
|
||||
maven("https://dl.bintray.com/mipt-npm/dev")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
|
@ -8,19 +8,17 @@ import kotlinx.html.unsafe
|
||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.plotly.Plot
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||
import space.kscience.visionforge.html.Page
|
||||
import space.kscience.visionforge.html.embedVisionFragment
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
import space.kscience.visionforge.plotly.toVision
|
||||
import space.kscience.visionforge.plotly.usePlotly
|
||||
import space.kscience.visionforge.plugins
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.visionManager
|
||||
|
||||
@ -28,6 +26,11 @@ import space.kscience.visionforge.visionManager
|
||||
@DFExperimental
|
||||
internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
|
||||
private val context = Context("VisionForge") {
|
||||
plugin(Solids)
|
||||
plugin(PlotlyPlugin)
|
||||
}
|
||||
|
||||
private val jsBundle = ResourceFallbacksBundle(listOf(
|
||||
ResourceLocation("js/visionforge-playground.js", ResourcePathType.CLASSPATH_PATH))
|
||||
)
|
||||
@ -39,22 +42,17 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
val id = "visionforge.vision[${counter++}]"
|
||||
div {
|
||||
this.id = id
|
||||
embedVisionFragment(VisionForge.visionManager, fragment = fragment)
|
||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||
}
|
||||
script {
|
||||
type = "text/javascript"
|
||||
unsafe { +"VisionForge.renderVisionsAt(\"$id\");" }
|
||||
unsafe { +"window.renderAllVisionsById(\"$id\");" }
|
||||
}
|
||||
}
|
||||
|
||||
override fun Builder.onLoaded() {
|
||||
resource(jsResource)
|
||||
|
||||
onLoaded {
|
||||
VisionForge.plugins.fetch(Solids)
|
||||
VisionForge.usePlotly()
|
||||
}
|
||||
|
||||
import(
|
||||
"space.kscience.gdml.*",
|
||||
"space.kscience.plotly.*",
|
||||
@ -65,17 +63,15 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
"space.kscience.visionforge.html.page"
|
||||
)
|
||||
|
||||
import<VisionForge>()
|
||||
|
||||
render<Gdml> { gdmlModel ->
|
||||
val fragment = VisionForge.fragment {
|
||||
val fragment = HtmlVisionFragment {
|
||||
vision(gdmlModel.toVision())
|
||||
}
|
||||
HTML(produceHtmlVisionString(fragment))
|
||||
}
|
||||
|
||||
render<Vision> { vision ->
|
||||
val fragment = VisionForge.fragment {
|
||||
val fragment = HtmlVisionFragment {
|
||||
vision(vision)
|
||||
}
|
||||
|
||||
@ -83,7 +79,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
}
|
||||
|
||||
render<Plot> { plot ->
|
||||
val fragment = VisionForge.fragment {
|
||||
val fragment = HtmlVisionFragment {
|
||||
vision(plot.toVision())
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,7 @@ kotlin {
|
||||
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||
afterEvaluate {
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
@ -57,6 +58,12 @@ application {
|
||||
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
||||
}
|
||||
|
||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile>(){
|
||||
kotlinOptions{
|
||||
freeCompilerArgs = freeCompilerArgs + "-Xir-property-lazy-initialization"
|
||||
}
|
||||
}
|
||||
|
||||
//distributions {
|
||||
// main {
|
||||
// contents {
|
||||
|
@ -26,7 +26,7 @@ private class MMDemoApp : Application {
|
||||
|
||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||
|
||||
val context = Global.context("demo") {}
|
||||
val context = Global.buildContext("demo") {}
|
||||
render(element) {
|
||||
child(MMApp) {
|
||||
attrs {
|
||||
|
@ -26,6 +26,7 @@ import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
||||
import ru.mipt.npm.muon.monitor.sim.simulateOne
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.Global
|
||||
import space.kscience.dataforge.context.fetch
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import java.awt.Desktop
|
||||
@ -38,7 +39,7 @@ private val generator = Cos2TrackGenerator(JDKRandomGenerator(223))
|
||||
fun Application.module(context: Context = Global) {
|
||||
val currentDir = File(".").absoluteFile
|
||||
environment.log.info("Current directory: $currentDir")
|
||||
val solidManager = context.plugins.load(Solids)
|
||||
val solidManager = context.fetch(Solids)
|
||||
|
||||
install(DefaultHeaders)
|
||||
install(CallLogging)
|
||||
|
@ -1,14 +1,10 @@
|
||||
import kotlinx.browser.window
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.plotly.usePlotly
|
||||
import space.kscience.visionforge.solid.three.useThreeJs
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
|
||||
@DFExperimental
|
||||
fun main(): Unit = VisionForge.run{
|
||||
console.info("Starting VisionForge context")
|
||||
usePlotly()
|
||||
useThreeJs()
|
||||
window.asDynamic()["VisionForge"] = VisionForge
|
||||
renderVisionsInWindow()
|
||||
fun main() = runVisionClient {
|
||||
plugin(PlotlyPlugin)
|
||||
plugin(ThreePlugin)
|
||||
}
|
@ -1,20 +1,19 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.gdml.GdmlShowCase
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.invoke
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
|
||||
@DFExperimental
|
||||
fun main() = VisionForge(Solids) {
|
||||
val content = VisionForge.fragment {
|
||||
fun main() {
|
||||
val context = Context {
|
||||
plugin(Solids)
|
||||
}
|
||||
|
||||
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||
vision("canvas") {
|
||||
cubes.toVision()
|
||||
GdmlShowCase.cubes().toVision()
|
||||
}
|
||||
}
|
||||
makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
@ -1,24 +1,22 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.gdml.LUnit
|
||||
import space.kscience.gdml.decodeFromStream
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.invoke
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
|
||||
@DFExperimental
|
||||
fun main() = VisionForge(Solids) {
|
||||
val content = VisionForge.fragment {
|
||||
fun main() {
|
||||
val context = Context {
|
||||
plugin(Solids)
|
||||
}
|
||||
context.makeVisionFile(resourceLocation = ResourceLocation.EMBED) {
|
||||
vision("canvas") {
|
||||
Gdml.decodeFromStream(Gdml.javaClass.getResourceAsStream("/gdml/babyIAXO.gdml")!!, true).toVision {
|
||||
Gdml.decodeFromStream(javaClass.getResourceAsStream("/gdml/babyIAXO.gdml")!!, true).toVision {
|
||||
lUnit = LUnit.MM
|
||||
}
|
||||
}
|
||||
}
|
||||
makeVisionFile(content, resourceLocation = ResourceLocation.EMBED)
|
||||
}
|
@ -1,17 +1,16 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.plotly.scatter
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.invoke
|
||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||
import space.kscience.visionforge.plotly.plotly
|
||||
|
||||
@DFExperimental
|
||||
fun main() = VisionForge(PlotlyPlugin) {
|
||||
val fragment = fragment {
|
||||
fun main() {
|
||||
val context = Context {
|
||||
plugin(PlotlyPlugin)
|
||||
}
|
||||
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||
vision {
|
||||
plotly {
|
||||
scatter {
|
||||
@ -21,5 +20,4 @@ fun main() = VisionForge(PlotlyPlugin) {
|
||||
}
|
||||
}
|
||||
}
|
||||
makeVisionFile(fragment, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
@ -1,20 +1,23 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import kotlinx.html.h1
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.invoke
|
||||
import space.kscience.visionforge.solid.*
|
||||
import java.nio.file.Paths
|
||||
import kotlin.random.Random
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
fun main() = VisionForge(Solids) {
|
||||
fun main() {
|
||||
val context = Context {
|
||||
plugin(Solids)
|
||||
}
|
||||
|
||||
val random = Random(112233)
|
||||
val fragment = fragment {
|
||||
|
||||
context.makeVisionFile(
|
||||
Paths.get("randomSpheres.html"),
|
||||
resourceLocation = ResourceLocation.EMBED
|
||||
) {
|
||||
h1 { +"Happy new year!" }
|
||||
vision {
|
||||
solid {
|
||||
@ -33,9 +36,4 @@ fun main() = VisionForge(Solids) {
|
||||
}
|
||||
}
|
||||
}
|
||||
makeVisionFile(
|
||||
fragment,
|
||||
Paths.get("randomSpheres.html"),
|
||||
resourceLocation = ResourceLocation.EMBED
|
||||
)
|
||||
}
|
@ -1,10 +1,9 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.VisionTagConsumer
|
||||
import space.kscience.visionforge.html.page
|
||||
import space.kscience.visionforge.html.scriptHeader
|
||||
import space.kscience.visionforge.makeFile
|
||||
@ -18,25 +17,26 @@ public fun VisionServer.usePlayground(): Unit {
|
||||
useScript("js/visionforge-playground.js")
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun VisionForge.makeVisionFile(
|
||||
content: HtmlVisionFragment,
|
||||
@OptIn(DFExperimental::class)
|
||||
public fun Context.makeVisionFile(
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||
show: Boolean = true,
|
||||
content: VisionTagConsumer<*>.() -> Unit
|
||||
): Unit {
|
||||
|
||||
val actualPath = page(title, content = content).makeFile(path) { actualPath ->
|
||||
mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", resourceLocation, actualPath))
|
||||
}
|
||||
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun VisionForge.makeVisionFile(
|
||||
vision: Vision,
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||
show: Boolean = true,
|
||||
): Unit = makeVisionFile({ vision(vision) }, path, title, resourceLocation, show)
|
||||
//@DFExperimental
|
||||
//public fun Context.makeVisionFile(
|
||||
// vision: Vision,
|
||||
// path: Path? = null,
|
||||
// title: String = "VisionForge page",
|
||||
// resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||
// show: Boolean = true,
|
||||
//): Unit = makeVisionFile({ vision(vision) }, path, title, resourceLocation, show)
|
||||
|
@ -1,22 +1,21 @@
|
||||
package space.kscience.visionforge.examples
|
||||
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.invoke
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.solid.box
|
||||
import space.kscience.visionforge.solid.solid
|
||||
|
||||
@DFExperimental
|
||||
fun main() = VisionForge(Solids) {
|
||||
val content = fragment {
|
||||
fun main() {
|
||||
val context = Context {
|
||||
plugin(Solids)
|
||||
}
|
||||
|
||||
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||
vision("canvas") {
|
||||
solid {
|
||||
box(100, 100, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
57
demo/plotly-fx/build.gradle.kts
Normal file
57
demo/plotly-fx/build.gradle.kts
Normal file
@ -0,0 +1,57 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
application
|
||||
id("org.openjfx.javafxplugin") version "0.0.9"
|
||||
}
|
||||
|
||||
repositories {
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenLocal()
|
||||
jcenter()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
jvm {
|
||||
withJava()
|
||||
}
|
||||
|
||||
js(IR) {
|
||||
browser()
|
||||
}
|
||||
|
||||
sourceSets{
|
||||
commonMain{
|
||||
dependencies {
|
||||
|
||||
}
|
||||
}
|
||||
val jvmMain by getting {
|
||||
dependencies {
|
||||
implementation("no.tornado:tornadofx:1.7.19")
|
||||
implementation(project(":visionforge-server"))
|
||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
javafx {
|
||||
modules("javafx.web")
|
||||
version = "16"
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "space.kscience.plotly.fx.PlotlyFXAppKt"
|
||||
}
|
||||
|
||||
|
||||
//
|
||||
//val compileKotlin: KotlinCompile by tasks
|
||||
//compileKotlin.kotlinOptions {
|
||||
// jvmTarget = "11"
|
||||
//}
|
||||
//val compileTestKotlin: KotlinCompile by tasks
|
||||
//compileTestKotlin.kotlinOptions {
|
||||
// jvmTarget = "11"
|
||||
//}
|
@ -15,7 +15,7 @@ import space.kscience.visionforge.visionManager
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
val satContext = Global.context("sat") {
|
||||
val satContext = Global.buildContext ("sat") {
|
||||
plugin(Solids)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,10 @@
|
||||
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
|
||||
kotlin.native.enableDependencyPropagation=false
|
||||
kotlin.parallel.tasks.in.project=true
|
||||
|
||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
|
||||
org.gradle.parallel=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.8.3-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -1,16 +1,14 @@
|
||||
package space.kscience.visionforge.gdml.jupyter
|
||||
|
||||
import kotlinx.browser.window
|
||||
import kotlinx.css.ListStyleType
|
||||
import kotlinx.css.listStyleType
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||
import space.kscience.visionforge.plugins
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
import styled.injectGlobal
|
||||
|
||||
@DFExperimental
|
||||
fun main(): Unit = VisionForge.run {
|
||||
fun main(): Unit = runVisionClient {
|
||||
useBootstrap()
|
||||
injectGlobal {
|
||||
rule("ul.nav") {
|
||||
@ -25,8 +23,5 @@ fun main(): Unit = VisionForge.run {
|
||||
listStyleType = ListStyleType.none
|
||||
}
|
||||
}
|
||||
console.info("Starting VisionForge context")
|
||||
plugins.fetch(ThreeWithControls)
|
||||
window.asDynamic()["VisionForge"] = VisionForge
|
||||
renderVisionsInWindow()
|
||||
plugin(ThreeWithControls)
|
||||
}
|
@ -9,16 +9,14 @@ import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.resources
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.gdml.toVision
|
||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||
import space.kscience.visionforge.html.Page
|
||||
import space.kscience.visionforge.html.embedVisionFragment
|
||||
import space.kscience.visionforge.html.fragment
|
||||
import space.kscience.visionforge.plugins
|
||||
import space.kscience.visionforge.solid.Solids
|
||||
import space.kscience.visionforge.visionManager
|
||||
|
||||
@ -26,13 +24,17 @@ import space.kscience.visionforge.visionManager
|
||||
@DFExperimental
|
||||
internal class GdmlForJupyter : JupyterIntegration() {
|
||||
|
||||
private val context = Context("GDML") {
|
||||
plugin(Solids)
|
||||
}
|
||||
|
||||
private var counter = 0
|
||||
|
||||
private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div {
|
||||
val id = "visionforge.vision[${counter++}]"
|
||||
div {
|
||||
this.id = id
|
||||
embedVisionFragment(VisionForge.visionManager, fragment = fragment)
|
||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||
}
|
||||
script {
|
||||
type = "text/javascript"
|
||||
@ -43,7 +45,7 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
||||
override fun Builder.onLoaded() {
|
||||
|
||||
resources {
|
||||
js("three"){
|
||||
js("three") {
|
||||
classPath("js/gdml-jupyter.js")
|
||||
}
|
||||
// css("override") {
|
||||
@ -51,10 +53,6 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
||||
// }
|
||||
}
|
||||
|
||||
onLoaded {
|
||||
VisionForge.plugins.fetch(Solids)
|
||||
}
|
||||
|
||||
import(
|
||||
"space.kscience.gdml.*",
|
||||
"kotlinx.html.*",
|
||||
@ -64,17 +62,15 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
||||
"space.kscience.visionforge.gdml.jupyter.*"
|
||||
)
|
||||
|
||||
import<VisionForge>()
|
||||
|
||||
render<Gdml> { gdmlModel ->
|
||||
val fragment = VisionForge.fragment {
|
||||
val fragment = HtmlVisionFragment {
|
||||
vision(gdmlModel.toVision())
|
||||
}
|
||||
HTML(produceHtmlVisionString(fragment))
|
||||
}
|
||||
|
||||
render<Vision> { vision ->
|
||||
val fragment = VisionForge.fragment {
|
||||
val fragment = HtmlVisionFragment {
|
||||
vision(vision)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,8 @@
|
||||
pluginManagement {
|
||||
val kotlinVersion = "1.4.31"
|
||||
val toolsVersion = "0.9.2"
|
||||
val kotlinVersion = "1.5.0"
|
||||
val toolsVersion = "0.9.5"
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
maven("https://repo.kotlin.link")
|
||||
mavenCentral()
|
||||
gradlePluginPortal()
|
||||
@ -14,11 +13,10 @@ pluginManagement {
|
||||
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.js") version toolsVersion
|
||||
id("ru.mipt.npm.gradle.publish") version toolsVersion
|
||||
kotlin("jvm") version kotlinVersion
|
||||
kotlin("jupyter.api") version "0.8.3.279"
|
||||
kotlin("js") version kotlinVersion
|
||||
kotlin("multiplatform") version kotlinVersion
|
||||
kotlin("jvm") version kotlinVersion
|
||||
kotlin("js") version kotlinVersion
|
||||
kotlin("jupyter.api") version "0.9.1-20"
|
||||
}
|
||||
}
|
||||
|
||||
@ -47,5 +45,6 @@ include(
|
||||
":demo:sat-demo",
|
||||
":demo:playground",
|
||||
":demo:jupyter-playground",
|
||||
":demo:plotly-fx",
|
||||
":jupyter:visionforge-gdml-jupyter"
|
||||
)
|
@ -1,4 +1,5 @@
|
||||
plugins {
|
||||
kotlin("js")
|
||||
id("ru.mipt.npm.gradle.js")
|
||||
}
|
||||
|
||||
|
@ -1,25 +1,25 @@
|
||||
package space.kscience.visionforge.bootstrap
|
||||
|
||||
import kotlinx.css.*
|
||||
import kotlinx.css.BorderStyle
|
||||
import kotlinx.css.Color
|
||||
import kotlinx.css.padding
|
||||
import kotlinx.css.properties.border
|
||||
import kotlinx.html.InputType
|
||||
import kotlinx.html.js.onChangeFunction
|
||||
import kotlinx.css.px
|
||||
import kotlinx.html.js.onClickFunction
|
||||
import org.w3c.dom.HTMLInputElement
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.files.Blob
|
||||
import org.w3c.files.BlobPropertyBag
|
||||
import react.*
|
||||
import react.dom.button
|
||||
import react.dom.h3
|
||||
import react.dom.input
|
||||
import react.dom.label
|
||||
import space.kscience.dataforge.meta.descriptors.defaultMeta
|
||||
import space.kscience.dataforge.meta.withDefault
|
||||
import space.kscience.visionforge.react.flexColumn
|
||||
import space.kscience.visionforge.react.flexRow
|
||||
import space.kscience.visionforge.react.propertyEditor
|
||||
import space.kscience.visionforge.solid.SolidGroup
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import space.kscience.visionforge.solid.three.ThreeCanvas
|
||||
import styled.css
|
||||
import styled.styledDiv
|
||||
|
||||
private fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
||||
event.stopPropagation();
|
||||
@ -48,7 +48,35 @@ public val CanvasControls: FunctionalComponent<CanvasControlsProps> = functional
|
||||
arrayOf(props.canvas)
|
||||
)
|
||||
flexColumn {
|
||||
h3 { +"Axes" }
|
||||
flexRow {
|
||||
css{
|
||||
border(1.px, BorderStyle.solid, Color.blue)
|
||||
padding(4.px)
|
||||
}
|
||||
button {
|
||||
+"Export"
|
||||
attrs {
|
||||
onClickFunction = {
|
||||
val json = (props.canvas.content as? SolidGroup)?.let { group ->
|
||||
visionManager.encodeToString(group)
|
||||
}
|
||||
if (json != null) {
|
||||
saveData(it, "object.json", "text/json") {
|
||||
json
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
propertyEditor(
|
||||
ownProperties = props.canvas.options,
|
||||
allProperties = props.canvas.options.withDefault(Canvas3DOptions.descriptor.defaultMeta()),
|
||||
descriptor = Canvas3DOptions.descriptor,
|
||||
expanded = false
|
||||
)
|
||||
|
||||
/* h3 { +"Axes" }
|
||||
flexRow {
|
||||
css{
|
||||
border(1.px,BorderStyle.solid, Color.blue)
|
||||
@ -57,9 +85,9 @@ public val CanvasControls: FunctionalComponent<CanvasControlsProps> = functional
|
||||
label("checkbox-inline") {
|
||||
input(type = InputType.checkBox) {
|
||||
attrs {
|
||||
defaultChecked = props.canvas.axes.visible
|
||||
defaultChecked = props.canvas.options.axes.visible
|
||||
onChangeFunction = {
|
||||
props.canvas.axes.visible = (it.target as HTMLInputElement).checked
|
||||
props.canvas.options.axes.visible = (it.target as HTMLInputElement).checked
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -118,5 +146,6 @@ public val CanvasControls: FunctionalComponent<CanvasControlsProps> = functional
|
||||
}
|
||||
}
|
||||
}
|
||||
*/
|
||||
}
|
||||
}
|
@ -2,12 +2,11 @@ plugins {
|
||||
id("ru.mipt.npm.gradle.js")
|
||||
}
|
||||
|
||||
val reactVersion by extra("17.0.1")
|
||||
val kotlinWrappersVersion: String by rootProject.extra
|
||||
|
||||
dependencies{
|
||||
api(project(":visionforge-solid"))
|
||||
api("org.jetbrains:kotlin-styled:5.2.1-$kotlinWrappersVersion")
|
||||
api("org.jetbrains:kotlin-react-dom:$reactVersion-$kotlinWrappersVersion")
|
||||
api("org.jetbrains:kotlin-styled:5.2.3-$kotlinWrappersVersion")
|
||||
api("org.jetbrains:kotlin-react-dom:17.0.2-$kotlinWrappersVersion")
|
||||
implementation(project(":visionforge-threejs"))
|
||||
}
|
@ -59,6 +59,11 @@ public external interface PropertyEditorProps : RProps {
|
||||
* Flow names of updated properties
|
||||
*/
|
||||
public var updateFlow: Flow<Name>?
|
||||
|
||||
/**
|
||||
* Initial expanded state
|
||||
*/
|
||||
public var expanded: Boolean?
|
||||
}
|
||||
|
||||
private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
||||
@ -67,7 +72,7 @@ private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
||||
}
|
||||
|
||||
private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
||||
var expanded: Boolean by useState { true }
|
||||
var expanded: Boolean by useState { props.expanded ?: true }
|
||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
||||
var ownProperty: MetaItem? by useState { props.ownProperties.getItem(props.name) }
|
||||
val actualItem: MetaItem? = props.allProperties?.getItem(props.name)
|
||||
@ -110,7 +115,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
||||
if (actualItem is MetaItemNode) {
|
||||
val keys = buildSet {
|
||||
(descriptorItem as? NodeDescriptor)?.items?.filterNot {
|
||||
it.key.startsWith("@") || it.value.hidden
|
||||
it.key.startsWith("@") || it.value.hidden
|
||||
}?.forEach {
|
||||
add(NameToken(it.key))
|
||||
}
|
||||
@ -232,11 +237,12 @@ public val PropertyEditor: FunctionalComponent<PropertyEditorProps> = functional
|
||||
|
||||
public fun RBuilder.propertyEditor(
|
||||
ownProperties: MutableItemProvider,
|
||||
allProperties: ItemProvider?,
|
||||
allProperties: ItemProvider? = ownProperties,
|
||||
updateFlow: Flow<Name>? = null,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
scope: CoroutineScope? = null,
|
||||
key: Any? = null,
|
||||
expanded: Boolean? = null
|
||||
) {
|
||||
child(PropertyEditor) {
|
||||
attrs {
|
||||
@ -246,6 +252,7 @@ public fun RBuilder.propertyEditor(
|
||||
this.descriptor = descriptor
|
||||
this.key = key?.toString() ?: ""
|
||||
this.scope = scope
|
||||
this.expanded = expanded
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -5,11 +5,13 @@ import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.NameToken
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.plus
|
||||
import kotlin.jvm.JvmInline
|
||||
|
||||
/**
|
||||
* A container for styles
|
||||
*/
|
||||
public inline class StyleSheet(private val owner: VisionGroup) {
|
||||
@JvmInline
|
||||
public value class StyleSheet(private val owner: VisionGroup) {
|
||||
|
||||
private val styleNode get() = owner.ownProperties[STYLESHEET_KEY].node
|
||||
|
||||
|
@ -1,16 +0,0 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.PluginManager
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
|
||||
public expect object VisionForge
|
||||
|
||||
@DFExperimental
|
||||
public expect val VisionForge.context: Context
|
||||
|
||||
@DFExperimental
|
||||
public val VisionForge.plugins: PluginManager get() = context.plugins
|
||||
|
||||
@DFExperimental
|
||||
public val VisionForge.visionManager: VisionManager get() = plugins.fetch(VisionManager)
|
@ -93,6 +93,6 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a [VisionManager] from this plugin
|
||||
* Fetch a [VisionManager] from this plugin or create a child plugin with a [VisionManager]
|
||||
*/
|
||||
public val Context.visionManager: VisionManager get() = plugins.fetch(VisionManager)
|
||||
public val Context.visionManager: VisionManager get() = fetch(VisionManager)
|
@ -4,7 +4,6 @@ import kotlinx.html.FlowContent
|
||||
import kotlinx.html.TagConsumer
|
||||
import kotlinx.html.stream.createHTML
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
|
||||
public typealias HtmlFragment = TagConsumer<*>.() -> Unit
|
||||
|
||||
@ -21,4 +20,4 @@ public fun FlowContent.fragment(fragment: HtmlFragment) {
|
||||
public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit
|
||||
|
||||
@DFExperimental
|
||||
public fun VisionForge.fragment(content: HtmlVisionFragment): VisionTagConsumer<*>.() -> Unit = content
|
||||
public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content
|
@ -3,15 +3,13 @@ package space.kscience.visionforge.html
|
||||
import kotlinx.html.*
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.context
|
||||
import space.kscience.visionforge.visionManager
|
||||
|
||||
public data class Page(
|
||||
public val context: Context,
|
||||
public val title: String,
|
||||
public val headers: Map<String, HtmlFragment>,
|
||||
public val content: HtmlVisionFragment
|
||||
public val content: HtmlVisionFragment,
|
||||
) {
|
||||
public fun <R> render(root: TagConsumer<R>): R = root.apply {
|
||||
head {
|
||||
@ -31,8 +29,8 @@ public data class Page(
|
||||
|
||||
|
||||
@DFExperimental
|
||||
public fun VisionForge.page(
|
||||
public fun Context.page(
|
||||
title: String = "VisionForge page",
|
||||
vararg headers: Pair<String, HtmlFragment>,
|
||||
content: HtmlVisionFragment,
|
||||
): Page = Page(context, title, mapOf(*headers), content)
|
||||
): Page = Page(this, title, mapOf(*headers), content)
|
@ -79,6 +79,9 @@ public abstract class VisionTagConsumer<R>(
|
||||
return vision(name, vision, output.meta)
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO to be replaced by multi-receiver
|
||||
*/
|
||||
@OptIn(DFExperimental::class)
|
||||
public inline fun <T> TagConsumer<T>.vision(
|
||||
name: String = DEFAULT_VISION_NAME,
|
||||
|
@ -0,0 +1,62 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import space.kscience.dataforge.meta.Scheme
|
||||
import space.kscience.dataforge.meta.SchemeSpec
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptorBuilder
|
||||
import space.kscience.dataforge.meta.descriptors.ValueDescriptor
|
||||
import space.kscience.dataforge.meta.toConfig
|
||||
import space.kscience.dataforge.values.ValueType
|
||||
import kotlin.reflect.KProperty1
|
||||
import kotlin.reflect.typeOf
|
||||
|
||||
/**
|
||||
* TODO to be moved into the core
|
||||
*/
|
||||
public inline fun <S : Scheme, reified T> NodeDescriptorBuilder.value(
|
||||
property: KProperty1<S, T>,
|
||||
noinline block: ValueDescriptor.() -> Unit = {},
|
||||
) {
|
||||
when (typeOf<T>()) {
|
||||
typeOf<Number>(), typeOf<Int>(), typeOf<Double>(), typeOf<Short>(), typeOf<Long>(), typeOf<Float>() ->
|
||||
value(property.name) {
|
||||
type(ValueType.NUMBER)
|
||||
block()
|
||||
}
|
||||
typeOf<Boolean>() -> value(property.name) {
|
||||
type(ValueType.BOOLEAN)
|
||||
block()
|
||||
}
|
||||
typeOf<List<Number>>(), typeOf<List<Int>>(), typeOf<List<Double>>(), typeOf<List<Short>>(), typeOf<List<Long>>(), typeOf<List<Float>>(),
|
||||
typeOf<IntArray>(), typeOf<DoubleArray>(), typeOf<ShortArray>(), typeOf<LongArray>(), typeOf<FloatArray>(),
|
||||
-> value(property.name) {
|
||||
type(ValueType.NUMBER)
|
||||
multiple = true
|
||||
block()
|
||||
}
|
||||
typeOf<String>() -> value(property.name) {
|
||||
type(ValueType.STRING)
|
||||
block()
|
||||
}
|
||||
typeOf<List<String>>(), typeOf<Array<String>>() -> value(property.name) {
|
||||
type(ValueType.STRING)
|
||||
multiple = true
|
||||
block()
|
||||
}
|
||||
else -> value(property.name, block)
|
||||
}
|
||||
}
|
||||
|
||||
public fun NodeDescriptor.copy(block: NodeDescriptorBuilder.() -> Unit = {}): NodeDescriptor {
|
||||
return NodeDescriptorBuilder(toMeta().toConfig()).apply(block)
|
||||
}
|
||||
|
||||
public inline fun <S : Scheme, reified T : Scheme> NodeDescriptorBuilder.scheme(
|
||||
property: KProperty1<S, T>,
|
||||
spec: SchemeSpec<T>,
|
||||
noinline block: NodeDescriptor.() -> Unit = {},
|
||||
) {
|
||||
spec.descriptor?.let { descriptor ->
|
||||
item(property.name, descriptor.copy(block))
|
||||
}
|
||||
}
|
@ -1,10 +1,7 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.meta.descriptors.ItemDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.ValueDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.attributes
|
||||
import space.kscience.dataforge.meta.descriptors.*
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.values.ValueType
|
||||
import space.kscience.dataforge.values.asValue
|
||||
@ -12,13 +9,19 @@ import space.kscience.dataforge.values.asValue
|
||||
private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited"
|
||||
private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles"
|
||||
|
||||
public var ItemDescriptor.inherited: Boolean
|
||||
public val ItemDescriptor.inherited: Boolean
|
||||
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean ?: false
|
||||
|
||||
public var ItemDescriptorBuilder.inherited: Boolean
|
||||
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean ?: false
|
||||
set(value) = attributes {
|
||||
set(INHERITED_DESCRIPTOR_ATTRIBUTE, value)
|
||||
}
|
||||
|
||||
public var ItemDescriptor.usesStyles: Boolean
|
||||
public val ItemDescriptor.usesStyles: Boolean
|
||||
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean ?: true
|
||||
|
||||
public var ItemDescriptorBuilder.usesStyles: Boolean
|
||||
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean ?: true
|
||||
set(value) = attributes {
|
||||
set(STYLE_DESCRIPTOR_ATTRIBUTE, value)
|
||||
@ -32,10 +35,13 @@ public val Vision.describedProperties: Meta
|
||||
}
|
||||
}
|
||||
|
||||
public val ValueDescriptor.widget: Meta
|
||||
get() = attributes["widget"].node ?: Meta.EMPTY
|
||||
|
||||
/**
|
||||
* Extension property to access the "widget" key of [ValueDescriptor]
|
||||
*/
|
||||
public var ValueDescriptor.widget: Meta
|
||||
public var ValueDescriptorBuilder.widget: Meta
|
||||
get() = attributes["widget"].node ?: Meta.EMPTY
|
||||
set(value) {
|
||||
attributes {
|
||||
@ -43,10 +49,13 @@ public var ValueDescriptor.widget: Meta
|
||||
}
|
||||
}
|
||||
|
||||
public val ValueDescriptor.widgetType: String?
|
||||
get() = attributes["widget.type"].string
|
||||
|
||||
/**
|
||||
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
||||
*/
|
||||
public var ValueDescriptor.widgetType: String?
|
||||
public var ValueDescriptorBuilder.widgetType: String?
|
||||
get() = attributes["widget.type"].string
|
||||
set(value) {
|
||||
attributes {
|
||||
@ -60,15 +69,15 @@ public var ValueDescriptor.widgetType: String?
|
||||
public val ItemDescriptor.hidden: Boolean
|
||||
get() = attributes["widget.hide"].boolean ?: false
|
||||
|
||||
public fun ItemDescriptor.hide(): Unit = attributes {
|
||||
public fun ItemDescriptorBuilder.hide(): Unit = attributes {
|
||||
set("widget.hide", true)
|
||||
}
|
||||
|
||||
|
||||
public inline fun <reified E : Enum<E>> NodeDescriptor.enum(
|
||||
public inline fun <reified E : Enum<E>> NodeDescriptorBuilder.enum(
|
||||
key: Name,
|
||||
default: E?,
|
||||
crossinline modifier: ValueDescriptor.() -> Unit = {},
|
||||
crossinline modifier: ValueDescriptorBuilder.() -> Unit = {},
|
||||
): Unit = value(key) {
|
||||
type(ValueType.STRING)
|
||||
default?.let {
|
||||
|
@ -46,7 +46,7 @@ class HtmlTagTest {
|
||||
}
|
||||
}
|
||||
|
||||
val groupRenderer: HtmlVisionRenderer = { _, group, _ ->
|
||||
val groupRenderer: HtmlVisionRenderer = { _, _, _ ->
|
||||
p { +"This is group" }
|
||||
}
|
||||
|
||||
|
@ -2,10 +2,7 @@ package space.kscience.visionforge
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.browser.window
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.WebSocket
|
||||
import org.w3c.dom.asList
|
||||
import org.w3c.dom.get
|
||||
import org.w3c.dom.*
|
||||
import org.w3c.dom.url.URL
|
||||
import space.kscience.dataforge.context.*
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
@ -66,7 +63,7 @@ public class VisionClient : AbstractPlugin() {
|
||||
/**
|
||||
* Fetch from server and render a vision, described in a given with [VisionTagConsumer.OUTPUT_CLASS] class.
|
||||
*/
|
||||
public fun renderVisionAt(element: Element) {
|
||||
public fun renderVisionIn(element: Element) {
|
||||
val name = resolveName(element) ?: error("The element is not a vision output")
|
||||
logger.info { "Found DF output with name $name" }
|
||||
if (!element.classList.contains(VisionTagConsumer.OUTPUT_CLASS)) error("The element $element is not an output element")
|
||||
@ -173,21 +170,58 @@ public class VisionClient : AbstractPlugin() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and render visions for all elements with [VisionTagConsumer.OUTPUT_CLASS] class inside given [element].
|
||||
*/
|
||||
public fun VisionClient.renderAllVisionsAt(element: Element) {
|
||||
val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS)
|
||||
console.info("Finished search for outputs. Found ${elements.length} items")
|
||||
elements.asList().forEach { child ->
|
||||
renderVisionAt(child)
|
||||
|
||||
private fun whenDocumentLoaded(block: Document.() -> Unit): Unit {
|
||||
if (document.readyState == DocumentReadyState.COMPLETE) {
|
||||
block(document)
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", { block(document) })
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch and render visions for all elements with [VisionTagConsumer.OUTPUT_CLASS] class inside given [element].
|
||||
*/
|
||||
public fun VisionClient.renderAllVisionsIn(element: Element) {
|
||||
val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS)
|
||||
console.info("Finished search for outputs. Found ${elements.length} items")
|
||||
elements.asList().forEach { child ->
|
||||
renderVisionIn(child)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Render all visions in an element with a given [id]
|
||||
*/
|
||||
public fun VisionClient.renderAllVisionsById(id: String): Unit = whenDocumentLoaded {
|
||||
val element = getElementById(id)
|
||||
if (element != null) {
|
||||
renderAllVisionsIn(element)
|
||||
} else {
|
||||
console.warn("Element with id $id not found")
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Fetch visions from the server for all elements with [VisionTagConsumer.OUTPUT_CLASS] class in the document body
|
||||
*/
|
||||
public fun VisionClient.renderAllVisions() {
|
||||
val element = document.body ?: error("Document does not have a body")
|
||||
renderAllVisionsAt(element)
|
||||
public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded {
|
||||
val element = body ?: error("Document does not have a body")
|
||||
renderAllVisionsIn(element)
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a vision client context and render all visions on the page.
|
||||
*/
|
||||
public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) {
|
||||
console.info("Starting VisionForge context")
|
||||
val context = Context("VisionForge"){
|
||||
contextBuilder()
|
||||
plugin(VisionClient)
|
||||
}
|
||||
val visionClient = context.fetch(VisionClient)
|
||||
window.asDynamic()["renderAllVisionsById"] = visionClient::renderAllVisionsById
|
||||
|
||||
visionClient.renderAllVisions()
|
||||
}
|
@ -1,73 +0,0 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.browser.window
|
||||
import org.w3c.dom.COMPLETE
|
||||
import org.w3c.dom.Document
|
||||
import org.w3c.dom.DocumentReadyState
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
|
||||
|
||||
private fun whenDocumentLoaded(block: Document.() -> Unit): Unit {
|
||||
if(document.readyState == DocumentReadyState.COMPLETE){
|
||||
block(document)
|
||||
} else {
|
||||
document.addEventListener("DOMContentLoaded", { block(document) })
|
||||
}
|
||||
}
|
||||
|
||||
@JsExport
|
||||
@DFExperimental
|
||||
@JsName("VisionForge")
|
||||
public actual object VisionForge {
|
||||
/**
|
||||
* Render all visions in this [window] using current global state of [VisionForge]
|
||||
*/
|
||||
public fun renderVisionsInWindow(): Unit = whenDocumentLoaded {
|
||||
visionClient.renderAllVisions()
|
||||
}
|
||||
|
||||
/**
|
||||
* Render all visions in an element with a given [id]
|
||||
*/
|
||||
public fun renderVisionsAt(id: String): Unit = whenDocumentLoaded {
|
||||
val element = getElementById(id)
|
||||
if (element != null) {
|
||||
visionClient.renderAllVisionsAt(element)
|
||||
} else {
|
||||
console.warn("Element with id $id not found")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private val visionForgeContext = Context("VisionForge") {
|
||||
plugin(VisionClient)
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public actual val VisionForge.context: Context
|
||||
get() = visionForgeContext
|
||||
|
||||
@DFExperimental
|
||||
public val VisionForge.visionClient: VisionClient
|
||||
get() = plugins.fetch(VisionClient)
|
||||
|
||||
|
||||
///**
|
||||
// * Render all visions in this [window] using current global state of [VisionForge]
|
||||
// */
|
||||
//@DFExperimental
|
||||
//@JsExport
|
||||
//public fun renderVisionsInWindow(): Unit {
|
||||
// VisionForge.renderVisionsInWindow()
|
||||
//}
|
||||
//
|
||||
///**
|
||||
// * Render all visions in an element with a given [id]
|
||||
// */
|
||||
//@DFExperimental
|
||||
//@JsExport
|
||||
//public fun renderVisionsAt(id: String): Unit {
|
||||
// VisionForge.renderVisionsAt(id)
|
||||
//}
|
@ -1,21 +0,0 @@
|
||||
package space.kscience.visionforge
|
||||
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.context.PluginFactory
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
|
||||
public actual object VisionForge
|
||||
|
||||
@DFExperimental
|
||||
private val visionForgeContext = Context("VisionForge")
|
||||
|
||||
@DFExperimental
|
||||
public actual val VisionForge.context: Context get() = visionForgeContext
|
||||
|
||||
@DFExperimental
|
||||
public operator fun VisionForge.invoke(vararg modules: PluginFactory<out VisionPlugin>, block: VisionForge.() -> Unit): Unit {
|
||||
modules.forEach {
|
||||
plugins.fetch(it)
|
||||
}
|
||||
run(block)
|
||||
}
|
@ -1,4 +1,5 @@
|
||||
plugins {
|
||||
kotlin("multiplatform")
|
||||
id("ru.mipt.npm.gradle.mpp")
|
||||
}
|
||||
|
||||
@ -7,7 +8,7 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
api(project(":visionforge-solid"))
|
||||
api("space.kscience:gdml:0.3.2")
|
||||
api("space.kscience:gdml:0.4.0")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,57 +0,0 @@
|
||||
package space.kscience.visionforge.gdml
|
||||
|
||||
import space.kscience.gdml.*
|
||||
|
||||
public object GdmlShowcase {
|
||||
public val cubes: Gdml = Gdml {
|
||||
val center = define.position("center")
|
||||
structure {
|
||||
val air = materials.composite("G4_AIR") {}
|
||||
val tubeMaterial = materials.composite("tube") {}
|
||||
val boxMaterial = materials.composite("box") {}
|
||||
|
||||
val segment = solids.tube("segment", 20, 5.0) {
|
||||
rmin = 17
|
||||
deltaphi = 60
|
||||
aunit = AUnit.DEG
|
||||
}
|
||||
val worldBox = solids.box("largeBox", 200, 200, 200)
|
||||
val smallBox = solids.box("smallBox", 30, 30, 30)
|
||||
val segmentVolume = volume("segment", tubeMaterial, segment) {}
|
||||
val circle = volume("composite", boxMaterial, smallBox) {
|
||||
for (i in 0 until 6) {
|
||||
physVolume(segmentVolume) {
|
||||
name = "segment[$i]"
|
||||
positionref = center
|
||||
rotation {
|
||||
z = 60 * i
|
||||
unit = AUnit.DEG
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
world = volume("world", air, worldBox) {
|
||||
for (i in 0 until 3) {
|
||||
for (j in 0 until 3) {
|
||||
for (k in 0 until 3) {
|
||||
physVolume(circle) {
|
||||
name = "composite[$i,$j,$k]"
|
||||
position {
|
||||
x = (-50 + i * 50)
|
||||
y = (-50 + j * 50)
|
||||
z = (-50 + k * 50)
|
||||
}
|
||||
rotation {
|
||||
x = i * 120
|
||||
y = j * 120
|
||||
z = 120 * k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -35,13 +35,13 @@ public class GdmlTransformerSettings {
|
||||
PROTOTYPE
|
||||
}
|
||||
|
||||
public var lUnit: LUnit = LUnit.CM
|
||||
public var lUnit: LUnit = LUnit.MM
|
||||
public var aUnit: AUnit = AUnit.RADIAN
|
||||
|
||||
public var solidAction: (GdmlSolid) -> Action = { Action.PROTOTYPE }
|
||||
public var volumeAction: (GdmlGroup) -> Action = { Action.PROTOTYPE }
|
||||
|
||||
public var paint: SolidMaterial.(material: GdmlMaterial) -> Unit = { _->
|
||||
public var paint: SolidMaterial.(material: GdmlMaterial) -> Unit = { _ ->
|
||||
color(random.nextInt(16777216))
|
||||
}
|
||||
}
|
||||
@ -110,7 +110,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
val styleName = "materials.${material.name}"
|
||||
|
||||
obj.useStyle(styleName) {
|
||||
val vfMaterial = settings.run { SolidMaterial().apply { paint(material)}}
|
||||
val vfMaterial = settings.run { SolidMaterial().apply { paint(material) } }
|
||||
MATERIAL_KEY put vfMaterial.toMeta()
|
||||
"Gdml.material" put material.name
|
||||
}
|
||||
@ -151,6 +151,24 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
physVolume.resolveScale(root)
|
||||
)
|
||||
|
||||
private fun GdmlSolid.lscale(targetUnit: LUnit): Float {
|
||||
val solidUnit = lunit ?: return 1f
|
||||
return if (solidUnit == targetUnit) {
|
||||
1f
|
||||
} else {
|
||||
solidUnit.value / targetUnit.value
|
||||
}
|
||||
}
|
||||
|
||||
private fun GdmlSolid.ascale(targetUnit: AUnit = AUnit.RAD): Float {
|
||||
val solidUnit = aunit ?: return 1f
|
||||
return if (solidUnit == targetUnit) {
|
||||
1f
|
||||
} else {
|
||||
solidUnit.value / targetUnit.value
|
||||
}
|
||||
}
|
||||
|
||||
fun SolidGroup.addSolid(
|
||||
root: Gdml,
|
||||
solid: GdmlSolid,
|
||||
@ -158,7 +176,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
): Solid {
|
||||
//context.solidAdded(solid)
|
||||
val lScale = solid.lscale(settings.lUnit)
|
||||
val aScale = solid.ascale()
|
||||
val aScale = solid.ascale(settings.aUnit)
|
||||
return when (solid) {
|
||||
is GdmlBox -> box(solid.x * lScale, solid.y * lScale, solid.z * lScale, name)
|
||||
is GdmlTube -> tube(
|
||||
@ -201,7 +219,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
scaleZ = solid.scale.z.toFloat()
|
||||
}
|
||||
}
|
||||
is GdmlSphere -> sphereLayer(solid.rmax * lScale, solid.rmin * lScale, name) {
|
||||
is GdmlSphere -> sphereLayer(solid.rmax * lScale, solid.rmin * lScale, name) {
|
||||
phi = solid.deltaphi * aScale
|
||||
theta = solid.deltatheta * aScale
|
||||
phiStart = solid.startphi * aScale
|
||||
@ -299,7 +317,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
when (settings.volumeAction(volume)) {
|
||||
GdmlTransformerSettings.Action.ADD -> {
|
||||
val group: SolidGroup = volume(root, volume)
|
||||
this[physVolume.name ?: ""] = group.withPosition(root, physVolume)
|
||||
this[physVolume.name] = group.withPosition(root, physVolume)
|
||||
}
|
||||
GdmlTransformerSettings.Action.PROTOTYPE -> {
|
||||
proxyVolume(root, this, physVolume, volume)
|
||||
@ -378,7 +396,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
||||
return final
|
||||
}
|
||||
|
||||
fun transform(root: Gdml): SolidGroup = finalize(volume(root, root.world))
|
||||
fun transform(root: Gdml): SolidGroup = finalize(volume(root, root.world.resolve(root) ?: error("GDML root is not resolved")))
|
||||
}
|
||||
|
||||
|
||||
|
@ -2,12 +2,8 @@ package space.kscience.visionforge.gdml
|
||||
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.names.toName
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.gdml.GdmlBox
|
||||
import space.kscience.gdml.decodeFromString
|
||||
import space.kscience.gdml.encodeToString
|
||||
import space.kscience.gdml.*
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
||||
import space.kscience.visionforge.get
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.visionManager
|
||||
@ -21,13 +17,16 @@ internal val testContext = Context("TEST") {
|
||||
|
||||
class TestCubes {
|
||||
|
||||
val cubes = GdmlShowCase.cubes()
|
||||
|
||||
@Test
|
||||
fun testCubesDirect() {
|
||||
val vision = cubes.toVision()
|
||||
// println(Solids.encodeToString(vision))
|
||||
val smallBoxPrototype = vision.getPrototype("solids.smallBox".toName()) as? Box
|
||||
assertNotNull(smallBoxPrototype)
|
||||
assertEquals(30.0, smallBoxPrototype.xSize.toDouble())
|
||||
val smallBoxVision = vision["composite[1,1,1].smallBox"]?.prototype as? Box
|
||||
val smallBoxVision = vision["composite-111.smallBox"]?.prototype as? Box
|
||||
assertNotNull(smallBoxVision)
|
||||
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers
|
||||
import kotlinx.coroutines.withContext
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import space.kscience.gdml.Gdml
|
||||
import space.kscience.gdml.decodeFromReader
|
||||
import space.kscience.visionforge.solid.prototype
|
||||
import space.kscience.visionforge.visitor.countDistinct
|
||||
import space.kscience.visionforge.visitor.flowStatistics
|
||||
@ -17,7 +18,7 @@ suspend fun main() {
|
||||
File("D:\\Work\\Projects\\dataforge-vis\\visionforge-gdml\\src\\jvmTest\\resources\\gdml\\BM@N.gdml").inputStream()
|
||||
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = Gdml.format.decodeFromReader(Gdml.serializer(), xmlReader)
|
||||
val xml = Gdml.decodeFromReader( xmlReader)
|
||||
val vision = xml.toVision()
|
||||
|
||||
|
||||
|
@ -4,12 +4,12 @@ plugins {
|
||||
|
||||
val plotlyVersion = "0.4.0-dev-1"
|
||||
|
||||
kscience{
|
||||
kscience {
|
||||
useSerialization()
|
||||
}
|
||||
|
||||
kotlin {
|
||||
js{
|
||||
js {
|
||||
//binaries.library()
|
||||
binaries.executable()
|
||||
browser {
|
||||
@ -19,15 +19,11 @@ kotlin {
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
val jsBrowserDistribution by tasks.getting
|
||||
val jsBrowserDistribution by tasks.getting
|
||||
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
afterEvaluate {
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
}
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
|
@ -4,26 +4,15 @@ import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import kotlinx.serialization.modules.subclass
|
||||
import space.kscience.dataforge.context.PluginFactory
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.VisionPlugin
|
||||
import space.kscience.visionforge.plugins
|
||||
|
||||
public expect class PlotlyPlugin : VisionPlugin{
|
||||
public companion object: PluginFactory<PlotlyPlugin>
|
||||
public expect class PlotlyPlugin : VisionPlugin {
|
||||
public companion object : PluginFactory<PlotlyPlugin>
|
||||
}
|
||||
|
||||
internal val plotlySerializersModule = SerializersModule {
|
||||
polymorphic(Vision::class) {
|
||||
subclass(VisionOfPlotly.serializer())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that [PlotlyPlugin] is loaded in the global [VisionForge] context
|
||||
*/
|
||||
@DFExperimental
|
||||
public fun VisionForge.usePlotly() {
|
||||
plugins.fetch(PlotlyPlugin)
|
||||
}
|
@ -1,30 +1,22 @@
|
||||
package space.kscience.visionforge.plotly
|
||||
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.unsafe
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.html.HtmlFragment
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.scriptHeader
|
||||
import java.nio.file.Path
|
||||
|
||||
internal val plotlyScriptLocation = "js/visionforge-three.js"
|
||||
|
||||
/**
|
||||
* A header that stores/embeds plotly bundle and registers plotly renderer in the frontend
|
||||
*/
|
||||
@OptIn(DFExperimental::class)
|
||||
public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
|
||||
scriptHeader(
|
||||
plotlyScriptLocation,
|
||||
resourceLocation = location,
|
||||
htmlPath = filePath
|
||||
).invoke(this)
|
||||
script {
|
||||
type = "text/javascript"
|
||||
unsafe {
|
||||
//language=JavaScript
|
||||
+"space.kscience.visionforge.plotly.loadPlotly()"
|
||||
}
|
||||
}
|
||||
}
|
||||
//internal val plotlyScriptLocation = "js/visionforge-three.js"
|
||||
//
|
||||
///**
|
||||
// * A header that stores/embeds plotly bundle and registers plotly renderer in the frontend
|
||||
// */
|
||||
//@OptIn(DFExperimental::class)
|
||||
//public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
|
||||
// scriptHeader(
|
||||
// plotlyScriptLocation,
|
||||
// resourceLocation = location,
|
||||
// htmlPath = filePath
|
||||
// ).invoke(this)
|
||||
// script {
|
||||
// type = "text/javascript"
|
||||
// unsafe {
|
||||
// //language=JavaScript
|
||||
// +"space.kscience.visionforge.plotly.loadPlotly()"
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
|
@ -17,9 +17,7 @@ import kotlin.reflect.KClass
|
||||
|
||||
|
||||
public class Solids(meta: Meta) : VisionPlugin(meta) {
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids
|
||||
|
||||
public companion object : PluginFactory<Solids> {
|
||||
|
@ -9,6 +9,9 @@ import kotlin.math.PI
|
||||
import kotlin.math.cos
|
||||
import kotlin.math.sin
|
||||
|
||||
/**
|
||||
* A spherical layer
|
||||
*/
|
||||
@Serializable
|
||||
@SerialName("solid.sphereLayer")
|
||||
public class SphereLayer(
|
||||
|
@ -3,7 +3,9 @@ package space.kscience.visionforge.solid.specifications
|
||||
import space.kscience.dataforge.meta.Scheme
|
||||
import space.kscience.dataforge.meta.SchemeSpec
|
||||
import space.kscience.dataforge.meta.boolean
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.double
|
||||
import space.kscience.visionforge.value
|
||||
|
||||
public class Axes : Scheme() {
|
||||
public var visible: Boolean by boolean(false)
|
||||
@ -13,5 +15,13 @@ public class Axes : Scheme() {
|
||||
public companion object : SchemeSpec<Axes>(::Axes) {
|
||||
public const val AXIS_SIZE: Double = 1000.0
|
||||
public const val AXIS_WIDTH: Double = 3.0
|
||||
|
||||
override val descriptor: NodeDescriptor by lazy {
|
||||
NodeDescriptor {
|
||||
value(Axes::visible)
|
||||
value(Axes::size)
|
||||
value(Axes::width)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -2,8 +2,10 @@ package space.kscience.visionforge.solid.specifications
|
||||
|
||||
import space.kscience.dataforge.meta.Scheme
|
||||
import space.kscience.dataforge.meta.SchemeSpec
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.meta.double
|
||||
import space.kscience.dataforge.meta.int
|
||||
import space.kscience.visionforge.value
|
||||
import kotlin.math.PI
|
||||
|
||||
public class Camera : Scheme() {
|
||||
@ -25,5 +27,16 @@ public class Camera : Scheme() {
|
||||
public const val NEAR_CLIP: Double = 0.1
|
||||
public const val FAR_CLIP: Double = 10000.0
|
||||
public const val FIELD_OF_VIEW: Int = 75
|
||||
|
||||
override val descriptor: NodeDescriptor by lazy {
|
||||
NodeDescriptor {
|
||||
value(Camera::fov)
|
||||
value(Camera::nearClip)
|
||||
value(Camera::farClip)
|
||||
value(Camera::distance)
|
||||
value(Camera::azimuth)
|
||||
value(Camera::zenith)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,10 @@
|
||||
package space.kscience.visionforge.solid.specifications
|
||||
|
||||
import space.kscience.dataforge.meta.*
|
||||
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.visionforge.scheme
|
||||
import space.kscience.visionforge.value
|
||||
|
||||
public class Canvas3DOptions : Scheme() {
|
||||
public var axes: Axes by spec(Axes)
|
||||
@ -17,14 +20,29 @@ public class Canvas3DOptions : Scheme() {
|
||||
public var maxWith: Number by number { maxSize }
|
||||
public var maxHeight: Number by number { maxSize }
|
||||
|
||||
public var onSelect: ((Name?)->Unit)? = null
|
||||
public var onSelect: ((Name?) -> Unit)? = null
|
||||
|
||||
|
||||
public companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions)
|
||||
public companion object : SchemeSpec<Canvas3DOptions>(::Canvas3DOptions) {
|
||||
override val descriptor: NodeDescriptor by lazy {
|
||||
NodeDescriptor {
|
||||
scheme(Canvas3DOptions::axes, Axes)
|
||||
scheme(Canvas3DOptions::light, Light)
|
||||
scheme(Canvas3DOptions::camera, Camera)
|
||||
scheme(Canvas3DOptions::controls, Controls)
|
||||
value(Canvas3DOptions::minSize)
|
||||
value(Canvas3DOptions::minWith)
|
||||
value(Canvas3DOptions::minHeight)
|
||||
value(Canvas3DOptions::maxSize)
|
||||
value(Canvas3DOptions::maxWith)
|
||||
value(Canvas3DOptions::maxHeight)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public fun Canvas3DOptions.computeWidth(external: Number): Int =
|
||||
(external.toInt()).coerceIn(minWith.toInt()..maxWith.toInt())
|
||||
|
||||
public fun Canvas3DOptions.computeHeight(external: Number): Int =
|
||||
(external.toInt()).coerceIn(minHeight.toInt()..maxHeight.toInt())
|
||||
(external.toInt()).coerceIn(minHeight.toInt()..maxHeight.toInt())
|
||||
|
@ -0,0 +1,22 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import space.kscience.dataforge.meta.descriptors.ValueDescriptor
|
||||
import space.kscience.dataforge.meta.descriptors.get
|
||||
import space.kscience.dataforge.values.ValueType
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertNotNull
|
||||
import kotlin.test.assertTrue
|
||||
|
||||
class DescriptorTest {
|
||||
@Test
|
||||
fun canvasDescriptor() {
|
||||
val descriptor = Canvas3DOptions.descriptor
|
||||
//println(descriptor.config)
|
||||
val axesSize = descriptor["axes.size"]
|
||||
assertNotNull(axesSize)
|
||||
assertTrue {
|
||||
ValueType.NUMBER in (axesSize as ValueDescriptor).type!!
|
||||
}
|
||||
}
|
||||
}
|
@ -11,5 +11,5 @@ kotlin{
|
||||
dependencies {
|
||||
api(project(":visionforge-solid"))
|
||||
implementation(npm("three", "0.124.0"))
|
||||
implementation(npm("three-csg-ts", "2.2.0"))
|
||||
implementation(npm("three-csg-ts", "2.2.2"))
|
||||
}
|
||||
|
@ -28,6 +28,7 @@
|
||||
package info.laht.threekt.renderers
|
||||
|
||||
import info.laht.threekt.cameras.Camera
|
||||
import info.laht.threekt.math.Plane
|
||||
import info.laht.threekt.scenes.Scene
|
||||
import org.w3c.dom.Node
|
||||
|
||||
@ -103,4 +104,17 @@ external class WebGLRenderer(params: WebGLRendererParams = definedExternally) {
|
||||
)
|
||||
|
||||
fun setPixelRatio(value: Number)
|
||||
|
||||
//clipping
|
||||
|
||||
/**
|
||||
* User-defined clipping planes specified as THREE.Plane objects in world space. These planes apply globally.
|
||||
* Points in space whose dot product with the plane is negative are cut away. Default is [].
|
||||
*/
|
||||
var clippingPlanes: Array<Plane>
|
||||
|
||||
/**
|
||||
* Defines whether the renderer respects object-level clipping planes. Default is false.
|
||||
*/
|
||||
var localClippingEnabled: Boolean
|
||||
}
|
||||
|
@ -23,6 +23,7 @@ import space.kscience.dataforge.context.info
|
||||
import space.kscience.dataforge.context.logger
|
||||
import space.kscience.dataforge.meta.get
|
||||
import space.kscience.dataforge.meta.string
|
||||
import space.kscience.dataforge.meta.useProperty
|
||||
import space.kscience.dataforge.names.Name
|
||||
import space.kscience.dataforge.names.asName
|
||||
import space.kscience.dataforge.names.plus
|
||||
@ -41,7 +42,7 @@ import kotlin.math.sin
|
||||
public class ThreeCanvas(
|
||||
public val three: ThreePlugin,
|
||||
public val options: Canvas3DOptions,
|
||||
) {
|
||||
) {
|
||||
private var root: Object3D? = null
|
||||
|
||||
private val raycaster = Raycaster()
|
||||
@ -50,14 +51,23 @@ public class ThreeCanvas(
|
||||
public var content: Solid? = null
|
||||
private set
|
||||
|
||||
public var axes: AxesHelper = AxesHelper(options.axes.size.toInt()).apply { visible = options.axes.visible }
|
||||
private set
|
||||
|
||||
private var light = buildLight(options.light)
|
||||
|
||||
private val scene: Scene = Scene().apply {
|
||||
add(axes)
|
||||
add(light)
|
||||
options.useProperty(Canvas3DOptions::axes){axesConfig->
|
||||
getObjectByName(AXES_NAME)?.let { remove(it) }
|
||||
val axesObject = AxesHelper(axes.size.toInt()).apply { visible = axes.visible }
|
||||
axesObject.name = AXES_NAME
|
||||
add(axesObject)
|
||||
}
|
||||
|
||||
//Set up light
|
||||
options.useProperty(Canvas3DOptions::light){lightConfig->
|
||||
//remove old light if present
|
||||
getObjectByName(LIGHT_NAME)?.let { remove(it) }
|
||||
//add new light
|
||||
val lightObject = buildLight(lightConfig)
|
||||
lightObject.name = LIGHT_NAME
|
||||
add(lightObject)
|
||||
}
|
||||
}
|
||||
|
||||
public var camera: PerspectiveCamera = buildCamera(options.camera)
|
||||
@ -138,7 +148,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
|
||||
internal fun attach(element: Element) {
|
||||
check(element.getElementsByClassName("three-canvas").length == 0){"Three canvas already created in this element"}
|
||||
check(element.getElementsByClassName("three-canvas").length == 0) { "Three canvas already created in this element" }
|
||||
element.appendChild(canvas)
|
||||
updateSize()
|
||||
}
|
||||
@ -171,7 +181,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
}
|
||||
|
||||
private fun buildLight(spec: Light): info.laht.threekt.lights.Light = AmbientLight(0x404040)
|
||||
private fun buildLight(spec: Light?): info.laht.threekt.lights.Light = AmbientLight(0x404040)
|
||||
|
||||
private fun buildCamera(spec: Camera) = PerspectiveCamera(
|
||||
spec.fov,
|
||||
@ -262,5 +272,7 @@ public class ThreeCanvas(
|
||||
public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight"
|
||||
private const val HIGHLIGHT_NAME = "@highlight"
|
||||
private const val SELECT_NAME = "@select"
|
||||
private const val LIGHT_NAME = "@light"
|
||||
private const val AXES_NAME = "@axes"
|
||||
}
|
||||
}
|
@ -8,11 +8,13 @@ import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLElement
|
||||
import space.kscience.dataforge.context.*
|
||||
import space.kscience.dataforge.meta.Meta
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.dataforge.names.*
|
||||
import space.kscience.visionforge.*
|
||||
import space.kscience.visionforge.ElementVisionRenderer
|
||||
import space.kscience.visionforge.Vision
|
||||
import space.kscience.visionforge.onPropertyChange
|
||||
import space.kscience.visionforge.solid.*
|
||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||
import space.kscience.visionforge.visible
|
||||
import kotlin.collections.set
|
||||
import kotlin.reflect.KClass
|
||||
import info.laht.threekt.objects.Group as ThreeGroup
|
||||
@ -149,14 +151,6 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
|
||||
*/
|
||||
@DFExperimental
|
||||
public fun VisionForge.useThreeJs() {
|
||||
plugins.fetch(ThreePlugin)
|
||||
}
|
||||
|
||||
public fun ThreePlugin.render(
|
||||
element: HTMLElement,
|
||||
obj: Solid,
|
||||
|
@ -1,14 +1,11 @@
|
||||
package space.kscience.visionforge.three.server
|
||||
|
||||
import kotlinx.browser.window
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.solid.three.useThreeJs
|
||||
import space.kscience.visionforge.runVisionClient
|
||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||
|
||||
|
||||
@DFExperimental
|
||||
public fun main(): Unit = VisionForge.run {
|
||||
console.info("Starting VisionForge context")
|
||||
useThreeJs()
|
||||
window.asDynamic()["VisionForge"] = VisionForge
|
||||
renderVisionsInWindow()
|
||||
public fun main(): Unit = runVisionClient {
|
||||
plugin(ThreePlugin)
|
||||
}
|
@ -1,7 +1,7 @@
|
||||
package space.kscience.visionforge.three.server
|
||||
|
||||
import space.kscience.dataforge.context.Context
|
||||
import space.kscience.dataforge.misc.DFExperimental
|
||||
import space.kscience.visionforge.VisionForge
|
||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||
import space.kscience.visionforge.html.ResourceLocation
|
||||
import space.kscience.visionforge.html.page
|
||||
@ -16,7 +16,7 @@ public fun VisionServer.useThreeJs(): Unit {
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun VisionForge.makeThreeJsFile(
|
||||
public fun Context.makeThreeJsFile(
|
||||
content: HtmlVisionFragment,
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
|
Loading…
Reference in New Issue
Block a user