Updated build and used new core version

This commit is contained in:
Alexander Nozik 2019-03-27 22:14:42 +03:00
parent d874c3cdd6
commit 9a7fcfe9c6
18 changed files with 367 additions and 117 deletions

View File

@ -1,4 +1,8 @@
import com.moowork.gradle.node.NodeExtension
import com.moowork.gradle.node.npm.NpmTask
import com.moowork.gradle.node.task.NodeTask
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.tasks.Kotlin2JsCompile
import org.jetbrains.kotlin.gradle.tasks.KotlinCompile import org.jetbrains.kotlin.gradle.tasks.KotlinCompile
buildscript { buildscript {
@ -9,7 +13,7 @@ buildscript {
val dokkaVersion: String by rootProject.extra("0.9.17") val dokkaVersion: String by rootProject.extra("0.9.17")
val serializationVersion: String by rootProject.extra("0.10.0") val serializationVersion: String by rootProject.extra("0.10.0")
val dataforgeVersion: String by rootProject.extra("0.1.2-dev-1") val dataforgeVersion: String by rootProject.extra("0.1.2-dev-2")
repositories { repositories {
jcenter() jcenter()
@ -28,6 +32,7 @@ buildscript {
plugins { plugins {
id("com.jfrog.artifactory") version "4.8.1" apply false id("com.jfrog.artifactory") version "4.8.1" apply false
id("com.moowork.node") version "1.3.1" apply false
// id("org.jetbrains.kotlin.multiplatform") apply false // id("org.jetbrains.kotlin.multiplatform") apply false
} }
@ -86,6 +91,7 @@ subprojects {
afterEvaluate { afterEvaluate {
extensions.findByType<KotlinMultiplatformExtension>()?.apply { extensions.findByType<KotlinMultiplatformExtension>()?.apply {
apply(plugin = "com.moowork.node")
jvm { jvm {
compilations.all { compilations.all {
kotlinOptions { kotlinOptions {
@ -113,6 +119,75 @@ subprojects {
} }
} }
} }
configure<NodeExtension>{
nodeModulesDir = file("$buildDir/node_modules")
}
val compileKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val compileTestKotlinJs by tasks.getting(Kotlin2JsCompile::class)
val populateNodeModules by tasks.registering(Copy::class) {
dependsOn(compileKotlinJs)
from(compileKotlinJs.destinationDir)
compilations["test"].runtimeDependencyFiles.forEach {
if (it.exists() && !it.isDirectory) {
from(zipTree(it.absolutePath).matching { include("*.js") })
}
}
into("$buildDir/node_modules")
}
val installMocha by tasks.registering(NpmTask::class) {
setWorkingDir(buildDir)
setArgs(listOf("install", "mocha"))
}
val runMocha by tasks.registering(NodeTask::class) {
dependsOn(compileTestKotlinJs, populateNodeModules, installMocha)
setScript(file("$buildDir/node_modules/mocha/bin/mocha"))
setArgs(listOf(compileTestKotlinJs.outputFile))
}
tasks["jsTest"].dependsOn(runMocha)
}
sourceSets {
val commonMain by getting {
dependencies {
api(kotlin("stdlib"))
}
}
val commonTest by getting {
dependencies {
implementation(kotlin("test-common"))
implementation(kotlin("test-annotations-common"))
}
}
val jvmMain by getting {
dependencies {
api(kotlin("stdlib-jdk8"))
}
}
val jvmTest by getting {
dependencies {
implementation(kotlin("test"))
implementation(kotlin("test-junit"))
}
}
val jsMain by getting {
dependencies {
api(kotlin("stdlib-js"))
}
}
val jsTest by getting {
dependencies {
implementation(kotlin("test-js"))
}
}
} }
targets.all { targets.all {

View File

@ -8,10 +8,12 @@ plugins {
id("org.jetbrains.kotlin.frontend") id("org.jetbrains.kotlin.frontend")
} }
val kotlinVersion: String by rootProject.extra
dependencies { dependencies {
api(project(":dataforge-vis-spatial")) api(project(":dataforge-vis-spatial"))
implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2") implementation("info.laht.threekt:threejs-wrapper:0.88-npm-2")
testCompile("org.jetbrains.kotlin:kotlin-test-js:$kotlinVersion")
} }
configure<KotlinFrontendExtension> { configure<KotlinFrontendExtension> {

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis package hep.dataforge.vis
import hep.dataforge.vis.spatial.ThreeDemoApp import hep.dataforge.vis.spatial.jsroot.JSRootDemoApp
import kotlin.browser.document import kotlin.browser.document
import kotlin.dom.hasClass import kotlin.dom.hasClass
@ -37,7 +37,7 @@ fun main() {
fun start(state: dynamic): ApplicationBase? { fun start(state: dynamic): ApplicationBase? {
return if (document.body?.hasClass("testApp") == true) { return if (document.body?.hasClass("testApp") == true) {
val application = ThreeDemoApp() val application = JSRootDemoApp()
@Suppress("UnsafeCastFromDynamic") @Suppress("UnsafeCastFromDynamic")
application.start(state?.appState ?: emptyMap()) application.start(state?.appState ?: emptyMap())

View File

@ -1,9 +1,7 @@
package hep.dataforge.vis.spatial package hep.dataforge.vis.spatial
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.context.members
import hep.dataforge.meta.number import hep.dataforge.meta.number
import hep.dataforge.meta.set
import hep.dataforge.vis.ApplicationBase import hep.dataforge.vis.ApplicationBase
import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayGroup
import hep.dataforge.vis.require import hep.dataforge.vis.require
@ -26,20 +24,10 @@ class ThreeDemoApp : ApplicationBase() {
//TODO remove after DI fix //TODO remove after DI fix
Global.plugins.load(ThreePlugin()) // Global.plugins.load(ThreePlugin())
Global.plugins.load(JSRootPlugin()) // Global.plugins.load(JSRootPlugin())
// Global.plugins.load(JSRootPlugin) Global.plugins.load(JSRootPlugin)
println(Global.plugins.count())
Global.plugins.forEach {
println(it)
}
Global.members<ThreeFactory<*>>(ThreeFactory.TYPE).forEach {
println(it)
}
val renderer = ThreeOutput(Global) val renderer = ThreeOutput(Global)
renderer.start(document.getElementById("canvas")!!) renderer.start(document.getElementById("canvas")!!)
@ -50,31 +38,37 @@ class ThreeDemoApp : ApplicationBase() {
renderer.render { renderer.render {
group = group { group = group {
box { box {
z = 110.0
xSize = 100.0 xSize = 100.0
ySize = 100.0 ySize = 100.0
zSize = 100.0 zSize = 100.0
} }
box { box {
visible = false
x = 110.0 x = 110.0
xSize = 100.0 xSize = 100.0
ySize = 100.0 ySize = 100.0
zSize = 100.0 zSize = 100.0
properties.style["color"] = 1530 color(1530)
GlobalScope.launch {
while (isActive) {
delay(500)
visible = !visible
}
}
} }
} }
// convex { convex {
// point(50, 50, -50) point(50,50,50)
// point(50, -50, -50) point(-50,-50,50)
// point(-50, -50, -50) point(-50,50,-50)
// point(-50, 50, -50) point(50,-50,-50)
// point(50, 50, 50) }
// point(50, -50, 50)
// point(-50, -50, 50)
// point(-50, 50, 50)
// }
jsRoot { jsRoot {
y = 110.0 y = 110.0
shape = box(50, 50, 50) shape = box(50, 50, 50)
color(12285)
} }
} }

View File

@ -8,7 +8,7 @@ import hep.dataforge.vis.onChange
import hep.dataforge.vis.spatial.ThreeFactory.Companion.TYPE import hep.dataforge.vis.spatial.ThreeFactory.Companion.TYPE
import hep.dataforge.vis.spatial.ThreeFactory.Companion.buildMesh import hep.dataforge.vis.spatial.ThreeFactory.Companion.buildMesh
import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh import hep.dataforge.vis.spatial.ThreeFactory.Companion.updateMesh
import hep.dataforge.vis.spatial.three.ConvexGeometry import hep.dataforge.vis.spatial.three.ConvexBufferGeometry
import hep.dataforge.vis.spatial.three.EdgesGeometry import hep.dataforge.vis.spatial.three.EdgesGeometry
import hep.dataforge.vis.spatial.three.euler import hep.dataforge.vis.spatial.three.euler
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
@ -77,6 +77,9 @@ abstract class MeshThreeFactory<T : DisplayObject>(override val type: KClass<out
override fun invoke(obj: T): Mesh { override fun invoke(obj: T): Mesh {
val geometry = buildGeometry(obj) val geometry = buildGeometry(obj)
@Suppress("USELESS_IS_CHECK") if (geometry !is BufferGeometry) error("BufferGeometry expected")
val mesh = buildMesh(obj, geometry) val mesh = buildMesh(obj, geometry)
ThreeFactory.updatePosition(obj, mesh) ThreeFactory.updatePosition(obj, mesh)
obj.onChange(this) { _, _, _ -> obj.onChange(this) { _, _, _ ->
@ -92,9 +95,11 @@ object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize) BoxBufferGeometry(obj.xSize, obj.ySize, obj.zSize)
} }
fun Point3D.asVector(): Vector3 = this.asDynamic() as Vector3 fun Point3D.asVector(): Vector3 = Vector3(this.x, this.y, this.z)
object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) { object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) {
override fun buildGeometry(obj: Convex) = override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
ConvexGeometry(obj.points.map { it.asVector() }.toTypedArray()) val vectors = obj.points.map { it.asVector() }.toTypedArray()
return ConvexBufferGeometry(vectors)
}
} }

View File

@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial
import hep.dataforge.context.Context import hep.dataforge.context.Context
import hep.dataforge.context.members import hep.dataforge.context.members
import hep.dataforge.meta.Meta import hep.dataforge.meta.*
import hep.dataforge.output.Output import hep.dataforge.output.Output
import hep.dataforge.vis.DisplayGroup import hep.dataforge.vis.DisplayGroup
import hep.dataforge.vis.DisplayObject import hep.dataforge.vis.DisplayObject
@ -18,7 +18,7 @@ import org.w3c.dom.Element
import kotlin.browser.window import kotlin.browser.window
import kotlin.reflect.KClass import kotlin.reflect.KClass
class ThreeOutput(override val context: Context) : Output<DisplayObject> { class ThreeOutput(override val context: Context, val meta: Meta = EmptyMeta) : Output<DisplayObject> {
private val renderer = WebGLRenderer { antialias = true }.apply { private val renderer = WebGLRenderer { antialias = true }.apply {
setClearColor(ColorConstants.skyblue, 1) setClearColor(ColorConstants.skyblue, 1)
@ -30,10 +30,10 @@ class ThreeOutput(override val context: Context) : Output<DisplayObject> {
} }
val camera = PerspectiveCamera( val camera = PerspectiveCamera(
75, meta["fov"].int ?: 75,
window.innerWidth.toDouble() / window.innerHeight, window.innerWidth.toDouble() / window.innerHeight,
World.CAMERA_NEAR_CLIP, meta["camera.nearClip"].double?: World.CAMERA_NEAR_CLIP,
World.CAMERA_FAR_CLIP meta["camera.farClip"].double?: World.CAMERA_FAR_CLIP
).apply { ).apply {
position.setZ(World.CAMERA_INITIAL_DISTANCE) position.setZ(World.CAMERA_INITIAL_DISTANCE)
rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE) rotation.set(World.CAMERA_INITIAL_X_ANGLE, World.CAMERA_INITIAL_Y_ANGLE, World.CAMERA_INITIAL_Z_ANGLE)
@ -70,7 +70,7 @@ class ThreeOutput(override val context: Context) : Output<DisplayObject> {
//is Box -> ThreeBoxFactory(obj) //is Box -> ThreeBoxFactory(obj)
//is JSRootObject -> ThreeJSRootFactory(obj) //is JSRootObject -> ThreeJSRootFactory(obj)
//is Convex -> ThreeConvexFactory(obj) //is Convex -> ThreeConvexFactory(obj)
else -> findFactory(obj::class)?.invoke(obj)?: error("Factory not found") else -> findFactory(obj::class)?.invoke(obj) ?: error("Factory not found")
} }
} }

View File

@ -33,6 +33,6 @@ class ThreePlugin : AbstractPlugin() {
companion object : PluginFactory<ThreePlugin> { companion object : PluginFactory<ThreePlugin> {
override val tag = PluginTag("vis.three", "hep.dataforge") override val tag = PluginTag("vis.three", "hep.dataforge")
override val type = ThreePlugin::class override val type = ThreePlugin::class
override fun build() = ThreePlugin() override fun invoke() = ThreePlugin()
} }
} }

View File

@ -0,0 +1,39 @@
package hep.dataforge.vis.spatial.jsroot
import hep.dataforge.context.Global
import hep.dataforge.vis.ApplicationBase
import hep.dataforge.vis.DisplayGroup
import hep.dataforge.vis.require
import hep.dataforge.vis.spatial.ThreeOutput
import hep.dataforge.vis.spatial.render
import kotlin.browser.document
class JSRootDemoApp : ApplicationBase() {
override val stateKeys: List<String> = emptyList()
override fun start(state: Map<String, Any>) {
require("JSRootGeoBase.js")
//TODO remove after DI fix
// Global.plugins.load(ThreePlugin())
// Global.plugins.load(JSRootPlugin())
Global.plugins.load(JSRootPlugin)
val renderer = ThreeOutput(Global)
renderer.start(document.getElementById("canvas")!!)
println("started")
lateinit var group: DisplayGroup
renderer.render {
jsRoot ("./geofile_full.json")
}
}
override fun dispose() = emptyMap<String, Any>()//mapOf("lines" to presenter.dispose())
}

View File

@ -4,5 +4,8 @@
package hep.dataforge.vis.spatial.jsroot package hep.dataforge.vis.spatial.jsroot
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D
external fun createGeometry(shape: dynamic, limit: Int): BufferGeometry external fun createGeometry(shape: dynamic, limit: Int): BufferGeometry
external fun build(obj: dynamic, opt: dynamic): Object3D

View File

@ -0,0 +1,82 @@
package hep.dataforge.vis.spatial.jsroot
import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.buildMeta
import hep.dataforge.meta.toDynamic
import hep.dataforge.vis.*
import hep.dataforge.vis.spatial.MeshThreeFactory
import info.laht.threekt.core.BufferGeometry
class JSRootGeometry(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) {
var shape by node()
var facesLimit by int(0)
fun box(xSize: Number, ySize: Number, zSize: Number) = buildMeta {
"_typename" to "TGeoBBox"
"fDX" to xSize
"fDY" to ySize
"fDZ" to zSize
}
/**
* Create a GDML union
*/
operator fun Meta.plus(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoUnion"
}
/**
* Create a GDML subtraction
*/
operator fun Meta.minus(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoSubtraction"
}
/**
* Intersect two GDML geometries
*/
infix fun Meta.intersect(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoIntersection"
}
companion object {
const val TYPE = "geometry.spatial.jsRoot.geometry"
}
}
fun DisplayGroup.jsRoot(meta: Meta = EmptyMeta, action: JSRootGeometry.() -> Unit = {}) =
JSRootGeometry(this, meta).apply(action).also { addChild(it) }
//fun Meta.toDynamic(): dynamic {
// fun MetaItem<*>.toDynamic(): dynamic = when (this) {
// is MetaItem.ValueItem -> this.value.value.asDynamic()
// is MetaItem.NodeItem -> this.node.toDynamic()
// }
//
// val res = js("{}")
// this.items.entries.groupBy { it.key.body }.forEach { (key, value) ->
// val list = value.map { it.value }
// res[key] = when (list.size) {
// 1 -> list.first().toDynamic()
// else -> list.map { it.toDynamic() }
// }
// }
// return res
//}
object ThreeJSRootFactory : MeshThreeFactory<JSRootGeometry>(JSRootGeometry::class) {
override fun buildGeometry(obj: JSRootGeometry): BufferGeometry {
val shapeMeta = obj.shape?.toDynamic() ?: error("The shape not defined")
return createGeometry(shapeMeta, obj.facesLimit)
}
}

View File

@ -1,84 +1,37 @@
package hep.dataforge.vis.spatial.jsroot package hep.dataforge.vis.spatial.jsroot
import hep.dataforge.meta.DynamicMeta
import hep.dataforge.meta.EmptyMeta import hep.dataforge.meta.EmptyMeta
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaItem import hep.dataforge.meta.toDynamic
import hep.dataforge.meta.buildMeta import hep.dataforge.vis.DisplayGroup
import hep.dataforge.vis.* import hep.dataforge.vis.DisplayLeaf
import hep.dataforge.vis.spatial.MeshThreeFactory import hep.dataforge.vis.DisplayObject
import info.laht.threekt.core.BufferGeometry import hep.dataforge.vis.node
import hep.dataforge.vis.spatial.ThreeFactory
import info.laht.threekt.core.Object3D
class JSRootObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) { class JSRootObject(parent: DisplayObject?, meta: Meta) : DisplayLeaf(parent, TYPE, meta) {
var shape by node() var data by node()
var options by node()
var color by item()
var facesLimit by int(0)
fun box(xSize: Number, ySize: Number, zSize: Number) = buildMeta {
"_typename" to "TGeoBBox"
"fDX" to xSize
"fDY" to ySize
"fDZ" to zSize
}
/**
* Create a GDML union
*/
operator fun Meta.plus(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoUnion"
}
/**
* Create a GDML subtraction
*/
operator fun Meta.minus(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoSubtraction"
}
/**
* Intersect two GDML geometries
*/
infix fun Meta.intersect(other: Meta) = buildMeta {
"fNode.fLeft" to this
"fNode.fRight" to other
"fNode._typename" to "TGeoIntersection"
}
companion object { companion object {
const val TYPE = "geometry.spatial.jsRoot" const val TYPE = "geometry.spatial.jsRoot.object"
} }
} }
fun DisplayGroup.jsRoot(meta: Meta = EmptyMeta, action: JSRootObject.() -> Unit = {}) = object JSRootObjectFactory : ThreeFactory<JSRootObject> {
JSRootObject(this, meta).apply(action).also { addChild(it) }
fun Meta.toDynamic(): dynamic { override val type = JSRootObject::class
fun MetaItem<*>.toDynamic(): dynamic = when (this) {
is MetaItem.ValueItem -> this.value.value.asDynamic()
is MetaItem.NodeItem -> this.node.toDynamic()
}
val res = js("{}") override fun invoke(obj: JSRootObject): Object3D {
this.items.entries.groupBy { it.key.body }.forEach { (key, value) -> return build(obj.data?.toDynamic(), obj.options?.toDynamic())
val list = value.map { it.value }
res[key] = when (list.size) {
1 -> list.first().toDynamic()
else -> list.map { it.toDynamic() }
}
}
return res
}
object ThreeJSRootFactory : MeshThreeFactory<JSRootObject>(JSRootObject::class) {
override fun buildGeometry(obj: JSRootObject): BufferGeometry {
val shapeMeta = obj.shape?.toDynamic() ?: error("The shape not defined")
return createGeometry(shapeMeta, obj.facesLimit)
} }
} }
fun DisplayGroup.jsRoot(path: String) {
JSRootObject(this, EmptyMeta).apply{
data = DynamicMeta(hep.dataforge.vis.require(path))
}.also { addChild(it) }
}

View File

@ -20,6 +20,6 @@ class JSRootPlugin : AbstractPlugin() {
companion object: PluginFactory<JSRootPlugin> { companion object: PluginFactory<JSRootPlugin> {
override val tag = PluginTag("vis.jsroot", "hep.dataforge") override val tag = PluginTag("vis.jsroot", "hep.dataforge")
override val type = JSRootPlugin::class override val type = JSRootPlugin::class
override fun build() = JSRootPlugin() override fun invoke() = JSRootPlugin()
} }
} }

View File

@ -3,6 +3,9 @@
package hep.dataforge.vis.spatial.three package hep.dataforge.vis.spatial.three
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Geometry
import info.laht.threekt.math.Vector3 import info.laht.threekt.math.Vector3
external class ConvexGeometry(points: Array<Vector3>) : BufferGeometry external class ConvexGeometry(points: Array<Vector3>) : Geometry
external class ConvexBufferGeometry(points: Array<Vector3>) : BufferGeometry

View File

@ -9,6 +9,8 @@ import hep.dataforge.vis.spatial.rotationOrder
import hep.dataforge.vis.spatial.rotationX import hep.dataforge.vis.spatial.rotationX
import hep.dataforge.vis.spatial.rotationY import hep.dataforge.vis.spatial.rotationY
import hep.dataforge.vis.spatial.rotationZ import hep.dataforge.vis.spatial.rotationZ
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Geometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.math.Euler import info.laht.threekt.math.Euler
import info.laht.threekt.math.Vector3 import info.laht.threekt.math.Vector3
@ -26,3 +28,5 @@ fun Group(children: Collection<Object3D>) = info.laht.threekt.objects.Group().ap
val DisplayObject.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name) val DisplayObject.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f) val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) }

View File

@ -3398,7 +3398,7 @@
process(toplevel, 0, 1, 1000000); process(toplevel, 0, 1, 1000000);
}; };
GEO.build = function (obj, opt, call_back) { GEO.build = function (obj, opt) {
// function can be used to build three.js model for TGeo object // function can be used to build three.js model for TGeo object
if (!obj) return; if (!obj) return;
@ -3510,7 +3510,7 @@
// mesh.renderOrder = clones.maxdepth - entry.stack.length; // mesh.renderOrder = clones.maxdepth - entry.stack.length;
} }
JSROOT.CallBack(call_back, toplevel); //JSROOT.CallBack(call_back, toplevel);
return toplevel; return toplevel;
}; };

View File

@ -32,10 +32,12 @@ class ConvexBuilder {
} }
fun build(parent: DisplayObject?, meta: Meta): Convex { fun build(parent: DisplayObject?, meta: Meta): Convex {
val builder = meta.builder() val points = buildMeta {
points.forEachIndexed { index, value -> points.forEachIndexed { index, value ->
builder["points.point[$index]"] = value.toMeta() "points.point[$index]" to value.toMeta()
} }
return Convex(parent, builder.seal()) }.seal()
return Convex(parent, points)
} }
} }

View File

@ -6,6 +6,7 @@ import hep.dataforge.vis.DisplayGroup
import hep.dataforge.vis.DisplayNode import hep.dataforge.vis.DisplayNode
import hep.dataforge.vis.DisplayObject import hep.dataforge.vis.DisplayObject
import hep.dataforge.vis.DisplayObject.Companion.DEFAULT_TYPE import hep.dataforge.vis.DisplayObject.Companion.DEFAULT_TYPE
import hep.dataforge.vis.get
fun DisplayGroup.group(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit = {}) = fun DisplayGroup.group(meta: Meta = EmptyMeta, action: DisplayGroup.() -> Unit = {}) =
DisplayNode(this, DEFAULT_TYPE, meta).apply(action).also { addChild(it) } DisplayNode(this, DEFAULT_TYPE, meta).apply(action).also { addChild(it) }
@ -18,26 +19,38 @@ fun Output<DisplayObject>.render(meta: Meta = EmptyMeta, action: DisplayGroup.()
// Common properties // Common properties
/**
* Visibility property. Inherited from parent
*/
var DisplayObject.visible var DisplayObject.visible
get() = properties["visible"].boolean ?: true get() = this["visible"].boolean ?: true
set(value) { set(value) {
properties.style["visible"] = value properties.style["visible"] = value
} }
// 3D Object position // 3D Object position
/**
* x position property relative to parent. Not inherited
*/
var DisplayObject.x var DisplayObject.x
get() = properties["pos.x"].number ?: 0.0 get() = properties["pos.x"].number ?: 0.0
set(value) { set(value) {
properties.style["pos.x"] = value properties.style["pos.x"] = value
} }
/**
* y position property. Not inherited
*/
var DisplayObject.y var DisplayObject.y
get() = properties["pos.y"].number ?: 0.0 get() = properties["pos.y"].number ?: 0.0
set(value) { set(value) {
properties.style["pos.y"] = value properties.style["pos.y"] = value
} }
/**
* z position property. Not inherited
*/
var DisplayObject.z var DisplayObject.z
get() = properties["pos.z"].number ?: 0.0 get() = properties["pos.z"].number ?: 0.0
set(value) { set(value) {
@ -46,18 +59,27 @@ var DisplayObject.z
// 3D Object rotation // 3D Object rotation
/**
* x rotation relative to parent. Not inherited
*/
var DisplayObject.rotationX var DisplayObject.rotationX
get() = properties["rotation.x"].number ?: 0.0 get() = properties["rotation.x"].number ?: 0.0
set(value) { set(value) {
properties.style["rotation.x"] = value properties.style["rotation.x"] = value
} }
/**
* y rotation relative to parent. Not inherited
*/
var DisplayObject.rotationY var DisplayObject.rotationY
get() = properties["rotation.y"].number ?: 0.0 get() = properties["rotation.y"].number ?: 0.0
set(value) { set(value) {
properties.style["rotation.y"] = value properties.style["rotation.y"] = value
} }
/**
* z rotation relative to parent. Not inherited
*/
var DisplayObject.rotationZ var DisplayObject.rotationZ
get() = properties["rotation.z"].number ?: 0.0 get() = properties["rotation.z"].number ?: 0.0
set(value) { set(value) {
@ -73,6 +95,9 @@ enum class RotationOrder {
ZYX ZYX
} }
/**
* Rotation order. Not inherited
*/
var DisplayObject.rotationOrder: RotationOrder var DisplayObject.rotationOrder: RotationOrder
get() = properties["rotation.order"].enum<RotationOrder>() ?: RotationOrder.XYZ get() = properties["rotation.order"].enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) { set(value) {
@ -81,24 +106,50 @@ var DisplayObject.rotationOrder: RotationOrder
// 3D object scale // 3D object scale
/**
* X scale. Not inherited
*/
var DisplayObject.scaleX var DisplayObject.scaleX
get() = properties["scale.x"].number ?: 1.0 get() = properties["scale.x"].number ?: 1.0
set(value) { set(value) {
properties.style["scale.x"] = value properties.style["scale.x"] = value
} }
/**
* Y scale. Not inherited
*/
var DisplayObject.scaleY var DisplayObject.scaleY
get() = properties["scale.y"].number ?: 1.0 get() = properties["scale.y"].number ?: 1.0
set(value) { set(value) {
properties.style["scale.y"] = value properties.style["scale.y"] = value
} }
/**
* Z scale. Not inherited
*/
var DisplayObject.scaleZ var DisplayObject.scaleZ
get() = properties["scale.z"].number ?: 1.0 get() = properties["scale.z"].number ?: 1.0
set(value) { set(value) {
properties.style["scale.z"] = value properties.style["scale.z"] = value
} }
fun DisplayObject.color(rgb: Int){
this.properties.style["color"] = rgb
}
fun DisplayObject.color(meta: Meta){
this.properties.style["color"] = meta
}
fun DisplayObject.color(r: Int, g: Int, b: Int) = color(buildMeta {
"red" to r
"green" to g
"blue" to b
})
//TODO add inherited scale
object World { object World {
const val CAMERA_INITIAL_DISTANCE = -500.0 const val CAMERA_INITIAL_DISTANCE = -500.0
const val CAMERA_INITIAL_X_ANGLE = -50.0 const val CAMERA_INITIAL_X_ANGLE = -50.0

View File

@ -0,0 +1,37 @@
package hep.dataforge.vis.spatial
import hep.dataforge.meta.get
import hep.dataforge.meta.getAll
import hep.dataforge.meta.node
import hep.dataforge.names.toName
import hep.dataforge.vis.DisplayNode
import kotlin.test.Test
import kotlin.test.assertEquals
class ConvexTest {
@Test
fun testConvexBuilder() {
val group = DisplayNode().apply {
convex {
point(50, 50, -50)
point(50, -50, -50)
point(-50, -50, -50)
point(-50, 50, -50)
point(50, 50, 50)
point(50, -50, 50)
point(-50, -50, 50)
point(-50, 50, 50)
}
}
val convex = group.children.first() as Convex
val pointsNode = convex.properties["points"].node
assertEquals(8, pointsNode?.items?.count())
val points = pointsNode?.getAll("point".toName())
assertEquals(8, convex.points.size)
}
}