Style cleanup

Fix rotation order
This commit is contained in:
Alexander Nozik 2019-12-23 15:53:47 +03:00
parent 8189012b70
commit a5a03f1c02
11 changed files with 126 additions and 70 deletions

View File

@ -3,8 +3,7 @@
package hep.dataforge.vis.common
import hep.dataforge.io.serialization.MetaSerializer
import hep.dataforge.meta.Meta
import hep.dataforge.meta.get
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import kotlinx.serialization.Serializable
@ -37,6 +36,15 @@ class StyleSheet() {
}
owner?.styleChanged(key, oldStyle, style)
}
infix fun String.put(style: Meta?) {
set(this, style)
}
operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
val newStyle = get(key)?.let { buildMeta(it, builder) } ?: buildMeta(builder)
set(key, newStyle.seal())
}
}
private fun VisualObject.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {

View File

@ -1,8 +1,5 @@
package hep.dataforge.vis.common
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.meta.buildMeta
import hep.dataforge.meta.seal
import hep.dataforge.names.*
import hep.dataforge.provider.Provider
@ -14,7 +11,7 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
override val defaultTarget: String get() = VisualObject.TYPE
val styleSheet: StyleSheet
val styleSheet: StyleSheet?
override fun provideTop(target: String): Map<Name, Any> =
when (target) {
@ -26,7 +23,7 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
}
res.entries
}.associate { it.toPair() }
STYLE_TARGET -> styleSheet.items.mapKeys { it.key.toName() }
STYLE_TARGET -> styleSheet?.items?.mapKeys { it.key.toName() } ?: emptyMap()
else -> emptyMap()
}
@ -47,8 +44,8 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
/**
* A fix for serialization bug that writes all proper parents inside the tree after deserialization
*/
fun attachChildren(){
styleSheet.owner = this
fun attachChildren() {
styleSheet?.owner = this
this.children.values.forEach {
it.parent = this
(it as? VisualGroup)?.attachChildren()
@ -60,11 +57,6 @@ interface VisualGroup : Provider, Iterable<VisualObject>, VisualObject {
}
}
fun VisualGroup.updateStyle(key: String, builder: MetaBuilder.() -> Unit) {
val newStyle = styleSheet[key]?.let { buildMeta(it, builder) } ?: buildMeta(builder)
styleSheet[key] = newStyle.seal()
}
data class StyleRef(val group: VisualGroup, val styleName: Name)
val VisualGroup.isEmpty: Boolean get() = this.children.isEmpty()

View File

@ -40,7 +40,7 @@ class GDMLTransformer(val root: GDML) {
var solidConfiguration: VisualObject3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { _, _ -> }
fun VisualObject.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
styleCache.getOrPut(name.toName()){
styleCache.getOrPut(name.toName()) {
buildMeta(builder)
}
useStyle(name)
@ -51,7 +51,7 @@ class GDMLTransformer(val root: GDML) {
val styleName = "material[${material.name}]"
obj.useStyle(styleName){
obj.useStyle(styleName) {
MATERIAL_COLOR_KEY put random.nextInt(16777216)
"gdml.material" put material.name
}
@ -68,7 +68,9 @@ class GDMLTransformer(val root: GDML) {
internal fun finalize(final: VisualGroup3D): VisualGroup3D {
final.prototypes = proto
styleCache.forEach {
final.styleSheet[it.key.toString()] = it.value
final.styleSheet {
this[it.key.toString()] = it.value
}
}
final.rotationOrder = RotationOrder.ZXY
onFinish(this@GDMLTransformer)

View File

@ -250,5 +250,7 @@ fun GDML.toVisual(block: GDMLTransformer.() -> Unit = {}): VisualGroup3D {
* Append gdml node to the group
*/
fun VisualGroup3D.gdml(gdml: GDML, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
set(key, gdml.toVisual(transformer))
val visual = gdml.toVisual(transformer)
println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(),visual))
set(key, visual)
}

View File

@ -47,9 +47,15 @@ inline fun VisualGroup3D.composite(
it.config.update(group.config)
//it.material = group.material
it.position = group.position
it.rotation = group.rotation
it.scale = group.scale
if(group.position!=null) {
it.position = group.position
}
if(group.rotation!=null) {
it.rotation = group.rotation
}
if(group.scale!=null) {
it.scale = group.scale
}
set(name, it)
}
}

View File

@ -46,8 +46,8 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
return if (inherit) {
properties?.get(name)
?: mergedStyles[name]
?: prototype.getProperty(name, false)
?: parent?.getProperty(name, inherit)
?: prototype.getProperty(name)
?: parent?.getProperty(name)
} else {
properties?.get(name)
?: mergedStyles[name]
@ -74,7 +74,6 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
?: error("Prototype with name $name not found in $this")
}
override var styles: List<String>
get() = super.styles + prototype.styles
set(value) {
@ -119,12 +118,12 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
return if (inherit) {
properties?.get(name)
?: mergedStyles[name]
?: prototype.getProperty(name, inherit)
?: parent?.getProperty(name, inherit)
?: prototype.getProperty(name)
?: parent?.getProperty(name)
} else {
properties?.get(name)
?: mergedStyles[name]
?: prototype.getProperty(name, inherit)
?: prototype.getProperty(name, false)
}
}
@ -135,11 +134,11 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
}
}
val VisualObject.prototype: VisualObject?
val VisualObject.prototype: VisualObject
get() = when (this) {
is Proxy -> prototype
is Proxy.ProxyChild -> prototype
else -> null
else -> this
}
/**
@ -158,12 +157,11 @@ fun VisualGroup3D.proxy(
templateName: Name,
obj: VisualObject3D,
name: String = "",
attachToParent: Boolean = false,
block: Proxy.() -> Unit = {}
): Proxy {
val existing = getPrototype(templateName)
if (existing == null) {
setPrototype(templateName, obj, attachToParent)
setPrototype(templateName, obj)
} else if (existing != obj) {
error("Can't add different prototype on top of existing one")
}

View File

@ -18,7 +18,6 @@ import hep.dataforge.names.asName
import hep.dataforge.names.isEmpty
import hep.dataforge.vis.common.AbstractVisualGroup
import hep.dataforge.vis.common.StyleSheet
import hep.dataforge.vis.common.VisualGroup
import hep.dataforge.vis.common.VisualObject
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
@ -37,7 +36,8 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
field = value
}
override val styleSheet: StyleSheet = StyleSheet(this)
override var styleSheet: StyleSheet? = null
private set
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var properties: Config? = null
@ -55,6 +55,14 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
attachChildren()
}
/**
* Update or create stylesheet
*/
fun styleSheet(block: StyleSheet.() -> Unit) {
val res = this.styleSheet ?: StyleSheet(this).also { this.styleSheet = it }
res.block()
}
override fun removeChild(token: NameToken) {
_children.remove(token)
childrenChanged(token.asName(), null)
@ -90,18 +98,6 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
}
}
fun getPrototype(name: Name): VisualObject3D? =
prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name)
fun setPrototype(name: Name, obj: VisualObject3D, attachToParent: Boolean = false) {
val parent = this.parent
if (attachToParent && parent is VisualGroup3D) {
parent.setPrototype(name, obj, attachToParent)
} else {
(prototypes ?: VisualGroup3D().also { this.prototypes = it }).set(name, obj)
}
}
override fun attachChildren() {
super.attachChildren()
prototypes?.run {
@ -115,5 +111,28 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
}
}
/**
* Ger a prototype redirecting the request to the parent if prototype is not found
*/
fun VisualGroup3D.getPrototype(name: Name): VisualObject3D? =
prototypes?.get(name) as? VisualObject3D ?: (parent as? VisualGroup3D)?.getPrototype(name)
/**
* Defined a prototype inside current group
*/
fun VisualGroup3D.setPrototype(name: Name, obj: VisualObject3D) {
(prototypes ?: VisualGroup3D().also { this.prototypes = it })[name] = obj
}
/**
* Define a group with given [key], attach it to this parent and return it.
*/
fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
VisualGroup3D().apply(action).also { set(key, it) }
VisualGroup3D().apply(action).also { set(key, it) }
/**
* Create or edit prototype node as a group
*/
inline fun VisualGroup3D.prototypes(builder: VisualGroup3D.() -> Unit): Unit {
(prototypes ?: VisualGroup3D().also { this.prototypes = it }).run(builder)
}

View File

@ -3,33 +3,34 @@ package hep.dataforge.vis.spatial
import hep.dataforge.meta.int
import hep.dataforge.meta.set
import hep.dataforge.names.asName
import hep.dataforge.vis.common.updateStyle
import hep.dataforge.vis.common.useStyle
import kotlin.test.Test
import kotlin.test.assertEquals
class PropertyTest {
@Test
fun testInheritedProperty(){
fun testInheritedProperty() {
var box: Box? = null
val group = VisualGroup3D().apply {
config["test"] = 22
group {
box = box(100,100,100)
box = box(100, 100, 100)
}
}
assertEquals(22, box?.getProperty("test".asName()).int)
}
@Test
fun testStyleProperty(){
fun testStyleProperty() {
var box: Box? = null
val group = VisualGroup3D().apply {
updateStyle("testStyle"){
"test" put 22
styleSheet {
set("testStyle") {
"test" put 22
}
}
group {
box = box(100,100,100).apply {
box = box(100, 100, 100).apply {
useStyle("testStyle")
}
}
@ -38,18 +39,41 @@ class PropertyTest {
}
@Test
fun testColor(){
fun testColor() {
var box: Box? = null
val group = VisualGroup3D().apply {
updateStyle("testStyle"){
Material3D.MATERIAL_COLOR_KEY put "#555555"
styleSheet {
set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555"
}
}
group {
box = box(100,100,100){
box = box(100, 100, 100) {
useStyle("testStyle")
}
}
}
assertEquals("#555555", box?.color)
}
@Test
fun testProxyStyleProperty() {
var box: Proxy? = null
val group = VisualGroup3D().apply {
styleSheet {
set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555"
}
}
prototypes {
box(100, 100, 100, name = "box") {
styles = listOf("testStyle")
}
}
group {
box = ref("box".asName())
}
}
assertEquals("#555555", box?.color)
}
}

View File

@ -2,7 +2,10 @@ package hep.dataforge.vis.spatial.editor
import hep.dataforge.io.toJson
import hep.dataforge.js.jsObject
import hep.dataforge.meta.*
import hep.dataforge.meta.DynamicMeta
import hep.dataforge.meta.Meta
import hep.dataforge.meta.builder
import hep.dataforge.meta.update
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.findStyle
import hep.dataforge.vis.spatial.*
@ -24,11 +27,7 @@ fun Element.propertyEditor(item: VisualObject?) {
if (item != null) {
append {
card("Properties") {
val config: Meta = if (item is Proxy || item is Proxy.ProxyChild) {
item.prototype?.config ?: EmptyMeta
} else {
item.config
}
val config: Meta = item.prototype.config
val metaToEdit = config.builder().apply {
VISIBLE_KEY to (item.visible ?: true)
if (item is VisualObject3D) {

View File

@ -3,7 +3,6 @@ package hep.dataforge.vis.spatial.fx
import hep.dataforge.context.*
import hep.dataforge.meta.Meta
import hep.dataforge.meta.boolean
import hep.dataforge.meta.get
import hep.dataforge.provider.Type
import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_KEY
@ -20,6 +19,13 @@ import javafx.scene.transform.Rotate
import org.fxyz3d.shapes.composites.PolyLine3D
import org.fxyz3d.shapes.primitives.CuboidMesh
import org.fxyz3d.shapes.primitives.SpheroidMesh
import kotlin.collections.HashMap
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.find
import kotlin.collections.map
import kotlin.collections.mapNotNull
import kotlin.collections.set
import kotlin.math.PI
import kotlin.reflect.KClass
@ -106,11 +112,11 @@ class FX3DPlugin : AbstractPlugin() {
when (obj.rotationOrder) {
RotationOrder.ZYX -> transforms.addAll(rotateZ, rotateY, rotateX)
RotationOrder.XZY -> transforms.addAll(rotateY, rotateZ, rotateX)
RotationOrder.YXZ -> transforms.addAll(rotateZ, rotateX, rotateY)
RotationOrder.YZX -> transforms.addAll(rotateX, rotateZ, rotateY)
RotationOrder.ZXY -> transforms.addAll(rotateY, rotateX, rotateZ)
RotationOrder.XYZ -> transforms.addAll(rotateZ, rotateY, rotateX)
RotationOrder.XZY -> transforms.addAll(rotateX, rotateZ, rotateY)
RotationOrder.YXZ -> transforms.addAll(rotateY, rotateX, rotateZ)
RotationOrder.YZX -> transforms.addAll(rotateY, rotateZ, rotateX)
RotationOrder.ZXY -> transforms.addAll(rotateZ, rotateX, rotateY)
RotationOrder.XYZ -> transforms.addAll(rotateX, rotateY, rotateZ)
}
if (this is Shape3D) {

View File

@ -17,7 +17,7 @@ class FXDemoApp : App(FXDemoGrid::class) {
stage.width = 400.0
stage.height = 400.0
//view.showcase()
view.showcase()
view.demo("gdml", "gdml") {
gdml(Paths.get("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.gdml")) {
lUnit = LUnit.CM