Fix plotly renderer and resource serialization
This commit is contained in:
parent
60906db32e
commit
5d0ceb8e50
@ -3,23 +3,24 @@ package hep.dataforge.playground
|
||||
import hep.dataforge.context.Context
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.gdml.gdml
|
||||
import hep.dataforge.vision.html.Page
|
||||
import hep.dataforge.vision.html.embedVisionFragment
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.html.scriptHeader
|
||||
import hep.dataforge.vision.html.*
|
||||
import hep.dataforge.vision.plotly.PlotlyPlugin
|
||||
import hep.dataforge.vision.plotly.VisionOfPlotly
|
||||
import hep.dataforge.vision.solid.SolidManager
|
||||
import hep.dataforge.vision.solid.solid
|
||||
import hep.dataforge.vision.visionManager
|
||||
import kotlinx.html.div
|
||||
import kotlinx.html.id
|
||||
import kotlinx.html.script
|
||||
import kotlinx.html.stream.createHTML
|
||||
import kotlinx.html.unsafe
|
||||
import kscience.plotly.Plot
|
||||
import kscience.plotly.PlotlyFragment
|
||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||
import org.jetbrains.kotlinx.jupyter.api.Notebook
|
||||
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
||||
import org.jetbrains.kotlinx.jupyter.api.libraries.ResourceLocation
|
||||
import space.kscience.gdml.Gdml
|
||||
|
||||
@JupyterLibrary
|
||||
@ -34,16 +35,25 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
ResourcePathType.CLASSPATH_PATH)))
|
||||
val jsResource = LibraryResource(name = "VisionForge", type = ResourceType.JS, bundles = listOf(jsBundle))
|
||||
|
||||
private var counter = 0
|
||||
|
||||
private fun produceHtmlVisionString(fragment: HtmlVisionFragment) = createHTML().div {
|
||||
val id = "visionforge.vision[${counter++}]"
|
||||
div {
|
||||
this.id = id
|
||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||
}
|
||||
script {
|
||||
type = "text/javascript"
|
||||
unsafe { +"window.renderVisionsAt(\"$id\");" }
|
||||
}
|
||||
}
|
||||
|
||||
override fun Builder.onLoaded(notebook: Notebook?) {
|
||||
resource(jsResource)
|
||||
|
||||
import("space.kscience.gdml.*", "kscience.plotly.*", "kscience.plotly.models.*")
|
||||
|
||||
onLoaded {
|
||||
val header = scriptHeader("js/visionforge-playground.js", null, hep.dataforge.vision.html.ResourceLocation.EMBED)
|
||||
display(HTML(createHTML().apply(header).finalize()))
|
||||
}
|
||||
|
||||
render<Gdml> { gdmlModel ->
|
||||
val fragment = VisionManager.fragment {
|
||||
vision {
|
||||
@ -53,11 +63,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
}
|
||||
}
|
||||
|
||||
val html = createHTML().div {
|
||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||
}
|
||||
|
||||
HTML(html)
|
||||
HTML(produceHtmlVisionString(fragment))
|
||||
}
|
||||
|
||||
render<Plot> { plot ->
|
||||
@ -67,11 +73,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
||||
}
|
||||
}
|
||||
|
||||
val html = createHTML().div {
|
||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
||||
}
|
||||
|
||||
HTML(html)
|
||||
HTML( produceHtmlVisionString(fragment))
|
||||
}
|
||||
|
||||
render<kscience.plotly.HtmlFragment> { fragment ->
|
||||
|
@ -1,10 +1,14 @@
|
||||
//import hep.dataforge.vision.plotly.withPlotly
|
||||
import hep.dataforge.vision.plotly.withPlotly
|
||||
import hep.dataforge.vision.renderVisionsAt
|
||||
import hep.dataforge.vision.renderVisionsInWindow
|
||||
import hep.dataforge.vision.solid.three.loadThreeJs
|
||||
import hep.dataforge.vision.solid.three.withThreeJs
|
||||
import kotlinx.browser.window
|
||||
|
||||
fun main() {
|
||||
withPlotly()
|
||||
loadThreeJs()
|
||||
withThreeJs()
|
||||
renderVisionsInWindow()
|
||||
window.asDynamic()["renderVisionsInWindow"] = ::renderVisionsInWindow
|
||||
window.asDynamic()["renderVisionsAt"] = ::renderVisionsAt
|
||||
}
|
74
demo/playground/src/jvmMain/kotlin/gdmlCubes.kt
Normal file
74
demo/playground/src/jvmMain/kotlin/gdmlCubes.kt
Normal file
@ -0,0 +1,74 @@
|
||||
package hep.dataforge.vision.examples
|
||||
|
||||
import hep.dataforge.misc.DFExperimental
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionManager
|
||||
import hep.dataforge.vision.gdml.gdml
|
||||
import hep.dataforge.vision.html.ResourceLocation
|
||||
import hep.dataforge.vision.html.fragment
|
||||
import hep.dataforge.vision.solid.solid
|
||||
import hep.dataforge.vision.solid.withSolids
|
||||
import space.kscience.gdml.*
|
||||
|
||||
internal val cubes = Gdml {
|
||||
val center = define.position("center")
|
||||
structure {
|
||||
val air = ref<GdmlMaterial>("G4_AIR")
|
||||
val tubeMaterial = ref<GdmlMaterial>("tube")
|
||||
val boxMaterial = ref<GdmlMaterial>("box")
|
||||
|
||||
val segment = solids.tube("segment", 20, 5.0) {
|
||||
rmin = 17
|
||||
deltaphi = 60
|
||||
aunit = AUnit.DEG.title
|
||||
}
|
||||
val worldBox = solids.box("largeBox", 200, 200, 200)
|
||||
val smallBox = solids.box("smallBox", 30, 30, 30)
|
||||
val segmentVolume = volume("segment", tubeMaterial, segment.ref()) {}
|
||||
val circle = volume("composite", boxMaterial, smallBox.ref()) {
|
||||
for (i in 0 until 6) {
|
||||
physVolume(segmentVolume) {
|
||||
positionref = center.ref()
|
||||
rotation {
|
||||
z = 60 * i
|
||||
unit = AUnit.DEG.title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
world = volume("world", air, worldBox.ref()) {
|
||||
for (i in 0 until 3) {
|
||||
for (j in 0 until 3) {
|
||||
for (k in 0 until 3) {
|
||||
physVolume(circle) {
|
||||
position {
|
||||
x = (-50 + i * 50)
|
||||
y = (-50 + j * 50)
|
||||
z = (-50 + k * 50)
|
||||
}
|
||||
rotation {
|
||||
x = i * 120
|
||||
y = j * 120
|
||||
z = 120 * k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
fun main() {
|
||||
val content = VisionManager.fragment {
|
||||
vision("canvas") {
|
||||
solid {
|
||||
gdml(cubes)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VisionForge.withSolids().makeVisionFile(content, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.examples
|
||||
import hep.dataforge.misc.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.plotly.plotly
|
||||
import hep.dataforge.vision.plotly.withPlotly
|
||||
@ -21,5 +22,5 @@ fun main() {
|
||||
}
|
||||
}
|
||||
|
||||
VisionForge.withPlotly().makeVisionFile(fragment)
|
||||
VisionForge.withPlotly().makeVisionFile(fragment, resourceLocation = ResourceLocation.SYSTEM)
|
||||
}
|
@ -9,7 +9,7 @@ import hep.dataforge.vision.solid.box
|
||||
import hep.dataforge.vision.solid.solid
|
||||
import hep.dataforge.vision.solid.withSolids
|
||||
|
||||
@OptIn(DFExperimental::class)
|
||||
@DFExperimental
|
||||
fun main() {
|
||||
val content = VisionManager.fragment {
|
||||
vision("canvas") {
|
||||
|
@ -83,7 +83,7 @@ public abstract class VisionTagConsumer<R>(
|
||||
visionProvider: VisionOutput.() -> Vision,
|
||||
): T = vision(name.toName(), visionProvider)
|
||||
|
||||
public inline fun <T> TagConsumer<T>.vision(
|
||||
public fun <T> TagConsumer<T>.vision(
|
||||
vision: Vision,
|
||||
): T = vision("vision[${vision.hashCode()}]".toName(), vision)
|
||||
|
||||
|
@ -4,19 +4,32 @@ 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.client.renderAllVisionsAt
|
||||
import kotlinx.browser.document
|
||||
import kotlinx.browser.window
|
||||
|
||||
public actual val VisionForge: Context = Global.context("VisionForge").apply{
|
||||
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(){
|
||||
public fun renderVisionsInWindow() {
|
||||
window.onload = {
|
||||
VisionForge.plugins[VisionClient]?.renderAllVisions()
|
||||
}
|
||||
}
|
||||
|
||||
@JsExport
|
||||
public fun renderVisionsAt(id: String) {
|
||||
val element = document.getElementById(id)
|
||||
if (element != null) {
|
||||
VisionForge.plugins[VisionClient]?.renderAllVisionsAt(element)
|
||||
} else {
|
||||
console.warn("Element with id $id not found")
|
||||
}
|
||||
}
|
@ -43,8 +43,16 @@ public class VisionClient : AbstractPlugin() {
|
||||
|
||||
private fun getRenderers() = context.gather<ElementVisionRenderer>(ElementVisionRenderer.TYPE).values
|
||||
|
||||
private fun findRendererFor(vision: Vision): ElementVisionRenderer? =
|
||||
getRenderers().maxByOrNull { it.rateVision(vision) }
|
||||
private fun findRendererFor(vision: Vision): ElementVisionRenderer? {
|
||||
return getRenderers().mapNotNull {
|
||||
val rating = it.rateVision(vision)
|
||||
if (rating > 0) {
|
||||
rating to it
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}.maxByOrNull { it.first }?.second
|
||||
}
|
||||
|
||||
private fun Element.getEmbeddedData(className: String): String? = getElementsByClassName(className)[0]?.innerHTML
|
||||
|
||||
|
@ -8,6 +8,10 @@ import kotlinx.html.unsafe
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Path
|
||||
import java.nio.file.StandardOpenOption
|
||||
import java.security.MessageDigest
|
||||
import kotlin.io.path.ExperimentalPathApi
|
||||
import kotlin.io.path.readText
|
||||
|
||||
|
||||
/**
|
||||
* The location of resources for plot.
|
||||
@ -37,21 +41,29 @@ public enum class ResourceLocation {
|
||||
internal const val VISIONFORGE_ASSETS_PATH = ".dataforge/vision/assets"
|
||||
|
||||
|
||||
private fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toString(16).padStart(2, '0') }
|
||||
|
||||
/**
|
||||
* Check if the asset exists in given local location and put it there if it does not
|
||||
* @param
|
||||
*/
|
||||
@OptIn(ExperimentalPathApi::class)
|
||||
internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path {
|
||||
//TODO add logging
|
||||
val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
||||
|
||||
if (Files.exists(fullPath)) {
|
||||
//TODO checksum
|
||||
} else {
|
||||
//TODO add logging
|
||||
val bytes = VisionManager::class.java.getResourceAsStream("/$resource").readAllBytes()
|
||||
val md = MessageDigest.getInstance("MD5")
|
||||
|
||||
val bytes = VisionManager::class.java.getResourceAsStream("/$resource").readAllBytes()
|
||||
val checksum = md.digest(bytes).toHexString()
|
||||
|
||||
val md5File = fullPath.resolveSibling(fullPath.fileName.toString() + ".md5")
|
||||
val skip: Boolean = Files.exists(fullPath) && Files.exists(md5File) && md5File.readText() == checksum
|
||||
|
||||
if (!skip) {
|
||||
Files.createDirectories(fullPath.parent)
|
||||
Files.write(fullPath, bytes, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE)
|
||||
Files.write(fullPath, bytes, StandardOpenOption.CREATE, StandardOpenOption.WRITE)
|
||||
Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.WRITE)
|
||||
}
|
||||
|
||||
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
||||
|
@ -1,38 +1,36 @@
|
||||
package hep.dataforge.vision.gdml
|
||||
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.solid.SolidManager
|
||||
import space.kscience.gdml.Gdml
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import org.junit.jupiter.api.Test
|
||||
import space.kscience.gdml.decodeFromStream
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class TestConvertor {
|
||||
|
||||
@Test
|
||||
fun testBMNGeometry() {
|
||||
val stream = javaClass.getResourceAsStream("/gdml/BM@N.gdml")
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
||||
val vision = xml.toVision()
|
||||
println(SolidManager.encodeToString(vision))
|
||||
val gdml = Gdml.decodeFromStream(stream)
|
||||
val vision = gdml.toVision()
|
||||
//println(SolidManager.encodeToString(vision))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCubes() {
|
||||
val stream = javaClass.getResourceAsStream("/gdml/cubes.gdml")
|
||||
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
||||
val visual = xml.toVision()
|
||||
// println(visual)
|
||||
val gdml = Gdml.decodeFromStream(stream)
|
||||
val vision = gdml.toVision()
|
||||
assertNotNull(vision.getPrototype("solids.box".toName()))
|
||||
//println(SolidManager.encodeToString(vision))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testSimple() {
|
||||
val stream = javaClass.getResourceAsStream("/gdml/simple1.gdml")
|
||||
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
||||
val vision = xml.toVision()
|
||||
println(SolidManager.encodeToString(vision))
|
||||
val gdml = Gdml.decodeFromStream(stream)
|
||||
val vision = gdml.toVision()
|
||||
//println(SolidManager.encodeToString(vision))
|
||||
}
|
||||
}
|
@ -0,0 +1,74 @@
|
||||
package hep.dataforge.vision.gdml
|
||||
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.solid.SolidGroup
|
||||
import hep.dataforge.vision.solid.SolidManager
|
||||
import org.junit.jupiter.api.Test
|
||||
import space.kscience.gdml.*
|
||||
import kotlin.test.assertNotNull
|
||||
|
||||
class TestCubes {
|
||||
internal val cubes = Gdml {
|
||||
val center = define.position("center")
|
||||
structure {
|
||||
val air = ref<GdmlMaterial>("G4_AIR")
|
||||
val tubeMaterial = ref<GdmlMaterial>("tube")
|
||||
val boxMaterial = ref<GdmlMaterial>("box")
|
||||
|
||||
val segment = solids.tube("segment", 20, 5.0) {
|
||||
rmin = 17
|
||||
deltaphi = 60
|
||||
aunit = AUnit.DEG.title
|
||||
}
|
||||
val worldBox = solids.box("largeBox", 200, 200, 200)
|
||||
val smallBox = solids.box("smallBox", 30, 30, 30)
|
||||
val segmentVolume = volume("segment", tubeMaterial, segment.ref()) {}
|
||||
val circle = volume("composite", boxMaterial, smallBox.ref()) {
|
||||
for (i in 0 until 6) {
|
||||
physVolume(segmentVolume) {
|
||||
positionref = center.ref()
|
||||
rotation {
|
||||
z = 60 * i
|
||||
unit = AUnit.DEG.title
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
world = volume("world", air, worldBox.ref()) {
|
||||
for (i in 0 until 3) {
|
||||
for (j in 0 until 3) {
|
||||
for (k in 0 until 3) {
|
||||
physVolume(circle) {
|
||||
position {
|
||||
x = (-50 + i * 50)
|
||||
y = (-50 + j * 50)
|
||||
z = (-50 + k * 50)
|
||||
}
|
||||
rotation {
|
||||
x = i * 120
|
||||
y = j * 120
|
||||
z = 120 * k
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCubesDirect(){
|
||||
val vision = cubes.toVision()
|
||||
assertNotNull(vision.getPrototype("solids.smallBox".toName()))
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testCubesReSerialize(){
|
||||
val vision = cubes.toVision()
|
||||
val serialized = SolidManager.encodeToString(vision)
|
||||
val deserialized = SolidManager.decodeFromString(serialized) as SolidGroup
|
||||
assertNotNull(deserialized.getPrototype("solids.smallBox".toName()))
|
||||
}
|
||||
}
|
@ -2,6 +2,8 @@ package hep.dataforge.vision.plotly
|
||||
|
||||
import hep.dataforge.context.*
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionForge
|
||||
import hep.dataforge.vision.VisionPlugin
|
||||
@ -26,11 +28,18 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
|
||||
override fun render(element: Element, vision: Vision, meta: Meta) {
|
||||
val plot = (vision as? VisionOfPlotly)?.plot ?: error("Only VisionOfPlotly visions are supported")
|
||||
val plot = (vision as? VisionOfPlotly)?.plot ?: error("VisionOfPlotly expected but ${vision::class} found")
|
||||
val config = PlotlyConfig.read(meta)
|
||||
element.plot(plot, config)
|
||||
}
|
||||
|
||||
override fun content(target: String): Map<Name, Any> {
|
||||
return when (target) {
|
||||
ElementVisionRenderer.TYPE -> mapOf("plotly".asName() to this)
|
||||
else -> super.content(target)
|
||||
}
|
||||
}
|
||||
|
||||
public companion object : PluginFactory<PlotlyPlugin> {
|
||||
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
|
||||
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
|
||||
|
@ -35,27 +35,6 @@ public class Box(
|
||||
geometryBuilder.face4(node8, node5, node6, node7)
|
||||
}
|
||||
|
||||
// override fun equals(other: Any?): Boolean {
|
||||
// if (this === other) return true
|
||||
// if (other == null || this::class != other::class) return false
|
||||
//
|
||||
// other as Box
|
||||
//
|
||||
// if (xSize != other.xSize) return false
|
||||
// if (ySize != other.ySize) return false
|
||||
// if (zSize != other.zSize) return false
|
||||
//
|
||||
// return solidEquals(this, other)
|
||||
// }
|
||||
//
|
||||
// override fun hashCode(): Int {
|
||||
// var result = xSize.hashCode()
|
||||
// result = 31 * result + ySize.hashCode()
|
||||
// result = 31 * result + zSize.hashCode()
|
||||
// return 31 * result + Solid.solidHashCode(this)
|
||||
// }
|
||||
|
||||
|
||||
public companion object {
|
||||
|
||||
}
|
||||
|
@ -28,9 +28,13 @@ public interface PrototypeHolder {
|
||||
@Serializable
|
||||
@SerialName("group.solid")
|
||||
public class SolidGroup(
|
||||
@Serializable(Prototypes.Companion::class) @SerialName("prototypes") private var prototypes: MutableVisionGroup? = null,
|
||||
@Serializable(Prototypes.Companion::class) @SerialName("prototypes") internal var prototypes: MutableVisionGroup? = null,
|
||||
) : VisionGroupBase(), Solid, PrototypeHolder {
|
||||
|
||||
init {
|
||||
prototypes?.parent = this
|
||||
}
|
||||
|
||||
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
||||
|
||||
/**
|
||||
|
@ -8,21 +8,21 @@ import kotlin.test.assertEquals
|
||||
|
||||
class SolidPluginTest {
|
||||
val vision = SolidGroup {
|
||||
box(100,100,100, name = "aBox")
|
||||
box(100, 100, 100, name = "aBox")
|
||||
|
||||
sphere(100,name = "aSphere"){
|
||||
sphere(100, name = "aSphere") {
|
||||
z = 200
|
||||
}
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
@Test
|
||||
fun testPluginConverter(){
|
||||
fun testPluginConverter() {
|
||||
val visionManager = Global.plugins.fetch(SolidManager).visionManager
|
||||
val meta = visionManager.encodeToMeta(vision)
|
||||
|
||||
val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup
|
||||
|
||||
assertEquals(vision["aBox"],reconstructed["aBox"])
|
||||
assertEquals(visionManager.encodeToJsonElement(vision["aBox"]!!), visionManager.encodeToJsonElement(reconstructed["aBox"]!!))
|
||||
}
|
||||
}
|
@ -3,6 +3,8 @@ package hep.dataforge.vision.solid
|
||||
import hep.dataforge.vision.get
|
||||
import hep.dataforge.vision.style
|
||||
import hep.dataforge.vision.useStyle
|
||||
import kotlinx.serialization.json.Json
|
||||
import kotlinx.serialization.json.encodeToJsonElement
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -22,4 +24,11 @@ class SolidReferenceTest {
|
||||
fun testReferenceProperty(){
|
||||
assertEquals("blue", (groupWithReference["test"] as Solid).color.string)
|
||||
}
|
||||
|
||||
@Test
|
||||
fun testReferenceSerialization(){
|
||||
val serialized = SolidManager.jsonForSolids.encodeToJsonElement(groupWithReference)
|
||||
val deserialized = SolidManager.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized)
|
||||
assertEquals("blue", (deserialized["test"] as Solid).color.string)
|
||||
}
|
||||
}
|
@ -126,9 +126,8 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
}
|
||||
}
|
||||
|
||||
override fun rateVision(vision: Vision): Int {
|
||||
return if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
||||
}
|
||||
override fun rateVision(vision: Vision): Int =
|
||||
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
||||
|
||||
public fun renderSolid(
|
||||
element: Element,
|
||||
@ -141,7 +140,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
override fun render(element: Element, vision: Vision, meta: Meta) {
|
||||
renderSolid(
|
||||
element,
|
||||
vision as? Solid ?: error("Solid expected but ${vision::class} is found"),
|
||||
vision as? Solid ?: error("Solid expected but ${vision::class} found"),
|
||||
Canvas3DOptions.read(meta)
|
||||
)
|
||||
}
|
||||
@ -157,7 +156,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
||||
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
|
||||
*/
|
||||
@JsExport
|
||||
public fun loadThreeJs() {
|
||||
public fun withThreeJs() {
|
||||
VisionForge.plugins.fetch(ThreePlugin)
|
||||
}
|
||||
|
||||
|
@ -1,9 +1,9 @@
|
||||
package hep.dataforge.vision.three.server
|
||||
|
||||
import hep.dataforge.vision.renderVisionsInWindow
|
||||
import hep.dataforge.vision.solid.three.loadThreeJs
|
||||
import hep.dataforge.vision.solid.three.withThreeJs
|
||||
|
||||
public fun main() {
|
||||
loadThreeJs()
|
||||
withThreeJs()
|
||||
renderVisionsInWindow()
|
||||
}
|
Loading…
Reference in New Issue
Block a user