forked from kscience/visionforge
Fix after dev merge.
This commit is contained in:
parent
33146fef1b
commit
0c1d6139ae
@ -1,9 +1,9 @@
|
||||
package hep.dataforge.vision.gdml.demo
|
||||
|
||||
import hep.dataforge.Application
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.startApplication
|
||||
import hep.dataforge.vision.Application
|
||||
import hep.dataforge.vision.gdml.toVision
|
||||
import hep.dataforge.vision.startApplication
|
||||
import kotlinx.browser.document
|
||||
import react.child
|
||||
import react.dom.render
|
||||
|
@ -1,8 +1,8 @@
|
||||
package ru.mipt.npm.muon.monitor
|
||||
|
||||
import hep.dataforge.Application
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.startApplication
|
||||
import hep.dataforge.vision.Application
|
||||
import hep.dataforge.vision.startApplication
|
||||
import io.ktor.client.HttpClient
|
||||
import io.ktor.client.features.json.JsonFeature
|
||||
import io.ktor.client.features.json.serializer.KotlinxSerializer
|
||||
|
@ -4,7 +4,7 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.invoke
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.Colors
|
||||
import hep.dataforge.vision.layout.Page
|
||||
import hep.dataforge.vision.VisionLayout
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import hep.dataforge.vision.visible
|
||||
@ -15,12 +15,12 @@ import kotlin.math.sin
|
||||
import kotlin.random.Random
|
||||
|
||||
|
||||
fun Page<Solid>.demo(name: String, title: String = name, block: SolidGroup.() -> Unit) {
|
||||
fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGroup.() -> Unit) {
|
||||
val meta = Meta {
|
||||
"title" put title
|
||||
}
|
||||
val output = output(name.toName(), meta)?: error("Output with name $name not found")
|
||||
output.solidGroup (builder = block)
|
||||
val vision = SolidGroup(block)
|
||||
render(name.toName(), vision)
|
||||
}
|
||||
|
||||
val canvasOptions = Canvas3DOptions {
|
||||
@ -35,7 +35,7 @@ val canvasOptions = Canvas3DOptions {
|
||||
}
|
||||
}
|
||||
|
||||
fun Page<Solid>.showcase() {
|
||||
fun VisionLayout<Solid>.showcase() {
|
||||
demo("shapes", "Basic shapes") {
|
||||
box(100.0, 100.0, 100.0) {
|
||||
z = -110.0
|
||||
@ -136,14 +136,14 @@ fun Page<Solid>.showcase() {
|
||||
}
|
||||
}
|
||||
|
||||
fun Page<Solid>.showcaseCSG() {
|
||||
fun VisionLayout<Solid>.showcaseCSG() {
|
||||
demo("CSG.simple", "CSG operations") {
|
||||
composite(CompositeType.INTERSECT) {
|
||||
y = 300
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50){
|
||||
sphere(50) {
|
||||
detail = 32
|
||||
}
|
||||
material {
|
||||
@ -154,7 +154,7 @@ fun Page<Solid>.showcaseCSG() {
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50){
|
||||
sphere(50) {
|
||||
detail = 32
|
||||
}
|
||||
color("lightgreen")
|
||||
@ -165,7 +165,7 @@ fun Page<Solid>.showcaseCSG() {
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50){
|
||||
sphere(50) {
|
||||
detail = 32
|
||||
}
|
||||
color("teal")
|
||||
|
@ -1,9 +1,9 @@
|
||||
package hep.dataforge.vision.solid.demo
|
||||
|
||||
import hep.dataforge.Application
|
||||
import hep.dataforge.startApplication
|
||||
import hep.dataforge.vision.Application
|
||||
import hep.dataforge.vision.solid.x
|
||||
import hep.dataforge.vision.solid.y
|
||||
import hep.dataforge.vision.startApplication
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
|
@ -5,8 +5,7 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.layout.Page
|
||||
import hep.dataforge.vision.VisionLayout
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.three.ThreeCanvas
|
||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||
@ -20,7 +19,7 @@ import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
import org.w3c.dom.HTMLElement
|
||||
|
||||
class ThreeDemoGrid(element: Element) : Page<Solid> {
|
||||
class ThreeDemoGrid(element: Element) : VisionLayout<Solid> {
|
||||
private lateinit var navigationElement: HTMLElement
|
||||
private lateinit var contentElement: HTMLDivElement
|
||||
|
||||
@ -47,9 +46,8 @@ class ThreeDemoGrid(element: Element) : Page<Solid> {
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
override fun output(name: Name, meta: Meta): Output<Solid> = outputs.getOrPut(name) {
|
||||
override fun render(name: Name, vision: Solid, meta: Meta) {
|
||||
outputs.getOrPut(name) {
|
||||
navigationElement.append {
|
||||
li("nav-item") {
|
||||
a(classes = "nav-link") {
|
||||
@ -72,6 +70,7 @@ class ThreeDemoGrid(element: Element) : Page<Solid> {
|
||||
}
|
||||
val element = document.getElementById("output-$name") ?: error("Element not found")
|
||||
three.createCanvas(element, canvasOptions)
|
||||
}.render(vision)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -3,8 +3,7 @@ package hep.dataforge.vision.solid.demo
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.layout.Page
|
||||
import hep.dataforge.vision.VisionLayout
|
||||
import hep.dataforge.vision.solid.FX3DPlugin
|
||||
import hep.dataforge.vision.solid.FXCanvas3D
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
@ -13,7 +12,7 @@ import javafx.scene.Parent
|
||||
import javafx.scene.control.Tab
|
||||
import tornadofx.*
|
||||
|
||||
class FXDemoGrid : View(title = "DataForge-vis FX demo"), Page<Solid> {
|
||||
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
||||
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
||||
|
||||
override val root: Parent = borderpane {
|
||||
@ -26,8 +25,8 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), Page<Solid> {
|
||||
|
||||
private val fx3d = Global.plugins.fetch(FX3DPlugin)
|
||||
|
||||
override fun output(name: Name, meta: Meta): Output<Solid> = outputs.getOrPut(name) {
|
||||
FXCanvas3D(fx3d, canvasOptions)
|
||||
override fun render(name: Name, vision: Solid, meta: Meta) {
|
||||
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
||||
}
|
||||
|
||||
}
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.7.1-bin.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.8-bin.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
@ -1,2 +0,0 @@
|
||||
|
||||
|
@ -1,27 +1,9 @@
|
||||
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
|
||||
import hep.dataforge.vision.plotly.withPlotly
|
||||
import hep.dataforge.vision.renderVisionsInWindow
|
||||
import hep.dataforge.vision.solid.three.loadThreeJs
|
||||
|
||||
@DFExperimental
|
||||
fun main() {
|
||||
|
||||
val visionContext: Context = Global.context("VISION") {
|
||||
plugin(ThreePlugin)
|
||||
plugin(PlotlyPlugin)
|
||||
plugin(VisionClient)
|
||||
}
|
||||
|
||||
//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)
|
||||
withPlotly()
|
||||
loadThreeJs()
|
||||
renderVisionsInWindow()
|
||||
}
|
@ -1,6 +1,8 @@
|
||||
package hep.dataforge.vision.solid
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import com.github.ricky12awesome.jss.encodeToSchema
|
||||
import hep.dataforge.vision.solid.SolidGroup
|
||||
import hep.dataforge.vision.solid.SolidManager
|
||||
import kotlinx.serialization.json.Json
|
||||
|
||||
fun main() {
|
@ -1,38 +0,0 @@
|
||||
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 VisionForge: 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)
|
||||
}
|
@ -1,19 +0,0 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.ResourceLocation
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.html.fragment
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
fun main() {
|
||||
val fragment = VisionManager.fragment {
|
||||
vision("canvas") {
|
||||
solid {
|
||||
box(100, 100, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisionForge.makeVisionFile(fragment = fragment, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
25
playground/src/jvmMain/kotlin/plotlyVision.kt
Normal file
25
playground/src/jvmMain/kotlin/plotlyVision.kt
Normal file
@ -0,0 +1,25 @@
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.plotly.plotly
|
||||
import hep.dataforge.vision.plotly.withPlotly
|
||||
import kscience.plotly.scatter
|
||||
|
||||
@DFExperimental
|
||||
fun main() {
|
||||
val fragment = VisionManager.fragment {
|
||||
vision {
|
||||
plotly {
|
||||
scatter {
|
||||
x(1,2,3)
|
||||
y(5,8,7)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisionForge.withPlotly().makeVisionFile(fragment)
|
||||
}
|
@ -1,9 +1,11 @@
|
||||
package hep.dataforge.vision.solid
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.ResourceLocation
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.solid.*
|
||||
import kotlinx.html.h1
|
||||
import java.nio.file.Paths
|
||||
import kotlin.random.Random
|
35
playground/src/jvmMain/kotlin/serverExtensions.kt
Normal file
35
playground/src/jvmMain/kotlin/serverExtensions.kt
Normal file
@ -0,0 +1,35 @@
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.scriptHeader
|
||||
import hep.dataforge.vision.makeFile
|
||||
import hep.dataforge.vision.page
|
||||
import hep.dataforge.vision.three.server.VisionServer
|
||||
import hep.dataforge.vision.three.server.useScript
|
||||
import java.awt.Desktop
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
public fun VisionServer.usePlayground(): Unit {
|
||||
useScript("js/visionforge-playground.js")
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun Context.makeVisionFile(
|
||||
content: HtmlVisionFragment,
|
||||
path: Path? = null,
|
||||
title: String = "VisionForge page",
|
||||
resourceLocation: ResourceLocation = ResourceLocation.SYSTEM,
|
||||
show: Boolean = true,
|
||||
): Unit {
|
||||
val actualPath = page(title, content).makeFile(path) { actualPath ->
|
||||
mapOf("threeJs" to scriptHeader("js/visionforge-playground.js", actualPath, resourceLocation))
|
||||
}
|
||||
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
||||
}
|
||||
// makeVisionFile(fragment, path = path, title = title, show = show) { actualPath ->
|
||||
// scriptHeader("js/visionforge-playground.js", actualPath, resourceLocation)
|
||||
//}
|
22
playground/src/jvmMain/kotlin/simpleCube.kt
Normal file
22
playground/src/jvmMain/kotlin/simpleCube.kt
Normal file
@ -0,0 +1,22 @@
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.solid.box
|
||||
import hep.dataforge.vision.solid.solid
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
fun main() {
|
||||
val content = VisionManager.fragment {
|
||||
vision("canvas") {
|
||||
solid {
|
||||
box(100, 100, 100)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisionForge.makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
@ -0,0 +1,5 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
|
||||
public expect val VisionForge: Context
|
@ -0,0 +1,8 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
|
||||
public interface VisionLayout<in V: Vision> {
|
||||
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
||||
}
|
@ -3,6 +3,8 @@ package hep.dataforge.vision
|
||||
import hep.dataforge.context.*
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.JsonElement
|
||||
@ -75,6 +77,18 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
}
|
||||
}
|
||||
|
||||
public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(meta) {
|
||||
public val visionManager: VisionManager by require(VisionManager)
|
||||
|
||||
protected abstract val visionSerializersModule: SerializersModule
|
||||
|
||||
override fun content(target: String): Map<Name, Any> = when (target) {
|
||||
VisionManager.VISION_SERIALIZER_MODULE_TARGET -> mapOf(tag.toString().toName() to visionSerializersModule)
|
||||
else -> super.content(target)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Fetch a [VisionManager] from this plugin
|
||||
*/
|
||||
|
@ -0,0 +1,26 @@
|
||||
package hep.dataforge.vision.html
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import kotlinx.html.*
|
||||
|
||||
public data class Page(
|
||||
public val context: Context,
|
||||
public val title: String,
|
||||
public val headers: Map<String, HtmlFragment>,
|
||||
public val content: HtmlVisionFragment
|
||||
) {
|
||||
public fun <R> render(root: TagConsumer<R>): R = root.apply {
|
||||
head {
|
||||
meta {
|
||||
charset = "utf-8"
|
||||
headers.values.forEach {
|
||||
fragment(it)
|
||||
}
|
||||
}
|
||||
title(title)
|
||||
}
|
||||
body {
|
||||
embedVisionFragment(context.visionManager, fragment = content)
|
||||
}
|
||||
}.finalize()
|
||||
}
|
@ -4,19 +4,18 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import kotlinx.html.DIV
|
||||
import kotlinx.html.FlowContent
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.unsafe
|
||||
import kotlinx.html.*
|
||||
|
||||
|
||||
public fun FlowContent.embedVisionFragment(
|
||||
public fun TagConsumer<*>.embedVisionFragment(
|
||||
manager: VisionManager,
|
||||
idPrefix: String? = null,
|
||||
fragment: HtmlVisionFragment,
|
||||
) {
|
||||
val consumer = object : VisionTagConsumer<Any?>(consumer, idPrefix) {
|
||||
): Map<Name, Vision> {
|
||||
val visionMap = HashMap<Name, Vision>()
|
||||
val consumer = object : VisionTagConsumer<Any?>(this@embedVisionFragment, idPrefix) {
|
||||
override fun DIV.renderVision(name: Name, vision: Vision, outputMeta: Meta) {
|
||||
visionMap[name] = vision
|
||||
script {
|
||||
type = "text/json"
|
||||
attributes["class"] = OUTPUT_DATA_CLASS
|
||||
@ -27,17 +26,29 @@ public fun FlowContent.embedVisionFragment(
|
||||
}
|
||||
}
|
||||
fragment(consumer)
|
||||
return visionMap
|
||||
}
|
||||
|
||||
public fun FlowContent.embedVisionFragment(
|
||||
manager: VisionManager,
|
||||
idPrefix: String? = null,
|
||||
fragment: HtmlVisionFragment,
|
||||
): Map<Name, Vision> = consumer.embedVisionFragment(manager, idPrefix, fragment)
|
||||
|
||||
public typealias HtmlVisionRenderer = FlowContent.(name: Name, vision: Vision, meta: Meta) -> Unit
|
||||
|
||||
public fun <R> FlowContent.renderVisionFragment(
|
||||
public fun FlowContent.renderVisionFragment(
|
||||
renderer: DIV.(name: Name, vision: Vision, meta: Meta) -> Unit,
|
||||
idPrefix: String? = null,
|
||||
fragment: HtmlVisionFragment,
|
||||
) {
|
||||
): Map<Name, Vision> {
|
||||
val visionMap = HashMap<Name, Vision>()
|
||||
val consumer = object : VisionTagConsumer<Any?>(consumer, idPrefix) {
|
||||
override fun DIV.renderVision(name: Name, vision: Vision, outputMeta: Meta) = renderer(name, vision, outputMeta)
|
||||
override fun DIV.renderVision(name: Name, vision: Vision, outputMeta: Meta) {
|
||||
visionMap[name] = vision
|
||||
renderer(name, vision, outputMeta)
|
||||
}
|
||||
}
|
||||
fragment(consumer)
|
||||
return visionMap
|
||||
}
|
@ -1,16 +0,0 @@
|
||||
package hep.dataforge.vision.layout
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.vision.Vision
|
||||
|
||||
public fun interface Output<in V : Vision> {
|
||||
public fun render(vision: V)
|
||||
}
|
||||
|
||||
public interface Page<in V : Vision> {
|
||||
public fun output(name: Name, meta: Meta = Meta.EMPTY): Output<V>?
|
||||
}
|
||||
|
||||
public fun <V : Vision> Page<V>.render(name: Name, vision: V): Unit =
|
||||
output(name)?.render(vision) ?: error("Could not resolve renderer for name $name")
|
@ -3,7 +3,6 @@ package hep.dataforge.vision.html
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.vision.VisionBase
|
||||
import hep.dataforge.vision.configure
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.stream.createHTML
|
||||
import kotlin.test.Test
|
||||
@ -54,7 +53,7 @@ class HtmlTagTest {
|
||||
fun testStringRender() {
|
||||
println(
|
||||
createHTML().div {
|
||||
renderVisionFragment<String>(simpleVisionRenderer, fragment = fragment)
|
||||
renderVisionFragment(simpleVisionRenderer, fragment = fragment)
|
||||
}
|
||||
)
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
package hep.dataforge
|
||||
package hep.dataforge.vision
|
||||
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.dom.hasClass
|
@ -0,0 +1,22 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.vision.client.VisionClient
|
||||
import hep.dataforge.vision.client.renderAllVisions
|
||||
import kotlinx.browser.window
|
||||
|
||||
public actual val VisionForge: Context = Global.context("VisionForge").apply{
|
||||
plugins.fetch(VisionManager)
|
||||
plugins.fetch(VisionClient)
|
||||
}
|
||||
|
||||
/**
|
||||
* Render all visions in this [window] using current global state of [VisionForge]
|
||||
*/
|
||||
@JsExport
|
||||
public fun renderVisionsInWindow(){
|
||||
window.onload = {
|
||||
VisionForge.plugins[VisionClient]?.renderAllVisions()
|
||||
}
|
||||
}
|
@ -0,0 +1,8 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Global
|
||||
|
||||
public actual val VisionForge: Context = Global.context("VisionForge").apply{
|
||||
plugins.fetch(VisionManager)
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
package hep.dataforge.vision
|
||||
package hep.dataforge.vision.html
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.html.HtmlFragment
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import kotlinx.html.link
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.unsafe
|
||||
@ -100,14 +99,14 @@ internal fun fileCssHeader(
|
||||
* Make a script header, automatically copying file to appropriate location
|
||||
*/
|
||||
@DFExperimental
|
||||
public fun Context.scriptHeader(
|
||||
public fun scriptHeader(
|
||||
scriptResource: String,
|
||||
htmlPath: Path,
|
||||
htmlPath: Path?,
|
||||
resourceLocation: ResourceLocation,
|
||||
): HtmlFragment {
|
||||
val targetPath = when (resourceLocation) {
|
||||
ResourceLocation.LOCAL -> checkOrStoreFile(
|
||||
htmlPath,
|
||||
htmlPath ?: Path.of("."),
|
||||
Path.of(VISIONFORGE_ASSETS_PATH),
|
||||
scriptResource
|
||||
)
|
@ -0,0 +1,89 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.html.HtmlFragment
|
||||
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||
import hep.dataforge.vision.html.Page
|
||||
import kotlinx.html.stream.createHTML
|
||||
import java.awt.Desktop
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
|
||||
//
|
||||
///**
|
||||
// * Create a full html string (including the head) for a given [HtmlVisionFragment]
|
||||
// */
|
||||
//@DFExperimental
|
||||
//public fun Context.makeVisionString(
|
||||
// fragment: HtmlVisionFragment,
|
||||
// title: String = "VisionForge page",
|
||||
// headerBuilder: () -> HtmlFragment,
|
||||
//): String = createHTML().apply {
|
||||
// head {
|
||||
// meta {
|
||||
// charset = "utf-8"
|
||||
// fragment(headerBuilder())
|
||||
// }
|
||||
// title(title)
|
||||
// }
|
||||
// body {
|
||||
// embedVisionFragment(visionManager, fragment = fragment)
|
||||
// }
|
||||
//}.finalize()
|
||||
//
|
||||
//
|
||||
///**
|
||||
// * Make a file with the embedded vision data
|
||||
// */
|
||||
//@DFExperimental
|
||||
//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)
|
||||
// } ?: Files.createTempFile("tempPlot", ".html")
|
||||
// //Files.createDirectories(actualFile.parent)
|
||||
// val htmlString = makeVisionString(fragment, title) { headerBuilder(actualFile) }
|
||||
//
|
||||
// Files.writeString(actualFile, htmlString)
|
||||
// if (show) {
|
||||
// Desktop.getDesktop().browse(actualFile.toFile().toURI())
|
||||
// }
|
||||
//}
|
||||
|
||||
@DFExperimental
|
||||
public fun Context.page(
|
||||
title: String,
|
||||
content: HtmlVisionFragment,
|
||||
vararg headers: Pair<String, HtmlFragment>,
|
||||
): Page = Page(this, title, mapOf(*headers), content)
|
||||
|
||||
|
||||
@DFExperimental
|
||||
public fun Page.makeFile(
|
||||
path: Path?,
|
||||
defaultHeaders: ((Path) -> Map<String,HtmlFragment>)? = null,
|
||||
): Path {
|
||||
val actualFile = path?.let {
|
||||
Path.of(System.getProperty("user.home")).resolve(path)
|
||||
} ?: Files.createTempFile("tempPlot", ".html")
|
||||
|
||||
val actualDefaultHeaders = defaultHeaders?.invoke(actualFile)
|
||||
val actualPage = if(actualDefaultHeaders == null) this else copy(headers = actualDefaultHeaders + headers)
|
||||
|
||||
val htmlString = actualPage.render(createHTML())
|
||||
|
||||
Files.writeString(actualFile, htmlString)
|
||||
return actualFile
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun Page.show(path: Path? = null) {
|
||||
val actualPath = makeFile(path)
|
||||
Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
||||
}
|
@ -1,51 +0,0 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
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
|
||||
|
||||
|
||||
/**
|
||||
* Make a file with the embedded vision data
|
||||
*/
|
||||
@DFExperimental
|
||||
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)
|
||||
} ?: Files.createTempFile("tempPlot", ".html")
|
||||
//Files.createDirectories(actualFile.parent)
|
||||
val htmlString = createHTML().apply {
|
||||
head {
|
||||
meta {
|
||||
charset = "utf-8"
|
||||
fragment(headerBuilder(actualFile))
|
||||
}
|
||||
title(title)
|
||||
}
|
||||
body {
|
||||
embedVisionFragment(visionManager, fragment = fragment)
|
||||
}
|
||||
}.finalize()
|
||||
|
||||
Files.writeString(actualFile, htmlString)
|
||||
if (show) {
|
||||
Desktop.getDesktop().browse(actualFile.toFile().toURI())
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.ContextAware
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import javafx.application.Platform
|
||||
import javafx.beans.property.ObjectProperty
|
||||
@ -12,8 +11,10 @@ import javafx.scene.paint.Color
|
||||
import org.fxyz3d.scene.Axes
|
||||
import tornadofx.*
|
||||
|
||||
class FXCanvas3D(val plugin: FX3DPlugin, val spec: Canvas3DOptions = Canvas3DOptions.empty()) :
|
||||
Fragment(), Output<Solid>, ContextAware {
|
||||
class FXCanvas3D(
|
||||
val plugin: FX3DPlugin,
|
||||
val spec: Canvas3DOptions = Canvas3DOptions.empty(),
|
||||
) : Fragment(), ContextAware {
|
||||
|
||||
override val context: Context get() = plugin.context
|
||||
|
||||
@ -78,7 +79,7 @@ class FXCanvas3D(val plugin: FX3DPlugin, val spec: Canvas3DOptions = Canvas3DOpt
|
||||
}
|
||||
}
|
||||
|
||||
override fun render(vision: Solid) {
|
||||
fun render(vision: Solid) {
|
||||
rootObject = vision
|
||||
}
|
||||
}
|
@ -9,6 +9,27 @@ kscience {
|
||||
val plotlyVersion = "0.3.1-dev"
|
||||
|
||||
kotlin {
|
||||
js{
|
||||
//binaries.library()
|
||||
binaries.executable()
|
||||
browser {
|
||||
webpackTask {
|
||||
this.outputFileName = "js/visionforge-three.js"
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
afterEvaluate {
|
||||
val jsBrowserDistribution by tasks.getting
|
||||
|
||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
||||
dependsOn(jsBrowserDistribution)
|
||||
afterEvaluate {
|
||||
from(jsBrowserDistribution)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
commonMain {
|
||||
dependencies {
|
||||
|
@ -1,12 +1,16 @@
|
||||
package hep.dataforge.vision.plotly
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
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)
|
||||
@Serializable
|
||||
public class VisionOfPlotly(private val plotConfig: Config) : VisionBase(plotConfig){
|
||||
public val plot: Plot get() = Plot(plotConfig)
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public inline fun VisionOutput.plotly(block: Plot.() -> Unit): VisionOfPlotly = VisionOfPlotly(Plotly.plot(block))
|
||||
public inline fun VisionOutput.plotly(block: Plot.() -> Unit): VisionOfPlotly = VisionOfPlotly(Plotly.plot(block).config)
|
@ -0,0 +1,15 @@
|
||||
package hep.dataforge.vision.plotly
|
||||
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionPlugin
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlinx.serialization.modules.polymorphic
|
||||
import kotlinx.serialization.modules.subclass
|
||||
|
||||
public expect class PlotlyPlugin : VisionPlugin
|
||||
|
||||
internal val plotlySerializersModule = SerializersModule {
|
||||
polymorphic(Vision::class) {
|
||||
subclass(VisionOfPlotly.serializer())
|
||||
}
|
||||
}
|
@ -1,15 +0,0 @@
|
||||
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()
|
||||
// }
|
||||
//}
|
@ -1,23 +1,29 @@
|
||||
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.context.*
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionPlugin
|
||||
import hep.dataforge.vision.client.ElementVisionRenderer
|
||||
import hep.dataforge.vision.client.VisionClient
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kscience.plotly.PlotlyConfig
|
||||
import kscience.plotly.plot
|
||||
import org.w3c.dom.Element
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public class PlotlyPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer {
|
||||
public val visionClient: VisionClient by require(VisionClient)
|
||||
|
||||
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 val visionSerializersModule: SerializersModule get() = plotlySerializersModule
|
||||
|
||||
override fun rateVision(vision: Vision): Int = when (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")
|
||||
@ -31,3 +37,11 @@ public class PlotlyPlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that [PlotlyPlugin] is loaded in the global [VisionForge] context
|
||||
*/
|
||||
@JsExport
|
||||
public fun withPlotly() {
|
||||
VisionForge.plugins.fetch(PlotlyPlugin)
|
||||
}
|
@ -0,0 +1,30 @@
|
||||
package hep.dataforge.vision.plotly
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.html.HtmlFragment
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.scriptHeader
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.unsafe
|
||||
import java.nio.file.Path
|
||||
|
||||
internal val plotlyScriptLocation = "js/visionforge-three.js"
|
||||
|
||||
/**
|
||||
* A header that stores/embeds plotly bundle and registers plotly renderer in the frontend
|
||||
*/
|
||||
@OptIn(DFExperimental::class)
|
||||
public fun plotlyHeader(location: ResourceLocation, filePath: Path? = null): HtmlFragment = {
|
||||
scriptHeader(
|
||||
plotlyScriptLocation,
|
||||
filePath,
|
||||
resourceLocation = location
|
||||
).invoke(this)
|
||||
script {
|
||||
type = "text/javascript"
|
||||
unsafe {
|
||||
//language=JavaScript
|
||||
+"hep.dataforge.vision.plotly.loadPlotly()"
|
||||
}
|
||||
}
|
||||
}
|
@ -0,0 +1,27 @@
|
||||
package hep.dataforge.vision.plotly
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.context.Plugin
|
||||
import hep.dataforge.context.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.vision.VisionPlugin
|
||||
import kotlinx.serialization.modules.SerializersModule
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
public actual class PlotlyPlugin : VisionPlugin(), Plugin {
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
override val visionSerializersModule: SerializersModule get() = plotlySerializersModule
|
||||
|
||||
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()
|
||||
}
|
||||
}
|
||||
|
||||
public fun Context.withPlotly(): Context = apply {
|
||||
plugins.fetch(PlotlyPlugin)
|
||||
}
|
@ -11,7 +11,6 @@ import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.*
|
||||
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
|
||||
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
|
||||
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
|
||||
@ -108,9 +107,6 @@ public var Solid.layer: Int
|
||||
setProperty(LAYER_KEY, value)
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun Output<Solid>.solidGroup(builder: SolidGroup.() -> Unit): Unit = render(SolidGroup().apply(builder))
|
||||
|
||||
// Common properties
|
||||
|
||||
public enum class RotationOrder {
|
||||
|
@ -1,18 +1,11 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
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
|
||||
import hep.dataforge.vision.Vision
|
||||
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.*
|
||||
import hep.dataforge.vision.html.VisionOutput
|
||||
import kotlinx.serialization.PolymorphicSerializer
|
||||
import kotlinx.serialization.json.Json
|
||||
@ -23,16 +16,11 @@ import kotlinx.serialization.modules.subclass
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
|
||||
public class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
|
||||
public val visionManager: VisionManager by require(VisionManager)
|
||||
public class SolidManager(meta: Meta) : VisionPlugin(meta) {
|
||||
|
||||
override val tag: PluginTag get() = Companion.tag
|
||||
|
||||
override fun content(target: String): Map<Name, Any> = when (target) {
|
||||
VISION_SERIALIZER_MODULE_TARGET -> mapOf(tag.name.toName() to serializersModuleForSolids)
|
||||
else -> super.content(target)
|
||||
}
|
||||
override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids
|
||||
|
||||
public companion object : PluginFactory<SolidManager> {
|
||||
override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP)
|
||||
@ -66,15 +54,18 @@ public class SolidManager(meta: Meta) : AbstractPlugin(meta) {
|
||||
}
|
||||
}
|
||||
|
||||
internal val jsonForSolids: Json = Json(VisionManager.defaultJson){
|
||||
internal val jsonForSolids: Json = Json(VisionManager.defaultJson) {
|
||||
serializersModule = serializersModuleForSolids
|
||||
}
|
||||
|
||||
public fun encodeToString(solid: Solid): String = jsonForSolids.encodeToString(PolymorphicSerializer(Vision::class), solid)
|
||||
public fun encodeToString(solid: Solid): String =
|
||||
jsonForSolids.encodeToString(PolymorphicSerializer(Vision::class), solid)
|
||||
|
||||
public fun decodeFromString(str: String): Solid = jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str)
|
||||
public fun decodeFromString(str: String): Solid =
|
||||
jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str)
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
@DFExperimental
|
||||
public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block)
|
@ -4,16 +4,14 @@ import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.double
|
||||
import hep.dataforge.meta.get
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlin.math.PI
|
||||
|
||||
public const val PI2: Float = 2 * PI.toFloat()
|
||||
|
||||
@Serializable
|
||||
public data class Point2D(public var x: Double, public var y: Double){
|
||||
public constructor(x: Number, y: Number) : this(x.toDouble(), y.toDouble())
|
||||
}
|
||||
public data class Point2D(public var x: Double, public var y: Double)
|
||||
|
||||
public fun Point2D(x: Number, y: Number): Point2D = Point2D(x.toDouble(), y.toDouble())
|
||||
|
||||
public fun Point2D.toMeta(): Meta = Meta {
|
||||
Solid.X_KEY put x
|
||||
@ -28,14 +26,14 @@ public data class Point3D(
|
||||
public var y: Double,
|
||||
public var z: Double,
|
||||
) {
|
||||
public constructor(x: Number, y: Number, z: Number) : this(x.toDouble(), y.toDouble(), z.toDouble())
|
||||
|
||||
public companion object{
|
||||
public companion object {
|
||||
public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0)
|
||||
public val ONE: Point3D = Point3D(1.0, 1.0, 1.0)
|
||||
}
|
||||
}
|
||||
|
||||
public fun Point3D(x: Number, y: Number, z: Number): Point3D = Point3D(x.toDouble(), y.toDouble(), z.toDouble())
|
||||
|
||||
public operator fun Point3D.plus(other: Point3D): Point3D = Point3D(
|
||||
this.x + other.x,
|
||||
this.y + other.y,
|
||||
|
@ -6,6 +6,12 @@ kscience {
|
||||
useSerialization()
|
||||
}
|
||||
|
||||
kotlin{
|
||||
js{
|
||||
binaries.library()
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
api(project(":visionforge-solid"))
|
||||
implementation(npm("three", "0.122.0"))
|
||||
|
@ -1,12 +1,9 @@
|
||||
package hep.dataforge.vision.solid.three
|
||||
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.Colors
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.specifications.*
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.HIGHLIGHT_MATERIAL
|
||||
@ -39,7 +36,7 @@ import kotlin.math.sin
|
||||
public class ThreeCanvas(
|
||||
public val three: ThreePlugin,
|
||||
public val options: Canvas3DOptions,
|
||||
) : Output<Solid> {
|
||||
) {
|
||||
private var root: Object3D? = null
|
||||
|
||||
private val raycaster = Raycaster()
|
||||
@ -195,7 +192,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
}
|
||||
|
||||
public override fun render(vision: Solid) {
|
||||
public fun render(vision: Solid) {
|
||||
scene.children.find { it.name == "@root" }?.let {
|
||||
//Throw error is something is already rendered here
|
||||
error("Root object already is present in the canvas")
|
||||
|
@ -4,14 +4,13 @@ import hep.dataforge.context.*
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.client.ElementVisionRenderer
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import hep.dataforge.vision.visible
|
||||
import info.laht.threekt.core.Object3D
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.flow.launchIn
|
||||
import kotlinx.coroutines.flow.onEach
|
||||
import org.w3c.dom.Element
|
||||
import org.w3c.dom.HTMLElement
|
||||
import kotlin.collections.set
|
||||
@ -151,6 +150,14 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
|
||||
*/
|
||||
@JsExport
|
||||
public fun loadThreeJs(){
|
||||
VisionForge.plugins.fetch(ThreePlugin)
|
||||
}
|
||||
|
||||
public fun ThreePlugin.render(
|
||||
element: HTMLElement,
|
||||
obj: Solid,
|
||||
|
@ -1,20 +1,9 @@
|
||||
package hep.dataforge.vision.three.server
|
||||
|
||||
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
|
||||
import hep.dataforge.vision.renderVisionsInWindow
|
||||
import hep.dataforge.vision.solid.three.loadThreeJs
|
||||
|
||||
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()
|
||||
}
|
||||
loadThreeJs()
|
||||
renderVisionsInWindow()
|
||||
}
|
@ -2,10 +2,12 @@ package hep.dataforge.vision.three.server
|
||||
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.vision.ResourceLocation
|
||||
import hep.dataforge.vision.html.HtmlVisionFragment
|
||||
import hep.dataforge.vision.makeVisionFile
|
||||
import hep.dataforge.vision.scriptHeader
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.scriptHeader
|
||||
import hep.dataforge.vision.makeFile
|
||||
import hep.dataforge.vision.page
|
||||
import java.awt.Desktop
|
||||
import java.nio.file.Path
|
||||
|
||||
|
||||
@ -14,12 +16,15 @@ public fun VisionServer.useThreeJs(): Unit {
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public fun Context.makeVisionFile(
|
||||
fragment: HtmlVisionFragment,
|
||||
public fun Context.makeThreeJsFile(
|
||||
content: 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-three.js", actualPath, resourceLocation)
|
||||
): Unit {
|
||||
val actualPath = page(title, content).makeFile(path) { actualPath ->
|
||||
mapOf("threeJs" to scriptHeader("js/visionforge-three.js", actualPath, resourceLocation))
|
||||
}
|
||||
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
||||
}
|
Loading…
Reference in New Issue
Block a user