forked from kscience/visionforge
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.context.Context
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
import hep.dataforge.vision.gdml.gdml
|
import hep.dataforge.vision.gdml.gdml
|
||||||
import hep.dataforge.vision.html.Page
|
import hep.dataforge.vision.html.*
|
||||||
import hep.dataforge.vision.html.embedVisionFragment
|
|
||||||
import hep.dataforge.vision.html.fragment
|
|
||||||
import hep.dataforge.vision.html.scriptHeader
|
|
||||||
import hep.dataforge.vision.plotly.PlotlyPlugin
|
import hep.dataforge.vision.plotly.PlotlyPlugin
|
||||||
import hep.dataforge.vision.plotly.VisionOfPlotly
|
import hep.dataforge.vision.plotly.VisionOfPlotly
|
||||||
import hep.dataforge.vision.solid.SolidManager
|
import hep.dataforge.vision.solid.SolidManager
|
||||||
import hep.dataforge.vision.solid.solid
|
import hep.dataforge.vision.solid.solid
|
||||||
import hep.dataforge.vision.visionManager
|
import hep.dataforge.vision.visionManager
|
||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
|
import kotlinx.html.id
|
||||||
|
import kotlinx.html.script
|
||||||
import kotlinx.html.stream.createHTML
|
import kotlinx.html.stream.createHTML
|
||||||
|
import kotlinx.html.unsafe
|
||||||
import kscience.plotly.Plot
|
import kscience.plotly.Plot
|
||||||
import kscience.plotly.PlotlyFragment
|
import kscience.plotly.PlotlyFragment
|
||||||
import org.jetbrains.kotlinx.jupyter.api.HTML
|
import org.jetbrains.kotlinx.jupyter.api.HTML
|
||||||
import org.jetbrains.kotlinx.jupyter.api.Notebook
|
import org.jetbrains.kotlinx.jupyter.api.Notebook
|
||||||
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
import org.jetbrains.kotlinx.jupyter.api.annotations.JupyterLibrary
|
||||||
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
import org.jetbrains.kotlinx.jupyter.api.libraries.*
|
||||||
|
import org.jetbrains.kotlinx.jupyter.api.libraries.ResourceLocation
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
|
|
||||||
@JupyterLibrary
|
@JupyterLibrary
|
||||||
@ -34,16 +35,25 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
ResourcePathType.CLASSPATH_PATH)))
|
ResourcePathType.CLASSPATH_PATH)))
|
||||||
val jsResource = LibraryResource(name = "VisionForge", type = ResourceType.JS, bundles = listOf(jsBundle))
|
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?) {
|
override fun Builder.onLoaded(notebook: Notebook?) {
|
||||||
resource(jsResource)
|
resource(jsResource)
|
||||||
|
|
||||||
import("space.kscience.gdml.*", "kscience.plotly.*", "kscience.plotly.models.*")
|
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 ->
|
render<Gdml> { gdmlModel ->
|
||||||
val fragment = VisionManager.fragment {
|
val fragment = VisionManager.fragment {
|
||||||
vision {
|
vision {
|
||||||
@ -53,11 +63,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val html = createHTML().div {
|
HTML(produceHtmlVisionString(fragment))
|
||||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
HTML(html)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render<Plot> { plot ->
|
render<Plot> { plot ->
|
||||||
@ -67,11 +73,7 @@ internal class VisionForgePlayGroundForJupyter : JupyterIntegration() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val html = createHTML().div {
|
HTML( produceHtmlVisionString(fragment))
|
||||||
embedVisionFragment(context.visionManager, fragment = fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
HTML(html)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
render<kscience.plotly.HtmlFragment> { 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.plotly.withPlotly
|
import hep.dataforge.vision.plotly.withPlotly
|
||||||
|
import hep.dataforge.vision.renderVisionsAt
|
||||||
import hep.dataforge.vision.renderVisionsInWindow
|
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() {
|
fun main() {
|
||||||
withPlotly()
|
withPlotly()
|
||||||
loadThreeJs()
|
withThreeJs()
|
||||||
renderVisionsInWindow()
|
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.misc.DFExperimental
|
||||||
import hep.dataforge.vision.VisionForge
|
import hep.dataforge.vision.VisionForge
|
||||||
import hep.dataforge.vision.VisionManager
|
import hep.dataforge.vision.VisionManager
|
||||||
|
import hep.dataforge.vision.html.ResourceLocation
|
||||||
import hep.dataforge.vision.html.fragment
|
import hep.dataforge.vision.html.fragment
|
||||||
import hep.dataforge.vision.plotly.plotly
|
import hep.dataforge.vision.plotly.plotly
|
||||||
import hep.dataforge.vision.plotly.withPlotly
|
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.solid
|
||||||
import hep.dataforge.vision.solid.withSolids
|
import hep.dataforge.vision.solid.withSolids
|
||||||
|
|
||||||
@OptIn(DFExperimental::class)
|
@DFExperimental
|
||||||
fun main() {
|
fun main() {
|
||||||
val content = VisionManager.fragment {
|
val content = VisionManager.fragment {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
|
@ -83,7 +83,7 @@ public abstract class VisionTagConsumer<R>(
|
|||||||
visionProvider: VisionOutput.() -> Vision,
|
visionProvider: VisionOutput.() -> Vision,
|
||||||
): T = vision(name.toName(), visionProvider)
|
): T = vision(name.toName(), visionProvider)
|
||||||
|
|
||||||
public inline fun <T> TagConsumer<T>.vision(
|
public fun <T> TagConsumer<T>.vision(
|
||||||
vision: Vision,
|
vision: Vision,
|
||||||
): T = vision("vision[${vision.hashCode()}]".toName(), vision)
|
): T = vision("vision[${vision.hashCode()}]".toName(), vision)
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@ import hep.dataforge.context.Context
|
|||||||
import hep.dataforge.context.Global
|
import hep.dataforge.context.Global
|
||||||
import hep.dataforge.vision.client.VisionClient
|
import hep.dataforge.vision.client.VisionClient
|
||||||
import hep.dataforge.vision.client.renderAllVisions
|
import hep.dataforge.vision.client.renderAllVisions
|
||||||
|
import hep.dataforge.vision.client.renderAllVisionsAt
|
||||||
|
import kotlinx.browser.document
|
||||||
import kotlinx.browser.window
|
import kotlinx.browser.window
|
||||||
|
|
||||||
public actual val VisionForge: Context = Global.context("VisionForge").apply {
|
public actual val VisionForge: Context = Global.context("VisionForge").apply {
|
||||||
@ -11,6 +13,7 @@ public actual val VisionForge: Context = Global.context("VisionForge").apply{
|
|||||||
plugins.fetch(VisionClient)
|
plugins.fetch(VisionClient)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Render all visions in this [window] using current global state of [VisionForge]
|
* Render all visions in this [window] using current global state of [VisionForge]
|
||||||
*/
|
*/
|
||||||
@ -20,3 +23,13 @@ public fun renderVisionsInWindow(){
|
|||||||
VisionForge.plugins[VisionClient]?.renderAllVisions()
|
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 getRenderers() = context.gather<ElementVisionRenderer>(ElementVisionRenderer.TYPE).values
|
||||||
|
|
||||||
private fun findRendererFor(vision: Vision): ElementVisionRenderer? =
|
private fun findRendererFor(vision: Vision): ElementVisionRenderer? {
|
||||||
getRenderers().maxByOrNull { it.rateVision(vision) }
|
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
|
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.Files
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.nio.file.StandardOpenOption
|
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.
|
* The location of resources for plot.
|
||||||
@ -37,21 +41,29 @@ public enum class ResourceLocation {
|
|||||||
internal const val VISIONFORGE_ASSETS_PATH = ".dataforge/vision/assets"
|
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
|
* Check if the asset exists in given local location and put it there if it does not
|
||||||
* @param
|
* @param
|
||||||
*/
|
*/
|
||||||
|
@OptIn(ExperimentalPathApi::class)
|
||||||
internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path {
|
internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path {
|
||||||
|
//TODO add logging
|
||||||
val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource)
|
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 bytes = VisionManager::class.java.getResourceAsStream("/$resource").readAllBytes()
|
||||||
|
val md = MessageDigest.getInstance("MD5")
|
||||||
|
|
||||||
|
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.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)) {
|
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
||||||
|
@ -1,38 +1,36 @@
|
|||||||
package hep.dataforge.vision.gdml
|
package hep.dataforge.vision.gdml
|
||||||
|
|
||||||
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vision.solid.SolidManager
|
import hep.dataforge.vision.solid.SolidManager
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
import nl.adaptivity.xmlutil.StAXReader
|
|
||||||
import org.junit.jupiter.api.Test
|
import org.junit.jupiter.api.Test
|
||||||
|
import space.kscience.gdml.decodeFromStream
|
||||||
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
class TestConvertor {
|
class TestConvertor {
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testBMNGeometry() {
|
fun testBMNGeometry() {
|
||||||
val stream = javaClass.getResourceAsStream("/gdml/BM@N.gdml")
|
val stream = javaClass.getResourceAsStream("/gdml/BM@N.gdml")
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val gdml = Gdml.decodeFromStream(stream)
|
||||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
val vision = gdml.toVision()
|
||||||
val vision = xml.toVision()
|
//println(SolidManager.encodeToString(vision))
|
||||||
println(SolidManager.encodeToString(vision))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCubes() {
|
fun testCubes() {
|
||||||
val stream = javaClass.getResourceAsStream("/gdml/cubes.gdml")
|
val stream = javaClass.getResourceAsStream("/gdml/cubes.gdml")
|
||||||
|
val gdml = Gdml.decodeFromStream(stream)
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val vision = gdml.toVision()
|
||||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
assertNotNull(vision.getPrototype("solids.box".toName()))
|
||||||
val visual = xml.toVision()
|
//println(SolidManager.encodeToString(vision))
|
||||||
// println(visual)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testSimple() {
|
fun testSimple() {
|
||||||
val stream = javaClass.getResourceAsStream("/gdml/simple1.gdml")
|
val stream = javaClass.getResourceAsStream("/gdml/simple1.gdml")
|
||||||
|
val gdml = Gdml.decodeFromStream(stream)
|
||||||
val xmlReader = StAXReader(stream, "UTF-8")
|
val vision = gdml.toVision()
|
||||||
val xml = Gdml.format.parse(Gdml.serializer(), xmlReader)
|
//println(SolidManager.encodeToString(vision))
|
||||||
val vision = xml.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.context.*
|
||||||
import hep.dataforge.meta.Meta
|
import hep.dataforge.meta.Meta
|
||||||
|
import hep.dataforge.names.Name
|
||||||
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.vision.Vision
|
import hep.dataforge.vision.Vision
|
||||||
import hep.dataforge.vision.VisionForge
|
import hep.dataforge.vision.VisionForge
|
||||||
import hep.dataforge.vision.VisionPlugin
|
import hep.dataforge.vision.VisionPlugin
|
||||||
@ -26,11 +28,18 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun render(element: Element, vision: Vision, meta: Meta) {
|
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)
|
val config = PlotlyConfig.read(meta)
|
||||||
element.plot(plot, config)
|
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> {
|
public companion object : PluginFactory<PlotlyPlugin> {
|
||||||
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
|
||||||
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
|
override val type: KClass<PlotlyPlugin> = PlotlyPlugin::class
|
||||||
|
@ -35,27 +35,6 @@ public class Box(
|
|||||||
geometryBuilder.face4(node8, node5, node6, node7)
|
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 {
|
public companion object {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -28,9 +28,13 @@ public interface PrototypeHolder {
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("group.solid")
|
@SerialName("group.solid")
|
||||||
public class SolidGroup(
|
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 {
|
) : VisionGroupBase(), Solid, PrototypeHolder {
|
||||||
|
|
||||||
|
init {
|
||||||
|
prototypes?.parent = this
|
||||||
|
}
|
||||||
|
|
||||||
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
override val descriptor: NodeDescriptor get() = Solid.descriptor
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -23,6 +23,6 @@ class SolidPluginTest {
|
|||||||
|
|
||||||
val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup
|
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.get
|
||||||
import hep.dataforge.vision.style
|
import hep.dataforge.vision.style
|
||||||
import hep.dataforge.vision.useStyle
|
import hep.dataforge.vision.useStyle
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.encodeToJsonElement
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -22,4 +24,11 @@ class SolidReferenceTest {
|
|||||||
fun testReferenceProperty(){
|
fun testReferenceProperty(){
|
||||||
assertEquals("blue", (groupWithReference["test"] as Solid).color.string)
|
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 {
|
override fun rateVision(vision: Vision): Int =
|
||||||
return if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING else ElementVisionRenderer.ZERO_RATING
|
||||||
}
|
|
||||||
|
|
||||||
public fun renderSolid(
|
public fun renderSolid(
|
||||||
element: Element,
|
element: Element,
|
||||||
@ -141,7 +140,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
override fun render(element: Element, vision: Vision, meta: Meta) {
|
override fun render(element: Element, vision: Vision, meta: Meta) {
|
||||||
renderSolid(
|
renderSolid(
|
||||||
element,
|
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)
|
Canvas3DOptions.read(meta)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -157,7 +156,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
|
* Ensure that [ThreePlugin] is loaded in the global [VisionForge] context
|
||||||
*/
|
*/
|
||||||
@JsExport
|
@JsExport
|
||||||
public fun loadThreeJs() {
|
public fun withThreeJs() {
|
||||||
VisionForge.plugins.fetch(ThreePlugin)
|
VisionForge.plugins.fetch(ThreePlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package hep.dataforge.vision.three.server
|
package hep.dataforge.vision.three.server
|
||||||
|
|
||||||
import hep.dataforge.vision.renderVisionsInWindow
|
import hep.dataforge.vision.renderVisionsInWindow
|
||||||
import hep.dataforge.vision.solid.three.loadThreeJs
|
import hep.dataforge.vision.solid.three.withThreeJs
|
||||||
|
|
||||||
public fun main() {
|
public fun main() {
|
||||||
loadThreeJs()
|
withThreeJs()
|
||||||
renderVisionsInWindow()
|
renderVisionsInWindow()
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user