Remove global VisionForge object
This commit is contained in:
parent
97b988d419
commit
0961ae90b7
@ -1,27 +1,29 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.project")
|
id("ru.mipt.npm.gradle.project")
|
||||||
|
kotlin("multiplatform") apply false
|
||||||
kotlin("jvm") apply false
|
kotlin("jvm") apply false
|
||||||
kotlin("js") apply false
|
kotlin("js") apply false
|
||||||
kotlin("jupyter.api") 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 dataforgeVersion by extra("0.4.0")
|
||||||
val kotlinWrappersVersion by extra("pre.148-kotlin-1.4.30")
|
val kotlinWrappersVersion by extra("pre.152-kotlin-1.4.32")
|
||||||
val fxVersion by extra("14")
|
val fxVersion by extra("11")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
jcenter()
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://kotlin.bintray.com/kotlin-js-wrappers")
|
|
||||||
maven("https://dl.bintray.com/pdvrieze/maven")
|
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"
|
group = "space.kscience"
|
||||||
version = "0.2.0-dev-13"
|
version = "0.2.0-dev-15"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
|
@ -2,8 +2,7 @@ import ru.mipt.npm.gradle.DependencyConfiguration
|
|||||||
import ru.mipt.npm.gradle.FXModule
|
import ru.mipt.npm.gradle.FXModule
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
id("ru.mipt.npm.gradle.common")
|
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,12 +3,12 @@ package space.kscience.visionforge.gdml
|
|||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.toName
|
import space.kscience.dataforge.names.toName
|
||||||
import space.kscience.dataforge.values.asValue
|
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.setProperty
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
class GDMLVisualTest {
|
class GDMLVisualTest {
|
||||||
|
|
||||||
@ -23,10 +23,10 @@ class GDMLVisualTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPrototypeProperty() {
|
fun testPrototypeProperty() {
|
||||||
val visual = cubes.toVision()
|
val vision = GdmlShowCase.cubes().toVision()
|
||||||
val child = visual["composite[0,0,0].segment[0]".toName()]
|
val child = vision["composite-000.segment-0".toName()]
|
||||||
assertTrue { child!= null }
|
assertNotNull(child)
|
||||||
child?.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
||||||
assertEquals("red", child?.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string)
|
assertEquals("red", child.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).string)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -4,9 +4,9 @@ import kotlinx.browser.document
|
|||||||
import react.child
|
import react.child
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||||
import space.kscience.visionforge.gdml.GdmlShowcase
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
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 element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||||
|
|
||||||
val context = Global.context("demo") .apply{
|
val context = Global.buildContext("demo"){
|
||||||
plugins.fetch(ThreePlugin)
|
plugin(ThreePlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
render(element) {
|
render(element) {
|
||||||
child(GDMLApp) {
|
child(GDMLApp) {
|
||||||
val vision = GdmlShowcase.cubes.toVision()
|
val vision = GdmlShowCase.cubes().toVision()
|
||||||
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
||||||
attrs {
|
attrs {
|
||||||
this.context = context
|
this.context = context
|
||||||
|
@ -3,12 +3,13 @@ package space.kscience.visionforge.gdml.demo
|
|||||||
import javafx.geometry.Orientation
|
import javafx.geometry.Orientation
|
||||||
import javafx.scene.Parent
|
import javafx.scene.Parent
|
||||||
import javafx.stage.FileChooser
|
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.VisionManager
|
||||||
import space.kscience.visionforge.describedProperties
|
import space.kscience.visionforge.describedProperties
|
||||||
import space.kscience.visionforge.editor.VisualObjectEditorFragment
|
import space.kscience.visionforge.editor.VisualObjectEditorFragment
|
||||||
import space.kscience.visionforge.editor.VisualObjectTreeFragment
|
import space.kscience.visionforge.editor.VisualObjectTreeFragment
|
||||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.solid.FX3DPlugin
|
import space.kscience.visionforge.solid.FX3DPlugin
|
||||||
import space.kscience.visionforge.solid.FXCanvas3D
|
import space.kscience.visionforge.solid.FXCanvas3D
|
||||||
@ -19,8 +20,13 @@ import tornadofx.*
|
|||||||
class GDMLDemoApp : App(GDMLView::class)
|
class GDMLDemoApp : App(GDMLView::class)
|
||||||
|
|
||||||
class GDMLView : View() {
|
class GDMLView : View() {
|
||||||
private val fx3d = Global.plugins.fetch(FX3DPlugin)
|
private val context = Context {
|
||||||
private val visionManager = Global.plugins.fetch(VisionManager)
|
plugin(FX3DPlugin)
|
||||||
|
plugin(VisionManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
private val fx3d = context.fetch(FX3DPlugin)
|
||||||
|
private val visionManager = context.fetch(VisionManager)
|
||||||
private val canvas = FXCanvas3D(fx3d)
|
private val canvas = FXCanvas3D(fx3d)
|
||||||
|
|
||||||
private val treeFragment = VisualObjectTreeFragment().apply {
|
private val treeFragment = VisualObjectTreeFragment().apply {
|
||||||
@ -61,7 +67,7 @@ class GDMLView : View() {
|
|||||||
|
|
||||||
init {
|
init {
|
||||||
runAsync {
|
runAsync {
|
||||||
cubes.toVision()
|
GdmlShowCase.cubes().toVision()
|
||||||
} ui {
|
} ui {
|
||||||
canvas.render(it)
|
canvas.render(it)
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,6 @@ plugins {
|
|||||||
repositories {
|
repositories {
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://repo.kotlin.link")
|
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 {
|
dependencies {
|
||||||
|
@ -8,19 +8,17 @@ import kotlinx.html.unsafe
|
|||||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||||
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||||
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
import space.kscience.plotly.Plot
|
import space.kscience.plotly.Plot
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||||
import space.kscience.visionforge.html.Page
|
import space.kscience.visionforge.html.Page
|
||||||
import space.kscience.visionforge.html.embedVisionFragment
|
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.toVision
|
||||||
import space.kscience.visionforge.plotly.usePlotly
|
|
||||||
import space.kscience.visionforge.plugins
|
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import space.kscience.visionforge.visionManager
|
import space.kscience.visionforge.visionManager
|
||||||
|
|
||||||
@ -28,6 +26,11 @@ import space.kscience.visionforge.visionManager
|
|||||||
@DFExperimental
|
@DFExperimental
|
||||||
internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||||
|
|
||||||
|
private val context = Context("VisionForge") {
|
||||||
|
plugin(Solids)
|
||||||
|
plugin(PlotlyPlugin)
|
||||||
|
}
|
||||||
|
|
||||||
private val jsBundle = ResourceFallbacksBundle(listOf(
|
private val jsBundle = ResourceFallbacksBundle(listOf(
|
||||||
ResourceLocation("js/visionforge-playground.js", ResourcePathType.CLASSPATH_PATH))
|
ResourceLocation("js/visionforge-playground.js", ResourcePathType.CLASSPATH_PATH))
|
||||||
)
|
)
|
||||||
@ -39,22 +42,17 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
val id = "visionforge.vision[${counter++}]"
|
val id = "visionforge.vision[${counter++}]"
|
||||||
div {
|
div {
|
||||||
this.id = id
|
this.id = id
|
||||||
embedVisionFragment(VisionForge.visionManager, fragment = fragment)
|
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
type = "text/javascript"
|
type = "text/javascript"
|
||||||
unsafe { +"VisionForge.renderVisionsAt(\"$id\");" }
|
unsafe { +"window.renderAllVisionsById(\"$id\");" }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun Builder.onLoaded() {
|
override fun Builder.onLoaded() {
|
||||||
resource(jsResource)
|
resource(jsResource)
|
||||||
|
|
||||||
onLoaded {
|
|
||||||
VisionForge.plugins.fetch(Solids)
|
|
||||||
VisionForge.usePlotly()
|
|
||||||
}
|
|
||||||
|
|
||||||
import(
|
import(
|
||||||
"space.kscience.gdml.*",
|
"space.kscience.gdml.*",
|
||||||
"space.kscience.plotly.*",
|
"space.kscience.plotly.*",
|
||||||
@ -65,17 +63,15 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
"space.kscience.visionforge.html.page"
|
"space.kscience.visionforge.html.page"
|
||||||
)
|
)
|
||||||
|
|
||||||
import<VisionForge>()
|
|
||||||
|
|
||||||
render<Gdml> { gdmlModel ->
|
render<Gdml> { gdmlModel ->
|
||||||
val fragment = VisionForge.fragment {
|
val fragment = HtmlVisionFragment {
|
||||||
vision(gdmlModel.toVision())
|
vision(gdmlModel.toVision())
|
||||||
}
|
}
|
||||||
HTML(produceHtmlVisionString(fragment))
|
HTML(produceHtmlVisionString(fragment))
|
||||||
}
|
}
|
||||||
|
|
||||||
render<Vision> { vision ->
|
render<Vision> { vision ->
|
||||||
val fragment = VisionForge.fragment {
|
val fragment = HtmlVisionFragment {
|
||||||
vision(vision)
|
vision(vision)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -83,7 +79,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
render<Plot> { plot ->
|
render<Plot> { plot ->
|
||||||
val fragment = VisionForge.fragment {
|
val fragment = HtmlVisionFragment {
|
||||||
vision(plot.toVision())
|
vision(plot.toVision())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -22,6 +22,7 @@ kotlin {
|
|||||||
|
|
||||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||||
dependsOn(jsBrowserDistribution)
|
dependsOn(jsBrowserDistribution)
|
||||||
|
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
||||||
afterEvaluate {
|
afterEvaluate {
|
||||||
from(jsBrowserDistribution)
|
from(jsBrowserDistribution)
|
||||||
}
|
}
|
||||||
@ -57,6 +58,12 @@ application {
|
|||||||
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
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 {
|
//distributions {
|
||||||
// main {
|
// main {
|
||||||
// contents {
|
// contents {
|
||||||
|
@ -26,7 +26,7 @@ private class MMDemoApp : Application {
|
|||||||
|
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
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) {
|
render(element) {
|
||||||
child(MMApp) {
|
child(MMApp) {
|
||||||
attrs {
|
attrs {
|
||||||
|
@ -26,6 +26,7 @@ import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
|||||||
import ru.mipt.npm.muon.monitor.sim.simulateOne
|
import ru.mipt.npm.muon.monitor.sim.simulateOne
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
@ -38,7 +39,7 @@ private val generator = Cos2TrackGenerator(JDKRandomGenerator(223))
|
|||||||
fun Application.module(context: Context = Global) {
|
fun Application.module(context: Context = Global) {
|
||||||
val currentDir = File(".").absoluteFile
|
val currentDir = File(".").absoluteFile
|
||||||
environment.log.info("Current directory: $currentDir")
|
environment.log.info("Current directory: $currentDir")
|
||||||
val solidManager = context.plugins.load(Solids)
|
val solidManager = context.fetch(Solids)
|
||||||
|
|
||||||
install(DefaultHeaders)
|
install(DefaultHeaders)
|
||||||
install(CallLogging)
|
install(CallLogging)
|
||||||
|
@ -1,14 +1,10 @@
|
|||||||
import kotlinx.browser.window
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.plotly.usePlotly
|
import space.kscience.visionforge.runVisionClient
|
||||||
import space.kscience.visionforge.solid.three.useThreeJs
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun main(): Unit = VisionForge.run{
|
fun main() = runVisionClient {
|
||||||
console.info("Starting VisionForge context")
|
plugin(PlotlyPlugin)
|
||||||
usePlotly()
|
plugin(ThreePlugin)
|
||||||
useThreeJs()
|
|
||||||
window.asDynamic()["VisionForge"] = VisionForge
|
|
||||||
renderVisionsInWindow()
|
|
||||||
}
|
}
|
@ -1,20 +1,19 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.visionforge.VisionForge
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
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.Solids
|
||||||
|
|
||||||
@DFExperimental
|
fun main() {
|
||||||
fun main() = VisionForge(Solids) {
|
val context = Context {
|
||||||
val content = VisionForge.fragment {
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
cubes.toVision()
|
GdmlShowCase.cubes().toVision()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
|
|
||||||
}
|
}
|
@ -1,24 +1,22 @@
|
|||||||
package space.kscience.visionforge.examples
|
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.Gdml
|
||||||
import space.kscience.gdml.LUnit
|
import space.kscience.gdml.LUnit
|
||||||
import space.kscience.gdml.decodeFromStream
|
import space.kscience.gdml.decodeFromStream
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
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.Solids
|
||||||
|
|
||||||
@DFExperimental
|
fun main() {
|
||||||
fun main() = VisionForge(Solids) {
|
val context = Context {
|
||||||
val content = VisionForge.fragment {
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
context.makeVisionFile(resourceLocation = ResourceLocation.EMBED) {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
Gdml.decodeFromStream(Gdml.javaClass.getResourceAsStream("/gdml/babyIAXO.gdml")!!, true).toVision {
|
Gdml.decodeFromStream(javaClass.getResourceAsStream("/gdml/babyIAXO.gdml")!!, true).toVision {
|
||||||
lUnit = LUnit.MM
|
lUnit = LUnit.MM
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
makeVisionFile(content, resourceLocation = ResourceLocation.EMBED)
|
|
||||||
}
|
}
|
@ -1,17 +1,16 @@
|
|||||||
package space.kscience.visionforge.examples
|
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.plotly.scatter
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
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.PlotlyPlugin
|
||||||
import space.kscience.visionforge.plotly.plotly
|
import space.kscience.visionforge.plotly.plotly
|
||||||
|
|
||||||
@DFExperimental
|
fun main() {
|
||||||
fun main() = VisionForge(PlotlyPlugin) {
|
val context = Context {
|
||||||
val fragment = fragment {
|
plugin(PlotlyPlugin)
|
||||||
|
}
|
||||||
|
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||||
vision {
|
vision {
|
||||||
plotly {
|
plotly {
|
||||||
scatter {
|
scatter {
|
||||||
@ -21,5 +20,4 @@ fun main() = VisionForge(PlotlyPlugin) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
makeVisionFile(fragment, resourceLocation = ResourceLocation.SYSTEM)
|
|
||||||
}
|
}
|
@ -1,20 +1,23 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import kotlinx.html.h1
|
import kotlinx.html.h1
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
import space.kscience.visionforge.html.fragment
|
|
||||||
import space.kscience.visionforge.invoke
|
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
fun main() {
|
||||||
fun main() = VisionForge(Solids) {
|
val context = Context {
|
||||||
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
|
||||||
val random = Random(112233)
|
val random = Random(112233)
|
||||||
val fragment = fragment {
|
|
||||||
|
context.makeVisionFile(
|
||||||
|
Paths.get("randomSpheres.html"),
|
||||||
|
resourceLocation = ResourceLocation.EMBED
|
||||||
|
) {
|
||||||
h1 { +"Happy new year!" }
|
h1 { +"Happy new year!" }
|
||||||
vision {
|
vision {
|
||||||
solid {
|
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
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
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.ResourceLocation
|
||||||
|
import space.kscience.visionforge.html.VisionTagConsumer
|
||||||
import space.kscience.visionforge.html.page
|
import space.kscience.visionforge.html.page
|
||||||
import space.kscience.visionforge.html.scriptHeader
|
import space.kscience.visionforge.html.scriptHeader
|
||||||
import space.kscience.visionforge.makeFile
|
import space.kscience.visionforge.makeFile
|
||||||
@ -18,25 +17,26 @@ public fun VisionServer.usePlayground(): Unit {
|
|||||||
useScript("js/visionforge-playground.js")
|
useScript("js/visionforge-playground.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@OptIn(DFExperimental::class)
|
||||||
public fun VisionForge.makeVisionFile(
|
public fun Context.makeVisionFile(
|
||||||
content: HtmlVisionFragment,
|
|
||||||
path: Path? = null,
|
path: Path? = null,
|
||||||
title: String = "VisionForge page",
|
title: String = "VisionForge page",
|
||||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||||
show: Boolean = true,
|
show: Boolean = true,
|
||||||
|
content: VisionTagConsumer<*>.() -> Unit
|
||||||
): Unit {
|
): Unit {
|
||||||
|
|
||||||
val actualPath = page(title, content = content).makeFile(path) { actualPath ->
|
val actualPath = page(title, content = content).makeFile(path) { actualPath ->
|
||||||
mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", resourceLocation, actualPath))
|
mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", resourceLocation, actualPath))
|
||||||
}
|
}
|
||||||
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
//@DFExperimental
|
||||||
public fun VisionForge.makeVisionFile(
|
//public fun Context.makeVisionFile(
|
||||||
vision: Vision,
|
// vision: Vision,
|
||||||
path: Path? = null,
|
// path: Path? = null,
|
||||||
title: String = "VisionForge page",
|
// title: String = "VisionForge page",
|
||||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
// resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||||
show: Boolean = true,
|
// show: Boolean = true,
|
||||||
): Unit = makeVisionFile({ vision(vision) }, path, title, resourceLocation, show)
|
//): Unit = makeVisionFile({ vision(vision) }, path, title, resourceLocation, show)
|
||||||
|
@ -1,22 +1,21 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
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.Solids
|
||||||
import space.kscience.visionforge.solid.box
|
import space.kscience.visionforge.solid.box
|
||||||
import space.kscience.visionforge.solid.solid
|
import space.kscience.visionforge.solid.solid
|
||||||
|
|
||||||
@DFExperimental
|
fun main() {
|
||||||
fun main() = VisionForge(Solids) {
|
val context = Context {
|
||||||
val content = fragment {
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
|
||||||
|
context.makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
solid {
|
solid {
|
||||||
box(100, 100, 100)
|
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
|
import kotlin.random.Random
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
val satContext = Global.context("sat") {
|
val satContext = Global.buildContext ("sat") {
|
||||||
plugin(Solids)
|
plugin(Solids)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
kotlin.parallel.tasks.in.project=true
|
|
||||||
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
kotlin.mpp.enableGranularSourceSetsMetadata=true
|
||||||
kotlin.native.enableDependencyPropagation=false
|
|
||||||
kotlin.mpp.stability.nowarn=true
|
kotlin.mpp.stability.nowarn=true
|
||||||
|
|
||||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=512m
|
kotlin.native.enableDependencyPropagation=false
|
||||||
|
kotlin.parallel.tasks.in.project=true
|
||||||
|
|
||||||
|
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
||||||
systemProp.org.gradle.internal.publish.checksums.insecure=true
|
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
distributionPath=wrapper/dists
|
||||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-bin.zip
|
distributionUrl=https\://services.gradle.org/distributions/gradle-7.0-bin.zip
|
||||||
zipStoreBase=GRADLE_USER_HOME
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -1,16 +1,14 @@
|
|||||||
package space.kscience.visionforge.gdml.jupyter
|
package space.kscience.visionforge.gdml.jupyter
|
||||||
|
|
||||||
import kotlinx.browser.window
|
|
||||||
import kotlinx.css.ListStyleType
|
import kotlinx.css.ListStyleType
|
||||||
import kotlinx.css.listStyleType
|
import kotlinx.css.listStyleType
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||||
import space.kscience.visionforge.plugins
|
import space.kscience.visionforge.runVisionClient
|
||||||
import styled.injectGlobal
|
import styled.injectGlobal
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
fun main(): Unit = VisionForge.run {
|
fun main(): Unit = runVisionClient {
|
||||||
useBootstrap()
|
useBootstrap()
|
||||||
injectGlobal {
|
injectGlobal {
|
||||||
rule("ul.nav") {
|
rule("ul.nav") {
|
||||||
@ -25,8 +23,5 @@ fun main(): Unit = VisionForge.run {
|
|||||||
listStyleType = ListStyleType.none
|
listStyleType = ListStyleType.none
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
console.info("Starting VisionForge context")
|
plugin(ThreeWithControls)
|
||||||
plugins.fetch(ThreeWithControls)
|
|
||||||
window.asDynamic()["VisionForge"] = VisionForge
|
|
||||||
renderVisionsInWindow()
|
|
||||||
}
|
}
|
@ -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.annotations.JupyterLibrary
|
||||||
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration
|
||||||
import org.jetbrains.kotlinx.jupyter.api.libraries.resources
|
import org.jetbrains.kotlinx.jupyter.api.libraries.resources
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||||
import space.kscience.visionforge.html.Page
|
import space.kscience.visionforge.html.Page
|
||||||
import space.kscience.visionforge.html.embedVisionFragment
|
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.solid.Solids
|
||||||
import space.kscience.visionforge.visionManager
|
import space.kscience.visionforge.visionManager
|
||||||
|
|
||||||
@ -26,13 +24,17 @@ import space.kscience.visionforge.visionManager
|
|||||||
@DFExperimental
|
@DFExperimental
|
||||||
internal class GdmlForJupyter : JupyterIntegration() {
|
internal class GdmlForJupyter : JupyterIntegration() {
|
||||||
|
|
||||||
|
private val context = Context("GDML") {
|
||||||
|
plugin(Solids)
|
||||||
|
}
|
||||||
|
|
||||||
private var counter = 0
|
private var counter = 0
|
||||||
|
|
||||||
private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div {
|
private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div {
|
||||||
val id = "visionforge.vision[${counter++}]"
|
val id = "visionforge.vision[${counter++}]"
|
||||||
div {
|
div {
|
||||||
this.id = id
|
this.id = id
|
||||||
embedVisionFragment(VisionForge.visionManager, fragment = fragment)
|
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||||
}
|
}
|
||||||
script {
|
script {
|
||||||
type = "text/javascript"
|
type = "text/javascript"
|
||||||
@ -43,7 +45,7 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
|||||||
override fun Builder.onLoaded() {
|
override fun Builder.onLoaded() {
|
||||||
|
|
||||||
resources {
|
resources {
|
||||||
js("three"){
|
js("three") {
|
||||||
classPath("js/gdml-jupyter.js")
|
classPath("js/gdml-jupyter.js")
|
||||||
}
|
}
|
||||||
// css("override") {
|
// css("override") {
|
||||||
@ -51,10 +53,6 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
|||||||
// }
|
// }
|
||||||
}
|
}
|
||||||
|
|
||||||
onLoaded {
|
|
||||||
VisionForge.plugins.fetch(Solids)
|
|
||||||
}
|
|
||||||
|
|
||||||
import(
|
import(
|
||||||
"space.kscience.gdml.*",
|
"space.kscience.gdml.*",
|
||||||
"kotlinx.html.*",
|
"kotlinx.html.*",
|
||||||
@ -64,17 +62,15 @@ internal class GdmlForJupyter : JupyterIntegration() {
|
|||||||
"space.kscience.visionforge.gdml.jupyter.*"
|
"space.kscience.visionforge.gdml.jupyter.*"
|
||||||
)
|
)
|
||||||
|
|
||||||
import<VisionForge>()
|
|
||||||
|
|
||||||
render<Gdml> { gdmlModel ->
|
render<Gdml> { gdmlModel ->
|
||||||
val fragment = VisionForge.fragment {
|
val fragment = HtmlVisionFragment {
|
||||||
vision(gdmlModel.toVision())
|
vision(gdmlModel.toVision())
|
||||||
}
|
}
|
||||||
HTML(produceHtmlVisionString(fragment))
|
HTML(produceHtmlVisionString(fragment))
|
||||||
}
|
}
|
||||||
|
|
||||||
render<Vision> { vision ->
|
render<Vision> { vision ->
|
||||||
val fragment = VisionForge.fragment {
|
val fragment = HtmlVisionFragment {
|
||||||
vision(vision)
|
vision(vision)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,8 @@
|
|||||||
pluginManagement {
|
pluginManagement {
|
||||||
val kotlinVersion = "1.4.31"
|
val kotlinVersion = "1.5.0"
|
||||||
val toolsVersion = "0.9.2"
|
val toolsVersion = "0.9.5"
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
@ -14,11 +13,10 @@ pluginManagement {
|
|||||||
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.js") 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("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:sat-demo",
|
||||||
":demo:playground",
|
":demo:playground",
|
||||||
":demo:jupyter-playground",
|
":demo:jupyter-playground",
|
||||||
|
":demo:plotly-fx",
|
||||||
":jupyter:visionforge-gdml-jupyter"
|
":jupyter:visionforge-gdml-jupyter"
|
||||||
)
|
)
|
@ -1,4 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
|
kotlin("js")
|
||||||
id("ru.mipt.npm.gradle.js")
|
id("ru.mipt.npm.gradle.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,25 +1,25 @@
|
|||||||
package space.kscience.visionforge.bootstrap
|
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.css.properties.border
|
||||||
import kotlinx.html.InputType
|
import kotlinx.css.px
|
||||||
import kotlinx.html.js.onChangeFunction
|
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import org.w3c.dom.HTMLInputElement
|
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import org.w3c.files.Blob
|
import org.w3c.files.Blob
|
||||||
import org.w3c.files.BlobPropertyBag
|
import org.w3c.files.BlobPropertyBag
|
||||||
import react.*
|
import react.*
|
||||||
import react.dom.button
|
import react.dom.button
|
||||||
import react.dom.h3
|
import space.kscience.dataforge.meta.descriptors.defaultMeta
|
||||||
import react.dom.input
|
import space.kscience.dataforge.meta.withDefault
|
||||||
import react.dom.label
|
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
|
import space.kscience.visionforge.react.propertyEditor
|
||||||
import space.kscience.visionforge.solid.SolidGroup
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import space.kscience.visionforge.solid.three.ThreeCanvas
|
import space.kscience.visionforge.solid.three.ThreeCanvas
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
|
||||||
|
|
||||||
private fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
private fun saveData(event: Event, fileName: String, mimeType: String = "text/plain", dataBuilder: () -> String) {
|
||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
@ -48,7 +48,35 @@ public val CanvasControls: FunctionalComponent<CanvasControlsProps> = functional
|
|||||||
arrayOf(props.canvas)
|
arrayOf(props.canvas)
|
||||||
)
|
)
|
||||||
flexColumn {
|
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 {
|
flexRow {
|
||||||
css{
|
css{
|
||||||
border(1.px,BorderStyle.solid, Color.blue)
|
border(1.px,BorderStyle.solid, Color.blue)
|
||||||
@ -57,9 +85,9 @@ public val CanvasControls: FunctionalComponent<CanvasControlsProps> = functional
|
|||||||
label("checkbox-inline") {
|
label("checkbox-inline") {
|
||||||
input(type = InputType.checkBox) {
|
input(type = InputType.checkBox) {
|
||||||
attrs {
|
attrs {
|
||||||
defaultChecked = props.canvas.axes.visible
|
defaultChecked = props.canvas.options.axes.visible
|
||||||
onChangeFunction = {
|
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")
|
id("ru.mipt.npm.gradle.js")
|
||||||
}
|
}
|
||||||
|
|
||||||
val reactVersion by extra("17.0.1")
|
|
||||||
val kotlinWrappersVersion: String by rootProject.extra
|
val kotlinWrappersVersion: String by rootProject.extra
|
||||||
|
|
||||||
dependencies{
|
dependencies{
|
||||||
api(project(":visionforge-solid"))
|
api(project(":visionforge-solid"))
|
||||||
api("org.jetbrains:kotlin-styled:5.2.1-$kotlinWrappersVersion")
|
api("org.jetbrains:kotlin-styled:5.2.3-$kotlinWrappersVersion")
|
||||||
api("org.jetbrains:kotlin-react-dom:$reactVersion-$kotlinWrappersVersion")
|
api("org.jetbrains:kotlin-react-dom:17.0.2-$kotlinWrappersVersion")
|
||||||
implementation(project(":visionforge-threejs"))
|
implementation(project(":visionforge-threejs"))
|
||||||
}
|
}
|
@ -59,6 +59,11 @@ public external interface PropertyEditorProps : RProps {
|
|||||||
* Flow names of updated properties
|
* Flow names of updated properties
|
||||||
*/
|
*/
|
||||||
public var updateFlow: Flow<Name>?
|
public var updateFlow: Flow<Name>?
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initial expanded state
|
||||||
|
*/
|
||||||
|
public var expanded: Boolean?
|
||||||
}
|
}
|
||||||
|
|
||||||
private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
||||||
@ -67,7 +72,7 @@ private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun RBuilder.propertyEditorItem(props: 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)
|
val descriptorItem: ItemDescriptor? = props.descriptor?.get(props.name)
|
||||||
var ownProperty: MetaItem? by useState { props.ownProperties.getItem(props.name) }
|
var ownProperty: MetaItem? by useState { props.ownProperties.getItem(props.name) }
|
||||||
val actualItem: MetaItem? = props.allProperties?.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) {
|
if (actualItem is MetaItemNode) {
|
||||||
val keys = buildSet {
|
val keys = buildSet {
|
||||||
(descriptorItem as? NodeDescriptor)?.items?.filterNot {
|
(descriptorItem as? NodeDescriptor)?.items?.filterNot {
|
||||||
it.key.startsWith("@") || it.value.hidden
|
it.key.startsWith("@") || it.value.hidden
|
||||||
}?.forEach {
|
}?.forEach {
|
||||||
add(NameToken(it.key))
|
add(NameToken(it.key))
|
||||||
}
|
}
|
||||||
@ -232,11 +237,12 @@ public val PropertyEditor: FunctionalComponent<PropertyEditorProps> = functional
|
|||||||
|
|
||||||
public fun RBuilder.propertyEditor(
|
public fun RBuilder.propertyEditor(
|
||||||
ownProperties: MutableItemProvider,
|
ownProperties: MutableItemProvider,
|
||||||
allProperties: ItemProvider?,
|
allProperties: ItemProvider? = ownProperties,
|
||||||
updateFlow: Flow<Name>? = null,
|
updateFlow: Flow<Name>? = null,
|
||||||
descriptor: NodeDescriptor? = null,
|
descriptor: NodeDescriptor? = null,
|
||||||
scope: CoroutineScope? = null,
|
scope: CoroutineScope? = null,
|
||||||
key: Any? = null,
|
key: Any? = null,
|
||||||
|
expanded: Boolean? = null
|
||||||
) {
|
) {
|
||||||
child(PropertyEditor) {
|
child(PropertyEditor) {
|
||||||
attrs {
|
attrs {
|
||||||
@ -246,6 +252,7 @@ public fun RBuilder.propertyEditor(
|
|||||||
this.descriptor = descriptor
|
this.descriptor = descriptor
|
||||||
this.key = key?.toString() ?: ""
|
this.key = key?.toString() ?: ""
|
||||||
this.scope = scope
|
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.NameToken
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
|
import kotlin.jvm.JvmInline
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A container for styles
|
* 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
|
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.TagConsumer
|
||||||
import kotlinx.html.stream.createHTML
|
import kotlinx.html.stream.createHTML
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
|
|
||||||
public typealias HtmlFragment = TagConsumer<*>.() -> Unit
|
public typealias HtmlFragment = TagConsumer<*>.() -> Unit
|
||||||
|
|
||||||
@ -21,4 +20,4 @@ public fun FlowContent.fragment(fragment: HtmlFragment) {
|
|||||||
public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit
|
public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit
|
||||||
|
|
||||||
@DFExperimental
|
@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 kotlinx.html.*
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.context
|
|
||||||
import space.kscience.visionforge.visionManager
|
import space.kscience.visionforge.visionManager
|
||||||
|
|
||||||
public data class Page(
|
public data class Page(
|
||||||
public val context: Context,
|
public val context: Context,
|
||||||
public val title: String,
|
public val title: String,
|
||||||
public val headers: Map<String, HtmlFragment>,
|
public val headers: Map<String, HtmlFragment>,
|
||||||
public val content: HtmlVisionFragment
|
public val content: HtmlVisionFragment,
|
||||||
) {
|
) {
|
||||||
public fun <R> render(root: TagConsumer<R>): R = root.apply {
|
public fun <R> render(root: TagConsumer<R>): R = root.apply {
|
||||||
head {
|
head {
|
||||||
@ -31,8 +29,8 @@ public data class Page(
|
|||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun VisionForge.page(
|
public fun Context.page(
|
||||||
title: String = "VisionForge page",
|
title: String = "VisionForge page",
|
||||||
vararg headers: Pair<String, HtmlFragment>,
|
vararg headers: Pair<String, HtmlFragment>,
|
||||||
content: HtmlVisionFragment,
|
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)
|
return vision(name, vision, output.meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* TODO to be replaced by multi-receiver
|
||||||
|
*/
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
public inline fun <T> TagConsumer<T>.vision(
|
public inline fun <T> TagConsumer<T>.vision(
|
||||||
name: String = DEFAULT_VISION_NAME,
|
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
|
package space.kscience.visionforge
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.dataforge.meta.descriptors.ItemDescriptor
|
import space.kscience.dataforge.meta.descriptors.*
|
||||||
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.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.values.ValueType
|
import space.kscience.dataforge.values.ValueType
|
||||||
import space.kscience.dataforge.values.asValue
|
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 INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited"
|
||||||
private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles"
|
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
|
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean ?: false
|
||||||
set(value) = attributes {
|
set(value) = attributes {
|
||||||
set(INHERITED_DESCRIPTOR_ATTRIBUTE, value)
|
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
|
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean ?: true
|
||||||
set(value) = attributes {
|
set(value) = attributes {
|
||||||
set(STYLE_DESCRIPTOR_ATTRIBUTE, value)
|
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]
|
* 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
|
get() = attributes["widget"].node ?: Meta.EMPTY
|
||||||
set(value) {
|
set(value) {
|
||||||
attributes {
|
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]
|
* 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
|
get() = attributes["widget.type"].string
|
||||||
set(value) {
|
set(value) {
|
||||||
attributes {
|
attributes {
|
||||||
@ -60,15 +69,15 @@ public var ValueDescriptor.widgetType: String?
|
|||||||
public val ItemDescriptor.hidden: Boolean
|
public val ItemDescriptor.hidden: Boolean
|
||||||
get() = attributes["widget.hide"].boolean ?: false
|
get() = attributes["widget.hide"].boolean ?: false
|
||||||
|
|
||||||
public fun ItemDescriptor.hide(): Unit = attributes {
|
public fun ItemDescriptorBuilder.hide(): Unit = attributes {
|
||||||
set("widget.hide", true)
|
set("widget.hide", true)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public inline fun <reified E : Enum<E>> NodeDescriptor.enum(
|
public inline fun <reified E : Enum<E>> NodeDescriptorBuilder.enum(
|
||||||
key: Name,
|
key: Name,
|
||||||
default: E?,
|
default: E?,
|
||||||
crossinline modifier: ValueDescriptor.() -> Unit = {},
|
crossinline modifier: ValueDescriptorBuilder.() -> Unit = {},
|
||||||
): Unit = value(key) {
|
): Unit = value(key) {
|
||||||
type(ValueType.STRING)
|
type(ValueType.STRING)
|
||||||
default?.let {
|
default?.let {
|
||||||
|
@ -46,7 +46,7 @@ class HtmlTagTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val groupRenderer: HtmlVisionRenderer = { _, group, _ ->
|
val groupRenderer: HtmlVisionRenderer = { _, _, _ ->
|
||||||
p { +"This is group" }
|
p { +"This is group" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,10 +2,7 @@ package space.kscience.visionforge
|
|||||||
|
|
||||||
import kotlinx.browser.document
|
import kotlinx.browser.document
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.*
|
||||||
import org.w3c.dom.WebSocket
|
|
||||||
import org.w3c.dom.asList
|
|
||||||
import org.w3c.dom.get
|
|
||||||
import org.w3c.dom.url.URL
|
import org.w3c.dom.url.URL
|
||||||
import space.kscience.dataforge.context.*
|
import space.kscience.dataforge.context.*
|
||||||
import space.kscience.dataforge.meta.Meta
|
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.
|
* 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")
|
val name = resolveName(element) ?: error("The element is not a vision output")
|
||||||
logger.info { "Found DF output with name $name" }
|
logger.info { "Found DF output with name $name" }
|
||||||
if (!element.classList.contains(VisionTagConsumer.OUTPUT_CLASS)) error("The element $element is not an output element")
|
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].
|
private fun whenDocumentLoaded(block: Document.() -> Unit): Unit {
|
||||||
*/
|
if (document.readyState == DocumentReadyState.COMPLETE) {
|
||||||
public fun VisionClient.renderAllVisionsAt(element: Element) {
|
block(document)
|
||||||
val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS)
|
} else {
|
||||||
console.info("Finished search for outputs. Found ${elements.length} items")
|
document.addEventListener("DOMContentLoaded", { block(document) })
|
||||||
elements.asList().forEach { child ->
|
|
||||||
renderVisionAt(child)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* 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
|
* Fetch visions from the server for all elements with [VisionTagConsumer.OUTPUT_CLASS] class in the document body
|
||||||
*/
|
*/
|
||||||
public fun VisionClient.renderAllVisions() {
|
public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded {
|
||||||
val element = document.body ?: error("Document does not have a body")
|
val element = body ?: error("Document does not have a body")
|
||||||
renderAllVisionsAt(element)
|
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 {
|
plugins {
|
||||||
|
kotlin("multiplatform")
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -7,7 +8,7 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":visionforge-solid"))
|
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
|
PROTOTYPE
|
||||||
}
|
}
|
||||||
|
|
||||||
public var lUnit: LUnit = LUnit.CM
|
public var lUnit: LUnit = LUnit.MM
|
||||||
public var aUnit: AUnit = AUnit.RADIAN
|
public var aUnit: AUnit = AUnit.RADIAN
|
||||||
|
|
||||||
public var solidAction: (GdmlSolid) -> Action = { Action.PROTOTYPE }
|
public var solidAction: (GdmlSolid) -> Action = { Action.PROTOTYPE }
|
||||||
public var volumeAction: (GdmlGroup) -> 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))
|
color(random.nextInt(16777216))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -110,7 +110,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
val styleName = "materials.${material.name}"
|
val styleName = "materials.${material.name}"
|
||||||
|
|
||||||
obj.useStyle(styleName) {
|
obj.useStyle(styleName) {
|
||||||
val vfMaterial = settings.run { SolidMaterial().apply { paint(material)}}
|
val vfMaterial = settings.run { SolidMaterial().apply { paint(material) } }
|
||||||
MATERIAL_KEY put vfMaterial.toMeta()
|
MATERIAL_KEY put vfMaterial.toMeta()
|
||||||
"Gdml.material" put material.name
|
"Gdml.material" put material.name
|
||||||
}
|
}
|
||||||
@ -151,6 +151,24 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
physVolume.resolveScale(root)
|
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(
|
fun SolidGroup.addSolid(
|
||||||
root: Gdml,
|
root: Gdml,
|
||||||
solid: GdmlSolid,
|
solid: GdmlSolid,
|
||||||
@ -158,7 +176,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
): Solid {
|
): Solid {
|
||||||
//context.solidAdded(solid)
|
//context.solidAdded(solid)
|
||||||
val lScale = solid.lscale(settings.lUnit)
|
val lScale = solid.lscale(settings.lUnit)
|
||||||
val aScale = solid.ascale()
|
val aScale = solid.ascale(settings.aUnit)
|
||||||
return when (solid) {
|
return when (solid) {
|
||||||
is GdmlBox -> box(solid.x * lScale, solid.y * lScale, solid.z * lScale, name)
|
is GdmlBox -> box(solid.x * lScale, solid.y * lScale, solid.z * lScale, name)
|
||||||
is GdmlTube -> tube(
|
is GdmlTube -> tube(
|
||||||
@ -201,7 +219,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
scaleZ = solid.scale.z.toFloat()
|
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
|
phi = solid.deltaphi * aScale
|
||||||
theta = solid.deltatheta * aScale
|
theta = solid.deltatheta * aScale
|
||||||
phiStart = solid.startphi * aScale
|
phiStart = solid.startphi * aScale
|
||||||
@ -299,7 +317,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
when (settings.volumeAction(volume)) {
|
when (settings.volumeAction(volume)) {
|
||||||
GdmlTransformerSettings.Action.ADD -> {
|
GdmlTransformerSettings.Action.ADD -> {
|
||||||
val group: SolidGroup = volume(root, volume)
|
val group: SolidGroup = volume(root, volume)
|
||||||
this[physVolume.name ?: ""] = group.withPosition(root, physVolume)
|
this[physVolume.name] = group.withPosition(root, physVolume)
|
||||||
}
|
}
|
||||||
GdmlTransformerSettings.Action.PROTOTYPE -> {
|
GdmlTransformerSettings.Action.PROTOTYPE -> {
|
||||||
proxyVolume(root, this, physVolume, volume)
|
proxyVolume(root, this, physVolume, volume)
|
||||||
@ -378,7 +396,7 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
|
|||||||
return final
|
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.context.Context
|
||||||
import space.kscience.dataforge.names.toName
|
import space.kscience.dataforge.names.toName
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.*
|
||||||
import space.kscience.gdml.GdmlBox
|
|
||||||
import space.kscience.gdml.decodeFromString
|
|
||||||
import space.kscience.gdml.encodeToString
|
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.gdml.GdmlShowcase.cubes
|
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.get
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.visionManager
|
import space.kscience.visionforge.visionManager
|
||||||
@ -21,13 +17,16 @@ internal val testContext = Context("TEST") {
|
|||||||
|
|
||||||
class TestCubes {
|
class TestCubes {
|
||||||
|
|
||||||
|
val cubes = GdmlShowCase.cubes()
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCubesDirect() {
|
fun testCubesDirect() {
|
||||||
val vision = cubes.toVision()
|
val vision = cubes.toVision()
|
||||||
|
// println(Solids.encodeToString(vision))
|
||||||
val smallBoxPrototype = vision.getPrototype("solids.smallBox".toName()) as? Box
|
val smallBoxPrototype = vision.getPrototype("solids.smallBox".toName()) as? Box
|
||||||
assertNotNull(smallBoxPrototype)
|
assertNotNull(smallBoxPrototype)
|
||||||
assertEquals(30.0, smallBoxPrototype.xSize.toDouble())
|
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)
|
assertNotNull(smallBoxVision)
|
||||||
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
||||||
}
|
}
|
||||||
|
@ -4,6 +4,7 @@ import kotlinx.coroutines.Dispatchers
|
|||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
import nl.adaptivity.xmlutil.StAXReader
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
|
import space.kscience.gdml.decodeFromReader
|
||||||
import space.kscience.visionforge.solid.prototype
|
import space.kscience.visionforge.solid.prototype
|
||||||
import space.kscience.visionforge.visitor.countDistinct
|
import space.kscience.visionforge.visitor.countDistinct
|
||||||
import space.kscience.visionforge.visitor.flowStatistics
|
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()
|
File("D:\\Work\\Projects\\dataforge-vis\\visionforge-gdml\\src\\jvmTest\\resources\\gdml\\BM@N.gdml").inputStream()
|
||||||
|
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val xmlReader = StAXReader(stream, "UTF-8")
|
||||||
val xml = Gdml.format.decodeFromReader(Gdml.serializer(), xmlReader)
|
val xml = Gdml.decodeFromReader( xmlReader)
|
||||||
val vision = xml.toVision()
|
val vision = xml.toVision()
|
||||||
|
|
||||||
|
|
||||||
|
@ -4,12 +4,12 @@ plugins {
|
|||||||
|
|
||||||
val plotlyVersion = "0.4.0-dev-1"
|
val plotlyVersion = "0.4.0-dev-1"
|
||||||
|
|
||||||
kscience{
|
kscience {
|
||||||
useSerialization()
|
useSerialization()
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
js{
|
js {
|
||||||
//binaries.library()
|
//binaries.library()
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
browser {
|
browser {
|
||||||
@ -19,15 +19,11 @@ kotlin {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
val jsBrowserDistribution by tasks.getting
|
||||||
val jsBrowserDistribution by tasks.getting
|
|
||||||
|
|
||||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||||
dependsOn(jsBrowserDistribution)
|
dependsOn(jsBrowserDistribution)
|
||||||
afterEvaluate {
|
from(jsBrowserDistribution)
|
||||||
from(jsBrowserDistribution)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
|
@ -4,14 +4,11 @@ import kotlinx.serialization.modules.SerializersModule
|
|||||||
import kotlinx.serialization.modules.polymorphic
|
import kotlinx.serialization.modules.polymorphic
|
||||||
import kotlinx.serialization.modules.subclass
|
import kotlinx.serialization.modules.subclass
|
||||||
import space.kscience.dataforge.context.PluginFactory
|
import space.kscience.dataforge.context.PluginFactory
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.VisionPlugin
|
import space.kscience.visionforge.VisionPlugin
|
||||||
import space.kscience.visionforge.plugins
|
|
||||||
|
|
||||||
public expect class PlotlyPlugin : VisionPlugin{
|
public expect class PlotlyPlugin : VisionPlugin {
|
||||||
public companion object: PluginFactory<PlotlyPlugin>
|
public companion object : PluginFactory<PlotlyPlugin>
|
||||||
}
|
}
|
||||||
|
|
||||||
internal val plotlySerializersModule = SerializersModule {
|
internal val plotlySerializersModule = SerializersModule {
|
||||||
@ -19,11 +16,3 @@ internal val plotlySerializersModule = SerializersModule {
|
|||||||
subclass(VisionOfPlotly.serializer())
|
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
|
package space.kscience.visionforge.plotly
|
||||||
|
|
||||||
import kotlinx.html.script
|
//internal val plotlyScriptLocation = "js/visionforge-three.js"
|
||||||
import kotlinx.html.unsafe
|
//
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
///**
|
||||||
import space.kscience.visionforge.html.HtmlFragment
|
// * A header that stores/embeds plotly bundle and registers plotly renderer in the frontend
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
// */
|
||||||
import space.kscience.visionforge.html.scriptHeader
|
//@OptIn(DFExperimental::class)
|
||||||
import java.nio.file.Path
|
//public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
|
||||||
|
// scriptHeader(
|
||||||
internal val plotlyScriptLocation = "js/visionforge-three.js"
|
// plotlyScriptLocation,
|
||||||
|
// resourceLocation = location,
|
||||||
/**
|
// htmlPath = filePath
|
||||||
* A header that stores/embeds plotly bundle and registers plotly renderer in the frontend
|
// ).invoke(this)
|
||||||
*/
|
// script {
|
||||||
@OptIn(DFExperimental::class)
|
// type = "text/javascript"
|
||||||
public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
|
// unsafe {
|
||||||
scriptHeader(
|
// //language=JavaScript
|
||||||
plotlyScriptLocation,
|
// +"space.kscience.visionforge.plotly.loadPlotly()"
|
||||||
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) {
|
public class Solids(meta: Meta) : VisionPlugin(meta) {
|
||||||
|
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids
|
override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids
|
||||||
|
|
||||||
public companion object : PluginFactory<Solids> {
|
public companion object : PluginFactory<Solids> {
|
||||||
|
@ -9,6 +9,9 @@ import kotlin.math.PI
|
|||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A spherical layer
|
||||||
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.sphereLayer")
|
@SerialName("solid.sphereLayer")
|
||||||
public class 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.Scheme
|
||||||
import space.kscience.dataforge.meta.SchemeSpec
|
import space.kscience.dataforge.meta.SchemeSpec
|
||||||
import space.kscience.dataforge.meta.boolean
|
import space.kscience.dataforge.meta.boolean
|
||||||
|
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import space.kscience.dataforge.meta.double
|
import space.kscience.dataforge.meta.double
|
||||||
|
import space.kscience.visionforge.value
|
||||||
|
|
||||||
public class Axes : Scheme() {
|
public class Axes : Scheme() {
|
||||||
public var visible: Boolean by boolean(false)
|
public var visible: Boolean by boolean(false)
|
||||||
@ -13,5 +15,13 @@ public class Axes : Scheme() {
|
|||||||
public companion object : SchemeSpec<Axes>(::Axes) {
|
public companion object : SchemeSpec<Axes>(::Axes) {
|
||||||
public const val AXIS_SIZE: Double = 1000.0
|
public const val AXIS_SIZE: Double = 1000.0
|
||||||
public const val AXIS_WIDTH: Double = 3.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.Scheme
|
||||||
import space.kscience.dataforge.meta.SchemeSpec
|
import space.kscience.dataforge.meta.SchemeSpec
|
||||||
|
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import space.kscience.dataforge.meta.double
|
import space.kscience.dataforge.meta.double
|
||||||
import space.kscience.dataforge.meta.int
|
import space.kscience.dataforge.meta.int
|
||||||
|
import space.kscience.visionforge.value
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
public class Camera : Scheme() {
|
public class Camera : Scheme() {
|
||||||
@ -25,5 +27,16 @@ public class Camera : Scheme() {
|
|||||||
public const val NEAR_CLIP: Double = 0.1
|
public const val NEAR_CLIP: Double = 0.1
|
||||||
public const val FAR_CLIP: Double = 10000.0
|
public const val FAR_CLIP: Double = 10000.0
|
||||||
public const val FIELD_OF_VIEW: Int = 75
|
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
|
package space.kscience.visionforge.solid.specifications
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
|
import space.kscience.dataforge.meta.descriptors.NodeDescriptor
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.visionforge.scheme
|
||||||
|
import space.kscience.visionforge.value
|
||||||
|
|
||||||
public class Canvas3DOptions : Scheme() {
|
public class Canvas3DOptions : Scheme() {
|
||||||
public var axes: Axes by spec(Axes)
|
public var axes: Axes by spec(Axes)
|
||||||
@ -17,10 +20,25 @@ public class Canvas3DOptions : Scheme() {
|
|||||||
public var maxWith: Number by number { maxSize }
|
public var maxWith: Number by number { maxSize }
|
||||||
public var maxHeight: 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 =
|
public fun Canvas3DOptions.computeWidth(external: Number): Int =
|
||||||
|
@ -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 {
|
dependencies {
|
||||||
api(project(":visionforge-solid"))
|
api(project(":visionforge-solid"))
|
||||||
implementation(npm("three", "0.124.0"))
|
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
|
package info.laht.threekt.renderers
|
||||||
|
|
||||||
import info.laht.threekt.cameras.Camera
|
import info.laht.threekt.cameras.Camera
|
||||||
|
import info.laht.threekt.math.Plane
|
||||||
import info.laht.threekt.scenes.Scene
|
import info.laht.threekt.scenes.Scene
|
||||||
import org.w3c.dom.Node
|
import org.w3c.dom.Node
|
||||||
|
|
||||||
@ -103,4 +104,17 @@ external class WebGLRenderer(params: WebGLRendererParams = definedExternally) {
|
|||||||
)
|
)
|
||||||
|
|
||||||
fun setPixelRatio(value: Number)
|
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.context.logger
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
|
import space.kscience.dataforge.meta.useProperty
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
@ -41,7 +42,7 @@ import kotlin.math.sin
|
|||||||
public class ThreeCanvas(
|
public class ThreeCanvas(
|
||||||
public val three: ThreePlugin,
|
public val three: ThreePlugin,
|
||||||
public val options: Canvas3DOptions,
|
public val options: Canvas3DOptions,
|
||||||
) {
|
) {
|
||||||
private var root: Object3D? = null
|
private var root: Object3D? = null
|
||||||
|
|
||||||
private val raycaster = Raycaster()
|
private val raycaster = Raycaster()
|
||||||
@ -50,14 +51,23 @@ public class ThreeCanvas(
|
|||||||
public var content: Solid? = null
|
public var content: Solid? = null
|
||||||
private set
|
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 {
|
private val scene: Scene = Scene().apply {
|
||||||
add(axes)
|
options.useProperty(Canvas3DOptions::axes){axesConfig->
|
||||||
add(light)
|
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)
|
public var camera: PerspectiveCamera = buildCamera(options.camera)
|
||||||
@ -138,7 +148,7 @@ public class ThreeCanvas(
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun attach(element: Element) {
|
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)
|
element.appendChild(canvas)
|
||||||
updateSize()
|
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(
|
private fun buildCamera(spec: Camera) = PerspectiveCamera(
|
||||||
spec.fov,
|
spec.fov,
|
||||||
@ -262,5 +272,7 @@ public class ThreeCanvas(
|
|||||||
public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight"
|
public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight"
|
||||||
private const val HIGHLIGHT_NAME = "@highlight"
|
private const val HIGHLIGHT_NAME = "@highlight"
|
||||||
private const val SELECT_NAME = "@select"
|
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 org.w3c.dom.HTMLElement
|
||||||
import space.kscience.dataforge.context.*
|
import space.kscience.dataforge.context.*
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
|
||||||
import space.kscience.dataforge.names.*
|
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.*
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
|
import space.kscience.visionforge.visible
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
import info.laht.threekt.objects.Group as ThreeGroup
|
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(
|
public fun ThreePlugin.render(
|
||||||
element: HTMLElement,
|
element: HTMLElement,
|
||||||
obj: Solid,
|
obj: Solid,
|
||||||
|
@ -1,14 +1,11 @@
|
|||||||
package space.kscience.visionforge.three.server
|
package space.kscience.visionforge.three.server
|
||||||
|
|
||||||
import kotlinx.browser.window
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
import space.kscience.visionforge.runVisionClient
|
||||||
import space.kscience.visionforge.solid.three.useThreeJs
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun main(): Unit = VisionForge.run {
|
public fun main(): Unit = runVisionClient {
|
||||||
console.info("Starting VisionForge context")
|
plugin(ThreePlugin)
|
||||||
useThreeJs()
|
|
||||||
window.asDynamic()["VisionForge"] = VisionForge
|
|
||||||
renderVisionsInWindow()
|
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package space.kscience.visionforge.three.server
|
package space.kscience.visionforge.three.server
|
||||||
|
|
||||||
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.VisionForge
|
|
||||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
import space.kscience.visionforge.html.HtmlVisionFragment
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
import space.kscience.visionforge.html.page
|
import space.kscience.visionforge.html.page
|
||||||
@ -16,7 +16,7 @@ public fun VisionServer.useThreeJs(): Unit {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun VisionForge.makeThreeJsFile(
|
public fun Context.makeThreeJsFile(
|
||||||
content: HtmlVisionFragment,
|
content: HtmlVisionFragment,
|
||||||
path: Path? = null,
|
path: Path? = null,
|
||||||
title: String = "VisionForge page",
|
title: String = "VisionForge page",
|
||||||
|
Loading…
Reference in New Issue
Block a user