New properties #34
@ -1,12 +1,11 @@
|
|||||||
package ru.mipt.npm.sat
|
package ru.mipt.npm.sat
|
||||||
|
|
||||||
|
|
||||||
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.solid.Solid
|
import hep.dataforge.vision.solid.*
|
||||||
import hep.dataforge.vision.solid.clear
|
|
||||||
import hep.dataforge.vision.solid.color
|
|
||||||
import hep.dataforge.vision.solid.invoke
|
|
||||||
import hep.dataforge.vision.three.server.*
|
import hep.dataforge.vision.three.server.*
|
||||||
|
import hep.dataforge.vision.visionManager
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
@ -16,10 +15,14 @@ import kotlinx.html.h1
|
|||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
fun main() {
|
fun main() {
|
||||||
|
val satContext = Global.context("sat") {
|
||||||
|
plugin(SolidManager)
|
||||||
|
}
|
||||||
|
|
||||||
//Create a geometry
|
//Create a geometry
|
||||||
val sat = visionOfSatellite(ySegments = 3)
|
val sat = visionOfSatellite(ySegments = 3)
|
||||||
|
|
||||||
val server = visionManager.serve {
|
val server = satContext.visionManager.serve {
|
||||||
//use client library
|
//use client library
|
||||||
useThreeJs()
|
useThreeJs()
|
||||||
//use css
|
//use css
|
||||||
|
@ -12,6 +12,16 @@ repositories{
|
|||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
kotlin {
|
||||||
|
|
||||||
|
js(IR) {
|
||||||
|
browser {
|
||||||
|
webpackTask {
|
||||||
|
this.outputFileName = "js/visionforge-playground.js"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binaries.executable()
|
||||||
|
}
|
||||||
|
|
||||||
jvm{
|
jvm{
|
||||||
compilations.all {
|
compilations.all {
|
||||||
kotlinOptions.jvmTarget = "11"
|
kotlinOptions.jvmTarget = "11"
|
||||||
@ -20,30 +30,39 @@ kotlin {
|
|||||||
useJUnitPlatform()
|
useJUnitPlatform()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
js(IR) {
|
|
||||||
browser {
|
afterEvaluate {
|
||||||
|
val jsBrowserDistribution by tasks.getting
|
||||||
|
|
||||||
|
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||||
|
dependsOn(jsBrowserDistribution)
|
||||||
|
afterEvaluate {
|
||||||
|
from(jsBrowserDistribution)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
binaries.executable()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
sourceSets {
|
sourceSets {
|
||||||
commonMain {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":visionforge-solid"))
|
implementation(project(":visionforge-solid"))
|
||||||
implementation(project(":visionforge-gdml"))
|
implementation(project(":visionforge-gdml"))
|
||||||
|
implementation(project(":visionforge-plotly"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val jsMain by getting{
|
val jsMain by getting{
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(project(":ui:bootstrap"))
|
implementation(project(":ui:bootstrap"))
|
||||||
|
implementation(project(":visionforge-threejs"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val jvmMain by getting{
|
val jvmMain by getting{
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation(project(":visionforge-server"))
|
||||||
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
|
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
|
||||||
implementation(project(":visionforge-threejs:visionforge-threejs-server"))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
2
playground/src/commonMain/kotlin/visionContext.kt
Normal file
2
playground/src/commonMain/kotlin/visionContext.kt
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
|
@ -1,58 +1,67 @@
|
|||||||
import hep.dataforge.Application
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.startApplication
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.vision.bootstrap.visionPropertyEditor
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.vision.react.ThreeCanvasComponent
|
import hep.dataforge.vision.client.VisionClient
|
||||||
import hep.dataforge.vision.react.objectTree
|
import hep.dataforge.vision.client.renderAllVisions
|
||||||
import hep.dataforge.vision.solid.*
|
import hep.dataforge.vision.plotly.PlotlyPlugin
|
||||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||||
import kotlinx.browser.document
|
import kotlinx.browser.window
|
||||||
import org.w3c.dom.HTMLElement
|
|
||||||
import react.RBuilder
|
|
||||||
import react.child
|
|
||||||
import react.dom.div
|
|
||||||
import react.dom.render
|
|
||||||
|
|
||||||
fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
|
||||||
child(ThreeCanvasComponent) {
|
|
||||||
attrs {
|
|
||||||
this.obj = object3D
|
|
||||||
this.options = Canvas3DOptions(options)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class PlayGroundApp : Application {
|
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
|
||||||
|
|
||||||
val element =
|
|
||||||
document.getElementById("app") as? HTMLElement ?: error("Element with id 'canvas' not found on page")
|
|
||||||
|
|
||||||
val obj = SolidGroup().apply {
|
|
||||||
box(100, 100, 100, name = "A")
|
|
||||||
group("B") {
|
|
||||||
position = Point3D(120, 0, 0)
|
|
||||||
box(100, 100, 100, name = "C")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render(element) {
|
|
||||||
div("row") {
|
|
||||||
div("col-3") {
|
|
||||||
objectTree(obj)
|
|
||||||
}
|
|
||||||
div("col-6") {
|
|
||||||
threeCanvas(obj)
|
|
||||||
}
|
|
||||||
div("col-3") {
|
|
||||||
visionPropertyEditor(obj)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
||||||
|
// child(ThreeCanvasComponent) {
|
||||||
|
// attrs {
|
||||||
|
// this.obj = object3D
|
||||||
|
// this.options = Canvas3DOptions(options)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//}
|
||||||
|
//
|
||||||
|
//private class PlayGroundApp : Application {
|
||||||
|
//
|
||||||
|
// override fun start(state: Map<String, Any>) {
|
||||||
|
//
|
||||||
|
// val element =
|
||||||
|
// document.getElementById("app") as? HTMLElement ?: error("Element with id 'canvas' not found on page")
|
||||||
|
//
|
||||||
|
// val obj = SolidGroup().apply {
|
||||||
|
// box(100, 100, 100, name = "A")
|
||||||
|
// group("B") {
|
||||||
|
// position = Point3D(120, 0, 0)
|
||||||
|
// box(100, 100, 100, name = "C")
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// render(element) {
|
||||||
|
// div("row") {
|
||||||
|
// div("col-3") {
|
||||||
|
// objectTree(obj)
|
||||||
|
// }
|
||||||
|
// div("col-6") {
|
||||||
|
// threeCanvas(obj)
|
||||||
|
// }
|
||||||
|
// div("col-3") {
|
||||||
|
// visionPropertyEditor(obj)
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
//}
|
||||||
|
|
||||||
|
public val visionContext: Context = Global.context("VISION") {
|
||||||
|
plugin(ThreePlugin)
|
||||||
|
plugin(PlotlyPlugin)
|
||||||
|
plugin(VisionClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
fun main() {
|
fun main() {
|
||||||
startApplication(::PlayGroundApp)
|
//Loading three-js renderer
|
||||||
|
val clientManager = visionContext.plugins.fetch(VisionClient)
|
||||||
|
|
||||||
|
//Fetch from server and render visions for all outputs
|
||||||
|
window.onload = {
|
||||||
|
clientManager.renderAllVisions()
|
||||||
|
}
|
||||||
|
//startApplication(::PlayGroundApp)
|
||||||
}
|
}
|
@ -4,21 +4,20 @@ import hep.dataforge.meta.DFExperimental
|
|||||||
import hep.dataforge.vision.ResourceLocation
|
import hep.dataforge.vision.ResourceLocation
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
import hep.dataforge.vision.html.fragment
|
import hep.dataforge.vision.html.fragment
|
||||||
import hep.dataforge.vision.three.server.makeFile
|
|
||||||
import hep.dataforge.vision.three.server.solid
|
|
||||||
import kotlinx.html.h1
|
import kotlinx.html.h1
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
fun main() {
|
fun main() {
|
||||||
|
|
||||||
val random = Random(112233)
|
val random = Random(112233)
|
||||||
val fragment = VisionManager.fragment {
|
val fragment = VisionManager.fragment {
|
||||||
h1 { +"Happy new year!" }
|
h1 { +"Happy new year!" }
|
||||||
vision {
|
vision {
|
||||||
solid {
|
solid {
|
||||||
repeat(100) {
|
repeat(100) {
|
||||||
sphere(5) {
|
sphere(5, name = "sphere[$it]") {
|
||||||
x = random.nextDouble(-300.0, 300.0)
|
x = random.nextDouble(-300.0, 300.0)
|
||||||
y = random.nextDouble(-300.0, 300.0)
|
y = random.nextDouble(-300.0, 300.0)
|
||||||
z = random.nextDouble(-300.0, 300.0)
|
z = random.nextDouble(-300.0, 300.0)
|
||||||
@ -33,5 +32,9 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment.makeFile(Paths.get("stars.html"), resourceLocation = ResourceLocation.EMBED)
|
visionContext.makeVisionFile(
|
||||||
|
fragment,
|
||||||
|
Paths.get("randomSpheres.html"),
|
||||||
|
resourceLocation = ResourceLocation.EMBED
|
||||||
|
)
|
||||||
}
|
}
|
@ -0,0 +1,38 @@
|
|||||||
|
package hep.dataforge.vision.solid
|
||||||
|
|
||||||
|
import hep.dataforge.context.Context
|
||||||
|
import hep.dataforge.context.Global
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
|
import hep.dataforge.vision.ResourceLocation
|
||||||
|
import hep.dataforge.vision.VisionManager
|
||||||
|
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||||
|
import hep.dataforge.vision.makeVisionFile
|
||||||
|
import hep.dataforge.vision.scriptHeader
|
||||||
|
import hep.dataforge.vision.three.server.VisionServer
|
||||||
|
import hep.dataforge.vision.three.server.useScript
|
||||||
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A global vision context used to resolve different vision renderers
|
||||||
|
*/
|
||||||
|
@DFExperimental
|
||||||
|
public val visionContext: Context = Global.context("VISION") {
|
||||||
|
plugin(VisionManager)
|
||||||
|
plugin(SolidManager)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun VisionServer.usePlayground(): Unit {
|
||||||
|
useScript("js/visionforge-playground.js")
|
||||||
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
public fun Context.makeVisionFile(
|
||||||
|
fragment: HtmlVisionFragment,
|
||||||
|
path: Path? = null,
|
||||||
|
title: String = "VisionForge page",
|
||||||
|
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||||
|
show: Boolean = true,
|
||||||
|
): Unit = makeVisionFile(fragment, path = path, title = title, show = show) { actualPath ->
|
||||||
|
scriptHeader("js/visionforge-playground.js", actualPath, resourceLocation)
|
||||||
|
}
|
@ -4,8 +4,6 @@ import hep.dataforge.meta.DFExperimental
|
|||||||
import hep.dataforge.vision.ResourceLocation
|
import hep.dataforge.vision.ResourceLocation
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
import hep.dataforge.vision.html.fragment
|
import hep.dataforge.vision.html.fragment
|
||||||
import hep.dataforge.vision.three.server.makeFile
|
|
||||||
import hep.dataforge.vision.three.server.solid
|
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@OptIn(DFExperimental::class)
|
||||||
fun main() {
|
fun main() {
|
||||||
@ -17,5 +15,5 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fragment.makeFile(resourceLocation = ResourceLocation.SYSTEM)
|
visionContext.makeVisionFile(fragment = fragment, resourceLocation = ResourceLocation.SYSTEM)
|
||||||
}
|
}
|
@ -33,7 +33,7 @@ rootProject.name = "visionforge"
|
|||||||
include(
|
include(
|
||||||
// ":ui",
|
// ":ui",
|
||||||
":ui:react",
|
":ui:react",
|
||||||
":ui:ring",
|
// ":ui:ring",
|
||||||
// ":ui:material",
|
// ":ui:material",
|
||||||
":ui:bootstrap",
|
":ui:bootstrap",
|
||||||
":visionforge-core",
|
":visionforge-core",
|
||||||
@ -43,6 +43,7 @@ include(
|
|||||||
":visionforge-threejs:visionforge-threejs-server",
|
":visionforge-threejs:visionforge-threejs-server",
|
||||||
":visionforge-gdml",
|
":visionforge-gdml",
|
||||||
":visionforge-server",
|
":visionforge-server",
|
||||||
|
":visionforge-plotly",
|
||||||
":demo:spatial-showcase",
|
":demo:spatial-showcase",
|
||||||
":demo:gdml",
|
":demo:gdml",
|
||||||
":demo:muon-monitor",
|
":demo:muon-monitor",
|
||||||
|
@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
|||||||
import kotlinx.coroutines.flow.launchIn
|
import kotlinx.coroutines.flow.launchIn
|
||||||
import kotlinx.coroutines.flow.onEach
|
import kotlinx.coroutines.flow.onEach
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.css.th
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.Transient
|
import kotlinx.serialization.Transient
|
||||||
@ -27,7 +26,6 @@ internal data class PropertyListener(
|
|||||||
val action: (name: Name) -> Unit,
|
val action: (name: Name) -> Unit,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A full base implementation for a [Vision]
|
* A full base implementation for a [Vision]
|
||||||
* @param properties Object own properties excluding styles and inheritance
|
* @param properties Object own properties excluding styles and inheritance
|
||||||
@ -53,7 +51,7 @@ public open class VisionBase(internal var properties: Config? = null) : Vision {
|
|||||||
override val meta: Meta get() = properties ?: Meta.EMPTY
|
override val meta: Meta get() = properties ?: Meta.EMPTY
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
private fun getOrCreateConfig(): Config {
|
protected fun getOrCreateConfig(): Config {
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
val newProperties = Config()
|
val newProperties = Config()
|
||||||
newProperties.onChange(this) { name, oldItem, newItem ->
|
newProperties.onChange(this) { name, oldItem, newItem ->
|
||||||
@ -91,7 +89,6 @@ public open class VisionBase(internal var properties: Config? = null) : Vision {
|
|||||||
yield(descriptor?.get(name)?.defaultItem())
|
yield(descriptor?.get(name)?.defaultItem())
|
||||||
}.merge()
|
}.merge()
|
||||||
|
|
||||||
@Synchronized
|
|
||||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||||
getOrCreateConfig().setItem(name, item)
|
getOrCreateConfig().setItem(name, item)
|
||||||
if (notify) {
|
if (notify) {
|
||||||
@ -117,6 +114,7 @@ public open class VisionBase(internal var properties: Config? = null) : Vision {
|
|||||||
@Transient
|
@Transient
|
||||||
private val propertyInvalidationFlow: MutableSharedFlow<Name> = MutableSharedFlow()
|
private val propertyInvalidationFlow: MutableSharedFlow<Name> = MutableSharedFlow()
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
override val propertyChanges: Flow<Name> get() = propertyInvalidationFlow
|
override val propertyChanges: Flow<Name> get() = propertyInvalidationFlow
|
||||||
|
|
||||||
override fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) {
|
override fun onPropertyChange(scope: CoroutineScope, callback: suspend (Name) -> Unit) {
|
||||||
|
@ -42,8 +42,8 @@ internal const val VISIONFORGE_ASSETS_PATH = ".dataforge/vision/assets"
|
|||||||
* Check if the asset exists in given local location and put it there if it does not
|
* Check if the asset exists in given local location and put it there if it does not
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
internal fun checkOrStoreFile(basePath: Path, filePath: Path, resource: String): Path {
|
internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path {
|
||||||
val fullPath = basePath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
||||||
|
|
||||||
if (Files.exists(fullPath)) {
|
if (Files.exists(fullPath)) {
|
||||||
//TODO checksum
|
//TODO checksum
|
||||||
@ -55,8 +55,8 @@ internal fun checkOrStoreFile(basePath: Path, filePath: Path, resource: String):
|
|||||||
Files.write(fullPath, bytes, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
Files.write(fullPath, bytes, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (basePath.isAbsolute && fullPath.startsWith(basePath)) {
|
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
||||||
basePath.relativize(fullPath)
|
htmlPath.parent.relativize(fullPath)
|
||||||
} else {
|
} else {
|
||||||
fullPath
|
fullPath
|
||||||
}
|
}
|
||||||
@ -100,14 +100,14 @@ internal fun fileCssHeader(
|
|||||||
* Make a script header, automatically copying file to appropriate location
|
* Make a script header, automatically copying file to appropriate location
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun Context.Companion.scriptHeader(
|
public fun Context.scriptHeader(
|
||||||
scriptResource: String,
|
scriptResource: String,
|
||||||
basePath: Path,
|
htmlPath: Path,
|
||||||
resourceLocation: ResourceLocation,
|
resourceLocation: ResourceLocation,
|
||||||
): HtmlFragment {
|
): HtmlFragment {
|
||||||
val targetPath = when (resourceLocation) {
|
val targetPath = when (resourceLocation) {
|
||||||
ResourceLocation.LOCAL -> checkOrStoreFile(
|
ResourceLocation.LOCAL -> checkOrStoreFile(
|
||||||
basePath,
|
htmlPath,
|
||||||
Path.of(VISIONFORGE_ASSETS_PATH),
|
Path.of(VISIONFORGE_ASSETS_PATH),
|
||||||
scriptResource
|
scriptResource
|
||||||
)
|
)
|
||||||
|
@ -1,9 +1,16 @@
|
|||||||
package hep.dataforge.vision
|
package hep.dataforge.vision
|
||||||
|
|
||||||
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.vision.html.*
|
import hep.dataforge.vision.html.HtmlFragment
|
||||||
import kotlinx.html.*
|
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||||
|
import hep.dataforge.vision.html.embedVisionFragment
|
||||||
|
import hep.dataforge.vision.html.fragment
|
||||||
|
import kotlinx.html.body
|
||||||
|
import kotlinx.html.head
|
||||||
|
import kotlinx.html.meta
|
||||||
import kotlinx.html.stream.createHTML
|
import kotlinx.html.stream.createHTML
|
||||||
|
import kotlinx.html.title
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
@ -13,12 +20,12 @@ import java.nio.file.Path
|
|||||||
* Make a file with the embedded vision data
|
* Make a file with the embedded vision data
|
||||||
*/
|
*/
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public fun HtmlVisionFragment.makeFile(
|
public fun Context.makeVisionFile(
|
||||||
manager: VisionManager,
|
fragment: HtmlVisionFragment,
|
||||||
vararg headers: HtmlFragment,
|
|
||||||
path: Path? = null,
|
path: Path? = null,
|
||||||
title: String = "VisionForge page",
|
title: String = "VisionForge page",
|
||||||
show: Boolean = true,
|
show: Boolean = true,
|
||||||
|
headerBuilder: (Path) -> HtmlFragment,
|
||||||
) {
|
) {
|
||||||
val actualFile = path?.let {
|
val actualFile = path?.let {
|
||||||
Path.of(System.getProperty("user.home")).resolve(path)
|
Path.of(System.getProperty("user.home")).resolve(path)
|
||||||
@ -28,14 +35,12 @@ public fun HtmlVisionFragment.makeFile(
|
|||||||
head {
|
head {
|
||||||
meta {
|
meta {
|
||||||
charset = "utf-8"
|
charset = "utf-8"
|
||||||
headers.forEach {
|
fragment(headerBuilder(actualFile))
|
||||||
fragment(it)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
title(title)
|
title(title)
|
||||||
}
|
}
|
||||||
body {
|
body {
|
||||||
embedVisionFragment(manager, fragment = this@makeFile)
|
embedVisionFragment(visionManager, fragment = fragment)
|
||||||
}
|
}
|
||||||
}.finalize()
|
}.finalize()
|
||||||
|
|
||||||
|
20
visionforge-plotly/build.gradle.kts
Normal file
20
visionforge-plotly/build.gradle.kts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.mpp")
|
||||||
|
}
|
||||||
|
|
||||||
|
kscience {
|
||||||
|
useSerialization()
|
||||||
|
}
|
||||||
|
|
||||||
|
val plotlyVersion = "0.3.1-dev"
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
commonMain {
|
||||||
|
dependencies {
|
||||||
|
api(project(":visionforge-core"))
|
||||||
|
api("kscience.plotlykt:plotlykt-core:${plotlyVersion}")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,12 @@
|
|||||||
|
package hep.dataforge.vision.plotly
|
||||||
|
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
|
import hep.dataforge.vision.VisionBase
|
||||||
|
import hep.dataforge.vision.html.VisionOutput
|
||||||
|
import kscience.plotly.Plot
|
||||||
|
import kscience.plotly.Plotly
|
||||||
|
|
||||||
|
public class VisionOfPlotly(public val plot: Plot): VisionBase(plot.config)
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
public inline fun VisionOutput.plotly(block: Plot.() -> Unit): VisionOfPlotly = VisionOfPlotly(Plotly.plot(block))
|
@ -0,0 +1,33 @@
|
|||||||
|
package hep.dataforge.vision.plotly
|
||||||
|
|
||||||
|
import hep.dataforge.context.AbstractPlugin
|
||||||
|
import hep.dataforge.context.Context
|
||||||
|
import hep.dataforge.context.PluginFactory
|
||||||
|
import hep.dataforge.context.PluginTag
|
||||||
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.vision.Vision
|
||||||
|
import hep.dataforge.vision.client.ElementVisionRenderer
|
||||||
|
import kscience.plotly.PlotlyConfig
|
||||||
|
import kscience.plotly.plot
|
||||||
|
import org.w3c.dom.Element
|
||||||
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
|
public class PlotlyPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||||
|
|
||||||
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
|
override fun rateVision(vision: Vision): Int =
|
||||||
|
if (vision is VisionOfPlotly) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
||||||
|
|
||||||
|
override fun render(element: Element, vision: Vision, meta: Meta) {
|
||||||
|
val plot = (vision as? VisionOfPlotly)?.plot ?: error("Only VisionOfPlotly visions are supported")
|
||||||
|
val config = PlotlyConfig.read(meta)
|
||||||
|
element.plot(plot, config)
|
||||||
|
}
|
||||||
|
|
||||||
|
public companion object : PluginFactory<PlotlyPlugin> {
|
||||||
|
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
|
||||||
|
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
|
||||||
|
override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin()
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,15 @@
|
|||||||
|
package hep.dataforge.vision.plotly
|
||||||
|
|
||||||
|
//public fun main() {
|
||||||
|
// val visionContext: Context = Global.context("vision-client")
|
||||||
|
//
|
||||||
|
// //Loading three-js renderer
|
||||||
|
// val threePlugin = visionContext.plugins.fetch(PlotlyPlugin)
|
||||||
|
//
|
||||||
|
// val clientManager = visionContext.plugins.fetch(VisionClient)
|
||||||
|
//
|
||||||
|
// //Fetch from server and render visions for all outputs
|
||||||
|
// window.onload = {
|
||||||
|
// clientManager.renderAllVisions()
|
||||||
|
// }
|
||||||
|
//}
|
@ -4,6 +4,7 @@ import hep.dataforge.context.AbstractPlugin
|
|||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.context.PluginFactory
|
import hep.dataforge.context.PluginFactory
|
||||||
import hep.dataforge.context.PluginTag
|
import hep.dataforge.context.PluginTag
|
||||||
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
import hep.dataforge.names.Name
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.toName
|
import hep.dataforge.names.toName
|
||||||
@ -12,6 +13,7 @@ import hep.dataforge.vision.VisionBase
|
|||||||
import hep.dataforge.vision.VisionGroupBase
|
import hep.dataforge.vision.VisionGroupBase
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIALIZER_MODULE_TARGET
|
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIALIZER_MODULE_TARGET
|
||||||
|
import hep.dataforge.vision.html.VisionOutput
|
||||||
import kotlinx.serialization.PolymorphicSerializer
|
import kotlinx.serialization.PolymorphicSerializer
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
import kotlinx.serialization.modules.PolymorphicModuleBuilder
|
||||||
@ -73,3 +75,6 @@ public class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
public fun decodeFromString(str: String): Solid = jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str)
|
public fun decodeFromString(str: String): Solid = jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@DFExperimental
|
||||||
|
public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)
|
@ -5,6 +5,7 @@ import hep.dataforge.names.Name
|
|||||||
|
|
||||||
public class Canvas3DOptions : Scheme() {
|
public class Canvas3DOptions : Scheme() {
|
||||||
public var axes: Axes by spec(Axes)
|
public var axes: Axes by spec(Axes)
|
||||||
|
public var light: Light by spec(Light)
|
||||||
public var camera: Camera by spec(Camera)
|
public var camera: Camera by spec(Camera)
|
||||||
public var controls: Controls by spec(Controls)
|
public var controls: Controls by spec(Controls)
|
||||||
|
|
||||||
|
@ -0,0 +1,8 @@
|
|||||||
|
package hep.dataforge.vision.solid.specifications
|
||||||
|
|
||||||
|
import hep.dataforge.meta.Scheme
|
||||||
|
import hep.dataforge.meta.SchemeSpec
|
||||||
|
|
||||||
|
public class Light : Scheme() {
|
||||||
|
public companion object : SchemeSpec<Light>(::Light)
|
||||||
|
}
|
@ -51,7 +51,7 @@ public class ThreeCanvas(
|
|||||||
public var axes: AxesHelper = AxesHelper(options.axes.size.toInt()).apply { visible = options.axes.visible }
|
public var axes: AxesHelper = AxesHelper(options.axes.size.toInt()).apply { visible = options.axes.visible }
|
||||||
private set
|
private set
|
||||||
|
|
||||||
private val light = AmbientLight(0x404040)
|
private var light = buildLight(options.light)
|
||||||
|
|
||||||
private val scene: Scene = Scene().apply {
|
private val scene: Scene = Scene().apply {
|
||||||
add(axes)
|
add(axes)
|
||||||
@ -169,6 +169,7 @@ public class ThreeCanvas(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
@ -28,7 +28,7 @@
|
|||||||
package info.laht.threekt.helpers
|
package info.laht.threekt.helpers
|
||||||
|
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.lights.HemiSphereLight
|
import info.laht.threekt.lights.HemisphereLight
|
||||||
import info.laht.threekt.lights.Light
|
import info.laht.threekt.lights.Light
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -39,7 +39,7 @@ import info.laht.threekt.lights.Light
|
|||||||
* @param color (optional) if this is not the set the helper will take the color of the light.
|
* @param color (optional) if this is not the set the helper will take the color of the light.
|
||||||
*/
|
*/
|
||||||
external class HemisphereLightHelper(
|
external class HemisphereLightHelper(
|
||||||
light: HemiSphereLight,
|
light: HemisphereLight,
|
||||||
size: Number,
|
size: Number,
|
||||||
color: Int = definedExternally
|
color: Int = definedExternally
|
||||||
) : Object3D {
|
) : Object3D {
|
||||||
|
@ -34,7 +34,7 @@ import info.laht.threekt.math.Color
|
|||||||
*
|
*
|
||||||
* This light cannot be used to cast shadows.
|
* This light cannot be used to cast shadows.
|
||||||
*/
|
*/
|
||||||
external class HemiSphereLight(
|
external class HemisphereLight(
|
||||||
skyColor: Int = definedExternally,
|
skyColor: Int = definedExternally,
|
||||||
groundColor: Int = definedExternally,
|
groundColor: Int = definedExternally,
|
||||||
intensity: Number = definedExternally
|
intensity: Number = definedExternally
|
||||||
@ -42,6 +42,6 @@ external class HemiSphereLight(
|
|||||||
|
|
||||||
var groundColor: Color
|
var groundColor: Color
|
||||||
|
|
||||||
fun copy(light: HemiSphereLight): HemiSphereLight
|
fun copy(light: HemisphereLight): HemisphereLight
|
||||||
|
|
||||||
}
|
}
|
@ -1,8 +0,0 @@
|
|||||||
package hep.dataforge.vision.three.server
|
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
|
||||||
import hep.dataforge.vision.VisionManager
|
|
||||||
|
|
||||||
public expect val visionContext: Context
|
|
||||||
|
|
||||||
public val visionManager: VisionManager get() = visionContext.plugins.fetch(VisionManager)
|
|
@ -1,46 +1,18 @@
|
|||||||
package hep.dataforge.vision.three.server
|
package hep.dataforge.vision.three.server
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
|
||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.vision.client.VisionClient
|
import hep.dataforge.vision.client.VisionClient
|
||||||
import hep.dataforge.vision.client.renderAllVisions
|
import hep.dataforge.vision.client.renderAllVisions
|
||||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
|
|
||||||
//FIXME check plugin loading in JS
|
|
||||||
//public actual val visionContext: Context = Global.context("vision-client") {
|
|
||||||
// //Loading three-js renderer
|
|
||||||
// plugin(ThreePlugin)
|
|
||||||
//}
|
|
||||||
|
|
||||||
public actual val visionContext: Context = Global.context("vision-client").apply {
|
|
||||||
//Loading three-js renderer
|
|
||||||
plugins.fetch(ThreePlugin)
|
|
||||||
}
|
|
||||||
|
|
||||||
public val clientManager: VisionClient get() = visionContext.plugins.fetch(VisionClient)
|
|
||||||
|
|
||||||
|
|
||||||
///**
|
|
||||||
// * Render all visions in the document using registered renderers
|
|
||||||
// */
|
|
||||||
//@JsExport
|
|
||||||
//public fun renderVisions() {
|
|
||||||
// //Fetch from server and render visions for all outputs
|
|
||||||
// window.onload = {
|
|
||||||
// clientManager.renderAllVisions()
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
//
|
|
||||||
///**
|
|
||||||
// * Render all visions in a given element, using registered renderers
|
|
||||||
// */
|
|
||||||
//@JsExport
|
|
||||||
//public fun renderAllVisionsAt(element: Element) {
|
|
||||||
// clientManager.renderAllVisionsAt(element)
|
|
||||||
//}
|
|
||||||
|
|
||||||
public fun main() {
|
public fun main() {
|
||||||
|
//Loading three-js renderer
|
||||||
|
val visionContext = Global.context("threejs") {
|
||||||
|
plugin(ThreePlugin)
|
||||||
|
}
|
||||||
|
val clientManager = visionContext.plugins.fetch(VisionClient)
|
||||||
|
|
||||||
//Fetch from server and render visions for all outputs
|
//Fetch from server and render visions for all outputs
|
||||||
window.onload = {
|
window.onload = {
|
||||||
clientManager.renderAllVisions()
|
clientManager.renderAllVisions()
|
||||||
|
@ -1,47 +1,25 @@
|
|||||||
package hep.dataforge.vision.three.server
|
package hep.dataforge.vision.three.server
|
||||||
|
|
||||||
import hep.dataforge.context.Context
|
import hep.dataforge.context.Context
|
||||||
import hep.dataforge.context.Global
|
|
||||||
import hep.dataforge.meta.DFExperimental
|
import hep.dataforge.meta.DFExperimental
|
||||||
import hep.dataforge.vision.ResourceLocation
|
import hep.dataforge.vision.ResourceLocation
|
||||||
import hep.dataforge.vision.html.HtmlVisionFragment
|
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||||
import hep.dataforge.vision.html.VisionOutput
|
import hep.dataforge.vision.makeVisionFile
|
||||||
import hep.dataforge.vision.makeFile
|
|
||||||
import hep.dataforge.vision.scriptHeader
|
import hep.dataforge.vision.scriptHeader
|
||||||
import hep.dataforge.vision.solid.SolidGroup
|
|
||||||
import hep.dataforge.vision.solid.SolidManager
|
|
||||||
import java.nio.file.Files
|
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
public actual val visionContext: Context = Global.context("vision-server") {
|
|
||||||
//Loading solid manager for the backend (it does not know about three
|
|
||||||
plugin(SolidManager)
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun VisionServer.useThreeJs(): Unit {
|
public fun VisionServer.useThreeJs(): Unit {
|
||||||
useScript("js/visionforge-three.js")
|
useScript("js/visionforge-three.js")
|
||||||
// header {
|
|
||||||
// script {
|
|
||||||
// unsafe {
|
|
||||||
// +"renderThreeVisions()"
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)
|
public fun Context.makeVisionFile(
|
||||||
|
fragment: HtmlVisionFragment,
|
||||||
@OptIn(DFExperimental::class)
|
|
||||||
public fun HtmlVisionFragment.makeFile(
|
|
||||||
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(fragment, path = path, title = title, show = show) { actualPath ->
|
||||||
val actualPath = path?.let {
|
scriptHeader("js/visionforge-three.js", actualPath, resourceLocation)
|
||||||
Path.of(System.getProperty("user.home")).resolve(path)
|
|
||||||
} ?: Files.createTempFile("tempPlot", ".html")
|
|
||||||
val scriptHeader = Context.scriptHeader("js/visionforge-three.js", actualPath, resourceLocation)
|
|
||||||
makeFile(visionManager, path = path, show = show, title = title, headers = arrayOf(scriptHeader))
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user