Add property flows
This commit is contained in:
parent
0ea1ee056a
commit
ecf4a6a198
@ -352,14 +352,14 @@ private fun SolidGroup.addRootVolume(
|
|||||||
}
|
}
|
||||||
block()
|
block()
|
||||||
}
|
}
|
||||||
set(combinedName?.let { Name.parse(it) }, group)
|
setChild(combinedName?.let { Name.parse(it) }, group)
|
||||||
} else {
|
} else {
|
||||||
val templateName = volumesName + volume.name
|
val templateName = volumesName + volume.name
|
||||||
val existing = getPrototype(templateName)
|
val existing = getPrototype(templateName)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
context.prototypeHolder.prototypes {
|
context.prototypeHolder.prototypes {
|
||||||
val group = buildVolume(volume, context)
|
val group = buildVolume(volume, context)
|
||||||
set(templateName, group)
|
setChild(templateName, group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import space.kscience.dataforge.meta.string
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
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.material
|
import space.kscience.visionforge.solid.material
|
||||||
@ -18,7 +18,7 @@ class GDMLVisionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCubesStyles(){
|
fun testCubesStyles(){
|
||||||
val segment = cubes.children["composite-000.segment-0"] as Solid
|
val segment = cubes.children.getChild("composite-000.segment-0") as Solid
|
||||||
println(segment.properties.getValue(Vision.STYLE_KEY))
|
println(segment.properties.getValue(Vision.STYLE_KEY))
|
||||||
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
||||||
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
||||||
|
@ -48,6 +48,7 @@ kotlin {
|
|||||||
implementation("io.ktor:ktor-server-cio:${ktorVersion}")
|
implementation("io.ktor:ktor-server-cio:${ktorVersion}")
|
||||||
implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}")
|
implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}")
|
||||||
implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}")
|
implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}")
|
||||||
|
implementation("ch.qos.logback:logback-classic:1.2.11")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jsMain {
|
jsMain {
|
||||||
|
@ -3,7 +3,10 @@ package space.kscience.visionforge.solid.demo
|
|||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
|
||||||
public interface VisionLayout<in V: Vision> {
|
public interface VisionLayout<in V: Vision> {
|
||||||
|
val solids: Solids
|
||||||
|
|
||||||
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
||||||
}
|
}
|
@ -5,6 +5,7 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
import space.kscience.dataforge.meta.invoke
|
import space.kscience.dataforge.meta.invoke
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
|
import space.kscience.visionforge.setAsRoot
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import space.kscience.visionforge.visible
|
import space.kscience.visionforge.visible
|
||||||
@ -22,6 +23,7 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
|
|||||||
ambientLight{
|
ambientLight{
|
||||||
color.set(Colors.white)
|
color.set(Colors.white)
|
||||||
}
|
}
|
||||||
|
setAsRoot(solids.visionManager)
|
||||||
}
|
}
|
||||||
render(Name.parse(name), vision, meta)
|
render(Name.parse(name), vision, meta)
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,7 @@ import space.kscience.dataforge.meta.get
|
|||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
import space.kscience.visionforge.solid.three.ThreeCanvas
|
import space.kscience.visionforge.solid.three.ThreeCanvas
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
|
||||||
@ -27,6 +28,8 @@ class ThreeDemoGrid(element: Element) : VisionLayout<Solid> {
|
|||||||
|
|
||||||
private val three = Global.fetch(ThreePlugin)
|
private val three = Global.fetch(ThreePlugin)
|
||||||
|
|
||||||
|
override val solids: Solids get() = three.solids
|
||||||
|
|
||||||
init {
|
init {
|
||||||
element.clear()
|
element.clear()
|
||||||
element.append {
|
element.append {
|
||||||
|
@ -9,7 +9,7 @@ import space.kscience.dataforge.meta.number
|
|||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.startsWith
|
import space.kscience.dataforge.names.startsWith
|
||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import space.kscience.visionforge.solid.SolidGroup
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
import space.kscience.visionforge.solid.layer
|
import space.kscience.visionforge.solid.layer
|
||||||
import space.kscience.visionforge.solid.three.*
|
import space.kscience.visionforge.solid.three.*
|
||||||
@ -20,7 +20,7 @@ internal fun SolidGroup.varBox(
|
|||||||
ySize: Number,
|
ySize: Number,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
action: VariableBox.() -> Unit = {},
|
action: VariableBox.() -> Unit = {},
|
||||||
): VariableBox = VariableBox(xSize, ySize).apply(action).also { set(name, it) }
|
): VariableBox = VariableBox(xSize, ySize).apply(action).also { setChild(name, it) }
|
||||||
|
|
||||||
internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() {
|
internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() {
|
||||||
|
|
||||||
@ -59,7 +59,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision
|
|||||||
material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256)
|
material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256)
|
||||||
mesh.updateMatrix()
|
mesh.updateMatrix()
|
||||||
}
|
}
|
||||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
|
||||||
else -> mesh.updateProperty(this@VariableBox, name)
|
else -> mesh.updateProperty(this@VariableBox, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,9 +10,11 @@ import space.kscience.dataforge.names.Name
|
|||||||
import space.kscience.visionforge.solid.FX3DPlugin
|
import space.kscience.visionforge.solid.FX3DPlugin
|
||||||
import space.kscience.visionforge.solid.FXCanvas3D
|
import space.kscience.visionforge.solid.FXCanvas3D
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
||||||
|
|
||||||
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
||||||
|
|
||||||
override val root: Parent = borderpane {
|
override val root: Parent = borderpane {
|
||||||
@ -24,6 +26,9 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val fx3d = Global.fetch(FX3DPlugin)
|
private val fx3d = Global.fetch(FX3DPlugin)
|
||||||
|
override val solids: Solids get() = fx3d.solids
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun render(name: Name, vision: Solid, meta: Meta) {
|
override fun render(name: Name, vision: Solid, meta: Meta) {
|
||||||
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
||||||
|
@ -13,6 +13,11 @@ kotlin {
|
|||||||
api("org.jetbrains.kotlin-wrappers:kotlin-css")
|
api("org.jetbrains.kotlin-wrappers:kotlin-css")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
commonTest{
|
||||||
|
dependencies{
|
||||||
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}")
|
||||||
|
}
|
||||||
|
}
|
||||||
jsMain {
|
jsMain {
|
||||||
dependencies {
|
dependencies {
|
||||||
api("org.jetbrains.kotlin-wrappers:kotlin-extensions")
|
api("org.jetbrains.kotlin-wrappers:kotlin-extensions")
|
||||||
|
@ -11,10 +11,8 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor
|
|||||||
import space.kscience.dataforge.misc.Type
|
import space.kscience.dataforge.misc.Type
|
||||||
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.startsWith
|
|
||||||
import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties
|
import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties
|
||||||
import space.kscience.visionforge.Vision.Companion.TYPE
|
import space.kscience.visionforge.Vision.Companion.TYPE
|
||||||
import kotlin.reflect.KProperty1
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A root type for display hierarchy
|
* A root type for display hierarchy
|
||||||
@ -73,18 +71,3 @@ public fun Vision.onPropertyChange(
|
|||||||
): Job = properties.changes.onEach {
|
): Job = properties.changes.onEach {
|
||||||
callback(it)
|
callback(it)
|
||||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||||
|
|
||||||
|
|
||||||
public fun <V : Vision, T> V.useProperty(
|
|
||||||
property: KProperty1<V, T>,
|
|
||||||
scope: CoroutineScope? = manager?.context,
|
|
||||||
callBack: V.(T) -> Unit,
|
|
||||||
): Job {
|
|
||||||
//Pass initial value.
|
|
||||||
callBack(property.get(this))
|
|
||||||
return properties.changes.onEach { name ->
|
|
||||||
if (name.startsWith(property.name.asName())) {
|
|
||||||
callBack(property.get(this@useProperty))
|
|
||||||
}
|
|
||||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
|
||||||
}
|
|
@ -47,7 +47,7 @@ public class VisionChangeBuilder(private val manager: VisionManager) : MutableVi
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun set(name: Name?, child: Vision?) {
|
override fun setChild(name: Name?, child: Vision?) {
|
||||||
if (name == null) error("Static children are not allowed in VisionChange")
|
if (name == null) error("Static children are not allowed in VisionChange")
|
||||||
getOrPutChild(name).apply {
|
getOrPutChild(name).apply {
|
||||||
vision = child
|
vision = child
|
||||||
@ -109,7 +109,7 @@ private fun CoroutineScope.collectChange(
|
|||||||
if (after != null) {
|
if (after != null) {
|
||||||
collectChange(fullName, after, collector)
|
collectChange(fullName, after, collector)
|
||||||
}
|
}
|
||||||
collector()[fullName] = after
|
collector().setChild(fullName, after)
|
||||||
}?.launchIn(this)
|
}?.launchIn(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,12 +11,12 @@ import kotlin.jvm.Synchronized
|
|||||||
public annotation class VisionBuilder
|
public annotation class VisionBuilder
|
||||||
|
|
||||||
public interface VisionContainer<out V : Vision> {
|
public interface VisionContainer<out V : Vision> {
|
||||||
public operator fun get(name: Name): V?
|
public fun getChild(name: Name): V?
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface MutableVisionContainer<in V : Vision> {
|
public interface MutableVisionContainer<in V : Vision> {
|
||||||
//TODO add documentation
|
//TODO add documentation
|
||||||
public operator fun set(name: Name?, child: V?)
|
public fun setChild(name: Name?, child: V?)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -33,10 +33,10 @@ public interface VisionChildren : VisionContainer<Vision> {
|
|||||||
|
|
||||||
public operator fun get(token: NameToken): Vision?
|
public operator fun get(token: NameToken): Vision?
|
||||||
|
|
||||||
override fun get(name: Name): Vision? = when (name.length) {
|
override fun getChild(name: Name): Vision? = when (name.length) {
|
||||||
0 -> group
|
0 -> group
|
||||||
1 -> get(name.first())
|
1 -> get(name.first())
|
||||||
else -> get(name.first())?.children?.get(name.cutFirst())
|
else -> get(name.first())?.children?.getChild(name.cutFirst())
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
@ -49,6 +49,10 @@ public interface VisionChildren : VisionContainer<Vision> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public operator fun VisionChildren.get(name: Name): Vision? = getChild(name)
|
||||||
|
public operator fun VisionChildren.get(name: String): Vision? = getChild(name)
|
||||||
|
|
||||||
|
|
||||||
public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty()
|
public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty()
|
||||||
|
|
||||||
public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) {
|
public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) {
|
||||||
@ -61,7 +65,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
|||||||
|
|
||||||
public operator fun set(token: NameToken, value: Vision?)
|
public operator fun set(token: NameToken, value: Vision?)
|
||||||
|
|
||||||
override fun set(name: Name?, child: Vision?) {
|
override fun setChild(name: Name?, child: Vision?) {
|
||||||
when {
|
when {
|
||||||
name == null -> {
|
name == null -> {
|
||||||
if (child != null) {
|
if (child != null) {
|
||||||
@ -81,7 +85,7 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
|||||||
val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also {
|
val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: group.createGroup().also {
|
||||||
set(name.first(), it)
|
set(name.first(), it)
|
||||||
}
|
}
|
||||||
parent.children[name.cutFirst()] = child
|
parent.children.setChild(name.cutFirst(), child)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -89,6 +93,15 @@ public interface MutableVisionChildren : VisionChildren, MutableVisionContainer<
|
|||||||
public fun clear()
|
public fun clear()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public operator fun MutableVisionChildren.set(name: Name?, vision: Vision?) {
|
||||||
|
setChild(name, vision)
|
||||||
|
}
|
||||||
|
|
||||||
|
public operator fun MutableVisionChildren.set(name: String?, vision: Vision?) {
|
||||||
|
setChild(name, vision)
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events.
|
* Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events.
|
||||||
*/
|
*/
|
||||||
@ -102,11 +115,11 @@ public fun VisionChildren.asSequence(): Sequence<Pair<NameToken, Vision>> = sequ
|
|||||||
|
|
||||||
public operator fun VisionChildren.iterator(): Iterator<Pair<NameToken, Vision>> = asSequence().iterator()
|
public operator fun VisionChildren.iterator(): Iterator<Pair<NameToken, Vision>> = asSequence().iterator()
|
||||||
|
|
||||||
public operator fun <V : Vision> VisionContainer<V>.get(str: String): V? = get(Name.parse(str))
|
public fun <V : Vision> VisionContainer<V>.getChild(str: String): V? = getChild(Name.parse(str))
|
||||||
|
|
||||||
public operator fun <V : Vision> MutableVisionContainer<V>.set(
|
public fun <V : Vision> MutableVisionContainer<V>.setChild(
|
||||||
str: String?, vision: V?,
|
str: String?, vision: V?,
|
||||||
): Unit = set(str?.parseAsName(), vision)
|
): Unit = setChild(str?.parseAsName(), vision)
|
||||||
|
|
||||||
internal abstract class VisionChildrenImpl(
|
internal abstract class VisionChildrenImpl(
|
||||||
override val group: MutableVisionGroup,
|
override val group: MutableVisionGroup,
|
||||||
|
@ -10,7 +10,6 @@ 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.visionforge.Vision.Companion.STYLE_KEY
|
import space.kscience.visionforge.Vision.Companion.STYLE_KEY
|
||||||
import kotlin.js.JsName
|
|
||||||
|
|
||||||
|
|
||||||
public interface VisionGroup : Vision {
|
public interface VisionGroup : Vision {
|
||||||
@ -35,9 +34,9 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
override fun update(change: VisionChange) {
|
override fun update(change: VisionChange) {
|
||||||
change.children?.forEach { (name, change) ->
|
change.children?.forEach { (name, change) ->
|
||||||
when {
|
when {
|
||||||
change.delete -> children[name] = null
|
change.delete -> children.setChild(name, null)
|
||||||
change.vision != null -> children[name] = change.vision
|
change.vision != null -> children.setChild(name, change.vision)
|
||||||
else -> children[name]?.update(change)
|
else -> children.getChild(name)?.update(change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
change.properties?.let {
|
change.properties?.let {
|
||||||
@ -87,12 +86,28 @@ public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("vision.group")
|
@SerialName("vision.group")
|
||||||
public class SimpleVisionGroup : AbstractVisionGroup() {
|
public class SimpleVisionGroup : AbstractVisionGroup(), MutableVisionContainer<Vision> {
|
||||||
override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup()
|
override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup()
|
||||||
|
|
||||||
|
override fun setChild(name: Name?, child: Vision?) {
|
||||||
|
children.setChild(name, child)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsName("createVisionGroup")
|
@VisionBuilder
|
||||||
public fun VisionGroup(): VisionGroup = SimpleVisionGroup()
|
public fun MutableVisionContainer<Vision>.group(
|
||||||
|
name: Name? = null,
|
||||||
|
builder: SimpleVisionGroup.() -> Unit = {},
|
||||||
|
): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Define a group with given [name], attach it to this parent and return it.
|
||||||
|
*/
|
||||||
|
@VisionBuilder
|
||||||
|
public fun MutableVisionContainer<Vision>.group(
|
||||||
|
name: String,
|
||||||
|
builder: SimpleVisionGroup.() -> Unit = {},
|
||||||
|
): SimpleVisionGroup = SimpleVisionGroup().apply(builder).also { setChild(name, it) }
|
||||||
|
|
||||||
//fun VisualObject.findStyle(styleName: Name): Meta? {
|
//fun VisualObject.findStyle(styleName: Name): Meta? {
|
||||||
// if (this is VisualGroup) {
|
// if (this is VisualGroup) {
|
||||||
|
@ -19,7 +19,7 @@ import space.kscience.visionforge.html.VisionOfNumberField
|
|||||||
import space.kscience.visionforge.html.VisionOfTextField
|
import space.kscience.visionforge.html.VisionOfTextField
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer<Vision> {
|
||||||
override val tag: PluginTag get() = Companion.tag
|
override val tag: PluginTag get() = Companion.tag
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -58,6 +58,10 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
|
|||||||
public fun encodeToMeta(vision: Vision, descriptor: MetaDescriptor? = null): Meta =
|
public fun encodeToMeta(vision: Vision, descriptor: MetaDescriptor? = null): Meta =
|
||||||
encodeToJsonElement(vision).toMeta(descriptor)
|
encodeToJsonElement(vision).toMeta(descriptor)
|
||||||
|
|
||||||
|
override fun setChild(name: Name?, child: Vision?) {
|
||||||
|
child?.setAsRoot(this)
|
||||||
|
}
|
||||||
|
|
||||||
public companion object : PluginFactory<VisionManager> {
|
public companion object : PluginFactory<VisionManager> {
|
||||||
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
|
||||||
override val type: KClass<out VisionManager> = VisionManager::class
|
override val type: KClass<out VisionManager> = VisionManager::class
|
||||||
|
@ -73,6 +73,19 @@ public interface MutableVisionProperties : VisionProperties {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public fun MutableVisionProperties.remove(name: Name){
|
||||||
|
setProperty(name, null)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun MutableVisionProperties.remove(name: String){
|
||||||
|
remove(name.parseAsName())
|
||||||
|
}
|
||||||
|
|
||||||
|
@VisionBuilder
|
||||||
|
public operator fun MutableVisionProperties.invoke(block: MutableMeta.() -> Unit) {
|
||||||
|
root(inherit = false, includeStyles = false).apply(block)
|
||||||
|
}
|
||||||
|
|
||||||
private class VisionPropertiesItem(
|
private class VisionPropertiesItem(
|
||||||
val properties: MutableVisionProperties,
|
val properties: MutableVisionProperties,
|
||||||
val nodeName: Name,
|
val nodeName: Name,
|
||||||
@ -190,7 +203,7 @@ public abstract class AbstractVisionProperties(
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Transient
|
@Transient
|
||||||
private val _changes = MutableSharedFlow<Name>(10)
|
private val _changes = MutableSharedFlow<Name>()
|
||||||
override val changes: SharedFlow<Name> get() = _changes
|
override val changes: SharedFlow<Name> get() = _changes
|
||||||
|
|
||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
|
@ -0,0 +1,55 @@
|
|||||||
|
package space.kscience.visionforge
|
||||||
|
|
||||||
|
import kotlinx.coroutines.flow.Flow
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.Value
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.parseAsName
|
||||||
|
import space.kscience.dataforge.names.startsWith
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Create a flow of a specific property
|
||||||
|
*/
|
||||||
|
public fun Vision.flowProperty(
|
||||||
|
propertyName: Name,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
): Flow<Meta> = flow {
|
||||||
|
//Pass initial value.
|
||||||
|
emit(properties.getProperty(propertyName, inherit, includeStyles))
|
||||||
|
properties.changes.collect { name ->
|
||||||
|
if (name.startsWith(propertyName)) {
|
||||||
|
emit(properties.getProperty(propertyName, inherit, includeStyles))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Vision.flowProperty(
|
||||||
|
propertyName: String,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
): Flow<Meta> = flowProperty(propertyName.parseAsName(), inherit, includeStyles)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Flow the value of specific property
|
||||||
|
*/
|
||||||
|
public fun Vision.flowPropertyValue(
|
||||||
|
propertyName: Name,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
): Flow<Value?> = flow {
|
||||||
|
//Pass initial value.
|
||||||
|
emit(properties.getValue(propertyName, inherit, includeStyles))
|
||||||
|
properties.changes.collect { name ->
|
||||||
|
if (name.startsWith(propertyName)) {
|
||||||
|
emit(properties.getValue(propertyName, inherit, includeStyles))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Vision.flowPropertyValue(
|
||||||
|
propertyName: String,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
): Flow<Value?> = flowPropertyValue(propertyName.parseAsName(), inherit, includeStyles)
|
@ -0,0 +1,54 @@
|
|||||||
|
package space.kscience.visionforge
|
||||||
|
|
||||||
|
import kotlinx.coroutines.CoroutineScope
|
||||||
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.flow.launchIn
|
||||||
|
import kotlinx.coroutines.flow.onEach
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.dataforge.names.asName
|
||||||
|
import space.kscience.dataforge.names.parseAsName
|
||||||
|
import space.kscience.dataforge.names.startsWith
|
||||||
|
import kotlin.reflect.KProperty1
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call [callBack] on initial value of the property and then on all subsequent values after change
|
||||||
|
*/
|
||||||
|
public fun Vision.useProperty(
|
||||||
|
propertyName: Name,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
scope: CoroutineScope? = manager?.context,
|
||||||
|
callBack: (Meta) -> Unit,
|
||||||
|
): Job {
|
||||||
|
//Pass initial value.
|
||||||
|
callBack(properties.getProperty(propertyName, inherit, includeStyles))
|
||||||
|
return properties.changes.onEach { name ->
|
||||||
|
if (name.startsWith(propertyName)) {
|
||||||
|
callBack(properties.getProperty(propertyName, inherit, includeStyles))
|
||||||
|
}
|
||||||
|
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Vision.useProperty(
|
||||||
|
propertyName: String,
|
||||||
|
inherit: Boolean? = null,
|
||||||
|
includeStyles: Boolean? = null,
|
||||||
|
scope: CoroutineScope? = manager?.context,
|
||||||
|
callBack: (Meta) -> Unit,
|
||||||
|
): Job = useProperty(propertyName.parseAsName(),inherit, includeStyles, scope, callBack)
|
||||||
|
|
||||||
|
public fun <V : Vision, T> V.useProperty(
|
||||||
|
property: KProperty1<V, T>,
|
||||||
|
scope: CoroutineScope? = manager?.context,
|
||||||
|
callBack: V.(T) -> Unit,
|
||||||
|
): Job {
|
||||||
|
//Pass initial value.
|
||||||
|
callBack(property.get(this))
|
||||||
|
return properties.changes.onEach { name ->
|
||||||
|
if (name.startsWith(property.name.asName())) {
|
||||||
|
callBack(property.get(this@useProperty))
|
||||||
|
}
|
||||||
|
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
||||||
|
}
|
@ -30,7 +30,7 @@ fun FlowContent.renderVisionFragment(
|
|||||||
|
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
private fun VisionOutput.base(block: VisionGroup.() -> Unit) = VisionGroup().apply(block)
|
private fun VisionOutput.base(block: VisionGroup.() -> Unit) = context.visionManager.group().apply(block)
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
class HtmlTagTest {
|
class HtmlTagTest {
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
package space.kscience.visionforge.meta
|
package space.kscience.visionforge.meta
|
||||||
|
|
||||||
|
import kotlinx.coroutines.cancel
|
||||||
|
import kotlinx.coroutines.delay
|
||||||
|
import kotlinx.coroutines.flow.collectIndexed
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.test.runTest
|
||||||
|
import space.kscience.dataforge.context.Global
|
||||||
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.dataforge.meta.*
|
import space.kscience.dataforge.meta.*
|
||||||
import space.kscience.visionforge.VisionGroup
|
import space.kscience.visionforge.*
|
||||||
import space.kscience.visionforge.getProperty
|
|
||||||
import space.kscience.visionforge.getValue
|
|
||||||
import space.kscience.visionforge.set
|
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertNotEquals
|
import kotlin.test.assertNotEquals
|
||||||
@ -17,9 +21,12 @@ private class TestScheme : Scheme() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal class VisionPropertyTest {
|
internal class VisionPropertyTest {
|
||||||
|
|
||||||
|
private val manager = Global.fetch(VisionManager)
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPropertyWrite() {
|
fun testPropertyWrite() {
|
||||||
val vision = VisionGroup()
|
val vision = manager.group()
|
||||||
vision.properties["fff"] = 2
|
vision.properties["fff"] = 2
|
||||||
vision.properties["fff.ddd"] = false
|
vision.properties["fff.ddd"] = false
|
||||||
|
|
||||||
@ -29,7 +36,7 @@ internal class VisionPropertyTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPropertyEdit() {
|
fun testPropertyEdit() {
|
||||||
val vision = VisionGroup()
|
val vision = manager.group()
|
||||||
vision.properties.getProperty("fff.ddd").apply {
|
vision.properties.getProperty("fff.ddd").apply {
|
||||||
value = 2.asValue()
|
value = 2.asValue()
|
||||||
}
|
}
|
||||||
@ -39,10 +46,78 @@ internal class VisionPropertyTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testPropertyUpdate() {
|
fun testPropertyUpdate() {
|
||||||
val vision = VisionGroup()
|
val vision = manager.group()
|
||||||
vision.properties.getProperty("fff").updateWith(TestScheme) {
|
vision.properties.getProperty("fff").updateWith(TestScheme) {
|
||||||
ddd = 2
|
ddd = 2
|
||||||
}
|
}
|
||||||
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
assertEquals(2, vision.properties.getValue("fff.ddd")?.int)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testChildrenPropertyPropagation() = runTest(dispatchTimeoutMs = 200) {
|
||||||
|
val group = Global.fetch(VisionManager).group {
|
||||||
|
properties {
|
||||||
|
"test" put 11
|
||||||
|
}
|
||||||
|
group("child") {
|
||||||
|
properties {
|
||||||
|
"test" put 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val child = group.children["child"]!!
|
||||||
|
|
||||||
|
var value: Value? = null
|
||||||
|
|
||||||
|
var callCounter = 0
|
||||||
|
|
||||||
|
child.useProperty("test", inherit = true) {
|
||||||
|
callCounter++
|
||||||
|
value = it.value
|
||||||
|
}
|
||||||
|
|
||||||
|
assertEquals(22, value?.int)
|
||||||
|
assertEquals(1, callCounter)
|
||||||
|
|
||||||
|
child.properties.remove("test")
|
||||||
|
|
||||||
|
//Need this to avoid the race
|
||||||
|
delay(20)
|
||||||
|
|
||||||
|
assertEquals(11, child.properties.getProperty("test", inherit = true).int)
|
||||||
|
assertEquals(11, value?.int)
|
||||||
|
assertEquals(2, callCounter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) {
|
||||||
|
val group = Global.fetch(VisionManager).group {
|
||||||
|
properties {
|
||||||
|
"test" put 11
|
||||||
|
}
|
||||||
|
group("child") {
|
||||||
|
properties {
|
||||||
|
"test" put 22
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val child = group.children["child"]!!
|
||||||
|
|
||||||
|
launch {
|
||||||
|
child.flowPropertyValue("test", inherit = true).collectIndexed { index, value ->
|
||||||
|
if (index == 0) {
|
||||||
|
assertEquals(22, value?.int)
|
||||||
|
} else if (index == 1) {
|
||||||
|
assertEquals(11, value?.int)
|
||||||
|
cancel()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//wait for subscription to be created
|
||||||
|
delay(10)
|
||||||
|
|
||||||
|
child.properties.remove("test")
|
||||||
|
}
|
||||||
}
|
}
|
@ -22,7 +22,7 @@ public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory<Sol
|
|||||||
if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) {
|
if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) {
|
||||||
val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'")
|
val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'")
|
||||||
val propertyName = name.cutFirst()
|
val propertyName = name.cutFirst()
|
||||||
val referenceChild = obj.children[childName] ?: error("Reference child with name '$childName' not found")
|
val referenceChild = obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found")
|
||||||
val child = node.findChild(childName) ?: error("Object child with name '$childName' not found")
|
val child = node.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||||
child.updateProperty(referenceChild, propertyName)
|
child.updateProperty(referenceChild, propertyName)
|
||||||
}
|
}
|
||||||
|
@ -62,7 +62,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
|||||||
): SolidReference {
|
): SolidReference {
|
||||||
val templateName = volumesName + volume.name.asName()
|
val templateName = volumesName + volume.name.asName()
|
||||||
if (proto[templateName] == null) {
|
if (proto[templateName] == null) {
|
||||||
proto[templateName] = volume(root, volume)
|
proto.setChild(templateName, volume(root, volume))
|
||||||
}
|
}
|
||||||
val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume)
|
val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume)
|
||||||
referenceStore.getOrPut(templateName) { ArrayList() }.add(ref)
|
referenceStore.getOrPut(templateName) { ArrayList() }.add(ref)
|
||||||
@ -302,7 +302,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
|||||||
when (settings.volumeAction(volume)) {
|
when (settings.volumeAction(volume)) {
|
||||||
GdmlLoaderOptions.Action.ADD -> {
|
GdmlLoaderOptions.Action.ADD -> {
|
||||||
val group: SolidGroup = volume(root, volume)
|
val group: SolidGroup = volume(root, volume)
|
||||||
this[physVolume.name] = group.withPosition(root, physVolume)
|
this.setChild(physVolume.name, group.withPosition(root, physVolume))
|
||||||
}
|
}
|
||||||
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||||
proxyVolume(root, this, physVolume, volume)
|
proxyVolume(root, this, physVolume, volume)
|
||||||
@ -357,7 +357,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
|||||||
final.prototypes {
|
final.prototypes {
|
||||||
proto.items.forEach { (token, item) ->
|
proto.items.forEach { (token, item) ->
|
||||||
item.parent = null
|
item.parent = null
|
||||||
set(token.asName(), item as? Solid)
|
setChild(token.asName(), item as? Solid)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
settings.styleCache.forEach {
|
settings.styleCache.forEach {
|
||||||
@ -385,7 +385,7 @@ public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup {
|
|||||||
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) {
|
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) {
|
||||||
val vision = gdml.toVision(transformer)
|
val vision = gdml.toVision(transformer)
|
||||||
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
|
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
|
||||||
children[key] = vision
|
children.setChild(key, vision)
|
||||||
}
|
}
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
|
@ -4,7 +4,7 @@ import space.kscience.dataforge.context.Context
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.gdml.*
|
import space.kscience.gdml.*
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.visionManager
|
import space.kscience.visionforge.visionManager
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -26,7 +26,7 @@ class TestCubes {
|
|||||||
val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box
|
val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box
|
||||||
assertNotNull(smallBoxPrototype)
|
assertNotNull(smallBoxPrototype)
|
||||||
assertEquals(30.0, smallBoxPrototype.xSize.toDouble())
|
assertEquals(30.0, smallBoxPrototype.xSize.toDouble())
|
||||||
val smallBoxVision = vision.children["composite-111.smallBox"]?.prototype as? Box
|
val smallBoxVision = vision.children.getChild("composite-111.smallBox")?.prototype as? Box
|
||||||
assertNotNull(smallBoxVision)
|
assertNotNull(smallBoxVision)
|
||||||
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
assertEquals(30.0, smallBoxVision.xSize.toDouble())
|
||||||
}
|
}
|
||||||
|
@ -1,3 +1,5 @@
|
|||||||
|
import space.kscience.gradle.KScienceVersions
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
}
|
}
|
||||||
@ -17,7 +19,7 @@ kotlin {
|
|||||||
}
|
}
|
||||||
commonTest{
|
commonTest{
|
||||||
dependencies{
|
dependencies{
|
||||||
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:1.6.4")
|
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${KScienceVersions.coroutinesVersion}")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
jvmTest{
|
jvmTest{
|
||||||
|
@ -35,7 +35,7 @@ public inline fun MutableVisionContainer<Solid>.composite(
|
|||||||
|
|
||||||
res.properties.setProperty(Name.EMPTY, group.properties.own)
|
res.properties.setProperty(Name.EMPTY, group.properties.own)
|
||||||
|
|
||||||
set(name, res)
|
setChild(name, res)
|
||||||
return res
|
return res
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -57,7 +57,7 @@ public fun SolidGroup.smartComposite(
|
|||||||
}
|
}
|
||||||
this
|
this
|
||||||
} else {
|
} else {
|
||||||
children[name] = group
|
children.setChild(name, group)
|
||||||
group
|
group
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ public inline fun MutableVisionContainer<Solid>.cylinder(
|
|||||||
r.toFloat(),
|
r.toFloat(),
|
||||||
height.toFloat(),
|
height.toFloat(),
|
||||||
r.toFloat()
|
r.toFloat()
|
||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { setChild(name, it) }
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun MutableVisionContainer<Solid>.cone(
|
public inline fun MutableVisionContainer<Solid>.cone(
|
||||||
@ -93,4 +93,4 @@ public inline fun MutableVisionContainer<Solid>.cone(
|
|||||||
topRadius = upperRadius.toFloat(),
|
topRadius = upperRadius.toFloat(),
|
||||||
startAngle = startAngle.toFloat(),
|
startAngle = startAngle.toFloat(),
|
||||||
angle = angle.toFloat()
|
angle = angle.toFloat()
|
||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
@ -139,7 +139,7 @@ public inline fun MutableVisionContainer<Solid>.tube(
|
|||||||
topInnerRadius = innerRadius.toFloat(),
|
topInnerRadius = innerRadius.toFloat(),
|
||||||
startAngle = startAngle.toFloat(),
|
startAngle = startAngle.toFloat(),
|
||||||
angle = angle.toFloat()
|
angle = angle.toFloat()
|
||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { setChild(name, it) }
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public inline fun MutableVisionContainer<Solid>.coneSurface(
|
public inline fun MutableVisionContainer<Solid>.coneSurface(
|
||||||
@ -160,4 +160,4 @@ public inline fun MutableVisionContainer<Solid>.coneSurface(
|
|||||||
topInnerRadius = topInnerRadius.toFloat(),
|
topInnerRadius = topInnerRadius.toFloat(),
|
||||||
startAngle = startAngle.toFloat(),
|
startAngle = startAngle.toFloat(),
|
||||||
angle = angle.toFloat()
|
angle = angle.toFloat()
|
||||||
).apply(block).also { set(name, it) }
|
).apply(block).also { setChild(name, it) }
|
@ -3,7 +3,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.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.convex")
|
@SerialName("solid.convex")
|
||||||
@ -12,7 +12,7 @@ public class Convex(public val points: List<Point3D>) : SolidBase<Convex>()
|
|||||||
public inline fun MutableVisionContainer<Solid>.convex(
|
public inline fun MutableVisionContainer<Solid>.convex(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: ConvexBuilder.() -> Unit = {},
|
action: ConvexBuilder.() -> Unit = {},
|
||||||
): Convex = ConvexBuilder().apply(action).build().also { set(name, it) }
|
): Convex = ConvexBuilder().apply(action).build().also { setChild(name, it) }
|
||||||
|
|
||||||
public class ConvexBuilder {
|
public class ConvexBuilder {
|
||||||
private val points = ArrayList<Point3D>()
|
private val points = ArrayList<Point3D>()
|
||||||
|
@ -115,4 +115,4 @@ public class ExtrudeBuilder(
|
|||||||
public fun MutableVisionContainer<Solid>.extruded(
|
public fun MutableVisionContainer<Solid>.extruded(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: ExtrudeBuilder.() -> Unit = {},
|
action: ExtrudeBuilder.() -> Unit = {},
|
||||||
): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) }
|
): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
|
|
||||||
public interface Hexagon : GeometrySolid {
|
public interface Hexagon : GeometrySolid {
|
||||||
public val node1: Point3D
|
public val node1: Point3D
|
||||||
@ -58,7 +58,7 @@ public inline fun MutableVisionContainer<Solid>.box(
|
|||||||
zSize: Number,
|
zSize: Number,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
block: Box.() -> Unit = {},
|
block: Box.() -> Unit = {},
|
||||||
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { set(name, it) }
|
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { setChild(name, it) }
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.hexagon")
|
@SerialName("solid.hexagon")
|
||||||
@ -85,4 +85,4 @@ public inline fun MutableVisionContainer<Solid>.hexagon(
|
|||||||
node8: Point3D,
|
node8: Point3D,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: Hexagon.() -> Unit = {},
|
action: Hexagon.() -> Unit = {},
|
||||||
): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { set(name, it) }
|
): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { setChild(name, it) }
|
@ -55,7 +55,7 @@ public class AmbientLightSource : LightSource()
|
|||||||
public fun MutableVisionContainer<Solid>.ambientLight(
|
public fun MutableVisionContainer<Solid>.ambientLight(
|
||||||
name: String? = "@ambientLight",
|
name: String? = "@ambientLight",
|
||||||
block: AmbientLightSource.() -> Unit = {},
|
block: AmbientLightSource.() -> Unit = {},
|
||||||
): AmbientLightSource = AmbientLightSource().apply(block).also { set(name, it) }
|
): AmbientLightSource = AmbientLightSource().apply(block).also { setChild(name, it) }
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.light.point")
|
@SerialName("solid.light.point")
|
||||||
@ -71,5 +71,5 @@ public fun MutableVisionContainer<Solid>.pointLight(
|
|||||||
block: PointLightSource.() -> Unit = {},
|
block: PointLightSource.() -> Unit = {},
|
||||||
): PointLightSource = PointLightSource().apply(block).also {
|
): PointLightSource = PointLightSource().apply(block).also {
|
||||||
it.position = Point3D(x, y, z)
|
it.position = Point3D(x, y, z)
|
||||||
set(name, it)
|
setChild(name, it)
|
||||||
}
|
}
|
@ -18,4 +18,4 @@ public fun MutableVisionContainer<Solid>.polyline(
|
|||||||
vararg points: Point3D,
|
vararg points: Point3D,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: PolyLine.() -> Unit = {},
|
action: PolyLine.() -> Unit = {},
|
||||||
): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) }
|
): PolyLine = PolyLine(points.toList()).apply(action).also { setChild(name, it) }
|
@ -38,7 +38,7 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable
|
|||||||
it to value
|
it to value
|
||||||
}.toMap()
|
}.toMap()
|
||||||
|
|
||||||
public operator fun get(name: Name): Solid? = children[name] as? Solid
|
public operator fun get(name: Name): Solid? = children.getChild(name) as? Solid
|
||||||
|
|
||||||
private var prototypes: SolidGroup?
|
private var prototypes: SolidGroup?
|
||||||
get() = items[PROTOTYPES_TOKEN] as? SolidGroup
|
get() = items[PROTOTYPES_TOKEN] as? SolidGroup
|
||||||
@ -70,8 +70,8 @@ public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, Mutable
|
|||||||
// super.update(change)
|
// super.update(change)
|
||||||
// }
|
// }
|
||||||
|
|
||||||
override fun set(name: Name?, child: Solid?) {
|
override fun setChild(name: Name?, child: Solid?) {
|
||||||
children[name] = child
|
children.setChild(name, child)
|
||||||
}
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
@ -85,7 +85,7 @@ public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGr
|
|||||||
public fun MutableVisionContainer<Solid>.group(
|
public fun MutableVisionContainer<Solid>.group(
|
||||||
name: Name? = null,
|
name: Name? = null,
|
||||||
builder: SolidGroup.() -> Unit = {},
|
builder: SolidGroup.() -> Unit = {},
|
||||||
): SolidGroup = SolidGroup(builder).also { set(name, it) }
|
): SolidGroup = SolidGroup(builder).also { setChild(name, it) }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Define a group with given [name], attach it to this parent and return it.
|
* Define a group with given [name], attach it to this parent and return it.
|
||||||
@ -94,4 +94,4 @@ public fun MutableVisionContainer<Solid>.group(
|
|||||||
public fun MutableVisionContainer<Solid>.group(
|
public fun MutableVisionContainer<Solid>.group(
|
||||||
name: String,
|
name: String,
|
||||||
action: SolidGroup.() -> Unit = {},
|
action: SolidGroup.() -> Unit = {},
|
||||||
): SolidGroup = SolidGroup(action).also { set(name, it) }
|
): SolidGroup = SolidGroup(action).also { setChild(name, it) }
|
||||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.label")
|
@SerialName("solid.label")
|
||||||
@ -21,4 +21,4 @@ public fun MutableVisionContainer<Solid>.label(
|
|||||||
fontFamily: String = "Arial",
|
fontFamily: String = "Arial",
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: SolidLabel.() -> Unit = {},
|
action: SolidLabel.() -> Unit = {},
|
||||||
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
|
): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { setChild(name, it) }
|
@ -97,7 +97,7 @@ internal class SolidReferenceChild(
|
|||||||
) : Solid, VisionGroup {
|
) : Solid, VisionGroup {
|
||||||
|
|
||||||
val prototype: Solid
|
val prototype: Solid
|
||||||
get() = owner.prototype.children?.get(childName) as? Solid
|
get() = owner.prototype.children?.getChild(childName) as? Solid
|
||||||
?: error("Prototype with name $childName not found")
|
?: error("Prototype with name $childName not found")
|
||||||
|
|
||||||
override val descriptor: MetaDescriptor get() = prototype.descriptor
|
override val descriptor: MetaDescriptor get() = prototype.descriptor
|
||||||
@ -137,7 +137,7 @@ internal class SolidReferenceChild(
|
|||||||
when {
|
when {
|
||||||
change.delete -> error("Deleting children inside ref is not allowed.")
|
change.delete -> error("Deleting children inside ref is not allowed.")
|
||||||
change.vision != null -> error("Updating content of the ref is not allowed")
|
change.vision != null -> error("Updating content of the ref is not allowed")
|
||||||
else -> children[name]?.update(change)
|
else -> children.getChild(name)?.update(change)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
change.properties?.let {
|
change.properties?.let {
|
||||||
@ -176,7 +176,7 @@ internal class SolidReferenceChild(
|
|||||||
public fun MutableVisionContainer<Solid>.ref(
|
public fun MutableVisionContainer<Solid>.ref(
|
||||||
templateName: Name,
|
templateName: Name,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
): SolidReference = SolidReference(templateName).also { set(name, it) }
|
): SolidReference = SolidReference(templateName).also { setChild(name, it) }
|
||||||
|
|
||||||
public fun MutableVisionContainer<Solid>.ref(
|
public fun MutableVisionContainer<Solid>.ref(
|
||||||
templateName: String,
|
templateName: String,
|
||||||
@ -195,7 +195,7 @@ public fun SolidGroup.newRef(
|
|||||||
val existing = prototypeHolder.getPrototype(prototypeName)
|
val existing = prototypeHolder.getPrototype(prototypeName)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
prototypeHolder.prototypes {
|
prototypeHolder.prototypes {
|
||||||
set(prototypeName, obj)
|
setChild(prototypeName, obj)
|
||||||
}
|
}
|
||||||
} else if (existing != obj) {
|
} else if (existing != obj) {
|
||||||
error("Can't add different prototype on top of existing one")
|
error("Can't add different prototype on top of existing one")
|
||||||
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
@ -58,4 +58,4 @@ public inline fun MutableVisionContainer<Solid>.sphere(
|
|||||||
action: Sphere.() -> Unit = {},
|
action: Sphere.() -> Unit = {},
|
||||||
): Sphere = Sphere(
|
): Sphere = Sphere(
|
||||||
radius.toFloat(),
|
radius.toFloat(),
|
||||||
).apply(action).also { set(name, it) }
|
).apply(action).also { setChild(name, it) }
|
@ -4,7 +4,7 @@ import kotlinx.serialization.SerialName
|
|||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.MutableVisionContainer
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.VisionBuilder
|
import space.kscience.visionforge.VisionBuilder
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
@ -85,4 +85,4 @@ public inline fun MutableVisionContainer<Solid>.sphereLayer(
|
|||||||
phi.toFloat(),
|
phi.toFloat(),
|
||||||
thetaStart.toFloat(),
|
thetaStart.toFloat(),
|
||||||
theta.toFloat()
|
theta.toFloat()
|
||||||
).apply(action).also { set(name, it) }
|
).apply(action).also { setChild(name, it) }
|
@ -39,7 +39,7 @@ internal object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
|
|||||||
val child: Solid = parent.items.values.first()
|
val child: Solid = parent.items.values.first()
|
||||||
val newParent = child.updateFrom(parent)
|
val newParent = child.updateFrom(parent)
|
||||||
newParent.parent = null
|
newParent.parent = null
|
||||||
children[childName.asName()] = newParent
|
children.setChild(childName.asName(), newParent)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,14 +4,8 @@ import space.kscience.dataforge.misc.DFExperimental
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.solid.SolidGroup
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
import space.kscience.visionforge.solid.SolidReference
|
import space.kscience.visionforge.solid.SolidReference
|
||||||
import kotlin.collections.HashMap
|
|
||||||
import kotlin.collections.Map
|
|
||||||
import kotlin.collections.component1
|
import kotlin.collections.component1
|
||||||
import kotlin.collections.component2
|
import kotlin.collections.component2
|
||||||
import kotlin.collections.filter
|
|
||||||
import kotlin.collections.filterIsInstance
|
|
||||||
import kotlin.collections.fold
|
|
||||||
import kotlin.collections.forEach
|
|
||||||
import kotlin.collections.set
|
import kotlin.collections.set
|
||||||
|
|
||||||
@DFExperimental
|
@DFExperimental
|
||||||
@ -33,7 +27,7 @@ internal object UnRef : VisualTreeTransform<SolidGroup>() {
|
|||||||
|
|
||||||
private fun SolidGroup.unref(name: Name) {
|
private fun SolidGroup.unref(name: Name) {
|
||||||
(this as? SolidGroup)?.prototypes{
|
(this as? SolidGroup)?.prototypes{
|
||||||
set(name, null)
|
setChild(name, null)
|
||||||
}
|
}
|
||||||
items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) ->
|
items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) ->
|
||||||
val reference = value as SolidReference
|
val reference = value as SolidReference
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
package space.kscience.visionforge.solid
|
package space.kscience.visionforge.solid
|
||||||
|
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
@ -45,7 +45,7 @@ class GroupTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assertEquals(3, group.items.count())
|
assertEquals(3, group.items.count())
|
||||||
assertEquals(300.0, (group.children["intersect"] as Solid).y.toDouble())
|
assertEquals(300.0, (group.children.getChild("intersect") as Solid).y.toDouble())
|
||||||
assertEquals(-300.0, (group.children["subtract"] as Solid).y.toDouble())
|
assertEquals(-300.0, (group.children.getChild("subtract") as Solid).y.toDouble())
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -2,7 +2,7 @@ package space.kscience.visionforge.solid
|
|||||||
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -52,7 +52,7 @@ class SerializationTest {
|
|||||||
val string = Solids.encodeToString(group)
|
val string = Solids.encodeToString(group)
|
||||||
println(string)
|
println(string)
|
||||||
val reconstructed = Solids.decodeFromString(string) as SolidGroup
|
val reconstructed = Solids.decodeFromString(string) as SolidGroup
|
||||||
assertEquals(group.children["cube"]?.properties?.own, reconstructed.children["cube"]?.properties?.own)
|
assertEquals(group.children.getChild("cube")?.properties?.own, reconstructed.children.getChild("cube")?.properties?.own)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -66,7 +66,7 @@ class SerializationTest {
|
|||||||
val serialized = Solids.encodeToString(group)
|
val serialized = Solids.encodeToString(group)
|
||||||
|
|
||||||
val reconstructed = Solids.decodeFromString(serialized) as SolidGroup
|
val reconstructed = Solids.decodeFromString(serialized) as SolidGroup
|
||||||
assertEquals(100.0, (reconstructed.children["@ambientLight"] as AmbientLightSource).intensity.toDouble())
|
assertEquals(100.0, (reconstructed.children.getChild("@ambientLight") as AmbientLightSource).intensity.toDouble())
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid
|
|||||||
import space.kscience.dataforge.context.Global
|
import space.kscience.dataforge.context.Global
|
||||||
import space.kscience.dataforge.context.fetch
|
import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
|
|
||||||
@ -25,8 +25,8 @@ class SolidPluginTest {
|
|||||||
val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup
|
val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup
|
||||||
|
|
||||||
assertEquals(
|
assertEquals(
|
||||||
visionManager.encodeToJsonElement(vision.children["aBox"]!!),
|
visionManager.encodeToJsonElement(vision.children.getChild("aBox")!!),
|
||||||
visionManager.encodeToJsonElement(reconstructed.children["aBox"]!!)
|
visionManager.encodeToJsonElement(reconstructed.children.getChild("aBox")!!)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid
|
|||||||
import kotlinx.serialization.json.encodeToJsonElement
|
import kotlinx.serialization.json.encodeToJsonElement
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.dataforge.names.get
|
import space.kscience.dataforge.names.get
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import space.kscience.visionforge.style
|
import space.kscience.visionforge.style
|
||||||
import space.kscience.visionforge.useStyle
|
import space.kscience.visionforge.useStyle
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
@ -24,7 +24,7 @@ class SolidReferenceTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testReferenceProperty(){
|
fun testReferenceProperty(){
|
||||||
assertEquals("blue", (groupWithReference.children["test"] as Solid).color.string)
|
assertEquals("blue", (groupWithReference.children.getChild("test") as Solid).color.string)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
@ -32,6 +32,6 @@ class SolidReferenceTest {
|
|||||||
val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference)
|
val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference)
|
||||||
val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized)
|
val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized)
|
||||||
assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string)
|
assertEquals(groupWithReference.items["test"]?.color.string, deserialized.items["test"]?.color.string)
|
||||||
assertEquals("blue", (deserialized.children["test"] as Solid).color.string)
|
assertEquals("blue", (deserialized.children.getChild("test") as Solid).color.string)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,7 +6,7 @@ import space.kscience.dataforge.meta.Meta
|
|||||||
import space.kscience.dataforge.meta.asValue
|
import space.kscience.dataforge.meta.asValue
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.visionforge.VisionChange
|
import space.kscience.visionforge.VisionChange
|
||||||
import space.kscience.visionforge.get
|
import space.kscience.visionforge.getChild
|
||||||
import kotlin.test.Test
|
import kotlin.test.Test
|
||||||
import kotlin.test.assertEquals
|
import kotlin.test.assertEquals
|
||||||
import kotlin.test.assertTrue
|
import kotlin.test.assertTrue
|
||||||
@ -29,9 +29,9 @@ internal class VisionUpdateTest {
|
|||||||
propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue()))
|
propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue()))
|
||||||
}
|
}
|
||||||
targetVision.update(dif)
|
targetVision.update(dif)
|
||||||
assertTrue { targetVision.children["top"] is SolidGroup }
|
assertTrue { targetVision.children.getChild("top") is SolidGroup }
|
||||||
assertEquals("red", (targetVision.children["origin"] as Solid).color.string) // Should work
|
assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work
|
||||||
assertEquals("#00007b", (targetVision.children["top"] as Solid).color.string) // new item always takes precedence
|
assertEquals("#00007b", (targetVision.children.getChild("top") as Solid).color.string) // new item always takes precedence
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -10,6 +10,6 @@ kotlin{
|
|||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
api(project(":visionforge-solid"))
|
api(project(":visionforge-solid"))
|
||||||
implementation(npm("three", "0.137.4"))
|
implementation(npm("three", "0.137.5"))
|
||||||
implementation(npm("three-csg-ts", "3.1.10"))
|
implementation(npm("three-csg-ts", "3.1.10"))
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@ import info.laht.threekt.geometries.BoxGeometry
|
|||||||
import space.kscience.visionforge.solid.Box
|
import space.kscience.visionforge.solid.Box
|
||||||
import space.kscience.visionforge.solid.detail
|
import space.kscience.visionforge.solid.detail
|
||||||
|
|
||||||
public object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {
|
public object ThreeBoxFactory : ThreeMeshFactory<Box>(Box::class) {
|
||||||
override fun buildGeometry(obj: Box): BoxGeometry =
|
override fun buildGeometry(obj: Box): BoxGeometry =
|
||||||
obj.detail?.let { detail ->
|
obj.detail?.let { detail ->
|
||||||
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
||||||
|
@ -50,7 +50,7 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
|
|||||||
obj.onPropertyChange { name ->
|
obj.onPropertyChange { name ->
|
||||||
when {
|
when {
|
||||||
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
|
||||||
name.startsWith(MeshThreeFactory.EDGES_KEY) -> applyEdges(obj)
|
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(obj)
|
||||||
else -> updateProperty(obj, name)
|
else -> updateProperty(obj, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ import space.kscience.visionforge.solid.detail
|
|||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
public object ThreeConeFactory : MeshThreeFactory<ConeSegment>(ConeSegment::class) {
|
public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::class) {
|
||||||
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
||||||
val cylinder = obj.detail?.let {
|
val cylinder = obj.detail?.let {
|
||||||
val segments = it.toDouble().pow(0.5).toInt()
|
val segments = it.toDouble().pow(0.5).toInt()
|
||||||
|
@ -3,7 +3,7 @@ package space.kscience.visionforge.solid.three
|
|||||||
import info.laht.threekt.external.geometries.ConvexBufferGeometry
|
import info.laht.threekt.external.geometries.ConvexBufferGeometry
|
||||||
import space.kscience.visionforge.solid.Convex
|
import space.kscience.visionforge.solid.Convex
|
||||||
|
|
||||||
public object ThreeConvexFactory : MeshThreeFactory<Convex>(Convex::class) {
|
public object ThreeConvexFactory : ThreeMeshFactory<Convex>(Convex::class) {
|
||||||
override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
||||||
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
||||||
return ConvexBufferGeometry(vectors)
|
return ConvexBufferGeometry(vectors)
|
||||||
|
@ -75,7 +75,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
|||||||
/**
|
/**
|
||||||
* Generic factory for elements which provide inside geometry builder
|
* Generic factory for elements which provide inside geometry builder
|
||||||
*/
|
*/
|
||||||
public object ThreeShapeFactory : MeshThreeFactory<GeometrySolid>(GeometrySolid::class) {
|
public object ThreeShapeFactory : ThreeMeshFactory<GeometrySolid>(GeometrySolid::class) {
|
||||||
override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
||||||
obj.toGeometry(this)
|
obj.toGeometry(this)
|
||||||
}.build()
|
}.build()
|
||||||
|
@ -15,14 +15,14 @@ import space.kscience.visionforge.set
|
|||||||
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.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY
|
||||||
import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_MATERIAL_KEY
|
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY
|
||||||
import kotlin.reflect.KClass
|
import kotlin.reflect.KClass
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Basic geometry-based factory
|
* Basic geometry-based factory
|
||||||
*/
|
*/
|
||||||
public abstract class MeshThreeFactory<in T : Solid>(
|
public abstract class ThreeMeshFactory<in T : Solid>(
|
||||||
override val type: KClass<in T>,
|
override val type: KClass<in T>,
|
||||||
) : ThreeFactory<T> {
|
) : ThreeFactory<T> {
|
||||||
/**
|
/**
|
@ -82,7 +82,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
}.launchIn(context)
|
}.launchIn(context)
|
||||||
|
|
||||||
obj.children.changes.onEach { childName ->
|
obj.children.changes.onEach { childName ->
|
||||||
val child = obj.children[childName]
|
val child = obj.children.getChild(childName)
|
||||||
|
|
||||||
//removing old object
|
//removing old object
|
||||||
findChild(childName)?.let { oldChild ->
|
findChild(childName)?.let { oldChild ->
|
||||||
|
@ -53,7 +53,7 @@ public object ThreeReferenceFactory : ThreeFactory<SolidReference> {
|
|||||||
?: error("Wrong syntax for reference child property: '$name'")
|
?: error("Wrong syntax for reference child property: '$name'")
|
||||||
val propertyName = name.cutFirst()
|
val propertyName = name.cutFirst()
|
||||||
val referenceChild =
|
val referenceChild =
|
||||||
obj.children[childName] ?: error("Reference child with name '$childName' not found")
|
obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found")
|
||||||
val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found")
|
val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found")
|
||||||
child.updateProperty(referenceChild, propertyName)
|
child.updateProperty(referenceChild, propertyName)
|
||||||
} else {
|
} else {
|
||||||
|
@ -5,7 +5,7 @@ import info.laht.threekt.geometries.SphereGeometry
|
|||||||
import space.kscience.visionforge.solid.Sphere
|
import space.kscience.visionforge.solid.Sphere
|
||||||
import space.kscience.visionforge.solid.detail
|
import space.kscience.visionforge.solid.detail
|
||||||
|
|
||||||
public object ThreeSphereFactory : MeshThreeFactory<Sphere>(Sphere::class) {
|
public object ThreeSphereFactory : ThreeMeshFactory<Sphere>(Sphere::class) {
|
||||||
override fun buildGeometry(obj: Sphere): BufferGeometry {
|
override fun buildGeometry(obj: Sphere): BufferGeometry {
|
||||||
return obj.detail?.let {detail ->
|
return obj.detail?.let {detail ->
|
||||||
SphereGeometry(
|
SphereGeometry(
|
||||||
|
Loading…
Reference in New Issue
Block a user