New properties #34
@ -2,8 +2,8 @@ plugins {
|
||||
id("ru.mipt.npm.project")
|
||||
}
|
||||
|
||||
val dataforgeVersion by extra("0.2.1-dev-5")
|
||||
val ktorVersion by extra("1.4.3")
|
||||
val dataforgeVersion by extra("0.3.0-dev")
|
||||
val ktorVersion by extra("1.5.0")
|
||||
val htmlVersion by extra("0.7.2")
|
||||
val kotlinWrappersVersion by extra("pre.129-kotlin-1.4.20")
|
||||
val fxVersion by extra("14")
|
||||
|
@ -1,7 +1,6 @@
|
||||
package hep.dataforge.vision.gdml.demo
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.setItem
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.gdml.readFile
|
||||
import hep.dataforge.vision.gdml.toVision
|
||||
|
@ -39,15 +39,18 @@ fun Page<Solid>.showcase() {
|
||||
demo("shapes", "Basic shapes") {
|
||||
box(100.0, 100.0, 100.0) {
|
||||
z = -110.0
|
||||
color("teal")
|
||||
}
|
||||
sphere(50.0) {
|
||||
x = 110
|
||||
detail = 16
|
||||
color("red")
|
||||
}
|
||||
tube(50, height = 10, innerRadius = 25, angle = PI) {
|
||||
y = 110
|
||||
detail = 16
|
||||
rotationX = PI / 4
|
||||
color("blue")
|
||||
}
|
||||
}
|
||||
|
||||
@ -55,6 +58,7 @@ fun Page<Solid>.showcase() {
|
||||
val group = group {
|
||||
box(100, 100, 100) {
|
||||
z = 110.0
|
||||
opacity = 0.5
|
||||
}
|
||||
|
||||
box(100, 100, 100) {
|
||||
@ -155,7 +159,7 @@ fun Page<Solid>.showcaseCSG() {
|
||||
detail = 32
|
||||
}
|
||||
color(Colors.lightgreen)
|
||||
opacity = 0.3
|
||||
opacity = 0.5
|
||||
}
|
||||
composite(CompositeType.SUBTRACT) {
|
||||
y = -300
|
||||
@ -173,9 +177,11 @@ fun Page<Solid>.showcaseCSG() {
|
||||
demo("CSG.custom", "CSG with manually created object") {
|
||||
intersect {
|
||||
tube(60, 10) {
|
||||
detail = 64
|
||||
detail = 32
|
||||
}
|
||||
box(100, 100, 100)
|
||||
color("red")
|
||||
opacity = 0.5
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,6 @@ import hep.dataforge.vision.set
|
||||
import hep.dataforge.vision.setProperty
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||
import hep.dataforge.vision.solid.three.*
|
||||
import info.laht.threekt.core.BufferGeometry
|
||||
import info.laht.threekt.core.Object3D
|
||||
@ -30,8 +29,6 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
||||
scaleX = xSize
|
||||
scaleY = ySize
|
||||
scaleZ = zSize
|
||||
// getProperty(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||
// getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY, inherit = false, includeStyles = false)
|
||||
}
|
||||
|
||||
override fun render(three: ThreePlugin): Object3D {
|
||||
@ -69,11 +66,8 @@ internal class VariableBox(xSize: Number, ySize: Number, zSize: Number) : ThreeV
|
||||
mesh.scale.set(newXSize, newYSize, newZSize)
|
||||
mesh.updateMatrix()
|
||||
}
|
||||
//name.startsWith(MeshThreeFactory.WIREFRAME_KEY) -> mesh.applyWireFrame(this@VariableBox)
|
||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||
name.startsWith(MATERIAL_COLOR_KEY) -> {
|
||||
mesh.updateMaterial(this)
|
||||
}
|
||||
//name.startsWith(MATERIAL_COLOR_KEY) -> mesh.updateMaterialProperty(this, name)
|
||||
else -> mesh.updateProperty(this@VariableBox, name)
|
||||
}
|
||||
}
|
||||
|
@ -1,7 +1,8 @@
|
||||
package hep.dataforge.vision.react
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.NodeItem
|
||||
import hep.dataforge.meta.ValueItem
|
||||
import hep.dataforge.meta.descriptors.ItemDescriptor
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.defaultItem
|
||||
@ -51,7 +52,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
|
||||
}
|
||||
|
||||
when (actualItem) {
|
||||
is MetaItem.NodeItem -> {
|
||||
is NodeItem -> {
|
||||
styledDiv {
|
||||
css {
|
||||
+TreeStyles.treeLeaf
|
||||
@ -108,7 +109,7 @@ private fun RBuilder.metaViewerItem(props: MetaViewerProps) {
|
||||
}
|
||||
}
|
||||
}
|
||||
is MetaItem.ValueItem -> {
|
||||
is ValueItem -> {
|
||||
styledDiv {
|
||||
css {
|
||||
+TreeStyles.treeLeaf
|
||||
|
@ -9,6 +9,7 @@ import hep.dataforge.names.plus
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.vision.hidden
|
||||
import kotlinx.coroutines.CoroutineScope
|
||||
import kotlinx.coroutines.ExperimentalCoroutinesApi
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.channels.awaitClose
|
||||
import kotlinx.coroutines.flow.Flow
|
||||
@ -65,12 +66,12 @@ private val PropertyEditorItem: FunctionalComponent<PropertyEditorProps> =
|
||||
private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
||||
var expanded: Boolean by useState { true }
|
||||
val itemName by useState { props.name ?: Name.EMPTY }
|
||||
var item: MetaItem<*>? by useState { props.provider.getItem(itemName) }
|
||||
var item: MetaItem? by useState { props.provider.getItem(itemName) }
|
||||
val descriptorItem: ItemDescriptor? = props.descriptor?.get(itemName)
|
||||
|
||||
if(descriptorItem?.hidden == true) return //fail fast for hidden property
|
||||
|
||||
var actualItem: MetaItem<Meta>? by useState {
|
||||
var actualItem: MetaItem? by useState {
|
||||
item ?: props.defaultProvider?.getItem(itemName) ?: descriptorItem?.defaultItem()
|
||||
}
|
||||
|
||||
@ -110,7 +111,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
||||
update()
|
||||
}
|
||||
|
||||
if (actualItem is MetaItem.NodeItem) {
|
||||
if (actualItem is NodeItem) {
|
||||
styledDiv {
|
||||
css {
|
||||
+TreeStyles.treeLeaf
|
||||
@ -248,6 +249,7 @@ public fun RBuilder.propertyEditor(
|
||||
}
|
||||
}
|
||||
|
||||
@OptIn(ExperimentalCoroutinesApi::class)
|
||||
private fun Config.flowUpdates(): Flow<Name> = callbackFlow {
|
||||
onChange(this) { name, _, _ ->
|
||||
launch {
|
||||
|
@ -17,7 +17,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
/**
|
||||
* Style the caret/arrow
|
||||
*/
|
||||
public val treeCaret by css {
|
||||
public val treeCaret: RuleSet by css {
|
||||
cursor = Cursor.pointer
|
||||
userSelect = UserSelect.none
|
||||
/* Create the caret/arrow with a unicode, and style it */
|
||||
@ -32,7 +32,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
/**
|
||||
* Rotate the caret/arrow icon when clicked on (using JavaScript)
|
||||
*/
|
||||
val treeCaredDown by css {
|
||||
public val treeCaredDown:RuleSet by css {
|
||||
before {
|
||||
content = "\u25B6".quoted
|
||||
color = Color.black
|
||||
@ -42,7 +42,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
}
|
||||
}
|
||||
|
||||
val treeItem by css {
|
||||
public val treeItem:RuleSet by css {
|
||||
alignItems = Align.center
|
||||
paddingLeft = 10.px
|
||||
borderLeftStyle = BorderStyle.dashed
|
||||
@ -53,27 +53,27 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
borderBottomColor = Color.lightGray
|
||||
}
|
||||
|
||||
val treeLeaf by css {
|
||||
public val treeLeaf:RuleSet by css {
|
||||
display = Display.flex
|
||||
flexDirection = FlexDirection.row
|
||||
flexWrap = FlexWrap.nowrap
|
||||
//alignItems = Align.center
|
||||
}
|
||||
|
||||
val treeLabel by css {
|
||||
public val treeLabel:RuleSet by css {
|
||||
overflow = Overflow.hidden
|
||||
flex(flexGrow = 1.0, flexShrink = 1.0)
|
||||
}
|
||||
|
||||
val treeLabelInactive by css {
|
||||
public val treeLabelInactive: RuleSet by css {
|
||||
color = Color.lightGray
|
||||
}
|
||||
|
||||
val treeLabelSelected by css {
|
||||
public val treeLabelSelected:RuleSet by css {
|
||||
backgroundColor = Color.lightBlue
|
||||
}
|
||||
|
||||
val linkButton by css {
|
||||
public val linkButton:RuleSet by css {
|
||||
backgroundColor = Color.white
|
||||
border = "none"
|
||||
padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt)
|
||||
@ -86,7 +86,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
}
|
||||
}
|
||||
|
||||
val removeButton by css {
|
||||
public val removeButton:RuleSet by css {
|
||||
backgroundColor = Color.white
|
||||
borderStyle = BorderStyle.solid
|
||||
borderRadius = 2.px
|
||||
@ -104,7 +104,7 @@ public object TreeStyles : StyleSheet("treeStyles", true) {
|
||||
}
|
||||
}
|
||||
|
||||
val resizeableInput by css {
|
||||
public val resizeableInput: RuleSet by css {
|
||||
overflow = Overflow.hidden
|
||||
maxWidth = 120.pt
|
||||
flex(flexGrow = 2.0, flexShrink = 2.0, flexBasis = 60.pt)
|
||||
|
@ -20,7 +20,7 @@ import styled.styledInput
|
||||
import styled.styledSelect
|
||||
|
||||
public external interface ValueChooserProps : RProps {
|
||||
var item: MetaItem<*>?
|
||||
var item: MetaItem?
|
||||
var descriptor: ValueDescriptor?
|
||||
var valueChanged: ((Value?) -> Unit)?
|
||||
}
|
||||
@ -140,7 +140,7 @@ class ValueChooserComponent(props: ValueChooserProps) : RComponent<ValueChooserP
|
||||
|
||||
internal fun RBuilder.valueChooser(
|
||||
name: Name,
|
||||
item: MetaItem<*>?,
|
||||
item: MetaItem?,
|
||||
descriptor: ValueDescriptor? = null,
|
||||
callback: (Value?) -> Unit
|
||||
) {
|
||||
|
@ -1,8 +1,6 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.number
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.int
|
||||
import hep.dataforge.values.string
|
||||
@ -192,9 +190,9 @@ public object Colors {
|
||||
/**
|
||||
* Convert color represented as Meta to string of format #rrggbb
|
||||
*/
|
||||
fun fromMeta(item: MetaItem<*>): String {
|
||||
fun fromMeta(item: MetaItem): String {
|
||||
return when (item) {
|
||||
is MetaItem.NodeItem<*> -> {
|
||||
is NodeItem -> {
|
||||
val node = item.node
|
||||
rgbToString(
|
||||
node[RED_KEY].number?.toByte()?.toUByte() ?: 0u,
|
||||
@ -202,7 +200,7 @@ public object Colors {
|
||||
node[BLUE_KEY].number?.toByte()?.toUByte() ?: 0u
|
||||
)
|
||||
}
|
||||
is MetaItem.ValueItem -> {
|
||||
is ValueItem -> {
|
||||
if (item.value.type == ValueType.NUMBER) {
|
||||
rgbToString(item.value.int)
|
||||
} else {
|
||||
|
@ -40,7 +40,7 @@ public inline class StyleSheet(private val owner: VisionGroup) {
|
||||
* Create and set a style
|
||||
*/
|
||||
public operator fun set(key: String, builder: MetaBuilder.() -> Unit) {
|
||||
val newStyle = get(key)?.edit(builder) ?: Meta(builder)
|
||||
val newStyle = get(key)?.builder()?.apply(builder) ?: Meta(builder)
|
||||
set(key, newStyle.seal())
|
||||
}
|
||||
|
||||
@ -99,7 +99,7 @@ public tailrec fun Vision.getStyle(name: String): Meta? =
|
||||
/**
|
||||
* Resolve an item in all style layers
|
||||
*/
|
||||
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem<*>> {
|
||||
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> {
|
||||
return styles.asSequence().map {
|
||||
getStyle(it)
|
||||
}.map {
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.MutableItemProvider
|
||||
import hep.dataforge.meta.descriptors.Described
|
||||
@ -28,6 +29,12 @@ public interface Vision : Described {
|
||||
@Transient
|
||||
public var parent: VisionGroup?
|
||||
|
||||
/**
|
||||
* Properties belonging to this [Vision] potentially including artificial properties
|
||||
*/
|
||||
@Transient
|
||||
public val meta: Meta
|
||||
|
||||
/**
|
||||
* A coroutine scope for asynchronous calls and locks
|
||||
*/
|
||||
@ -37,7 +44,7 @@ public interface Vision : Described {
|
||||
* A fast accessor method to get own property (no inheritance or styles).
|
||||
* Should be equivalent to `getProperty(name,false,false,false)`.
|
||||
*/
|
||||
public fun getOwnProperty(name: Name): MetaItem<*>?
|
||||
public fun getOwnProperty(name: Name): MetaItem?
|
||||
|
||||
/**
|
||||
* Get property.
|
||||
@ -49,13 +56,13 @@ public interface Vision : Described {
|
||||
inherit: Boolean = false,
|
||||
includeStyles: Boolean = true,
|
||||
includeDefaults: Boolean = true,
|
||||
): MetaItem<*>?
|
||||
): MetaItem?
|
||||
|
||||
|
||||
/**
|
||||
* Set the property value
|
||||
*/
|
||||
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
|
||||
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
|
||||
|
||||
/**
|
||||
* Subscribe on property updates. The subscription is bound to the given [scope] and canceled when the scope is canceled
|
||||
@ -109,8 +116,8 @@ public fun Vision.asyncNotifyPropertyChange(propertyName: Name) {
|
||||
*/
|
||||
public val Vision.ownProperties: MutableItemProvider
|
||||
get() = object : MutableItemProvider {
|
||||
override fun getItem(name: Name): MetaItem<*>? = getOwnProperty(name)
|
||||
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
|
||||
override fun getItem(name: Name): MetaItem? = getOwnProperty(name)
|
||||
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
|
||||
}
|
||||
|
||||
|
||||
@ -123,14 +130,14 @@ public fun Vision.allProperties(
|
||||
includeStyles: Boolean? = null,
|
||||
includeDefaults: Boolean = true,
|
||||
): MutableItemProvider = object : MutableItemProvider {
|
||||
override fun getItem(name: Name): MetaItem<*>? = getProperty(
|
||||
override fun getItem(name: Name): MetaItem? = getProperty(
|
||||
name,
|
||||
inherit = inherit ?: (descriptor?.get(name)?.inherited != false),
|
||||
includeStyles = includeStyles ?: (descriptor?.get(name)?.usesStyles == true),
|
||||
includeDefaults = includeDefaults
|
||||
)
|
||||
|
||||
override fun setItem(name: Name, item: MetaItem<*>?): Unit = setProperty(name, item)
|
||||
override fun setItem(name: Name, item: MetaItem?): Unit = setProperty(name, item)
|
||||
}
|
||||
|
||||
/**
|
||||
@ -141,7 +148,7 @@ public fun Vision.getProperty(
|
||||
inherit: Boolean = false,
|
||||
includeStyles: Boolean = true,
|
||||
includeDefaults: Boolean = true,
|
||||
): MetaItem<*>? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
||||
): MetaItem? = getProperty(key.toName(), inherit, includeStyles, includeDefaults)
|
||||
|
||||
/**
|
||||
* A convenience method to pair [getProperty]
|
||||
|
@ -1,9 +1,6 @@
|
||||
package hep.dataforge.vision
|
||||
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.MutableMeta
|
||||
import hep.dataforge.meta.asMetaItem
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.meta.descriptors.NodeDescriptor
|
||||
import hep.dataforge.meta.descriptors.defaultItem
|
||||
import hep.dataforge.meta.descriptors.get
|
||||
@ -40,14 +37,14 @@ public open class VisionBase : Vision {
|
||||
/**
|
||||
* Object own properties excluding styles and inheritance
|
||||
*/
|
||||
public var properties: Config? = null
|
||||
private set
|
||||
internal var properties: Config? = null
|
||||
|
||||
override val meta: Meta get() = properties ?: Meta.EMPTY
|
||||
|
||||
@Synchronized
|
||||
private fun getOrCreateConfig(): Config {
|
||||
if (properties == null) {
|
||||
val newProperties = Config()
|
||||
properties = newProperties
|
||||
newProperties.onChange(this) { name, oldItem, newItem ->
|
||||
if (oldItem != newItem) {
|
||||
scope.launch {
|
||||
@ -55,6 +52,7 @@ public open class VisionBase : Vision {
|
||||
}
|
||||
}
|
||||
}
|
||||
properties = newProperties
|
||||
}
|
||||
return properties!!
|
||||
}
|
||||
@ -62,7 +60,7 @@ public open class VisionBase : Vision {
|
||||
/**
|
||||
* A fast accessor method to get own property (no inheritance or styles
|
||||
*/
|
||||
override fun getOwnProperty(name: Name): MetaItem<*>? {
|
||||
override fun getOwnProperty(name: Name): MetaItem? {
|
||||
return properties?.getItem(name)
|
||||
}
|
||||
|
||||
@ -71,7 +69,7 @@ public open class VisionBase : Vision {
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = sequence {
|
||||
): MetaItem? = sequence {
|
||||
yield(getOwnProperty(name))
|
||||
if (includeStyles) {
|
||||
yieldAll(getStyleItems(name))
|
||||
@ -83,7 +81,7 @@ public open class VisionBase : Vision {
|
||||
}.merge()
|
||||
|
||||
@Synchronized
|
||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||
getOrCreateConfig().setItem(name, item)
|
||||
if (notify) {
|
||||
scope.launch {
|
||||
@ -121,23 +119,17 @@ public open class VisionBase : Vision {
|
||||
propertyInvalidationFlow.emit(propertyName)
|
||||
}
|
||||
|
||||
public fun configure(block: suspend MutableMeta<*>.() -> Unit) {
|
||||
scope.launch {
|
||||
getOrCreateConfig().block()
|
||||
}
|
||||
}
|
||||
|
||||
override fun update(change: VisionChange) {
|
||||
|
||||
fun updateProperties(at: Name, item: MetaItem<*>) {
|
||||
fun updateProperties(at: Name, item: MetaItem) {
|
||||
when (item) {
|
||||
is MetaItem.ValueItem -> {
|
||||
is ValueItem -> {
|
||||
if (item.value == Null) {
|
||||
setProperty(at, null)
|
||||
} else
|
||||
setProperty(at, item)
|
||||
}
|
||||
is MetaItem.NodeItem -> item.node.items.forEach { (token, childItem) ->
|
||||
is NodeItem -> item.node.items.forEach { (token, childItem) ->
|
||||
updateProperties(at + token, childItem)
|
||||
}
|
||||
}
|
||||
|
@ -29,7 +29,7 @@ public class VisionChangeBuilder : VisionContainerBuilder<Vision> {
|
||||
private fun getOrPutChild(visionName: Name): VisionChangeBuilder =
|
||||
children.getOrPut(visionName) { VisionChangeBuilder() }
|
||||
|
||||
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem<*>?) {
|
||||
public fun propertyChanged(visionName: Name, propertyName: Name, item: MetaItem?) {
|
||||
if (visionName == Name.EMPTY) {
|
||||
//Write property removal as [Null]
|
||||
propertyChange[propertyName] = (item ?: Null.asMetaItem())
|
||||
|
@ -12,7 +12,7 @@ public interface VisionPropertyContainer<out T> {
|
||||
inherit: Boolean = false,
|
||||
includeStyles: Boolean = true,
|
||||
includeDefaults: Boolean = true,
|
||||
): MetaItem<*>?
|
||||
): MetaItem?
|
||||
|
||||
public fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean = true)
|
||||
public fun setProperty(name: Name, item: MetaItem?, notify: Boolean = true)
|
||||
}
|
@ -6,20 +6,16 @@ import hep.dataforge.values.asValue
|
||||
@DslMarker
|
||||
public annotation class VisionBuilder
|
||||
|
||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? = when (val first = firstOrNull { it != null }) {
|
||||
public fun Sequence<MetaItem?>.merge(): MetaItem? = when (val first = firstOrNull { it != null }) {
|
||||
null -> null
|
||||
is MetaItem.ValueItem -> first //fast search for first entry if it is value
|
||||
is MetaItem.NodeItem -> {
|
||||
is ValueItem -> first //fast search for first entry if it is value
|
||||
is NodeItem -> {
|
||||
//merge nodes if first encountered node is meta
|
||||
val laminate: Laminate = Laminate(mapNotNull { it.node }.toList())
|
||||
MetaItem.NodeItem(laminate)
|
||||
NodeItem(laminate)
|
||||
}
|
||||
}
|
||||
|
||||
@DFExperimental
|
||||
public val Vision.properties: Config?
|
||||
get() = (this as? VisionBase)?.properties
|
||||
|
||||
/**
|
||||
* Control visibility of the element
|
||||
*/
|
||||
@ -29,4 +25,4 @@ public var Vision.visible: Boolean?
|
||||
|
||||
public fun Vision.configure(meta: Meta?): Unit = update(VisionChange(properties = meta))
|
||||
|
||||
public fun Vision.configure(block: MutableMeta<*>.() -> Unit): Unit = configure(Meta(block))
|
||||
public fun Vision.configure(block: MetaBuilder.() -> Unit): Unit = configure(Meta(block))
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.html
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.vision.VisionBase
|
||||
import hep.dataforge.vision.configure
|
||||
import kotlinx.html.*
|
||||
import kotlinx.html.stream.createHTML
|
||||
import kotlin.test.Test
|
||||
@ -34,7 +35,7 @@ class HtmlTagTest {
|
||||
div {
|
||||
h2 { +"Properties" }
|
||||
ul {
|
||||
(vision as? VisionBase)?.properties?.items?.forEach {
|
||||
(vision as? VisionBase)?.meta?.items?.forEach {
|
||||
li {
|
||||
a { +it.key.toString() }
|
||||
p { +it.value.toString() }
|
||||
|
@ -138,7 +138,7 @@ public class VisionClient : AbstractPlugin() {
|
||||
renderVision(element, change.vision, outputMeta)
|
||||
}
|
||||
|
||||
logger.info { "Got update ${change.toString()} for output with name $name" }
|
||||
logger.debug { "Got update $change for output with name $name" }
|
||||
visionMap[element]?.update(change)
|
||||
?: console.info("Target vision for element $element with name $name not found")
|
||||
} else {
|
||||
|
@ -18,7 +18,7 @@ import tornadofx.*
|
||||
/**
|
||||
* A display for meta and descriptor
|
||||
*/
|
||||
sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
||||
sealed class FXMeta<M : TypedMeta<M>> : Comparable<FXMeta<*>> {
|
||||
abstract val name: NameToken
|
||||
abstract val parent: FXMetaNode<M>?
|
||||
abstract val descriptionProperty: ObservableStringValue
|
||||
@ -35,7 +35,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun <M : MetaNode<M>> root(
|
||||
fun <M : TypedMeta<M>> root(
|
||||
node: M,
|
||||
descriptor: NodeDescriptor? = null,
|
||||
rootName: String = "root"
|
||||
@ -47,7 +47,7 @@ sealed class FXMeta<M : MetaNode<M>> : Comparable<FXMeta<*>> {
|
||||
}
|
||||
}
|
||||
|
||||
class FXMetaNode<M : MetaNode<M>>(
|
||||
class FXMetaNode<M : TypedMeta<M>>(
|
||||
override val name: NameToken,
|
||||
override val parent: FXMetaNode<M>?,
|
||||
nodeValue: M? = null,
|
||||
@ -89,7 +89,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
||||
init {
|
||||
bind(nodeProperty, descriptorProperty)
|
||||
|
||||
val listener: (Name, MetaItem<*>?, MetaItem<*>?) -> Unit = { name, _, _ ->
|
||||
val listener: (Name, MetaItem?, MetaItem?) -> Unit = { name, _, _ ->
|
||||
if (name.length == 1) invalidate()
|
||||
}
|
||||
|
||||
@ -115,7 +115,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
||||
val actualItem = node?.items?.get(token)
|
||||
val actualDescriptor = descriptor?.items?.get(token.body)
|
||||
|
||||
if (actualItem is MetaItem.NodeItem || actualDescriptor is NodeDescriptor) {
|
||||
if (actualItem is NodeItem || actualDescriptor is NodeDescriptor) {
|
||||
FXMetaNode(token, this@FXMetaNode)
|
||||
} else {
|
||||
FXMetaValue(token, this@FXMetaNode)
|
||||
@ -134,7 +134,7 @@ class FXMetaNode<M : MetaNode<M>>(
|
||||
}
|
||||
}
|
||||
|
||||
public class FXMetaValue<M : MetaNode<M>>(
|
||||
public class FXMetaValue<M : TypedMeta<M>>(
|
||||
override val name: NameToken,
|
||||
override val parent: FXMetaNode<M>
|
||||
) : FXMeta<M>() {
|
||||
@ -151,10 +151,10 @@ public class FXMetaValue<M : MetaNode<M>>(
|
||||
//private val innerValueProperty = SimpleObjectProperty(value)
|
||||
|
||||
public val valueProperty = descriptorProperty.objectBinding { descriptor ->
|
||||
parent.node[name].value ?: descriptor?.default
|
||||
parent.node?.get(name).value ?: descriptor?.default
|
||||
}
|
||||
|
||||
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it[name] != null }
|
||||
override val hasValue: ObservableBooleanValue = parent.nodeProperty.booleanBinding { it?.get(name) != null }
|
||||
|
||||
public val value by valueProperty
|
||||
|
||||
@ -169,12 +169,12 @@ public fun <M : MutableMeta<M>> FXMetaNode<M>.remove(name: NameToken) {
|
||||
private fun <M : MutableMeta<M>> M.createEmptyNode(token: NameToken, append: Boolean): M {
|
||||
return if (append && token.hasIndex()) {
|
||||
val name = token.asName()
|
||||
val index = (getIndexed(name).keys.mapNotNull { it.toIntOrNull() }.max() ?: -1) + 1
|
||||
val index = (getIndexed(name).keys.mapNotNull { it?.toIntOrNull() }.maxOrNull() ?: -1) + 1
|
||||
val newName = name.withIndex(index.toString())
|
||||
set(newName, Meta.EMPTY)
|
||||
get(newName).node!!
|
||||
} else {
|
||||
this.setNode(token.asName(), Meta.EMPTY)
|
||||
this.set(token.asName(), Meta.EMPTY)
|
||||
//FIXME possible concurrency bug
|
||||
get(token).node!!
|
||||
}
|
||||
|
@ -1,9 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.MetaItem
|
||||
import hep.dataforge.meta.double
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.int
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.int
|
||||
import hep.dataforge.values.string
|
||||
@ -35,9 +32,9 @@ public object FXMaterials {
|
||||
* Infer color based on meta item
|
||||
* @param opacity default opacity
|
||||
*/
|
||||
public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
||||
public fun MetaItem.color(opacity: Double = 1.0): Color {
|
||||
return when (this) {
|
||||
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||
val int = value.int
|
||||
val red = int and 0x00ff0000 shr 16
|
||||
val green = int and 0x0000ff00 shr 8
|
||||
@ -46,7 +43,7 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
||||
} else {
|
||||
Color.web(this.value.string)
|
||||
}
|
||||
is MetaItem.NodeItem -> {
|
||||
is NodeItem -> {
|
||||
Color.rgb(
|
||||
node[Colors.RED_KEY]?.int ?: 0,
|
||||
node[Colors.GREEN_KEY]?.int ?: 0,
|
||||
@ -60,11 +57,11 @@ public fun MetaItem<*>.color(opacity: Double = 1.0): Color {
|
||||
/**
|
||||
* Infer FX material based on meta item
|
||||
*/
|
||||
public fun MetaItem<*>?.material(): Material {
|
||||
public fun MetaItem?.material(): Material {
|
||||
return when (this) {
|
||||
null -> FXMaterials.GREY
|
||||
is MetaItem.ValueItem -> PhongMaterial(color())
|
||||
is MetaItem.NodeItem -> PhongMaterial().apply {
|
||||
is ValueItem -> PhongMaterial(color())
|
||||
is NodeItem -> PhongMaterial().apply {
|
||||
val opacity = node[SolidMaterial.OPACITY_KEY].double ?: 1.0
|
||||
diffuseColor = node[SolidMaterial.COLOR_KEY]?.color(opacity) ?: Color.DARKGREY
|
||||
specularColor = node[SolidMaterial.SPECULAR_COLOR_KEY]?.color(opacity) ?: Color.WHITE
|
||||
|
@ -13,7 +13,7 @@ import tornadofx.*
|
||||
* A caching binding collection for [Vision] properties
|
||||
*/
|
||||
class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
||||
private val bindings = HashMap<Name, ObjectBinding<MetaItem<*>?>>()
|
||||
private val bindings = HashMap<Name, ObjectBinding<MetaItem?>>()
|
||||
|
||||
init {
|
||||
obj.onPropertyChange(fx.context) { name ->
|
||||
@ -31,10 +31,10 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
||||
}
|
||||
}
|
||||
|
||||
operator fun get(key: Name): ObjectBinding<MetaItem<*>?> {
|
||||
operator fun get(key: Name): ObjectBinding<MetaItem?> {
|
||||
return bindings.getOrPut(key) {
|
||||
object : ObjectBinding<MetaItem<*>?>() {
|
||||
override fun computeValue(): MetaItem<*>? = obj.getProperty(key)
|
||||
object : ObjectBinding<MetaItem?>() {
|
||||
override fun computeValue(): MetaItem? = obj.getProperty(key)
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -42,19 +42,19 @@ class VisualObjectFXBinding(val fx: FX3DPlugin, val obj: Vision) {
|
||||
operator fun get(key: String) = get(key.toName())
|
||||
}
|
||||
|
||||
fun ObjectBinding<MetaItem<*>?>.value() = objectBinding { it.value }
|
||||
fun ObjectBinding<MetaItem<*>?>.string() = stringBinding { it.string }
|
||||
fun ObjectBinding<MetaItem<*>?>.number() = objectBinding { it.number }
|
||||
fun ObjectBinding<MetaItem<*>?>.double() = objectBinding { it.double }
|
||||
fun ObjectBinding<MetaItem<*>?>.float() = objectBinding { it.float }
|
||||
fun ObjectBinding<MetaItem<*>?>.int() = objectBinding { it.int }
|
||||
fun ObjectBinding<MetaItem<*>?>.long() = objectBinding { it.long }
|
||||
fun ObjectBinding<MetaItem<*>?>.node() = objectBinding { it.node }
|
||||
fun ObjectBinding<MetaItem?>.value() = objectBinding { it.value }
|
||||
fun ObjectBinding<MetaItem?>.string() = stringBinding { it.string }
|
||||
fun ObjectBinding<MetaItem?>.number() = objectBinding { it.number }
|
||||
fun ObjectBinding<MetaItem?>.double() = objectBinding { it.double }
|
||||
fun ObjectBinding<MetaItem?>.float() = objectBinding { it.float }
|
||||
fun ObjectBinding<MetaItem?>.int() = objectBinding { it.int }
|
||||
fun ObjectBinding<MetaItem?>.long() = objectBinding { it.long }
|
||||
fun ObjectBinding<MetaItem?>.node() = objectBinding { it.node }
|
||||
|
||||
fun ObjectBinding<MetaItem<*>?>.string(default: String) = stringBinding { it.string ?: default }
|
||||
fun ObjectBinding<MetaItem<*>?>.double(default: Double) = doubleBinding { it.double ?: default }
|
||||
fun ObjectBinding<MetaItem<*>?>.float(default: Float) = floatBinding { it.float ?: default }
|
||||
fun ObjectBinding<MetaItem<*>?>.int(default: Int) = integerBinding { it.int ?: default }
|
||||
fun ObjectBinding<MetaItem<*>?>.long(default: Long) = longBinding { it.long ?: default }
|
||||
fun ObjectBinding<MetaItem?>.string(default: String) = stringBinding { it.string ?: default }
|
||||
fun ObjectBinding<MetaItem?>.double(default: Double) = doubleBinding { it.double ?: default }
|
||||
fun ObjectBinding<MetaItem?>.float(default: Float) = floatBinding { it.float ?: default }
|
||||
fun ObjectBinding<MetaItem?>.int(default: Int) = integerBinding { it.int ?: default }
|
||||
fun ObjectBinding<MetaItem?>.long(default: Long) = longBinding { it.long ?: default }
|
||||
|
||||
fun <T> ObjectBinding<MetaItem<*>?>.transform(transform: (MetaItem<*>) -> T) = objectBinding { it?.let(transform) }
|
||||
fun <T> ObjectBinding<MetaItem?>.transform(transform: (MetaItem) -> T) = objectBinding { it?.let(transform) }
|
||||
|
@ -1,9 +1,8 @@
|
||||
package hep.dataforge.vision.gdml
|
||||
|
||||
import hep.dataforge.meta.DFExperimental
|
||||
import hep.dataforge.meta.sequence
|
||||
import hep.dataforge.meta.itemSequence
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.properties
|
||||
import hep.dataforge.vision.solid.*
|
||||
|
||||
public expect class Counter() {
|
||||
@ -27,7 +26,7 @@ internal fun Vision.updateFrom(other: Vision): Vision {
|
||||
scaleY = scaleY.toDouble() * other.scaleY.toDouble()
|
||||
scaleZ = scaleZ.toDouble() * other.scaleZ.toDouble()
|
||||
}
|
||||
other.properties?.sequence()?.forEach { (name, item) ->
|
||||
other.meta.itemSequence().forEach { (name, item) ->
|
||||
if (getProperty(name) == null) {
|
||||
setProperty(name, item)
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vision.*
|
||||
@ -39,18 +38,20 @@ public inline fun VisionContainerBuilder<Solid>.composite(
|
||||
val group = SolidGroup().apply(builder)
|
||||
val children = group.children.values.filterIsInstance<Solid>()
|
||||
if (children.size != 2) error("Composite requires exactly two children")
|
||||
return Composite(type, children[0], children[1]).also {
|
||||
it.configure { update(group.properties ?: Meta.EMPTY) }
|
||||
return Composite(type, children[0], children[1]).also { composite ->
|
||||
composite.configure {
|
||||
update(group.meta)
|
||||
}
|
||||
if (group.position != null) {
|
||||
it.position = group.position
|
||||
composite.position = group.position
|
||||
}
|
||||
if (group.rotation != null) {
|
||||
it.rotation = group.rotation
|
||||
composite.rotation = group.rotation
|
||||
}
|
||||
if (group.scale != null) {
|
||||
it.scale = group.scale
|
||||
composite.scale = group.scale
|
||||
}
|
||||
set(name, it)
|
||||
set(name, composite)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -85,7 +85,7 @@ public interface Solid : Vision {
|
||||
if (first.position != second.position) return false
|
||||
if (first.rotation != second.rotation) return false
|
||||
if (first.scale != second.scale) return false
|
||||
if (first.properties != second.properties) return false
|
||||
if (first.meta != second.meta) return false
|
||||
return true
|
||||
}
|
||||
|
||||
|
@ -106,16 +106,16 @@ internal class Prototypes(
|
||||
}
|
||||
}
|
||||
|
||||
override fun getOwnProperty(name: Name): MetaItem<*>? = null
|
||||
override fun getOwnProperty(name: Name): MetaItem? = null
|
||||
|
||||
override fun getProperty(
|
||||
name: Name,
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = null
|
||||
): MetaItem? = null
|
||||
|
||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||
error("Can't ser property of prototypes container")
|
||||
}
|
||||
|
||||
|
@ -19,12 +19,12 @@ public class SolidMaterial : Scheme() {
|
||||
/**
|
||||
* Primary web-color for the material
|
||||
*/
|
||||
public var color: ColorAccessor = ColorAccessor(config, COLOR_KEY)
|
||||
public var color: ColorAccessor = ColorAccessor(items, COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Specular color for phong material
|
||||
*/
|
||||
public var specularColor: ColorAccessor = ColorAccessor(config, SPECULAR_COLOR_KEY)
|
||||
public var specularColor: ColorAccessor = ColorAccessor(items, SPECULAR_COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Opacity
|
||||
@ -100,16 +100,17 @@ public val Solid.color: ColorAccessor
|
||||
|
||||
public var Solid.material: SolidMaterial?
|
||||
get() = getProperty(MATERIAL_KEY, inherit = true).node?.let { SolidMaterial.read(it) }
|
||||
set(value) = setProperty(MATERIAL_KEY, value?.config)
|
||||
set(value) = setProperty(MATERIAL_KEY, value?.rootNode)
|
||||
|
||||
@VisionBuilder
|
||||
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
||||
val node = allProperties(inherit = true).getItem(MATERIAL_KEY).node
|
||||
if (node != null) {
|
||||
SolidMaterial.update(node, builder)
|
||||
} else {
|
||||
setProperty(MATERIAL_KEY, SolidMaterial(builder))
|
||||
}
|
||||
// val node = getOwnProperty(MATERIAL_KEY).node
|
||||
// if (node != null) {
|
||||
// configure(SolidMaterial(builder).config)
|
||||
// } else {
|
||||
// setProperty(MATERIAL_KEY, SolidMaterial(builder))
|
||||
// }
|
||||
}
|
||||
|
||||
public var Solid.opacity: Number?
|
||||
|
@ -17,7 +17,7 @@ private fun SolidReference.getRefProperty(
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? {
|
||||
): MetaItem? {
|
||||
return sequence {
|
||||
yield(getOwnProperty(name))
|
||||
if (includeStyles) {
|
||||
@ -59,11 +59,11 @@ public class SolidReferenceGroup(
|
||||
private fun childPropertyName(childName: Name, propertyName: Name): Name =
|
||||
childToken(childName) + propertyName
|
||||
|
||||
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem<*>? {
|
||||
private fun getChildProperty(childName: Name, propertyName: Name): MetaItem? {
|
||||
return getOwnProperty(childPropertyName(childName, propertyName))
|
||||
}
|
||||
|
||||
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem<*>?, notify: Boolean) {
|
||||
private fun setChildProperty(childName: Name, propertyName: Name, item: MetaItem?, notify: Boolean) {
|
||||
setProperty(childPropertyName(childName, propertyName), item, notify)
|
||||
}
|
||||
|
||||
@ -79,7 +79,7 @@ public class SolidReferenceGroup(
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||
|
||||
override val descriptor: NodeDescriptor get() = prototype.descriptor
|
||||
|
||||
@ -99,9 +99,11 @@ public class SolidReferenceGroup(
|
||||
ReferenceChild(childName + key.asName())
|
||||
} ?: emptyMap()
|
||||
|
||||
override fun getOwnProperty(name: Name): MetaItem<*>? = getChildProperty(childName, name)
|
||||
override val meta: Meta get() =TODO()// getChildProperty(childName, Name.EMPTY).node ?: Meta.EMPTY
|
||||
|
||||
override fun setProperty(name: Name, item: MetaItem<*>?, notify: Boolean) {
|
||||
override fun getOwnProperty(name: Name): MetaItem? = getChildProperty(childName, name)
|
||||
|
||||
override fun setProperty(name: Name, item: MetaItem?, notify: Boolean) {
|
||||
setChildProperty(childName, name, item, notify)
|
||||
}
|
||||
|
||||
@ -110,7 +112,7 @@ public class SolidReferenceGroup(
|
||||
inherit: Boolean,
|
||||
includeStyles: Boolean,
|
||||
includeDefaults: Boolean,
|
||||
): MetaItem<*>? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||
): MetaItem? = getRefProperty(name, inherit, includeStyles, includeDefaults)
|
||||
|
||||
override var parent: VisionGroup?
|
||||
get() {
|
||||
|
@ -3,7 +3,7 @@ package hep.dataforge.vision.solid.specifications
|
||||
import hep.dataforge.meta.*
|
||||
|
||||
public class Axes : Scheme() {
|
||||
public var visible: Boolean by boolean(!config.isEmpty())
|
||||
public var visible: Boolean by boolean(rootNode?.isEmpty() != false)
|
||||
public var size: Double by double(AXIS_SIZE)
|
||||
public var width: Double by double(AXIS_WIDTH)
|
||||
|
||||
|
@ -9,7 +9,7 @@ import hep.dataforge.vision.solid.*
|
||||
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
|
||||
return child.apply {
|
||||
|
||||
configure(parent.properties)
|
||||
configure(parent.meta)
|
||||
|
||||
//parent.properties?.let { config.update(it) }
|
||||
|
||||
|
@ -28,7 +28,7 @@ class ConvexTest {
|
||||
val json = SolidManager.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex)
|
||||
val meta = json.toMetaItem().node!!
|
||||
|
||||
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }
|
||||
val points = meta.getIndexed("points").values.map { (it as NodeItem<*>).node.point3D() }
|
||||
assertEquals(8, points.count())
|
||||
|
||||
assertEquals(8, convex.points.size)
|
||||
|
@ -4,7 +4,6 @@ import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.MutableVisionGroup
|
||||
import hep.dataforge.vision.get
|
||||
import hep.dataforge.vision.properties
|
||||
import kotlin.test.Test
|
||||
import kotlin.test.assertEquals
|
||||
|
||||
@ -33,7 +32,7 @@ class SerializationTest {
|
||||
val string = SolidManager.encodeToString(cube)
|
||||
println(string)
|
||||
val newCube = SolidManager.decodeFromString(string)
|
||||
assertEquals(cube.properties, newCube.properties)
|
||||
assertEquals(cube.meta, newCube.meta)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -54,7 +53,7 @@ class SerializationTest {
|
||||
val string = SolidManager.encodeToString(group)
|
||||
println(string)
|
||||
val reconstructed = SolidManager.decodeFromString(string) as SolidGroup
|
||||
assertEquals(group["cube"]?.properties, reconstructed["cube"]?.properties)
|
||||
assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta)
|
||||
}
|
||||
|
||||
}
|
@ -1,6 +1,6 @@
|
||||
package hep.dataforge.vision.solid.three
|
||||
|
||||
import hep.dataforge.meta.getItem
|
||||
import hep.dataforge.meta.get
|
||||
import hep.dataforge.meta.string
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.plus
|
||||
@ -177,7 +177,7 @@ public class ThreeCanvas(
|
||||
}
|
||||
|
||||
private fun addControls(element: Node, controls: Controls) {
|
||||
when (controls.getItem("type").string) {
|
||||
when (controls.get("type").string) {
|
||||
"trackball" -> TrackballControls(camera, element)
|
||||
else -> OrbitControls(camera, element)
|
||||
}
|
||||
|
@ -109,15 +109,15 @@ public object ThreeMaterials {
|
||||
/**
|
||||
* Infer color based on meta item
|
||||
*/
|
||||
public fun MetaItem<*>.getColor(): Color {
|
||||
public fun MetaItem.getColor(): Color {
|
||||
return when (this) {
|
||||
is MetaItem.ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||
is ValueItem -> if (this.value.type == ValueType.NUMBER) {
|
||||
val int = value.int
|
||||
Color(int)
|
||||
} else {
|
||||
Color(this.value.string)
|
||||
}
|
||||
is MetaItem.NodeItem -> {
|
||||
is NodeItem -> {
|
||||
Color(
|
||||
node[Colors.RED_KEY]?.int ?: 0,
|
||||
node[Colors.GREEN_KEY]?.int ?: 0,
|
||||
@ -160,7 +160,7 @@ public fun Mesh.updateMaterial(vision: Vision) {
|
||||
}
|
||||
|
||||
public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
||||
if (material.cached) {
|
||||
if (material.cached || propertyName == SolidMaterial.MATERIAL_KEY) {
|
||||
//generate a new material since cached material should not be changed
|
||||
updateMaterial(vision)
|
||||
} else {
|
||||
|
@ -17,7 +17,7 @@ import kotlin.math.PI
|
||||
|
||||
public val Solid.euler: Euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
|
||||
|
||||
public val MetaItem<*>.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
|
||||
public val MetaItem.vector: Vector3 get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)
|
||||
|
||||
public fun Geometry.toBufferGeometry(): BufferGeometry = BufferGeometry().apply { fromGeometry(this@toBufferGeometry) }
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user