forked from kscience/visionforge
Finalizing GDML
This commit is contained in:
parent
effa19a95e
commit
687393c243
@ -39,6 +39,9 @@ class DisplayObjectDelegateWrapper<T>(
|
||||
val write: Config.(name: Name, value: T) -> Unit = { name, value -> set(name, value) },
|
||||
val read: (MetaItem<*>?) -> T?
|
||||
) : ReadWriteProperty<VisualObject, T> {
|
||||
|
||||
//private var cachedName: Name? = null
|
||||
|
||||
override fun getValue(thisRef: VisualObject, property: KProperty<*>): T {
|
||||
val name = key ?: property.name.toName()
|
||||
return if (inherited) {
|
||||
|
@ -0,0 +1,64 @@
|
||||
package hep.dataforge.vis.hmr
|
||||
|
||||
import kotlin.browser.document
|
||||
import kotlin.dom.hasClass
|
||||
|
||||
external val module: Module
|
||||
|
||||
external interface Module {
|
||||
val hot: Hot?
|
||||
}
|
||||
|
||||
external interface Hot {
|
||||
val data: dynamic
|
||||
|
||||
fun accept()
|
||||
fun accept(dependency: String, callback: () -> Unit)
|
||||
fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit)
|
||||
|
||||
fun dispose(callback: (data: dynamic) -> Unit)
|
||||
}
|
||||
|
||||
external fun require(name: String): dynamic
|
||||
|
||||
abstract class ApplicationBase {
|
||||
open val stateKeys: List<String> get() = emptyList()
|
||||
|
||||
abstract fun start(state: Map<String, Any>)
|
||||
open fun dispose(): Map<String, Any> = emptyMap()
|
||||
}
|
||||
|
||||
fun startApplication(builder: () -> ApplicationBase) {
|
||||
fun start(state: dynamic): ApplicationBase? {
|
||||
return if (document.body?.hasClass("testApp") == true) {
|
||||
val application = builder()
|
||||
|
||||
@Suppress("UnsafeCastFromDynamic")
|
||||
application.start(state?.appState ?: emptyMap())
|
||||
|
||||
application
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
var application: ApplicationBase? = null
|
||||
|
||||
val state: dynamic = module.hot?.let { hot ->
|
||||
hot.accept()
|
||||
|
||||
hot.dispose { data ->
|
||||
data.appState = application?.dispose()
|
||||
application = null
|
||||
}
|
||||
|
||||
hot.data
|
||||
}
|
||||
|
||||
if (document.body != null) {
|
||||
application = start(state)
|
||||
} else {
|
||||
application = null
|
||||
document.addEventListener("DOMContentLoaded", { application = start(state) })
|
||||
}
|
||||
}
|
@ -6,7 +6,7 @@
|
||||
<title>Three js demo for particle physics</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<script type="text/javascript" src="main.bundle.js"></script>
|
||||
<script type="text/javascript" src="dataforge-vis-spatial-gdml-0.1.0-dev.js"></script>
|
||||
</head>
|
||||
<body class="testApp">
|
||||
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
|
||||
|
@ -7,7 +7,12 @@ kotlin {
|
||||
val commonMain by getting {
|
||||
dependencies {
|
||||
api(project(":dataforge-vis-spatial"))
|
||||
api("scientifik:gdml:0.1.2")
|
||||
api("scientifik:gdml:0.1.3")
|
||||
}
|
||||
}
|
||||
val jsMain by getting{
|
||||
dependencies{
|
||||
api(project(":dataforge-vis-spatial-js"))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ private fun VisualGroup.addSolid(root: GDML, solid: GDMLSolid, block: VisualObje
|
||||
solid.resolveFirstPosition(root)?.let { applyPosition(it) }
|
||||
solid.resolveFirstRotation(root)?.let { applyRotation(it) }
|
||||
}
|
||||
addSolid(root, second) {}
|
||||
addSolid(root, second)
|
||||
solid.resolvePosition(root)?.let { applyPosition(it) }
|
||||
solid.resolveRotation(root)?.let { applyRotation(it) }
|
||||
}
|
||||
@ -96,22 +96,24 @@ private fun VisualGroup.addSolid(root: GDML, solid: GDMLSolid, block: VisualObje
|
||||
|
||||
private fun VisualGroup.addVolume(
|
||||
root: GDML,
|
||||
gdmlVolume: GDMLVolume,
|
||||
group: GDMLGroup,
|
||||
resolveColor: GDMLMaterial.() -> Meta
|
||||
): VisualGroup {
|
||||
val solid =
|
||||
gdmlVolume.solidref.resolve(root)
|
||||
?: error("Solid with tag ${gdmlVolume.solidref.ref} for volume ${gdmlVolume.name} not defined")
|
||||
val material =
|
||||
gdmlVolume.materialref.resolve(root)
|
||||
?: error("Material with tag ${gdmlVolume.materialref.ref} for volume ${gdmlVolume.name} not defined")
|
||||
if (group is GDMLVolume) {
|
||||
val solid = group.solidref.resolve(root)
|
||||
?: error("Solid with tag ${group.solidref.ref} for volume ${group.name} not defined")
|
||||
val material = group.materialref.resolve(root)
|
||||
?: error("Material with tag ${group.materialref.ref} for volume ${group.name} not defined")
|
||||
|
||||
addSolid(root, solid) {
|
||||
color(material.resolveColor())
|
||||
}
|
||||
//TODO render placements
|
||||
}
|
||||
|
||||
gdmlVolume.physVolumes.forEach {
|
||||
val volume = it.volumeref.resolve(root) ?: error("Volume with ref ${it.volumeref.ref} could not be resolved")
|
||||
group.physVolumes.forEach {
|
||||
val volume: GDMLGroup =
|
||||
it.volumeref.resolve(root) ?: error("Volume with ref ${it.volumeref.ref} could not be resolved")
|
||||
addVolume(root, volume, resolveColor).apply {
|
||||
it.resolvePosition(root)?.let { pos -> applyPosition(pos) }
|
||||
it.resolveRotation(root)?.let { rot -> applyRotation(rot) }
|
||||
|
@ -0,0 +1,82 @@
|
||||
package hep.dataforge.vis.spatial.gdml.demo
|
||||
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.vis.hmr.ApplicationBase
|
||||
import hep.dataforge.vis.hmr.startApplication
|
||||
import hep.dataforge.vis.spatial.gdml.toVisual
|
||||
import hep.dataforge.vis.spatial.three.ThreePlugin
|
||||
import hep.dataforge.vis.spatial.three.output
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.launch
|
||||
import org.w3c.dom.HTMLDivElement
|
||||
import org.w3c.dom.events.Event
|
||||
import org.w3c.files.FileList
|
||||
import org.w3c.files.FileReader
|
||||
import org.w3c.files.get
|
||||
import scientifik.gdml.GDML
|
||||
import kotlin.browser.document
|
||||
import kotlin.dom.clear
|
||||
|
||||
class GDMLDemoApp : ApplicationBase() {
|
||||
|
||||
|
||||
/**
|
||||
* Handle mouse drag according to https://www.html5rocks.com/en/tutorials/file/dndfiles/
|
||||
*/
|
||||
private fun handleDragOver(event: Event) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
event.asDynamic().dataTransfer.dropEffect = "copy"
|
||||
}
|
||||
|
||||
/**
|
||||
* Load data from text file
|
||||
*/
|
||||
private fun loadData(event: Event, block: suspend (String) -> Unit) {
|
||||
event.stopPropagation()
|
||||
event.preventDefault()
|
||||
|
||||
|
||||
val file = (event.asDynamic().dataTransfer.files as FileList)[0]
|
||||
?: throw RuntimeException("Failed to load file")
|
||||
|
||||
FileReader().apply {
|
||||
onload = {
|
||||
val string = result as String
|
||||
GlobalScope.launch {
|
||||
block(string)
|
||||
}
|
||||
}
|
||||
readAsText(file)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
override fun start(state: Map<String, Any>) {
|
||||
|
||||
val context = Global.context("demo") {}
|
||||
val three = context.plugins.load(ThreePlugin)
|
||||
val canvas = document.getElementById("canvas") ?: error("Element with id canvas not found on page")
|
||||
canvas.clear()
|
||||
val output = three.output(canvas)
|
||||
//val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO")
|
||||
|
||||
|
||||
val action: suspend (String) -> Unit = {
|
||||
val gdml = GDML.format.parse(GDML.serializer(), it)
|
||||
val visual = gdml.toVisual()
|
||||
output.render(visual)
|
||||
}
|
||||
|
||||
(document.getElementById("drop_zone") as? HTMLDivElement)?.apply {
|
||||
addEventListener("dragover", { handleDragOver(it) }, false)
|
||||
addEventListener("drop", { loadData(it, action) }, false)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
fun main() {
|
||||
startApplication(::GDMLDemoApp)
|
||||
}
|
33
dataforge-vis-spatial-gdml/src/jsMain/web/index.html
Normal file
33
dataforge-vis-spatial-gdml/src/jsMain/web/index.html
Normal file
@ -0,0 +1,33 @@
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
|
||||
<title>Three js demo for particle physics</title>
|
||||
<link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css"
|
||||
integrity="sha384-ggOyR0iXCbMQv3Xipma34MD+dH/1fQ784/j6cY/iJTQUOhcWr7x9JvoRxT2MZw1T" crossorigin="anonymous">
|
||||
<script type="text/javascript" src="main.bundle.js"></script>
|
||||
</head>
|
||||
<body class="testApp">
|
||||
<div class="container" id="drop_zone" data-toggle="tooltip" data-placement="right"
|
||||
title="Для загрузки данных в текстовом формате, надо перетащить файл сюда">
|
||||
Загрузить данные
|
||||
<br/>
|
||||
(перетащить файл сюда)
|
||||
</div>
|
||||
<div class="container">
|
||||
<h1>GDML demo</h1>
|
||||
</div>
|
||||
<div class="container" id="canvas"></div>
|
||||
|
||||
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"
|
||||
integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"
|
||||
integrity="sha384-UO2eT0CpHqdSJQ6hJty5KVphtPhzWj9WO1clHTMGa3JDZwrnQq4sF86dIHNDz0W1"
|
||||
crossorigin="anonymous"></script>
|
||||
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"
|
||||
integrity="sha384-JjSmVgyd0p3pXB1rRibZUAYoIIy6OrQ6VrjIEaFf/nJGzIxFDsf4x0xIM+B07jRM"
|
||||
crossorigin="anonymous"></script>
|
||||
</body>
|
||||
</html>
|
@ -0,0 +1,28 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import nl.adaptivity.xmlutil.StAXReader
|
||||
import org.junit.Test
|
||||
import scientifik.gdml.GDML
|
||||
import java.io.File
|
||||
import java.net.URL
|
||||
|
||||
class BMNTest {
|
||||
|
||||
@Test
|
||||
fun testRead() {
|
||||
|
||||
val url = URL("https://drive.google.com/open?id=1w5e7fILMN83JGgB8WANJUYm8OW2s0WVO")
|
||||
val file = File("D:\\Work\\Projects\\gdml.kt\\src\\commonTest\\resources\\gdml\\geofile_full.xml")
|
||||
val stream = if(file.exists()){
|
||||
file.inputStream()
|
||||
} else {
|
||||
url.openStream()
|
||||
}
|
||||
|
||||
val xmlReader = StAXReader(stream, "UTF-8")
|
||||
val xml = GDML.format.parse(GDML.serializer(), xmlReader)
|
||||
repeat(5) {
|
||||
xml.toVisual()
|
||||
}
|
||||
}
|
||||
}
|
@ -1,69 +1,21 @@
|
||||
plugins {
|
||||
id("scientifik.js")
|
||||
id("kotlin-dce-js")
|
||||
//id("kotlin-dce-js")
|
||||
}
|
||||
|
||||
//val kotlinVersion: String by rootProject.extra
|
||||
|
||||
dependencies {
|
||||
api(project(":dataforge-vis-spatial"))
|
||||
api(project(":dataforge-vis-spatial-gdml"))
|
||||
api("info.laht.threekt:threejs-wrapper:0.106-npm-2")
|
||||
api("info.laht.threekt:threejs-wrapper:0.106-npm-3")
|
||||
testCompile(kotlin("test-js"))
|
||||
}
|
||||
|
||||
kotlin{
|
||||
sourceSets["main"].dependencies{
|
||||
api(npm("three","0.106.2"))
|
||||
implementation(npm("three","0.106.2"))
|
||||
implementation(npm("@hi-level/three-csg"))
|
||||
implementation(npm("style-loader"))
|
||||
implementation(npm("element-resize-event"))
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//configure<KotlinFrontendExtension> {
|
||||
// downloadNodeJsVersion = "latest"
|
||||
//
|
||||
// configure<NpmExtension> {
|
||||
// dependency("three","0.106.2")
|
||||
// dependency("@hi-level/three-csg")
|
||||
// dependency("style-loader")
|
||||
// dependency("element-resize-event")
|
||||
// devDependency("karma")
|
||||
// }
|
||||
//
|
||||
// sourceMaps = true
|
||||
//
|
||||
// bundle<WebPackExtension>("webpack") {
|
||||
// this as WebPackExtension
|
||||
// bundleName = "main"
|
||||
// contentPath = file("src/main/web")
|
||||
// sourceMapEnabled = true
|
||||
// //mode = "production"
|
||||
// mode = "development"
|
||||
// }
|
||||
//}
|
||||
//
|
||||
//tasks {
|
||||
// "compileKotlin2Js"(Kotlin2JsCompile::class) {
|
||||
// kotlinOptions {
|
||||
// metaInfo = true
|
||||
// outputFile = "${project.buildDir.path}/js/${project.name}.js"
|
||||
// sourceMap = true
|
||||
// moduleKind = "commonjs"
|
||||
// main = "call"
|
||||
// kotlinOptions.sourceMapEmbedSources = "always"
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// "compileTestKotlin2Js"(Kotlin2JsCompile::class) {
|
||||
// kotlinOptions {
|
||||
// metaInfo = true
|
||||
// outputFile = "${project.buildDir.path}/js/${project.name}-test.js"
|
||||
// sourceMap = true
|
||||
// moduleKind = "commonjs"
|
||||
// kotlinOptions.sourceMapEmbedSources = "always"
|
||||
// }
|
||||
// }
|
||||
//}
|
@ -1,19 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.demo
|
||||
|
||||
external val module: Module
|
||||
|
||||
external interface Module {
|
||||
val hot: Hot?
|
||||
}
|
||||
|
||||
external interface Hot {
|
||||
val data: dynamic
|
||||
|
||||
fun accept()
|
||||
fun accept(dependency: String, callback: () -> Unit)
|
||||
fun accept(dependencies: Array<String>, callback: (updated: Array<String>) -> Unit)
|
||||
|
||||
fun dispose(callback: (data: dynamic) -> Unit)
|
||||
}
|
||||
|
||||
external fun require(name: String): dynamic
|
@ -4,6 +4,8 @@ import hep.dataforge.context.ContextBuilder
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.color
|
||||
import hep.dataforge.vis.hmr.ApplicationBase
|
||||
import hep.dataforge.vis.hmr.startApplication
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -136,3 +138,7 @@ class ThreeDemoApp : ApplicationBase() {
|
||||
|
||||
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
|
||||
}
|
||||
|
||||
fun main() {
|
||||
startApplication(::ThreeDemoApp)
|
||||
}
|
@ -50,7 +50,7 @@ class ThreeDemoGrid(meta: Meta) : AbstractPlugin(meta), OutputManager {
|
||||
|
||||
return outputs.getOrPut(name) {
|
||||
if (type != VisualObject::class) error("Supports only DisplayObject")
|
||||
val output = three.output(meta) {
|
||||
val output = three.output(meta = meta) {
|
||||
"axis" to {
|
||||
"size" to 500
|
||||
}
|
||||
|
@ -1,48 +0,0 @@
|
||||
package hep.dataforge.vis.spatial.demo
|
||||
|
||||
import kotlin.browser.document
|
||||
import kotlin.dom.hasClass
|
||||
|
||||
|
||||
abstract class ApplicationBase {
|
||||
abstract val stateKeys: List<String>
|
||||
|
||||
abstract fun start(state: Map<String, Any>)
|
||||
abstract fun dispose(): Map<String, Any>
|
||||
}
|
||||
|
||||
|
||||
fun main() {
|
||||
var application: ApplicationBase? = null
|
||||
|
||||
val state: dynamic = module.hot?.let { hot ->
|
||||
hot.accept()
|
||||
|
||||
hot.dispose { data ->
|
||||
data.appState = application?.dispose()
|
||||
application = null
|
||||
}
|
||||
|
||||
hot.data
|
||||
}
|
||||
|
||||
if (document.body != null) {
|
||||
application = start(state)
|
||||
} else {
|
||||
application = null
|
||||
document.addEventListener("DOMContentLoaded", { application = start(state) })
|
||||
}
|
||||
}
|
||||
|
||||
fun start(state: dynamic): ApplicationBase? {
|
||||
return if (document.body?.hasClass("testApp") == true) {
|
||||
val application = ThreeDemoApp()
|
||||
|
||||
@Suppress("UnsafeCastFromDynamic")
|
||||
application.start(state?.appState ?: emptyMap<String, Any>())
|
||||
|
||||
application
|
||||
} else {
|
||||
null
|
||||
}
|
||||
}
|
@ -0,0 +1,32 @@
|
||||
package hep.dataforge.vis.spatial.three
|
||||
|
||||
import hep.dataforge.vis.spatial.Cylinder
|
||||
import hep.dataforge.vis.spatial.detail
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.geometries.CylinderBufferGeometry
|
||||
import kotlin.math.pow
|
||||
|
||||
object ThreeCylinderFactory : MeshThreeFactory<Cylinder>(Cylinder::class) {
|
||||
override fun buildGeometry(obj: Cylinder): BufferGeometry {
|
||||
return obj.detail?.let {
|
||||
val segments = it.toDouble().pow(0.5).toInt()
|
||||
CylinderBufferGeometry(
|
||||
radiusTop = obj.upperRadius!!,
|
||||
radiusBottom = obj.radius!!,
|
||||
height = obj.height!!,
|
||||
radialSegments = segments,
|
||||
heightSegments = segments,
|
||||
openEnded = false,
|
||||
thetaStart = obj.startAngle,
|
||||
thetaLength = obj.angle
|
||||
)
|
||||
} ?: CylinderBufferGeometry(
|
||||
radiusTop = obj.upperRadius!!,
|
||||
radiusBottom = obj.radius!!,
|
||||
height = obj.height!!,
|
||||
openEnded = false,
|
||||
thetaStart = obj.startAngle,
|
||||
thetaLength = obj.angle
|
||||
)
|
||||
}
|
||||
}
|
@ -5,7 +5,7 @@ import hep.dataforge.meta.*
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.Colors
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.spatial.demo.require
|
||||
import hep.dataforge.vis.hmr.require
|
||||
import info.laht.threekt.WebGLRenderer
|
||||
import info.laht.threekt.helpers.AxesHelper
|
||||
import info.laht.threekt.lights.AmbientLight
|
||||
@ -39,7 +39,7 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<V
|
||||
setSize(width, height)
|
||||
}
|
||||
|
||||
three.addControls(camera,renderer.domElement, meta["controls"].node?:EmptyMeta)
|
||||
three.addControls(camera, renderer.domElement, meta["controls"].node ?: EmptyMeta)
|
||||
|
||||
fun animate() {
|
||||
window.requestAnimationFrame {
|
||||
@ -63,5 +63,9 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<V
|
||||
}
|
||||
}
|
||||
|
||||
fun ThreePlugin.output(meta: Meta = EmptyMeta, override: MetaBuilder.() -> Unit = {}) =
|
||||
ThreeOutput(this, buildMeta(meta, override))
|
||||
fun ThreePlugin.output(element: Element? = null, meta: Meta = EmptyMeta, override: MetaBuilder.() -> Unit = {}) =
|
||||
ThreeOutput(this, buildMeta(meta, override)).apply {
|
||||
if(element!=null){
|
||||
attach(element)
|
||||
}
|
||||
}
|
@ -28,6 +28,7 @@ class ThreePlugin : AbstractPlugin() {
|
||||
objectFactories[Box::class] = ThreeBoxFactory
|
||||
objectFactories[Convex::class] = ThreeConvexFactory
|
||||
objectFactories[Sphere::class] = ThreeSphereFactory
|
||||
objectFactories[Cylinder::class] = ThreeCylinderFactory
|
||||
}
|
||||
|
||||
private fun findObjectFactory(type: KClass<out VisualObject>): ThreeFactory<*>? {
|
||||
|
@ -25,7 +25,9 @@ fun VisualGroup.composite(type: CompositeType, builder: VisualGroup.() -> Unit):
|
||||
val group = VisualGroup().apply(builder)
|
||||
val children = group.toList()
|
||||
if (children.size != 2) error("Composite requires exactly two children")
|
||||
return Composite(this, children[0], children[1], type, group.properties.seal()).also { add(it) }
|
||||
return Composite(this, children[0], children[1], type, group.properties.seal()).also {
|
||||
this.add(it)
|
||||
}
|
||||
}
|
||||
|
||||
fun VisualGroup.union(builder: VisualGroup.() -> Unit) =
|
||||
|
@ -16,13 +16,13 @@ class Cylinder(parent: VisualObject?, meta: Meta) : DisplayLeaf(parent, meta) {
|
||||
var upperRadius by number(default = radius)
|
||||
var height by number()
|
||||
var startAngle by number(0.0)
|
||||
var angle by number(2* PI)
|
||||
var angle by number(2 * PI)
|
||||
}
|
||||
|
||||
fun VisualGroup.cylinder(r: Number, height: Number, meta: Meta = EmptyMeta, block: Cylinder.()->Unit = {}):Cylinder{
|
||||
val cylinder = Cylinder(this,meta)
|
||||
fun VisualGroup.cylinder(r: Number, height: Number, meta: Meta = EmptyMeta, block: Cylinder.() -> Unit = {}): Cylinder {
|
||||
val cylinder = Cylinder(this, meta)
|
||||
cylinder.radius = r
|
||||
cylinder.height = height
|
||||
cylinder.apply(block)
|
||||
return cylinder
|
||||
return cylinder.also { add(it) }
|
||||
}
|
@ -1,6 +1,7 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.VisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
@ -28,60 +29,71 @@ var VisualObject.visible
|
||||
|
||||
// 3D Object position
|
||||
|
||||
private val xPos = "pos.x".toName()
|
||||
/**
|
||||
* x position property relative to parent. Not inherited
|
||||
*/
|
||||
var VisualObject.x
|
||||
get() = properties["pos.x"].number ?: 0.0
|
||||
get() = properties[xPos].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.x"] = value
|
||||
properties[xPos] = value
|
||||
}
|
||||
|
||||
private val yPos = "pos.y".toName()
|
||||
|
||||
/**
|
||||
* y position property. Not inherited
|
||||
*/
|
||||
var VisualObject.y
|
||||
get() = properties["pos.y"].number ?: 0.0
|
||||
get() = properties[yPos].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.y"] = value
|
||||
properties[yPos] = value
|
||||
}
|
||||
|
||||
private val zPos = "pos.z".toName()
|
||||
|
||||
/**
|
||||
* z position property. Not inherited
|
||||
*/
|
||||
var VisualObject.z
|
||||
get() = properties["pos.z"].number ?: 0.0
|
||||
get() = properties[zPos].number ?: 0.0
|
||||
set(value) {
|
||||
properties["pos.z"] = value
|
||||
properties[zPos] = value
|
||||
}
|
||||
|
||||
// 3D Object rotation
|
||||
|
||||
private val xRotation = "rotation.x".toName()
|
||||
|
||||
/**
|
||||
* x rotation relative to parent. Not inherited
|
||||
*/
|
||||
var VisualObject.rotationX
|
||||
get() = properties["rotation.x"].number ?: 0.0
|
||||
get() = properties[xRotation].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.x"] = value
|
||||
properties[xRotation] = value
|
||||
}
|
||||
|
||||
private val yRotation = "rotation.y".toName()
|
||||
|
||||
/**
|
||||
* y rotation relative to parent. Not inherited
|
||||
*/
|
||||
var VisualObject.rotationY
|
||||
get() = properties["rotation.y"].number ?: 0.0
|
||||
get() = properties[yRotation].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.y"] = value
|
||||
properties[yRotation] = value
|
||||
}
|
||||
|
||||
private val zRotation = "rotation.z".toName()
|
||||
|
||||
/**
|
||||
* z rotation relative to parent. Not inherited
|
||||
*/
|
||||
var VisualObject.rotationZ
|
||||
get() = properties["rotation.z"].number ?: 0.0
|
||||
get() = properties[zRotation].number ?: 0.0
|
||||
set(value) {
|
||||
properties["rotation.z"] = value
|
||||
properties[zRotation] = value
|
||||
}
|
||||
|
||||
enum class RotationOrder {
|
||||
|
Loading…
Reference in New Issue
Block a user