0.2.0 #71
@ -2,14 +2,13 @@ plugins {
|
|||||||
id("ru.mipt.npm.gradle.project")
|
id("ru.mipt.npm.gradle.project")
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion by extra("0.5.0-dev-10")
|
val dataforgeVersion by extra("0.5.0-dev-11")
|
||||||
val fxVersion by extra("11")
|
val fxVersion by extra("11")
|
||||||
|
|
||||||
allprojects {
|
allprojects {
|
||||||
repositories {
|
repositories {
|
||||||
mavenLocal()
|
mavenLocal()
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
jcenter()
|
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
maven("https://maven.jzy3d.org/releases")
|
maven("https://maven.jzy3d.org/releases")
|
||||||
}
|
}
|
||||||
|
@ -4,27 +4,36 @@ import space.kscience.dataforge.names.Name
|
|||||||
import space.kscience.dataforge.values.asValue
|
import space.kscience.dataforge.values.asValue
|
||||||
import space.kscience.dataforge.values.string
|
import space.kscience.dataforge.values.string
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.computeProperties
|
||||||
|
import space.kscience.visionforge.get
|
||||||
import space.kscience.visionforge.setProperty
|
import space.kscience.visionforge.setProperty
|
||||||
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
|
import space.kscience.visionforge.solid.material
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotNull
|
import kotlin.test.assertNotNull
|
||||||
|
|
||||||
class GDMLVisionTest {
|
class GDMLVisionTest {
|
||||||
|
private val cubes = GdmlShowCase.cubes().toVision()
|
||||||
|
|
||||||
// @Test
|
@Test
|
||||||
// fun testCubesStyles(){
|
fun testCubesStyles(){
|
||||||
// val cubes = gdml.toVision()
|
val segment = cubes["composite-000.segment-0"] as Solid
|
||||||
// val segment = cubes["composite000.segment_0".toName()] as Solid
|
println(segment.computeProperties().getValue(Vision.STYLE_KEY))
|
||||||
// println(segment.styles)
|
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
||||||
// println(segment.material)
|
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
||||||
// }
|
|
||||||
|
println(segment.material?.meta)
|
||||||
|
|
||||||
|
//println(Solids.encodeToString(cubes))
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPrototypeProperty() {
|
fun testPrototypeProperty() {
|
||||||
val vision = GdmlShowCase.cubes().toVision()
|
val child = cubes[Name.of("composite-000","segment-0")]
|
||||||
val child = vision[Name.of("composite-000","segment-0")]
|
|
||||||
assertNotNull(child)
|
assertNotNull(child)
|
||||||
child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
||||||
assertEquals("red", child.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.string)
|
assertEquals("red", child.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.string)
|
||||||
|
@ -7,7 +7,6 @@ import space.kscience.dataforge.context.Context
|
|||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.computeProperties
|
|
||||||
import space.kscience.visionforge.editor.VisionEditorFragment
|
import space.kscience.visionforge.editor.VisionEditorFragment
|
||||||
import space.kscience.visionforge.editor.VisionTreeFragment
|
import space.kscience.visionforge.editor.VisionTreeFragment
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
@ -33,9 +32,7 @@ class GDMLView : View() {
|
|||||||
this.itemProperty.bind(canvas.rootObjectProperty)
|
this.itemProperty.bind(canvas.rootObjectProperty)
|
||||||
}
|
}
|
||||||
|
|
||||||
private val propertyEditor = VisionEditorFragment {
|
private val propertyEditor = VisionEditorFragment().apply {
|
||||||
it.computeProperties()
|
|
||||||
}.apply {
|
|
||||||
descriptorProperty.set(SolidMaterial.descriptor)
|
descriptorProperty.set(SolidMaterial.descriptor)
|
||||||
visionProperty.bind(treeFragment.selectedProperty)
|
visionProperty.bind(treeFragment.selectedProperty)
|
||||||
}
|
}
|
||||||
|
@ -28,6 +28,7 @@ class Model(val manager: VisionManager) {
|
|||||||
|
|
||||||
private fun SolidGroup.detector(detector: SC16) {
|
private fun SolidGroup.detector(detector: SC16) {
|
||||||
group(detector.name) {
|
group(detector.name) {
|
||||||
|
position = detector.center
|
||||||
detector.pixels.forEach {
|
detector.pixels.forEach {
|
||||||
pixel(it)
|
pixel(it)
|
||||||
}
|
}
|
||||||
@ -38,6 +39,10 @@ class Model(val manager: VisionManager) {
|
|||||||
|
|
||||||
val root: SolidGroup = SolidGroup().apply {
|
val root: SolidGroup = SolidGroup().apply {
|
||||||
root(this@Model.manager)
|
root(this@Model.manager)
|
||||||
|
material {
|
||||||
|
wireframe
|
||||||
|
color("darkgreen")
|
||||||
|
}
|
||||||
rotationX = PI / 2
|
rotationX = PI / 2
|
||||||
group("bottom") {
|
group("bottom") {
|
||||||
Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach {
|
Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach {
|
||||||
|
@ -3,7 +3,6 @@ package ru.mipt.npm.muon.monitor
|
|||||||
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
|
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
|
||||||
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE
|
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE
|
||||||
import space.kscience.visionforge.solid.Point3D
|
import space.kscience.visionforge.solid.Point3D
|
||||||
import space.kscience.visionforge.solid.plus
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single pixel
|
* A single pixel
|
||||||
@ -98,7 +97,7 @@ class SC16(
|
|||||||
}
|
}
|
||||||
val offset = Point3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0));
|
val offset = Point3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0));
|
||||||
val pixelName = "${name}_${index}"
|
val pixelName = "${name}_${index}"
|
||||||
SC1(pixelName, center + offset)
|
SC1(pixelName, offset)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package ru.mipt.npm.muon.monitor
|
|||||||
|
|
||||||
import io.ktor.client.HttpClient
|
import io.ktor.client.HttpClient
|
||||||
import io.ktor.client.request.get
|
import io.ktor.client.request.get
|
||||||
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.coroutines.GlobalScope
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
@ -23,6 +24,7 @@ import space.kscience.visionforge.react.flexColumn
|
|||||||
import space.kscience.visionforge.react.visionTree
|
import space.kscience.visionforge.react.visionTree
|
||||||
import space.kscience.visionforge.solid.specifications.Camera
|
import space.kscience.visionforge.solid.specifications.Camera
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
|
import space.kscience.visionforge.solid.three.edges
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
@ -34,6 +36,7 @@ external interface MMAppProps : RProps {
|
|||||||
var selected: Name?
|
var selected: Name?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
@JsExport
|
@JsExport
|
||||||
val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
||||||
var selected by useState { props.selected }
|
var selected by useState { props.selected }
|
||||||
@ -53,7 +56,9 @@ val MMApp = functionalComponent<MMAppProps>("Muon monitor") { props ->
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val root = props.model.root
|
val root = props.model.root.apply {
|
||||||
|
edges()
|
||||||
|
}
|
||||||
|
|
||||||
gridRow {
|
gridRow {
|
||||||
flexColumn {
|
flexColumn {
|
||||||
|
@ -7,18 +7,15 @@ import kotlinx.browser.document
|
|||||||
import react.child
|
import react.child
|
||||||
import react.dom.render
|
import react.dom.render
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Global
|
|
||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.bootstrap.useBootstrap
|
import space.kscience.visionforge.bootstrap.useBootstrap
|
||||||
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
|
|
||||||
private class MMDemoApp : Application {
|
private class MMDemoApp : Application {
|
||||||
|
|
||||||
private val visionManager = Global.fetch(VisionManager)
|
|
||||||
private val model = Model(visionManager)
|
|
||||||
|
|
||||||
private val connection = HttpClient {
|
private val connection = HttpClient {
|
||||||
install(JsonFeature) {
|
install(JsonFeature) {
|
||||||
serializer = KotlinxSerializer()
|
serializer = KotlinxSerializer()
|
||||||
@ -28,13 +25,18 @@ private class MMDemoApp : Application {
|
|||||||
override fun start(state: Map<String, Any>) {
|
override fun start(state: Map<String, Any>) {
|
||||||
useBootstrap()
|
useBootstrap()
|
||||||
|
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
val context = Context("MM-demo"){
|
||||||
|
plugin(ThreePlugin)
|
||||||
|
}
|
||||||
|
val visionManager = context.fetch(VisionManager)
|
||||||
|
|
||||||
val context = Context("demo")
|
val model = Model(visionManager)
|
||||||
|
|
||||||
|
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||||
render(element) {
|
render(element) {
|
||||||
child(MMApp) {
|
child(MMApp) {
|
||||||
attrs {
|
attrs {
|
||||||
this.model = this@MMDemoApp.model
|
this.model = model
|
||||||
this.connection = this@MMDemoApp.connection
|
this.connection = this@MMDemoApp.connection
|
||||||
this.context = context
|
this.context = context
|
||||||
}
|
}
|
||||||
|
@ -19,7 +19,7 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
|
|||||||
"title" put title
|
"title" put title
|
||||||
}
|
}
|
||||||
val vision = SolidGroup(block)
|
val vision = SolidGroup(block)
|
||||||
render(Name.parse(name), vision)
|
render(Name.parse(name), vision, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
val canvasOptions = Canvas3DOptions {
|
val canvasOptions = Canvas3DOptions {
|
||||||
@ -36,6 +36,7 @@ val canvasOptions = Canvas3DOptions {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
fun VisionLayout<Solid>.showcase() {
|
fun VisionLayout<Solid>.showcase() {
|
||||||
demo("shapes", "Basic shapes") {
|
demo("shapes", "Basic shapes") {
|
||||||
box(100.0, 100.0, 100.0) {
|
box(100.0, 100.0, 100.0) {
|
||||||
|
@ -14,7 +14,7 @@ class FXDemoApp : App(FXDemoGrid::class) {
|
|||||||
stage.height = 600.0
|
stage.height = 600.0
|
||||||
|
|
||||||
view.showcase()
|
view.showcase()
|
||||||
view.showcaseCSG()
|
//view.showcaseCSG()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
package space.kscience.visionforge.demo
|
package space.kscience.visionforge.demo
|
||||||
|
|
||||||
import javafx.geometry.Orientation
|
import javafx.geometry.Orientation
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.MutableMeta
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.node
|
import space.kscience.dataforge.meta.descriptors.node
|
||||||
@ -46,12 +45,12 @@ class MetaEditorDemo : View("Meta editor demo") {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val rootNode = FXMetaModel.root(meta, descriptor)
|
private val rootNode:FXMetaModel<MutableMeta> = FXMetaModel.root(meta, descriptor)
|
||||||
|
|
||||||
override val root = splitpane(
|
override val root = splitpane(
|
||||||
Orientation.HORIZONTAL,
|
Orientation.HORIZONTAL,
|
||||||
MetaViewer(rootNode as Meta).root,
|
MetaViewer(rootNode).root,
|
||||||
MutableMetaEditor(rootNode as FXMetaModel<MutableMeta>).root
|
MutableMetaEditor(rootNode).root
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -12,9 +12,9 @@ import org.w3c.files.BlobPropertyBag
|
|||||||
import react.*
|
import react.*
|
||||||
import react.dom.attrs
|
import react.dom.attrs
|
||||||
import react.dom.button
|
import react.dom.button
|
||||||
import space.kscience.dataforge.meta.descriptors.defaultNode
|
|
||||||
import space.kscience.dataforge.meta.withDefault
|
import space.kscience.dataforge.meta.withDefault
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.encodeToString
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
import space.kscience.visionforge.react.propertyEditor
|
import space.kscience.visionforge.react.propertyEditor
|
||||||
@ -51,12 +51,12 @@ public val CanvasControls: FunctionComponent<CanvasControlsProps> = functionalCo
|
|||||||
border(1.px, BorderStyle.solid, Color.blue)
|
border(1.px, BorderStyle.solid, Color.blue)
|
||||||
padding(4.px)
|
padding(4.px)
|
||||||
}
|
}
|
||||||
props.vision?.manager?.let { manager ->
|
props.vision?.let{ vision ->
|
||||||
button {
|
button {
|
||||||
+"Export"
|
+"Export"
|
||||||
attrs {
|
attrs {
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
val json = manager.encodeToString(props.vision!!)
|
val json = vision.encodeToString()
|
||||||
saveData(it, "object.json", "text/json") {
|
saveData(it, "object.json", "text/json") {
|
||||||
json
|
json
|
||||||
}
|
}
|
||||||
|
@ -21,7 +21,7 @@ public external interface ThreeControlsProps : RProps {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
public val ThreeControls: FunctionalComponent<ThreeControlsProps> = functionalComponent { props ->
|
public val ThreeControls: FunctionComponent<ThreeControlsProps> = functionalComponent { props ->
|
||||||
tabPane(if (props.selected != null) "Properties" else null) {
|
tabPane(if (props.selected != null) "Properties" else null) {
|
||||||
tab("Canvas") {
|
tab("Canvas") {
|
||||||
card("Canvas configuration") {
|
card("Canvas configuration") {
|
||||||
|
@ -9,7 +9,6 @@ import react.dom.a
|
|||||||
import react.dom.attrs
|
import react.dom.attrs
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.defaultNode
|
|
||||||
import space.kscience.dataforge.meta.descriptors.get
|
import space.kscience.dataforge.meta.descriptors.get
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.isLeaf
|
import space.kscience.dataforge.meta.isLeaf
|
||||||
|
@ -121,7 +121,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) {
|
|||||||
}?.forEach {
|
}?.forEach {
|
||||||
add(NameToken(it.key))
|
add(NameToken(it.key))
|
||||||
}
|
}
|
||||||
ownProperty?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) }
|
//ownProperty?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) }
|
||||||
}
|
}
|
||||||
|
|
||||||
flexRow {
|
flexRow {
|
||||||
|
@ -15,7 +15,6 @@ import react.dom.button
|
|||||||
import ringui.Island
|
import ringui.Island
|
||||||
import ringui.SmartTabs
|
import ringui.SmartTabs
|
||||||
import ringui.Tab
|
import ringui.Tab
|
||||||
import space.kscience.dataforge.meta.descriptors.defaultNode
|
|
||||||
import space.kscience.dataforge.meta.withDefault
|
import space.kscience.dataforge.meta.withDefault
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
|
@ -1,53 +1,84 @@
|
|||||||
package space.kscience.visionforge
|
package space.kscience.visionforge
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.ObservableMutableMeta
|
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.get
|
import space.kscience.dataforge.meta.descriptors.get
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.NameToken
|
import space.kscience.dataforge.names.NameToken
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
|
import space.kscience.dataforge.values.MutableValueProvider
|
||||||
import space.kscience.dataforge.values.Value
|
import space.kscience.dataforge.values.Value
|
||||||
|
|
||||||
private class ComputedVisionProperties(
|
private class ComputedVisionProperties(
|
||||||
public val vision: Vision,
|
val vision: Vision,
|
||||||
public val rootName: Name,
|
val pathName: Name,
|
||||||
public val visionDescriptor: MetaDescriptor
|
val visionDescriptor: MetaDescriptor,
|
||||||
) : ObservableMutableMeta by vision.meta {
|
val parentInheritFlag: Boolean?,
|
||||||
|
val parentStylesFlag: Boolean?
|
||||||
|
) : Meta {
|
||||||
|
|
||||||
public val descriptor: MetaDescriptor? = visionDescriptor[rootName]
|
val descriptor: MetaDescriptor? by lazy { visionDescriptor[pathName] }
|
||||||
|
|
||||||
override val items: Map<NameToken, ObservableMutableMeta>
|
override val items: Map<NameToken, Meta>
|
||||||
get() {
|
get() {
|
||||||
val metaKeys = vision.meta.items.keys
|
val metaKeys = vision.meta.getMeta(pathName)?.items?.keys ?: emptySet()
|
||||||
val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet()
|
val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet()
|
||||||
return (metaKeys + descriptorKeys).associateWith { getMeta(rootName + it) }
|
val inheritFlag = descriptor?.inherited ?: parentInheritFlag
|
||||||
|
val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag
|
||||||
|
return (metaKeys + descriptorKeys).associateWith {
|
||||||
|
ComputedVisionProperties(
|
||||||
|
vision,
|
||||||
|
pathName + it,
|
||||||
|
visionDescriptor,
|
||||||
|
inheritFlag,
|
||||||
|
stylesFlag
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override var value: Value?
|
override val value: Value?
|
||||||
get() {
|
get() {
|
||||||
val inheritFlag = descriptor?.inherited ?: false
|
val inheritFlag = descriptor?.inherited ?: parentInheritFlag ?: false
|
||||||
val stylesFlag = descriptor?.usesStyles ?: true
|
val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag ?: true
|
||||||
return vision.getPropertyValue(rootName, inheritFlag, stylesFlag, true)
|
return vision.getPropertyValue(pathName, inheritFlag, stylesFlag, true)
|
||||||
}
|
|
||||||
set(value) {
|
|
||||||
vision.meta.setValue(rootName, value)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getMeta(name: Name): ObservableMutableMeta =
|
override fun toString(): String = Meta.toString(this)
|
||||||
ComputedVisionProperties(vision, rootName + name, visionDescriptor)
|
override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta)
|
||||||
|
override fun hashCode(): Int = Meta.hashCode(this)
|
||||||
override fun getOrCreate(name: Name): ObservableMutableMeta = getMeta(name)
|
|
||||||
|
|
||||||
override fun toMeta(): Meta = this
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Compute property node based on inheritance and style information from the descriptor
|
* Compute property node based on inheritance and style information from the descriptor
|
||||||
*/
|
*/
|
||||||
public fun Vision.computeProperties(descriptor: MetaDescriptor? = this.descriptor): ObservableMutableMeta =
|
public fun Vision.computeProperties(descriptor: MetaDescriptor? = this.descriptor): Meta =
|
||||||
if (descriptor == null) meta else ComputedVisionProperties(this, Name.EMPTY, descriptor)
|
if (descriptor == null) meta else ComputedVisionProperties(this, Name.EMPTY, descriptor, null, null)
|
||||||
|
|
||||||
|
public fun Vision.computePropertyNode(
|
||||||
|
name: Name,
|
||||||
|
descriptor: MetaDescriptor? = this.descriptor
|
||||||
|
): Meta? = computeProperties(descriptor)[name]
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Compute the property based on the provided value descriptor. By default, use Vision own descriptor
|
||||||
|
*/
|
||||||
|
public fun Vision.computeProperty(name: Name, valueDescriptor: MetaDescriptor? = descriptor?.get(name)): Value? {
|
||||||
|
val inheritFlag = valueDescriptor?.inherited ?: false
|
||||||
|
val stylesFlag = valueDescriptor?.usesStyles ?: true
|
||||||
|
return getPropertyValue(name, inheritFlag, stylesFlag)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Accessor to all vision properties
|
||||||
|
*/
|
||||||
|
public fun Vision.computePropertyValues(
|
||||||
|
descriptor: MetaDescriptor? = this.descriptor
|
||||||
|
): MutableValueProvider = object : MutableValueProvider {
|
||||||
|
override fun getValue(name: Name): Value? = computeProperty(name, descriptor?.get(name))
|
||||||
|
|
||||||
|
override fun setValue(name: Name, value: Value?) {
|
||||||
|
setProperty(name, value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public fun Vision.computePropertyNode(name: Name, descriptor: MetaDescriptor? = this.descriptor): ObservableMutableMeta? =
|
|
||||||
computeProperties(descriptor)[name]
|
|
@ -7,6 +7,7 @@ import space.kscience.dataforge.names.asName
|
|||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
import space.kscience.dataforge.values.Value
|
import space.kscience.dataforge.values.Value
|
||||||
import space.kscience.dataforge.values.asValue
|
import space.kscience.dataforge.values.asValue
|
||||||
|
import space.kscience.dataforge.values.stringList
|
||||||
import kotlin.jvm.JvmInline
|
import kotlin.jvm.JvmInline
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -72,7 +73,7 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?)
|
|||||||
* List of names of styles applied to this object. Order matters. Not inherited.
|
* List of names of styles applied to this object. Order matters. Not inherited.
|
||||||
*/
|
*/
|
||||||
public var Vision.styles: List<String>
|
public var Vision.styles: List<String>
|
||||||
get() = meta.getMeta(Vision.STYLE_KEY)?.stringList ?: emptyList()
|
get() = meta.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList()
|
||||||
set(value) {
|
set(value) {
|
||||||
meta.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue())
|
meta.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue())
|
||||||
}
|
}
|
||||||
@ -105,7 +106,7 @@ public fun Vision.getStyleProperty(name: Name): Value? = styles.firstNotNullOfOr
|
|||||||
/**
|
/**
|
||||||
* Resolve an item in all style layers
|
* Resolve an item in all style layers
|
||||||
*/
|
*/
|
||||||
public fun Vision.getStyleItems(name: Name): List<Meta> = styles.mapNotNull {
|
public fun Vision.getStyleNodes(name: Name): List<Meta> = styles.mapNotNull {
|
||||||
getStyle(it)?.get(name)
|
getStyle(it)?.get(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
import space.kscience.dataforge.meta.MutableMeta
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.ObservableMutableMeta
|
import space.kscience.dataforge.meta.ObservableMutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.defaultNode
|
|
||||||
import space.kscience.dataforge.meta.descriptors.value
|
import space.kscience.dataforge.meta.descriptors.value
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
@ -30,9 +29,11 @@ internal data class MetaListener(
|
|||||||
@SerialName("vision")
|
@SerialName("vision")
|
||||||
public open class VisionBase(
|
public open class VisionBase(
|
||||||
@Transient override var parent: VisionGroup? = null,
|
@Transient override var parent: VisionGroup? = null,
|
||||||
protected var properties: MutableMeta? = null
|
|
||||||
) : Vision {
|
) : Vision {
|
||||||
|
|
||||||
|
@Transient
|
||||||
|
protected open var properties: MutableMeta? = null
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
protected fun getOrCreateProperties(): MutableMeta {
|
protected fun getOrCreateProperties(): MutableMeta {
|
||||||
if (properties == null) {
|
if (properties == null) {
|
||||||
@ -45,50 +46,55 @@ public open class VisionBase(
|
|||||||
@Transient
|
@Transient
|
||||||
private val listeners = HashSet<MetaListener>()
|
private val listeners = HashSet<MetaListener>()
|
||||||
|
|
||||||
private inner class VisionBaseProperties(val rootName: Name) : ObservableMutableMeta {
|
private inner class VisionProperties(val pathName: Name) : ObservableMutableMeta {
|
||||||
|
|
||||||
override val items: Map<NameToken, ObservableMutableMeta>
|
override val items: Map<NameToken, ObservableMutableMeta>
|
||||||
get() = properties?.get(rootName)?.items?.mapValues { entry ->
|
get() = properties?.get(pathName)?.items?.mapValues { entry ->
|
||||||
VisionBaseProperties(rootName + entry.key)
|
VisionProperties(pathName + entry.key)
|
||||||
} ?: emptyMap()
|
} ?: emptyMap()
|
||||||
|
|
||||||
override var value: Value?
|
override var value: Value?
|
||||||
get() = properties?.get(rootName)?.value
|
get() = properties?.get(pathName)?.value
|
||||||
set(value) {
|
set(value) {
|
||||||
getOrCreateProperties().setValue(rootName, value)
|
val oldValue = properties?.get(pathName)?.value
|
||||||
|
getOrCreateProperties().setValue(pathName, value)
|
||||||
|
if (oldValue != value) {
|
||||||
|
invalidate(Name.EMPTY)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getOrCreate(name: Name): ObservableMutableMeta = VisionBaseProperties(this.rootName + name)
|
override fun getOrCreate(name: Name): ObservableMutableMeta = VisionProperties(pathName + name)
|
||||||
|
|
||||||
override fun setMeta(name: Name, node: Meta?) {
|
override fun setMeta(name: Name, node: Meta?) {
|
||||||
getOrCreateProperties().setMeta(name, node)
|
getOrCreateProperties().setMeta(pathName + name, node)
|
||||||
|
invalidate(name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
override fun attach(name: Name, node: ObservableMutableMeta) {
|
override fun attach(name: Name, node: ObservableMutableMeta) {
|
||||||
val ownProperties = getOrCreateProperties()
|
val ownProperties = getOrCreateProperties()
|
||||||
if (ownProperties is ObservableMutableMeta) {
|
if (ownProperties is ObservableMutableMeta) {
|
||||||
ownProperties.attach(rootName + name, node)
|
ownProperties.attach(pathName + name, node)
|
||||||
} else {
|
} else {
|
||||||
ownProperties.setMeta(rootName + name, node)
|
ownProperties.setMeta(pathName + name, node)
|
||||||
node.onChange(this) { childName ->
|
node.onChange(this) { childName ->
|
||||||
ownProperties.setMeta(rootName + name + childName, this[childName])
|
ownProperties.setMeta(pathName + name + childName, this[childName])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun invalidate(name: Name) {
|
override fun invalidate(name: Name) {
|
||||||
invalidateProperty(rootName + name)
|
invalidateProperty(pathName + name)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Synchronized
|
@Synchronized
|
||||||
override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) {
|
override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) {
|
||||||
if (rootName.isEmpty()) {
|
if (pathName.isEmpty()) {
|
||||||
listeners.add((MetaListener(owner, callback)))
|
listeners.add((MetaListener(owner, callback)))
|
||||||
} else {
|
} else {
|
||||||
listeners.add(MetaListener(owner) { name ->
|
listeners.add(MetaListener(owner) { name ->
|
||||||
if (name.startsWith(rootName)) {
|
if (name.startsWith(pathName)) {
|
||||||
(get(rootName) ?: Meta.EMPTY).callback(name.removeHeadOrNull(rootName)!!)
|
(this@MetaListener[pathName] ?: Meta.EMPTY).callback(name.removeHeadOrNull(pathName)!!)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@ -104,7 +110,7 @@ public open class VisionBase(
|
|||||||
override fun hashCode(): Int = Meta.hashCode(this)
|
override fun hashCode(): Int = Meta.hashCode(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
override val meta: ObservableMutableMeta get() = VisionBaseProperties(Name.EMPTY)
|
override val meta: ObservableMutableMeta get() = VisionProperties(Name.EMPTY)
|
||||||
|
|
||||||
override fun getPropertyValue(
|
override fun getPropertyValue(
|
||||||
name: Name,
|
name: Name,
|
||||||
|
@ -4,6 +4,9 @@ import kotlinx.coroutines.flow.Flow
|
|||||||
import space.kscience.dataforge.names.*
|
import space.kscience.dataforge.names.*
|
||||||
import space.kscience.dataforge.provider.Provider
|
import space.kscience.dataforge.provider.Provider
|
||||||
|
|
||||||
|
@DslMarker
|
||||||
|
public annotation class VisionBuilder
|
||||||
|
|
||||||
public interface VisionContainer<out V : Vision> {
|
public interface VisionContainer<out V : Vision> {
|
||||||
public operator fun get(name: Name): V?
|
public operator fun get(name: Name): V?
|
||||||
}
|
}
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
package space.kscience.visionforge
|
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.Laminate
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.isLeaf
|
|
||||||
|
|
||||||
@DslMarker
|
|
||||||
public annotation class VisionBuilder
|
|
||||||
|
|
||||||
public fun List<Meta?>.merge(): Meta? {
|
|
||||||
val first = firstOrNull { it != null }
|
|
||||||
return when {
|
|
||||||
first == null -> null
|
|
||||||
first.isLeaf -> first //fast search for first entry if it is value
|
|
||||||
else -> Laminate(filterNotNull()) //merge nodes if first encountered node is meta
|
|
||||||
}
|
|
||||||
}
|
|
@ -7,20 +7,20 @@ import space.kscience.dataforge.values.asValue
|
|||||||
private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited"
|
private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited"
|
||||||
private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles"
|
private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles"
|
||||||
|
|
||||||
public val MetaDescriptor.inherited: Boolean
|
public val MetaDescriptor.inherited: Boolean?
|
||||||
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean ?: false
|
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean
|
||||||
|
|
||||||
public var MetaDescriptorBuilder.inherited: Boolean
|
public var MetaDescriptorBuilder.inherited: Boolean?
|
||||||
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean ?: false
|
get() = attributes[INHERITED_DESCRIPTOR_ATTRIBUTE].boolean
|
||||||
set(value) = attributes.set(INHERITED_DESCRIPTOR_ATTRIBUTE, value)
|
set(value) = attributes.set(INHERITED_DESCRIPTOR_ATTRIBUTE, value?.asValue())
|
||||||
|
|
||||||
|
|
||||||
public val MetaDescriptor.usesStyles: Boolean
|
public val MetaDescriptor.usesStyles: Boolean?
|
||||||
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean ?: true
|
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean
|
||||||
|
|
||||||
public var MetaDescriptorBuilder.usesStyles: Boolean
|
public var MetaDescriptorBuilder.usesStyles: Boolean?
|
||||||
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean ?: true
|
get() = attributes[STYLE_DESCRIPTOR_ATTRIBUTE].boolean
|
||||||
set(value) = attributes.set(STYLE_DESCRIPTOR_ATTRIBUTE, value)
|
set(value) = attributes.set(STYLE_DESCRIPTOR_ATTRIBUTE, value?.asValue())
|
||||||
|
|
||||||
public val MetaDescriptor.widget: Meta
|
public val MetaDescriptor.widget: Meta
|
||||||
get() = attributes["widget"] ?: Meta.EMPTY
|
get() = attributes["widget"] ?: Meta.EMPTY
|
||||||
@ -38,7 +38,7 @@ public val MetaDescriptor.widgetType: String?
|
|||||||
get() = attributes["widget.type"].string
|
get() = attributes["widget.type"].string
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Extension property to access the "widget.type" key of [ValueDescriptor]
|
* Extension property to access the "widget.type" key of [MetaDescriptorBuilder]
|
||||||
*/
|
*/
|
||||||
public var MetaDescriptorBuilder.widgetType: String?
|
public var MetaDescriptorBuilder.widgetType: String?
|
||||||
get() = attributes["widget.type"].string
|
get() = attributes["widget.type"].string
|
||||||
|
@ -12,9 +12,6 @@ import space.kscience.dataforge.names.Name
|
|||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionBase
|
import space.kscience.visionforge.VisionBase
|
||||||
import space.kscience.visionforge.VisionManager
|
import space.kscience.visionforge.VisionManager
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.collections.Map
|
|
||||||
import kotlin.collections.forEach
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
|
|
||||||
|
@ -14,17 +14,10 @@ dependencies {
|
|||||||
|
|
||||||
api("no.tornado:tornadofx:1.7.20")
|
api("no.tornado:tornadofx:1.7.20")
|
||||||
|
|
||||||
api("de.jensd:fontawesomefx-fontawesome:4.7.0-11") {
|
|
||||||
exclude(group = "org.openjfx")
|
|
||||||
}
|
|
||||||
|
|
||||||
api("de.jensd:fontawesomefx-commons:11.0") {
|
|
||||||
exclude(group = "org.openjfx")
|
|
||||||
}
|
|
||||||
|
|
||||||
api("org.fxyz3d:fxyz3d:0.5.4") {
|
api("org.fxyz3d:fxyz3d:0.5.4") {
|
||||||
exclude(module = "slf4j-simple")
|
exclude(module = "slf4j-simple")
|
||||||
}
|
}
|
||||||
|
|
||||||
api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}")
|
api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}")
|
||||||
|
|
||||||
implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") {
|
implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") {
|
||||||
|
@ -21,23 +21,29 @@ import tornadofx.*
|
|||||||
public class FXMetaModel<M : Meta>(
|
public class FXMetaModel<M : Meta>(
|
||||||
public val root: M,
|
public val root: M,
|
||||||
public val rootDescriptor: MetaDescriptor?,
|
public val rootDescriptor: MetaDescriptor?,
|
||||||
public val nodeName: Name,
|
public val defaultRoot: Meta?,
|
||||||
public val title: String = nodeName.lastOrNull()?.toString() ?: "Meta"
|
public val pathName: Name,
|
||||||
|
public val title: String = pathName.lastOrNull()?.toString() ?: "Meta"
|
||||||
) : Comparable<FXMetaModel<*>> {
|
) : Comparable<FXMetaModel<*>> {
|
||||||
|
|
||||||
private val existingNode = object: ObjectBinding<Meta?>() {
|
private val existingNode = object: ObjectBinding<Meta?>() {
|
||||||
override fun computeValue(): Meta? =root[nodeName]
|
override fun computeValue(): Meta? = root[pathName]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val defaultNode: Meta? get() = defaultRoot?.getMeta(pathName)
|
||||||
|
|
||||||
|
public val descriptor: MetaDescriptor? = rootDescriptor?.get(pathName)
|
||||||
|
|
||||||
public val children: ListBinding<FXMetaModel<M>> = object : ListBinding<FXMetaModel<M>>() {
|
public val children: ListBinding<FXMetaModel<M>> = object : ListBinding<FXMetaModel<M>>() {
|
||||||
override fun computeValue(): ObservableList<FXMetaModel<M>> {
|
override fun computeValue(): ObservableList<FXMetaModel<M>> {
|
||||||
val nodeKeys = existingNode.get()?.items?.keys?: emptySet()
|
val nodeKeys = existingNode.get()?.items?.keys?: emptySet()
|
||||||
val descriptorKeys = descriptor?.children?.keys?.map { NameToken(it) } ?: emptySet()
|
val defaultKeys = defaultNode?.items?.keys ?: emptySet()
|
||||||
return (nodeKeys + descriptorKeys).map {
|
return (nodeKeys + defaultKeys).map {
|
||||||
FXMetaModel(
|
FXMetaModel(
|
||||||
root,
|
root,
|
||||||
rootDescriptor,
|
rootDescriptor,
|
||||||
nodeName + it
|
defaultRoot,
|
||||||
|
pathName + it
|
||||||
)
|
)
|
||||||
}.filter(filter).asObservable()
|
}.filter(filter).asObservable()
|
||||||
}
|
}
|
||||||
@ -47,16 +53,14 @@ public class FXMetaModel<M : Meta>(
|
|||||||
//add listener to the root node if possible
|
//add listener to the root node if possible
|
||||||
if (root is ObservableMeta) {
|
if (root is ObservableMeta) {
|
||||||
root.onChange(this) { changed ->
|
root.onChange(this) { changed ->
|
||||||
if (changed.startsWith(nodeName)) {
|
if (changed.startsWith(pathName)) {
|
||||||
if (nodeName.length == changed.length) existingNode.invalidate()
|
if (pathName.length == changed.length) existingNode.invalidate()
|
||||||
else if (changed.length == nodeName.length + 1) children.invalidate()
|
else if (changed.length == pathName.length + 1) children.invalidate()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public val descriptor: MetaDescriptor? = rootDescriptor?.get(nodeName)
|
|
||||||
|
|
||||||
public val existsProperty: BooleanBinding = existingNode.isNotNull
|
public val existsProperty: BooleanBinding = existingNode.isNotNull
|
||||||
|
|
||||||
public val exists: Boolean by existsProperty
|
public val exists: Boolean by existsProperty
|
||||||
@ -66,7 +70,7 @@ public class FXMetaModel<M : Meta>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun compareTo(other: FXMetaModel<*>): Int = if (this.exists == other.exists) {
|
override fun compareTo(other: FXMetaModel<*>): Int = if (this.exists == other.exists) {
|
||||||
this.nodeName.toString().compareTo(other.nodeName.toString())
|
this.pathName.toString().compareTo(other.pathName.toString())
|
||||||
} else {
|
} else {
|
||||||
this.exists.compareTo(other.exists)
|
this.exists.compareTo(other.exists)
|
||||||
}
|
}
|
||||||
@ -79,7 +83,8 @@ public class FXMetaModel<M : Meta>(
|
|||||||
public fun <M : Meta> root(
|
public fun <M : Meta> root(
|
||||||
node: M,
|
node: M,
|
||||||
descriptor: MetaDescriptor? = null,
|
descriptor: MetaDescriptor? = null,
|
||||||
|
defaultRoot: Meta? = null,
|
||||||
rootName: String = "root"
|
rootName: String = "root"
|
||||||
): FXMetaModel<M> = FXMetaModel(node, descriptor, Name.EMPTY, title = rootName)
|
): FXMetaModel<M> = FXMetaModel(node, descriptor, defaultRoot, Name.EMPTY, title = rootName)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -26,14 +26,12 @@ import space.kscience.visionforge.dfIconView
|
|||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
public class MetaViewer(
|
public class MetaViewer(
|
||||||
private val rootNode: FXMetaModel<Meta>,
|
private val rootNode: FXMetaModel<out Meta>,
|
||||||
title: String = "Meta viewer"
|
title: String = "Meta viewer"
|
||||||
) : Fragment(title, dfIconView) {
|
) : Fragment(title, dfIconView) {
|
||||||
|
|
||||||
public constructor(meta: Meta, title: String = "Meta viewer") : this(
|
public constructor(meta: Meta, title: String = "Meta viewer") : this(
|
||||||
FXMetaModel.root(
|
FXMetaModel.root(meta), title = title
|
||||||
meta
|
|
||||||
), title = title
|
|
||||||
)
|
)
|
||||||
|
|
||||||
override val root: BorderPane = borderpane {
|
override val root: BorderPane = borderpane {
|
||||||
|
@ -13,7 +13,6 @@ import javafx.scene.paint.Color
|
|||||||
import javafx.scene.text.Text
|
import javafx.scene.text.Text
|
||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
import space.kscience.dataforge.meta.MutableMeta
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
|
||||||
import space.kscience.dataforge.meta.remove
|
import space.kscience.dataforge.meta.remove
|
||||||
import space.kscience.visionforge.dfIconView
|
import space.kscience.visionforge.dfIconView
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
@ -25,16 +24,16 @@ import tornadofx.*
|
|||||||
*/
|
*/
|
||||||
public class MutableMetaEditor(
|
public class MutableMetaEditor(
|
||||||
public val rootNode: FXMetaModel<MutableMeta>,
|
public val rootNode: FXMetaModel<MutableMeta>,
|
||||||
public val allowNew: Boolean = true,
|
//public val allowNew: Boolean = true,
|
||||||
title: String = "Configuration editor"
|
title: String = "Meta editor"
|
||||||
) : Fragment(title = title, icon = dfIconView) {
|
) : Fragment(title = title, icon = dfIconView) {
|
||||||
//TODO replace parameters by properties
|
//TODO replace parameters by properties
|
||||||
|
//
|
||||||
public constructor(
|
// public constructor(
|
||||||
MutableMeta: MutableMeta,
|
// MutableMeta: MutableMeta,
|
||||||
descriptor: MetaDescriptor?,
|
// descriptor: MetaDescriptor?,
|
||||||
title: String = "Configuration editor"
|
// title: String = "Configuration editor"
|
||||||
) : this(FXMetaModel.root(MutableMeta, descriptor = descriptor), title = title)
|
// ) : this(FXMetaModel.root(MutableMeta, descriptor = descriptor), title = title)
|
||||||
|
|
||||||
override val root: BorderPane = borderpane {
|
override val root: BorderPane = borderpane {
|
||||||
center = treetableview<FXMetaModel<MutableMeta>> {
|
center = treetableview<FXMetaModel<MutableMeta>> {
|
||||||
@ -65,7 +64,7 @@ public class MutableMetaEditor(
|
|||||||
contextmenu {
|
contextmenu {
|
||||||
item("Remove") {
|
item("Remove") {
|
||||||
action {
|
action {
|
||||||
content.root.remove(content.nodeName)
|
content.root.remove(content.pathName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -128,7 +127,7 @@ public class MutableMetaEditor(
|
|||||||
item.valueProperty,
|
item.valueProperty,
|
||||||
item.descriptor
|
item.descriptor
|
||||||
) { value ->
|
) { value ->
|
||||||
item.root.setValue(item.nodeName, value)
|
item.root.setValue(item.pathName, value)
|
||||||
}
|
}
|
||||||
graphic = chooser.node
|
graphic = chooser.node
|
||||||
|
|
||||||
|
@ -5,31 +5,40 @@ import javafx.beans.property.SimpleObjectProperty
|
|||||||
import javafx.scene.Node
|
import javafx.scene.Node
|
||||||
import javafx.scene.Parent
|
import javafx.scene.Parent
|
||||||
import javafx.scene.layout.VBox
|
import javafx.scene.layout.VBox
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.ObservableMutableMeta
|
import space.kscience.dataforge.meta.ObservableMutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.computeProperties
|
import space.kscience.visionforge.computeProperties
|
||||||
import space.kscience.visionforge.getStyle
|
import space.kscience.visionforge.getStyle
|
||||||
import space.kscience.visionforge.styles
|
import space.kscience.visionforge.styles
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
public class VisionEditorFragment(public val selector: (Vision) -> ObservableMutableMeta = {it.computeProperties()}) : Fragment() {
|
public class VisionEditorFragment : Fragment() {
|
||||||
|
|
||||||
public val visionProperty: SimpleObjectProperty<Vision> = SimpleObjectProperty<Vision>()
|
public val visionProperty: SimpleObjectProperty<Vision> = SimpleObjectProperty<Vision>()
|
||||||
public var vision: Vision? by visionProperty
|
public var vision: Vision? by visionProperty
|
||||||
public val descriptorProperty: SimpleObjectProperty<MetaDescriptor> = SimpleObjectProperty<MetaDescriptor>()
|
public val descriptorProperty: SimpleObjectProperty<MetaDescriptor> = SimpleObjectProperty<MetaDescriptor>()
|
||||||
|
|
||||||
private val configProperty: Binding<ObservableMutableMeta?> = visionProperty.objectBinding { vision ->
|
private val configProperty: Binding<ObservableMutableMeta?> = visionProperty.objectBinding { vision ->
|
||||||
vision?.let(selector)
|
vision?.meta
|
||||||
}
|
}
|
||||||
|
|
||||||
private val configEditorProperty: Binding<Node?> = configProperty.objectBinding(descriptorProperty) {
|
private val configEditorProperty: Binding<Node?> = configProperty.objectBinding(descriptorProperty) {
|
||||||
it?.let {
|
it?.let { meta ->
|
||||||
MutableMetaEditor(it, descriptorProperty.get()).root
|
val node:FXMetaModel<MutableMeta> = FXMetaModel(
|
||||||
|
meta,
|
||||||
|
vision?.descriptor,
|
||||||
|
vision?.computeProperties(),
|
||||||
|
Name.EMPTY,
|
||||||
|
"Vision properties"
|
||||||
|
)
|
||||||
|
MutableMetaEditor(node).root
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() {
|
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding {
|
||||||
VBox().apply {
|
VBox().apply {
|
||||||
vision?.styles?.forEach { styleName ->
|
vision?.styles?.forEach { styleName ->
|
||||||
val styleMeta = vision?.getStyle(styleName)
|
val styleMeta = vision?.getStyle(styleName)
|
||||||
|
@ -24,7 +24,7 @@ import kotlin.collections.set
|
|||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class FX3DPlugin : AbstractPlugin() {
|
public class FX3DPlugin : AbstractPlugin() {
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
private val objectFactories = HashMap<KClass<out Solid>, FX3DFactory<*>>()
|
private val objectFactories = HashMap<KClass<out Solid>, FX3DFactory<*>>()
|
||||||
@ -43,7 +43,7 @@ class FX3DPlugin : AbstractPlugin() {
|
|||||||
as FX3DFactory<Solid>?
|
as FX3DFactory<Solid>?
|
||||||
}
|
}
|
||||||
|
|
||||||
fun buildNode(obj: Solid): Node {
|
public fun buildNode(obj: Solid): Node {
|
||||||
val binding = VisualObjectFXBinding(this, obj)
|
val binding = VisualObjectFXBinding(this, obj)
|
||||||
return when (obj) {
|
return when (obj) {
|
||||||
is SolidReferenceGroup -> referenceFactory(obj, binding)
|
is SolidReferenceGroup -> referenceFactory(obj, binding)
|
||||||
|
@ -37,24 +37,22 @@ public object FXMaterials {
|
|||||||
* Infer color based on meta item
|
* Infer color based on meta item
|
||||||
* @param opacity default opacity
|
* @param opacity default opacity
|
||||||
*/
|
*/
|
||||||
public fun Meta.color(opacity: Double = 1.0): Color {
|
public fun Meta.color(opacity: Double = 1.0): Color = value?.let {
|
||||||
return value?.let {
|
if (it.type == ValueType.NUMBER) {
|
||||||
if (it.type == ValueType.NUMBER) {
|
val int = it.int
|
||||||
val int = it.int
|
val red = int and 0x00ff0000 shr 16
|
||||||
val red = int and 0x00ff0000 shr 16
|
val green = int and 0x0000ff00 shr 8
|
||||||
val green = int and 0x0000ff00 shr 8
|
val blue = int and 0x000000ff
|
||||||
val blue = int and 0x000000ff
|
Color.rgb(red, green, blue, opacity)
|
||||||
Color.rgb(red, green, blue, opacity)
|
} else {
|
||||||
} else {
|
Color.web(it.string)
|
||||||
Color.web(it.string)
|
}
|
||||||
}
|
} ?: Color.rgb(
|
||||||
} ?: Color.rgb(
|
this[Colors.RED_KEY]?.int ?: 0,
|
||||||
this[Colors.RED_KEY]?.int ?: 0,
|
this[Colors.GREEN_KEY]?.int ?: 0,
|
||||||
this[Colors.GREEN_KEY]?.int ?: 0,
|
this[Colors.BLUE_KEY]?.int ?: 0,
|
||||||
this[Colors.BLUE_KEY]?.int ?: 0,
|
this[SolidMaterial.OPACITY_KEY]?.double ?: opacity
|
||||||
this[SolidMaterial.OPACITY_KEY]?.double ?: opacity
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Infer FX material based on meta item
|
* Infer FX material based on meta item
|
||||||
|
@ -10,7 +10,7 @@ import space.kscience.visionforge.Vision
|
|||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
class FXReferenceFactory(val plugin: FX3DPlugin) : FX3DFactory<SolidReferenceGroup> {
|
public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory<SolidReferenceGroup> {
|
||||||
override val type: KClass<in SolidReferenceGroup> get() = SolidReferenceGroup::class
|
override val type: KClass<in SolidReferenceGroup> get() = SolidReferenceGroup::class
|
||||||
|
|
||||||
override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node {
|
override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node {
|
||||||
|
@ -441,20 +441,6 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
|||||||
}
|
}
|
||||||
final.useStyle(rootStyle)
|
final.useStyle(rootStyle)
|
||||||
|
|
||||||
//inline prototypes
|
|
||||||
// referenceStore.forEach { (protoName, list) ->
|
|
||||||
// val proxy = list.singleOrNull() ?: return@forEach
|
|
||||||
// val parent = proxy.parent as? MutableVisionGroup ?: return@forEach
|
|
||||||
// val token = parent.children.entries.find { it.value == proxy }?.key ?: error("Inconsistent reference cache")
|
|
||||||
// val prototype = proto[protoName] as? Solid ?: error("Inconsistent reference cache")
|
|
||||||
// prototype.parent = null
|
|
||||||
// parent[token] = prototype
|
|
||||||
// prototype.updateFrom(proxy)
|
|
||||||
//
|
|
||||||
// //FIXME update prototype
|
|
||||||
// proto[protoName] = null
|
|
||||||
// }
|
|
||||||
|
|
||||||
final.prototypes {
|
final.prototypes {
|
||||||
proto.children.forEach { (token, item) ->
|
proto.children.forEach { (token, item) ->
|
||||||
item.parent = null
|
item.parent = null
|
||||||
|
@ -15,7 +15,6 @@ public class VisionOfPlotly private constructor() : VisionBase() {
|
|||||||
public constructor(plot: Plot) : this() {
|
public constructor(plot: Plot) : this() {
|
||||||
properties = plot.meta
|
properties = plot.meta
|
||||||
}
|
}
|
||||||
|
|
||||||
public val plot: Plot get() = Plot(meta)
|
public val plot: Plot get() = Plot(meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,29 +1,28 @@
|
|||||||
package space.kscience.visionforge.solid
|
package space.kscience.visionforge.solid
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.*
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.plus
|
||||||
|
import space.kscience.dataforge.values.MutableValueProvider
|
||||||
import space.kscience.dataforge.values.Value
|
import space.kscience.dataforge.values.Value
|
||||||
import space.kscience.dataforge.values.asValue
|
import space.kscience.dataforge.values.asValue
|
||||||
import space.kscience.dataforge.values.string
|
import space.kscience.dataforge.values.string
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.Vision
|
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.VisionPropertyContainer
|
|
||||||
import kotlin.jvm.JvmInline
|
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public class ColorAccessor(private val colorKey: Name, private val parent: () -> MutableMetaProvider) {
|
public class ColorAccessor(private val provider: MutableValueProvider, private val colorKey: Name) :
|
||||||
|
MutableValueProvider {
|
||||||
public var value: Value?
|
public var value: Value?
|
||||||
get() = parent().getMeta(colorKey)?.value
|
get() = provider.getValue(colorKey)
|
||||||
set(value) {
|
set(value) {
|
||||||
parent().setValue(colorKey,value)
|
provider.setValue(colorKey, value)
|
||||||
}
|
}
|
||||||
|
|
||||||
public var item: Meta?
|
override fun getValue(name: Name): Value? = provider.getValue(colorKey + name)
|
||||||
get() = parent().getMeta(colorKey)
|
|
||||||
set(value) {
|
override fun setValue(name: Name, value: Value?) {
|
||||||
parent().setMeta(colorKey,value)
|
provider.setValue(colorKey + name, value)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public var ColorAccessor?.string: String?
|
public var ColorAccessor?.string: String?
|
||||||
|
@ -2,9 +2,10 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.dataforge.meta.configure
|
|
||||||
import space.kscience.dataforge.meta.update
|
import space.kscience.dataforge.meta.update
|
||||||
import space.kscience.visionforge.*
|
import space.kscience.visionforge.VisionBuilder
|
||||||
|
import space.kscience.visionforge.VisionContainerBuilder
|
||||||
|
import space.kscience.visionforge.set
|
||||||
|
|
||||||
public enum class CompositeType {
|
public enum class CompositeType {
|
||||||
SUM, // Dumb sum of meshes
|
SUM, // Dumb sum of meshes
|
||||||
@ -30,34 +31,38 @@ public inline fun VisionContainerBuilder<Solid>.composite(
|
|||||||
val group = SolidGroup().apply(builder)
|
val group = SolidGroup().apply(builder)
|
||||||
val children = group.children.values.filterIsInstance<Solid>()
|
val children = group.children.values.filterIsInstance<Solid>()
|
||||||
if (children.size != 2) error("Composite requires exactly two children")
|
if (children.size != 2) error("Composite requires exactly two children")
|
||||||
return Composite(type, children[0], children[1]).apply {
|
val res = Composite(type, children[0], children[1])
|
||||||
configure {
|
|
||||||
update(group.meta)
|
res.meta.update(group.meta)
|
||||||
}
|
|
||||||
if (group.position != null) {
|
if (group.position != null) {
|
||||||
position = group.position
|
res.position = group.position
|
||||||
}
|
|
||||||
if (group.rotation != null) {
|
|
||||||
rotation = group.rotation
|
|
||||||
}
|
|
||||||
if (group.scale != null) {
|
|
||||||
scale = group.scale
|
|
||||||
}
|
|
||||||
set(name, this)
|
|
||||||
}
|
}
|
||||||
|
if (group.rotation != null) {
|
||||||
|
res.rotation = group.rotation
|
||||||
|
}
|
||||||
|
if (group.scale != null) {
|
||||||
|
res.scale = group.scale
|
||||||
|
}
|
||||||
|
|
||||||
|
set(name, res)
|
||||||
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun VisionContainerBuilder<Solid>.union(name: String? = null, builder: SolidGroup.() -> Unit): Composite =
|
public inline fun VisionContainerBuilder<Solid>.union(
|
||||||
composite(CompositeType.UNION, name, builder = builder)
|
name: String? = null,
|
||||||
|
builder: SolidGroup.() -> Unit
|
||||||
|
): Composite = composite(CompositeType.UNION, name, builder = builder)
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun VisionContainerBuilder<Solid>.subtract(name: String? = null, builder: SolidGroup.() -> Unit): Composite =
|
public inline fun VisionContainerBuilder<Solid>.subtract(
|
||||||
composite(CompositeType.SUBTRACT, name, builder = builder)
|
name: String? = null,
|
||||||
|
builder: SolidGroup.() -> Unit
|
||||||
|
): Composite = composite(CompositeType.SUBTRACT, name, builder = builder)
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun VisionContainerBuilder<Solid>.intersect(
|
public inline fun VisionContainerBuilder<Solid>.intersect(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
builder: SolidGroup.() -> Unit,
|
builder: SolidGroup.() -> Unit,
|
||||||
): Composite =
|
): Composite = composite(CompositeType.INTERSECT, name, builder = builder)
|
||||||
composite(CompositeType.INTERSECT, name, builder = builder)
|
|
@ -2,6 +2,7 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.visionforge.VisionBase
|
import space.kscience.visionforge.VisionBase
|
||||||
import space.kscience.visionforge.VisionChange
|
import space.kscience.visionforge.VisionChange
|
||||||
@ -9,6 +10,9 @@ import space.kscience.visionforge.VisionChange
|
|||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid")
|
@SerialName("solid")
|
||||||
public open class SolidBase : VisionBase(), Solid {
|
public open class SolidBase : VisionBase(), Solid {
|
||||||
|
//FIXME to be removed after https://github.com/Kotlin/kotlinx.serialization/issues/1602 fix
|
||||||
|
override var properties: MutableMeta? = null
|
||||||
|
|
||||||
override val descriptor: MetaDescriptor get() = Solid.descriptor
|
override val descriptor: MetaDescriptor get() = Solid.descriptor
|
||||||
|
|
||||||
override fun update(change: VisionChange) {
|
override fun update(change: VisionChange) {
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.NameToken
|
import space.kscience.dataforge.names.NameToken
|
||||||
@ -31,6 +32,9 @@ public interface PrototypeHolder {
|
|||||||
@SerialName("group.solid")
|
@SerialName("group.solid")
|
||||||
public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder {
|
public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder {
|
||||||
|
|
||||||
|
//FIXME to be removed after https://github.com/Kotlin/kotlinx.serialization/issues/1602 fix
|
||||||
|
override var properties: MutableMeta? = null
|
||||||
|
|
||||||
override val children: Map<NameToken, Vision> get() = super.childrenInternal.filter { it.key != PROTOTYPES_TOKEN }
|
override val children: Map<NameToken, Vision> get() = super.childrenInternal.filter { it.key != PROTOTYPES_TOKEN }
|
||||||
|
|
||||||
private var prototypes: MutableVisionGroup?
|
private var prototypes: MutableVisionGroup?
|
||||||
|
@ -20,14 +20,14 @@ public class SolidMaterial : Scheme() {
|
|||||||
/**
|
/**
|
||||||
* Primary web-color for the material
|
* Primary web-color for the material
|
||||||
*/
|
*/
|
||||||
public val color: ColorAccessor = ColorAccessor(COLOR_KEY) { meta }
|
public val color: ColorAccessor = ColorAccessor(meta, COLOR_KEY)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Specular color for phong material
|
* Specular color for phong material
|
||||||
*/
|
*/
|
||||||
public val specularColor: ColorAccessor = ColorAccessor(SPECULAR_COLOR_KEY) { meta }
|
public val specularColor: ColorAccessor = ColorAccessor(meta, SPECULAR_COLOR_KEY)
|
||||||
|
|
||||||
public val emissiveColor: ColorAccessor = ColorAccessor("emissiveColor".asName()) { meta }
|
public val emissiveColor: ColorAccessor = ColorAccessor(meta, "emissiveColor".asName())
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Opacity
|
* Opacity
|
||||||
@ -55,33 +55,29 @@ public class SolidMaterial : Scheme() {
|
|||||||
//must be lazy to avoid initialization bug
|
//must be lazy to avoid initialization bug
|
||||||
MetaDescriptor {
|
MetaDescriptor {
|
||||||
inherited = true
|
inherited = true
|
||||||
usesStyles = true
|
|
||||||
|
|
||||||
value(COLOR_KEY, ValueType.STRING, ValueType.NUMBER) {
|
value(COLOR_KEY, ValueType.STRING, ValueType.NUMBER) {
|
||||||
inherited = true
|
inherited = true
|
||||||
usesStyles = true
|
|
||||||
widgetType = "color"
|
widgetType = "color"
|
||||||
}
|
}
|
||||||
|
|
||||||
value(SPECULAR_COLOR_KEY, ValueType.STRING, ValueType.NUMBER) {
|
value(SPECULAR_COLOR_KEY, ValueType.STRING, ValueType.NUMBER) {
|
||||||
inherited = true
|
inherited = true
|
||||||
usesStyles = true
|
|
||||||
widgetType = "color"
|
widgetType = "color"
|
||||||
hide()
|
hide()
|
||||||
}
|
}
|
||||||
|
|
||||||
value(OPACITY_KEY, ValueType.NUMBER) {
|
value(OPACITY_KEY, ValueType.NUMBER) {
|
||||||
inherited = true
|
inherited = true
|
||||||
usesStyles = true
|
|
||||||
default(1.0)
|
default(1.0)
|
||||||
attributes["min"] = 0.0
|
attributes["min"] = 0.0
|
||||||
attributes["max"] = 1.0
|
attributes["max"] = 1.0
|
||||||
attributes["step"] = 0.1
|
attributes["step"] = 0.1
|
||||||
widgetType = "slider"
|
widgetType = "slider"
|
||||||
}
|
}
|
||||||
|
|
||||||
value(WIREFRAME_KEY, ValueType.BOOLEAN) {
|
value(WIREFRAME_KEY, ValueType.BOOLEAN) {
|
||||||
inherited = true
|
inherited = true
|
||||||
usesStyles = true
|
|
||||||
default(false)
|
default(false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,7 +86,7 @@ public class SolidMaterial : Scheme() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public val Solid.color: ColorAccessor
|
public val Solid.color: ColorAccessor
|
||||||
get() = ColorAccessor(MATERIAL_COLOR_KEY) { computeProperties() }
|
get() = ColorAccessor(computePropertyValues(), MATERIAL_COLOR_KEY)
|
||||||
|
|
||||||
public var Solid.material: SolidMaterial?
|
public var Solid.material: SolidMaterial?
|
||||||
get() = computePropertyNode(MATERIAL_KEY)?.let { SolidMaterial.read(it) }
|
get() = computePropertyNode(MATERIAL_KEY)?.let { SolidMaterial.read(it) }
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
import kotlinx.serialization.SerialName
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
import space.kscience.dataforge.meta.ObservableMutableMeta
|
import space.kscience.dataforge.meta.ObservableMutableMeta
|
||||||
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
@ -12,11 +13,16 @@ import space.kscience.visionforge.*
|
|||||||
|
|
||||||
public interface SolidReference : VisionGroup {
|
public interface SolidReference : VisionGroup {
|
||||||
/**
|
/**
|
||||||
* The prototype for this reference. Always returns a "real" prototype, not a reference
|
* The prototype for this reference.
|
||||||
*/
|
*/
|
||||||
public val prototype: Solid
|
public val prototype: Solid
|
||||||
|
|
||||||
override fun getPropertyValue(name: Name, inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean): Value? {
|
override fun getPropertyValue(
|
||||||
|
name: Name,
|
||||||
|
inherit: Boolean,
|
||||||
|
includeStyles: Boolean,
|
||||||
|
includeDefaults: Boolean
|
||||||
|
): Value? {
|
||||||
meta[name]?.value?.let { return it }
|
meta[name]?.value?.let { return it }
|
||||||
if (includeStyles) {
|
if (includeStyles) {
|
||||||
getStyleProperty(name)?.let { return it }
|
getStyleProperty(name)?.let { return it }
|
||||||
@ -56,6 +62,8 @@ public class SolidReferenceGroup(
|
|||||||
public val refName: Name,
|
public val refName: Name,
|
||||||
) : VisionBase(), SolidReference, VisionGroup, Solid {
|
) : VisionBase(), SolidReference, VisionGroup, Solid {
|
||||||
|
|
||||||
|
override var properties: MutableMeta? = null
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Recursively search for defined template in the parent
|
* Recursively search for defined template in the parent
|
||||||
*/
|
*/
|
||||||
@ -72,8 +80,12 @@ public class SolidReferenceGroup(
|
|||||||
ReferenceChild(this, it.key.asName())
|
ReferenceChild(this, it.key.asName())
|
||||||
} ?: emptyMap()
|
} ?: emptyMap()
|
||||||
|
|
||||||
override fun getPropertyValue(name: Name, inherit: Boolean, includeStyles: Boolean, includeDefaults: Boolean): Value? =
|
override fun getPropertyValue(
|
||||||
super<SolidReference>.getPropertyValue(name, inherit, includeStyles, includeDefaults)
|
name: Name,
|
||||||
|
inherit: Boolean,
|
||||||
|
includeStyles: Boolean,
|
||||||
|
includeDefaults: Boolean
|
||||||
|
): Value? = super<SolidReference>.getPropertyValue(name, inherit, includeStyles, includeDefaults)
|
||||||
|
|
||||||
override val descriptor: MetaDescriptor get() = prototype.descriptor
|
override val descriptor: MetaDescriptor get() = prototype.descriptor
|
||||||
|
|
||||||
@ -88,11 +100,14 @@ public class SolidReferenceGroup(
|
|||||||
) : SolidReference, VisionGroup, Solid {
|
) : SolidReference, VisionGroup, Solid {
|
||||||
|
|
||||||
override val prototype: Solid by lazy {
|
override val prototype: Solid by lazy {
|
||||||
if (refName.isEmpty()) owner.prototype else {
|
if (refName.isEmpty()) {
|
||||||
|
owner.prototype
|
||||||
|
} else {
|
||||||
val proto = (owner.prototype as? VisionGroup)?.get(refName)
|
val proto = (owner.prototype as? VisionGroup)?.get(refName)
|
||||||
?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}")
|
?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}")
|
||||||
proto.unref as? Solid
|
proto as? Solid ?: error("Prototype with name $refName is ${proto::class} but expected Solid")
|
||||||
?: error("Prototype with name $refName is ${proto::class} but expected Solid")
|
// proto.unref as? Solid
|
||||||
|
// ?: error("Prototype with name $refName is ${proto::class} but expected Solid")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
package space.kscience.visionforge.solid
|
package space.kscience.visionforge.solid
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.get
|
||||||
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.values.int
|
import space.kscience.dataforge.values.int
|
||||||
import space.kscience.visionforge.*
|
import space.kscience.visionforge.*
|
||||||
@ -10,13 +11,32 @@ import kotlin.test.assertEquals
|
|||||||
@Suppress("UNUSED_VARIABLE")
|
@Suppress("UNUSED_VARIABLE")
|
||||||
class PropertyTest {
|
class PropertyTest {
|
||||||
@Test
|
@Test
|
||||||
fun testColorUpdate(){
|
fun testColor(){
|
||||||
val box = Box(10.0f, 10.0f,10.0f)
|
val box = Box(10.0f, 10.0f,10.0f)
|
||||||
box.material {
|
box.material {
|
||||||
//meta["color"] = "pink"
|
//meta["color"] = "pink"
|
||||||
color("pink")
|
color("pink")
|
||||||
}
|
}
|
||||||
assertEquals("pink", box.meta["material.color"]?.string)
|
assertEquals("pink", box.meta["material.color"]?.string)
|
||||||
|
assertEquals("pink", box.color.string)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testColorUpdate(){
|
||||||
|
val box = Box(10.0f, 10.0f,10.0f)
|
||||||
|
|
||||||
|
var c: String? = null
|
||||||
|
box.onPropertyChange {
|
||||||
|
if(it == SolidMaterial.MATERIAL_COLOR_KEY){
|
||||||
|
c = box.color.string
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
box.material {
|
||||||
|
color("pink")
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals("pink", c)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -4,17 +4,20 @@ import info.laht.threekt.core.BufferGeometry
|
|||||||
import info.laht.threekt.geometries.EdgesGeometry
|
import info.laht.threekt.geometries.EdgesGeometry
|
||||||
import info.laht.threekt.objects.LineSegments
|
import info.laht.threekt.objects.LineSegments
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.updateWith
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
import space.kscience.dataforge.names.startsWith
|
import space.kscience.dataforge.names.startsWith
|
||||||
import space.kscience.dataforge.values.boolean
|
import space.kscience.dataforge.values.boolean
|
||||||
import space.kscience.visionforge.computeProperties
|
import space.kscience.visionforge.computePropertyNode
|
||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
|
import space.kscience.visionforge.setProperty
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import space.kscience.visionforge.solid.layer
|
import space.kscience.visionforge.solid.layer
|
||||||
|
import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY
|
||||||
|
import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_MATERIAL_KEY
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -62,6 +65,7 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
|||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public val EDGES_KEY: Name = "edges".asName()
|
public val EDGES_KEY: Name = "edges".asName()
|
||||||
|
|
||||||
//public val WIREFRAME_KEY: Name = "wireframe".asName()
|
//public val WIREFRAME_KEY: Name = "wireframe".asName()
|
||||||
public val ENABLED_KEY: Name = "enabled".asName()
|
public val ENABLED_KEY: Name = "enabled".asName()
|
||||||
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
|
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
|
||||||
@ -71,6 +75,11 @@ public abstract class MeshThreeFactory<in T : Solid>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) {
|
||||||
|
setProperty(EDGES_ENABLED_KEY, enabled)
|
||||||
|
meta.getOrCreate(EDGES_MATERIAL_KEY).updateWith(SolidMaterial, block)
|
||||||
|
}
|
||||||
|
|
||||||
internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
||||||
updateMaterial(obj)
|
updateMaterial(obj)
|
||||||
applyEdges(obj)
|
applyEdges(obj)
|
||||||
@ -84,12 +93,9 @@ internal fun Mesh.applyProperties(obj: Solid): Mesh = apply {
|
|||||||
public fun Mesh.applyEdges(obj: Solid) {
|
public fun Mesh.applyEdges(obj: Solid) {
|
||||||
val edges = children.find { it.name == "@edges" } as? LineSegments
|
val edges = children.find { it.name == "@edges" } as? LineSegments
|
||||||
//inherited edges definition, enabled by default
|
//inherited edges definition, enabled by default
|
||||||
if (obj.getPropertyValue(MeshThreeFactory.EDGES_ENABLED_KEY, inherit = true, includeStyles = true)?.boolean != false) {
|
if (obj.getPropertyValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) {
|
||||||
val bufferGeometry = geometry as? BufferGeometry ?: return
|
val bufferGeometry = geometry as? BufferGeometry ?: return
|
||||||
val material = ThreeMaterials.getLineMaterial(
|
val material = ThreeMaterials.getLineMaterial(obj.computePropertyNode(EDGES_MATERIAL_KEY), true)
|
||||||
obj.computeProperties().get(MeshThreeFactory.EDGES_MATERIAL_KEY),
|
|
||||||
true
|
|
||||||
)
|
|
||||||
if (edges == null) {
|
if (edges == null) {
|
||||||
add(
|
add(
|
||||||
LineSegments(
|
LineSegments(
|
||||||
|
@ -12,7 +12,7 @@ import org.w3c.dom.CanvasTextBaseline
|
|||||||
import org.w3c.dom.HTMLCanvasElement
|
import org.w3c.dom.HTMLCanvasElement
|
||||||
import org.w3c.dom.MIDDLE
|
import org.w3c.dom.MIDDLE
|
||||||
import space.kscience.visionforge.solid.SolidLabel
|
import space.kscience.visionforge.solid.SolidLabel
|
||||||
import space.kscience.visionforge.solid.color
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG
|
import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
@ -26,7 +26,7 @@ public object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
|
|||||||
val canvas = document.createElement("canvas") as HTMLCanvasElement
|
val canvas = document.createElement("canvas") as HTMLCanvasElement
|
||||||
val context = canvas.getContext("2d") as CanvasRenderingContext2D
|
val context = canvas.getContext("2d") as CanvasRenderingContext2D
|
||||||
context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}"
|
context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}"
|
||||||
context.fillStyle = obj.color.value ?: "black"
|
context.fillStyle = obj.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black"
|
||||||
context.textBaseline = CanvasTextBaseline.MIDDLE
|
context.textBaseline = CanvasTextBaseline.MIDDLE
|
||||||
val metrics = context.measureText(obj.text)
|
val metrics = context.measureText(obj.text)
|
||||||
//canvas.width = metrics.width.toInt()
|
//canvas.width = metrics.width.toInt()
|
||||||
|
@ -3,16 +3,21 @@ package space.kscience.visionforge.solid.three
|
|||||||
import info.laht.threekt.materials.LineBasicMaterial
|
import info.laht.threekt.materials.LineBasicMaterial
|
||||||
import info.laht.threekt.materials.Material
|
import info.laht.threekt.materials.Material
|
||||||
import info.laht.threekt.materials.MeshBasicMaterial
|
import info.laht.threekt.materials.MeshBasicMaterial
|
||||||
import info.laht.threekt.materials.MeshPhongMaterial
|
|
||||||
import info.laht.threekt.math.Color
|
import info.laht.threekt.math.Color
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.boolean
|
||||||
|
import space.kscience.dataforge.meta.double
|
||||||
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.values.*
|
import space.kscience.dataforge.values.*
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.computePropertyNode
|
import space.kscience.visionforge.computePropertyNode
|
||||||
|
import space.kscience.visionforge.getStyleNodes
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
|
import space.kscience.visionforge.solid.SolidReference
|
||||||
|
|
||||||
|
|
||||||
public object ThreeMaterials {
|
public object ThreeMaterials {
|
||||||
@ -56,56 +61,57 @@ public object ThreeMaterials {
|
|||||||
|
|
||||||
private val materialCache = HashMap<Meta, Material>()
|
private val materialCache = HashMap<Meta, Material>()
|
||||||
|
|
||||||
internal fun buildMaterial(meta: Meta): Material {
|
internal fun buildMaterial(meta: Meta): Material = MeshBasicMaterial().apply {
|
||||||
val material = SolidMaterial.read(meta)
|
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
|
||||||
return meta[SolidMaterial.SPECULAR_COLOR_KEY]?.let { specularColor ->
|
opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
|
||||||
MeshPhongMaterial().apply {
|
transparent = opacity < 1.0
|
||||||
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
|
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
|
||||||
specular = specularColor.threeColor()
|
needsUpdate = true
|
||||||
emissive = material.emissiveColor.item?.threeColor() ?: specular
|
|
||||||
reflectivity = 0.5
|
|
||||||
refractionRatio = 1.0
|
|
||||||
shininess = 100.0
|
|
||||||
opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
|
|
||||||
transparent = opacity < 1.0
|
|
||||||
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
|
|
||||||
needsUpdate = true
|
|
||||||
}
|
|
||||||
} ?: MeshBasicMaterial().apply {
|
|
||||||
color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
|
|
||||||
opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
|
|
||||||
transparent = opacity < 1.0
|
|
||||||
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
|
|
||||||
needsUpdate = true
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
// val material = SolidMaterial.read(meta)
|
||||||
|
// return meta[SolidMaterial.SPECULAR_COLOR_KEY]?.let { specularColor ->
|
||||||
|
// MeshPhongMaterial().apply {
|
||||||
|
// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
|
||||||
|
// specular = specularColor.threeColor()
|
||||||
|
// emissive = material.emissiveColor.threeColor() ?: specular
|
||||||
|
// reflectivity = 0.5
|
||||||
|
// refractionRatio = 1.0
|
||||||
|
// shininess = 100.0
|
||||||
|
// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
|
||||||
|
// transparent = opacity < 1.0
|
||||||
|
// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
|
||||||
|
// needsUpdate = true
|
||||||
|
// }
|
||||||
|
// } ?: MeshBasicMaterial().apply {
|
||||||
|
// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR
|
||||||
|
// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
|
||||||
|
// transparent = opacity < 1.0
|
||||||
|
// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
|
||||||
|
// needsUpdate = true
|
||||||
|
// }
|
||||||
|
|
||||||
internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) {
|
internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) {
|
||||||
buildMaterial(meta).apply {
|
buildMaterial(meta).apply {
|
||||||
cached = true
|
cached = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Infer color based on meta item
|
* Compute color
|
||||||
*/
|
*/
|
||||||
public fun Meta.threeColor(): Color {
|
public fun Meta.threeColor(): Color = getValue(Name.EMPTY)?.let { value ->
|
||||||
return value?.let { value ->
|
if (value.type == ValueType.NUMBER) {
|
||||||
if (value.type == ValueType.NUMBER) {
|
val int = value.int
|
||||||
val int = value.int
|
Color(int)
|
||||||
Color(int)
|
} else {
|
||||||
} else {
|
Color(value.string)
|
||||||
Color(value.string)
|
}
|
||||||
}
|
} ?: Color(
|
||||||
} ?: Color(
|
getValue(Colors.RED_KEY.asName())?.int ?: 0,
|
||||||
this[Colors.RED_KEY]?.int ?: 0,
|
getValue(Colors.GREEN_KEY.asName())?.int ?: 0,
|
||||||
this[Colors.GREEN_KEY]?.int ?: 0,
|
getValue(Colors.BLUE_KEY.asName())?.int ?: 0
|
||||||
this[Colors.BLUE_KEY]?.int ?: 0
|
)
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private var Material.cached: Boolean
|
private var Material.cached: Boolean
|
||||||
get() = userData["cached"] == true
|
get() = userData["cached"] == true
|
||||||
@ -114,31 +120,19 @@ private var Material.cached: Boolean
|
|||||||
}
|
}
|
||||||
|
|
||||||
public fun Mesh.updateMaterial(vision: Vision) {
|
public fun Mesh.updateMaterial(vision: Vision) {
|
||||||
//val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node
|
|
||||||
val ownMaterialMeta = vision.meta.getMeta(SolidMaterial.MATERIAL_KEY)
|
val ownMaterialMeta = vision.meta.getMeta(SolidMaterial.MATERIAL_KEY)
|
||||||
val parentMaterialMeta = vision.parent?.getPropertyValue(
|
if (ownMaterialMeta == null) {
|
||||||
SolidMaterial.MATERIAL_KEY,
|
if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) {
|
||||||
inherit = true,
|
updateMaterial(vision.prototype)
|
||||||
includeStyles = false,
|
} else {
|
||||||
includeDefaults = false
|
material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let {
|
||||||
)
|
|
||||||
|
|
||||||
material = when {
|
|
||||||
ownMaterialMeta == null && parentMaterialMeta == null -> {
|
|
||||||
//If material is style-based, use cached
|
|
||||||
vision.computePropertyNode(
|
|
||||||
SolidMaterial.MATERIAL_KEY,
|
|
||||||
)?.let {
|
|
||||||
ThreeMaterials.cacheMaterial(it)
|
ThreeMaterials.cacheMaterial(it)
|
||||||
} ?: ThreeMaterials.DEFAULT
|
} ?: ThreeMaterials.DEFAULT
|
||||||
}
|
}
|
||||||
else -> {
|
} else {
|
||||||
vision.computePropertyNode(
|
material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let {
|
||||||
SolidMaterial.MATERIAL_KEY,
|
ThreeMaterials.buildMaterial(it)
|
||||||
)?.let {
|
} ?: ThreeMaterials.DEFAULT
|
||||||
ThreeMaterials.buildMaterial(it)
|
|
||||||
} ?: ThreeMaterials.DEFAULT
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -149,17 +143,14 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
|||||||
} else {
|
} else {
|
||||||
when (propertyName) {
|
when (propertyName) {
|
||||||
SolidMaterial.MATERIAL_COLOR_KEY -> {
|
SolidMaterial.MATERIAL_COLOR_KEY -> {
|
||||||
material.asDynamic().color = vision.computePropertyNode(
|
material.asDynamic().color = vision.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.threeColor()
|
||||||
SolidMaterial.MATERIAL_COLOR_KEY,
|
?: ThreeMaterials.DEFAULT_COLOR
|
||||||
)?.threeColor() ?: ThreeMaterials.DEFAULT_COLOR
|
|
||||||
material.needsUpdate = true
|
material.needsUpdate = true
|
||||||
}
|
}
|
||||||
SolidMaterial.MATERIAL_OPACITY_KEY -> {
|
SolidMaterial.MATERIAL_OPACITY_KEY -> {
|
||||||
val opacity = vision.getPropertyValue(
|
val opacity = vision.getPropertyValue(
|
||||||
SolidMaterial.MATERIAL_OPACITY_KEY,
|
SolidMaterial.MATERIAL_OPACITY_KEY,
|
||||||
inherit = true,
|
inherit = true,
|
||||||
includeStyles = true,
|
|
||||||
includeDefaults = false
|
|
||||||
)?.double ?: 1.0
|
)?.double ?: 1.0
|
||||||
material.opacity = opacity
|
material.opacity = opacity
|
||||||
material.transparent = opacity < 1.0
|
material.transparent = opacity < 1.0
|
||||||
@ -169,8 +160,6 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
|
|||||||
material.asDynamic().wireframe = vision.getPropertyValue(
|
material.asDynamic().wireframe = vision.getPropertyValue(
|
||||||
SolidMaterial.MATERIAL_WIREFRAME_KEY,
|
SolidMaterial.MATERIAL_WIREFRAME_KEY,
|
||||||
inherit = true,
|
inherit = true,
|
||||||
includeStyles = true,
|
|
||||||
includeDefaults = false
|
|
||||||
)?.boolean ?: false
|
)?.boolean ?: false
|
||||||
material.needsUpdate = true
|
material.needsUpdate = true
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
import info.laht.threekt.core.BufferGeometry
|
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
import info.laht.threekt.objects.Mesh
|
import info.laht.threekt.objects.Mesh
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
@ -19,7 +18,7 @@ public object ThreeReferenceFactory : ThreeFactory<SolidReferenceGroup> {
|
|||||||
|
|
||||||
private fun Object3D.replicate(): Object3D {
|
private fun Object3D.replicate(): Object3D {
|
||||||
return when (this) {
|
return when (this) {
|
||||||
is Mesh -> Mesh(geometry as BufferGeometry, material).also {
|
is Mesh -> Mesh(geometry, material).also {
|
||||||
it.applyMatrix4(matrix)
|
it.applyMatrix4(matrix)
|
||||||
}
|
}
|
||||||
else -> clone(false)
|
else -> clone(false)
|
||||||
|
Loading…
Reference in New Issue
Block a user