New properties #34
@ -1,12 +1,11 @@
|
||||
package ru.mipt.npm.sat
|
||||
|
||||
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.clear
|
||||
import hep.dataforge.vision.solid.color
|
||||
import hep.dataforge.vision.solid.invoke
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.three.server.*
|
||||
import hep.dataforge.vision.visionManager
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
import kotlinx.coroutines.isActive
|
||||
@ -16,10 +15,14 @@ import kotlinx.html.h1
|
||||
import kotlin.random.Random
|
||||
|
||||
fun main() {
|
||||
val satContext = Global.context("sat") {
|
||||
plugin(SolidManager)
|
||||
}
|
||||
|
||||
//Create a geometry
|
||||
val sat = visionOfSatellite(ySegments = 3)
|
||||
|
||||
val server = visionManager.serve {
|
||||
val server = satContext.visionManager.serve {
|
||||
//use client library
|
||||
useThreeJs()
|
||||
//use css
|
||||
|
@ -12,6 +12,16 @@ repositories{
|
||||
}
|
||||
|
||||
kotlin {
|
||||
|
||||
js(IR) {
|
||||
browser {
|
||||
webpackTask {
|
||||
this.outputFileName = "js/visionforge-playground.js"
|
||||
}
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
jvm{
|
||||
compilations.all {
|
||||
kotlinOptions.jvmTarget = "11"
|
||||
@ -20,30 +30,39 @@ kotlin {
|
||||
useJUnitPlatform()
|
||||
}
|
||||
}
|
||||
js(IR) {
|
||||
browser {
|
||||
|
||||
afterEvaluate {
|
||||
val jsBrowserDistribution by tasks.getting
|
||||
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
afterEvaluate {
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
}
|
||||
binaries.executable()
|
||||
}
|
||||
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
implementation(project(":visionforge-solid"))
|
||||
implementation(project(":visionforge-gdml"))
|
||||
|
||||
implementation(project(":visionforge-plotly"))
|
||||
}
|
||||
}
|
||||
|
||||
val jsMain by getting{
|
||||
dependencies {
|
||||
implementation(project(":ui:bootstrap"))
|
||||
implementation(project(":visionforge-threejs"))
|
||||
}
|
||||
}
|
||||
|
||||
val jvmMain by getting{
|
||||
dependencies {
|
||||
implementation(project(":visionforge-server"))
|
||||
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.startApplication
|
||||
import hep.dataforge.vision.bootstrap.visionPropertyEditor
|
||||
import hep.dataforge.vision.react.ThreeCanvasComponent
|
||||
import hep.dataforge.vision.react.objectTree
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import kotlinx.browser.document
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.client.VisionClient
|
||||
import hep.dataforge.vision.client.renderAllVisions
|
||||
import hep.dataforge.vision.plotly.PlotlyPlugin
|
||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||
import kotlinx.browser.window
|
||||
|
||||
//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() {
|
||||
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.VisionManager
|
||||
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 java.nio.file.Paths
|
||||
import kotlin.random.Random
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
fun main() {
|
||||
|
||||
val random = Random(112233)
|
||||
val fragment = VisionManager.fragment {
|
||||
h1 { +"Happy new year!" }
|
||||
vision {
|
||||
solid {
|
||||
repeat(100) {
|
||||
sphere(5) {
|
||||
sphere(5, name = "sphere[$it]") {
|
||||
x = random.nextDouble(-300.0, 300.0)
|
||||
y = 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.VisionManager
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.three.server.makeFile
|
||||
import hep.dataforge.vision.three.server.solid
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
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(
|
||||
// ":ui",
|
||||
":ui:react",
|
||||
":ui:ring",
|
||||
// ":ui:ring",
|
||||
// ":ui:material",
|
||||
":ui:bootstrap",
|
||||
":visionforge-core",
|
||||
@ -43,6 +43,7 @@ include(
|
||||
":visionforge-threejs:visionforge-threejs-server",
|
||||
":visionforge-gdml",
|
||||
":visionforge-server",
|
||||
":visionforge-plotly",
|
||||
":demo:spatial-showcase",
|
||||
":demo:gdml",
|
||||
":demo:muon-monitor",
|
||||
|
@ -16,7 +16,6 @@ import kotlinx.coroutines.flow.MutableSharedFlow
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import kotlinx.coroutines.launch
|
||||
import kotlinx.css.th
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.Transient
|
||||
@ -27,7 +26,6 @@ internal data class PropertyListener(
|
||||
val action: (name: Name) -> Unit,
|
||||
)
|
||||
|
||||
|
||||
/**
|
||||
* A full base implementation for a [Vision]
|
||||
* @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
|
||||
|
||||
@Synchronized
|
||||
private fun getOrCreateConfig(): Config {
|
||||
protected fun getOrCreateConfig(): Config {
|
||||
if (properties == null) {
|
||||
val newProperties = Config()
|
||||
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())
|
||||
}.merge()
|
||||
|
||||
@Synchronized
|
||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||
getOrCreateConfig().setItem(name, item)
|
||||
if (notify) {
|
||||
@ -117,6 +114,7 @@ public open class VisionBase(internal var properties: Config? = null) : Vision {
|
||||
@Transient
|
||||
private val propertyInvalidationFlow: MutableSharedFlow<Name> = MutableSharedFlow()
|
||||
|
||||
@DFExperimental
|
||||
override val propertyChanges: Flow<Name> get() = propertyInvalidationFlow
|
||||
|
||||
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
|
||||
* @param
|
||||
*/
|
||||
internal fun checkOrStoreFile(basePath: Path, filePath: Path, resource: String): Path {
|
||||
val fullPath = basePath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
||||
internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path {
|
||||
val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
||||
|
||||
if (Files.exists(fullPath)) {
|
||||
//TODO checksum
|
||||
@ -55,8 +55,8 @@ internal fun checkOrStoreFile(basePath: Path, filePath: Path, resource: String):
|
||||
Files.write(fullPath, bytes, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||
}
|
||||
|
||||
return if (basePath.isAbsolute && fullPath.startsWith(basePath)) {
|
||||
basePath.relativize(fullPath)
|
||||
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
||||
htmlPath.parent.relativize(fullPath)
|
||||
} else {
|
||||
fullPath
|
||||
}
|
||||
@ -100,14 +100,14 @@ internal fun fileCssHeader(
|
||||
* Make a script header, automatically copying file to appropriate location
|
||||
*/
|
||||
@DFExperimental
|
||||
public fun Context.Companion.scriptHeader(
|
||||
public fun Context.scriptHeader(
|
||||
scriptResource: String,
|
||||
basePath: Path,
|
||||
htmlPath: Path,
|
||||
resourceLocation: ResourceLocation,
|
||||
): HtmlFragment {
|
||||
val targetPath = when (resourceLocation) {
|
||||
ResourceLocation.LOCAL -> checkOrStoreFile(
|
||||
basePath,
|
||||
htmlPath,
|
||||
Path.of(VISIONFORGE_ASSETS_PATH),
|
||||
scriptResource
|
||||
)
|
||||
|
@ -1,9 +1,16 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.html.*
|
||||
import kotlinx.html.*
|
||||
import hep.dataforge.vision.html.HtmlFragment
|
||||
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.title
|
||||
import java.awt.Desktop
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
@ -13,12 +20,12 @@ import java.nio.file.Path
|
||||
* Make a file with the embedded vision data
|
||||
*/
|
||||
@DFExperimental
|
||||
public fun HtmlVisionFragment.makeFile(
|
||||
manager: VisionManager,
|
||||
vararg headers: HtmlFragment,
|
||||
public fun Context.makeVisionFile(
|
||||
fragment: HtmlVisionFragment,
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
show: Boolean = true,
|
||||
headerBuilder: (Path) -> HtmlFragment,
|
||||
) {
|
||||
val actualFile = path?.let {
|
||||
Path.of(System.getProperty("user.home")).resolve(path)
|
||||
@ -28,14 +35,12 @@ public fun HtmlVisionFragment.makeFile(
|
||||
head {
|
||||
meta {
|
||||
charset = "utf-8"
|
||||
headers.forEach {
|
||||
fragment(it)
|
||||
}
|
||||
fragment(headerBuilder(actualFile))
|
||||
}
|
||||
title(title)
|
||||
}
|
||||
body {
|
||||
embedVisionFragment(manager, fragment = this@makeFile)
|
||||
embedVisionFragment(visionManager, fragment = fragment)
|
||||
}
|
||||
}.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.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
@ -12,6 +13,7 @@ import hep.dataforge.vision.VisionBase
|
||||
import hep.dataforge.vision.VisionGroupBase
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIALIZER_MODULE_TARGET
|
||||
import hep.dataforge.vision.html.VisionOutput
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
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)
|
||||
}
|
||||
}
|
||||
|
||||
@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 var axes: Axes by spec(Axes)
|
||||
public var light: Light by spec(Light)
|
||||
public var camera: Camera by spec(Camera)
|
||||
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 }
|
||||
private set
|
||||
|
||||
private val light = AmbientLight(0x404040)
|
||||
private var light = buildLight(options.light)
|
||||
|
||||
private val scene: Scene = Scene().apply {
|
||||
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(
|
||||
spec.fov,
|
||||
|
@ -28,7 +28,7 @@
|
||||
package info.laht.threekt.helpers
|
||||
|
||||
import info.laht.threekt.core.Object3D
|
||||
import info.laht.threekt.lights.HemiSphereLight
|
||||
import info.laht.threekt.lights.HemisphereLight
|
||||
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.
|
||||
*/
|
||||
external class HemisphereLightHelper(
|
||||
light: HemiSphereLight,
|
||||
light: HemisphereLight,
|
||||
size: Number,
|
||||
color: Int = definedExternally
|
||||
) : Object3D {
|
||||
|
@ -34,7 +34,7 @@ import info.laht.threekt.math.Color
|
||||
*
|
||||
* This light cannot be used to cast shadows.
|
||||
*/
|
||||
external class HemiSphereLight(
|
||||
external class HemisphereLight(
|
||||
skyColor: Int = definedExternally,
|
||||
groundColor: Int = definedExternally,
|
||||
intensity: Number = definedExternally
|
||||
@ -42,6 +42,6 @@ external class HemiSphereLight(
|
||||
|
||||
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
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.vision.client.VisionClient
|
||||
import hep.dataforge.vision.client.renderAllVisions
|
||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||
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() {
|
||||
//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
|
||||
window.onload = {
|
||||
clientManager.renderAllVisions()
|
||||
|
@ -1,47 +1,25 @@
|
||||
package hep.dataforge.vision.three.server
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.ResourceLocation
|
||||
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||
import hep.dataforge.vision.html.VisionOutput
|
||||
import hep.dataforge.vision.makeFile
|
||||
import hep.dataforge.vision.makeVisionFile
|
||||
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
|
||||
|
||||
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 {
|
||||
useScript("js/visionforge-three.js")
|
||||
// header {
|
||||
// script {
|
||||
// unsafe {
|
||||
// +"renderThreeVisions()"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
public fun HtmlVisionFragment.makeFile(
|
||||
public fun Context.makeVisionFile(
|
||||
fragment: HtmlVisionFragment,
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||
show: Boolean = true,
|
||||
) {
|
||||
val actualPath = path?.let {
|
||||
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))
|
||||
): Unit = makeVisionFile(fragment, path = path, title = title, show = show) { actualPath ->
|
||||
scriptHeader("js/visionforge-three.js", actualPath, resourceLocation)
|
||||
}
|
Loading…
Reference in New Issue
Block a user