Fix proxy child property update issue on Three. Name refactoring.

This commit is contained in:
Alexander Nozik 2020-03-01 11:00:43 +03:00
parent 6b455b57aa
commit ab47652314
21 changed files with 126 additions and 48 deletions

View File

@ -13,7 +13,7 @@ interface VisualFactory<T : VisualObject> {
): T
}
class VisualPlugin(meta: Meta) : AbstractPlugin(meta) {
class Visual(meta: Meta) : AbstractPlugin(meta) {
override val tag: PluginTag get() = Companion.tag
/**
@ -27,11 +27,11 @@ class VisualPlugin(meta: Meta) : AbstractPlugin(meta) {
return visualFactories[T::class]?.invoke(context, parent, meta) as T?
}
companion object : PluginFactory<VisualPlugin> {
companion object : PluginFactory<Visual> {
override val tag: PluginTag = PluginTag(name = "visual", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out VisualPlugin> = VisualPlugin::class
override val type: KClass<out Visual> = Visual::class
override fun invoke(meta: Meta, context: Context): VisualPlugin = VisualPlugin(meta)
override fun invoke(meta: Meta, context: Context): Visual = Visual(meta)
const val VISUAL_FACTORY_TYPE = "visual.factory"
}

View File

@ -88,7 +88,7 @@ interface MutableVisualGroup : VisualGroup {
operator fun set(name: Name, child: VisualObject?)
}
operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: Name.EMPTY)
operator fun VisualGroup.get(str: String?): VisualObject? = get(str?.toName() ?: Name.EMPTY)
operator fun MutableVisualGroup.set(key: String, child: VisualObject?) {
set(key.toName(), child)

View File

@ -7,7 +7,7 @@ kotlin {
val commonMain by getting {
dependencies {
api(project(":dataforge-vis-spatial"))
api("scientifik:gdml:0.1.5")
api("scientifik:gdml:0.1.6")
}
}
}

View File

@ -135,7 +135,7 @@ private fun jsonSchema(descriptor: SerialDescriptor, context: SerialModule): Jso
}
fun main() {
val context = Visual3DPlugin.serialModule
val context = Visual3D.serialModule
val definitions = json {
"children" to json {
"anyOf" to jsonArray {

View File

@ -11,13 +11,14 @@ import hep.dataforge.vis.common.AbstractVisualObject
import hep.dataforge.vis.common.VisualFactory
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.set
import hep.dataforge.vis.spatial.Box.Companion.TYPE_NAME
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlin.reflect.KClass
@Serializable
@SerialName("3d.box")
@SerialName(TYPE_NAME)
class Box(
val xSize: Float,
val ySize: Float,
@ -53,7 +54,8 @@ class Box(
}
companion object : VisualFactory<Box> {
const val TYPE = "geometry.3d.box"
const val TYPE_NAME = "3d.box"
override val type: KClass<Box> get() = Box::class

View File

@ -59,7 +59,7 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
}
override val children: Map<NameToken, ProxyChild>
get() = (prototype as? MutableVisualGroup)?.children
get() = (prototype as? VisualGroup)?.children
?.filter { !it.key.toString().startsWith("@") }
?.mapValues {
ProxyChild(it.key.asName())
@ -85,7 +85,6 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
//override fun findAllStyles(): Laminate = Laminate((styles + prototype.styles).mapNotNull { findStyle(it) })
@Serializable
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
val prototype: VisualObject get() = prototypeFor(name)

View File

@ -9,29 +9,32 @@ import hep.dataforge.io.serialization.MetaSerializer
import hep.dataforge.io.serialization.NameSerializer
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.vis.common.Visual
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.common.VisualPlugin
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import kotlin.reflect.KClass
class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) {
class Visual3D(meta: Meta) : AbstractPlugin(meta) {
val visual by require(Visual)
override val tag: PluginTag get() = Companion.tag
override fun provideTop(target: String): Map<Name, Any> {
return if (target == VisualPlugin.VISUAL_FACTORY_TYPE) {
mapOf()
override fun provideTop(target: String): Map<Name, Any> = if (target == Visual.VISUAL_FACTORY_TYPE) {
mapOf(Box.TYPE_NAME.toName() to Box)
} else {
emptyMap()
}
super.provideTop(target)
}
companion object : PluginFactory<Visual3DPlugin> {
companion object : PluginFactory<Visual3D> {
override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out Visual3DPlugin> = Visual3DPlugin::class
override fun invoke(meta: Meta, context: Context): Visual3DPlugin = Visual3DPlugin(meta)
override val type: KClass<out Visual3D> = Visual3D::class
override fun invoke(meta: Meta, context: Context): Visual3D = Visual3D(meta)
val serialModule = SerializersModule {
contextual(Point3DSerializer)

View File

@ -112,7 +112,7 @@ class VisualGroup3D : AbstractVisualGroup(), VisualObject3D {
// val PROTOTYPES_KEY = NameToken("@prototypes")
fun fromJson(json: String): VisualGroup3D =
Visual3DPlugin.json.parse(serializer(), json).also { it.attachChildren() }
Visual3D.json.parse(serializer(), json).also { it.attachChildren() }
}
}

View File

@ -25,7 +25,7 @@ class ConvexTest {
val convex = group.first() as Convex
val json = Visual3DPlugin.json.toJson(Convex.serializer(), convex)
val json = Visual3D.json.toJson(Convex.serializer(), convex)
val meta = json.toMeta()
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D()}

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis.spatial
import hep.dataforge.vis.spatial.Visual3DPlugin.Companion.json
import hep.dataforge.vis.spatial.Visual3D.Companion.json
import kotlinx.serialization.ImplicitReflectionSerializer
import kotlin.test.Test
import kotlin.test.assertEquals

View File

@ -31,13 +31,15 @@ interface ThreeFactory<in T : VisualObject> {
/**
* Update position, rotation and visibility
*/
fun Object3D.updatePosition(obj: VisualObject3D) {
fun Object3D.updatePosition(obj: VisualObject) {
visible = obj.visible ?: true
if(obj is VisualObject3D) {
position.set(obj.x, obj.y, obj.z)
setRotationFromEuler(obj.euler)
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
updateMatrix()
}
}
///**
// * Unsafe invocation of a factory
@ -54,7 +56,7 @@ fun Object3D.updatePosition(obj: VisualObject3D) {
/**
* Update non-position non-geometry property
*/
fun Object3D.updateProperty(source: VisualObject3D, propertyName: Name) {
fun Object3D.updateProperty(source: VisualObject, propertyName: Name) {
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
this.material = getMaterial(source)
} else if (

View File

@ -3,8 +3,8 @@ package hep.dataforge.vis.spatial.three
import hep.dataforge.meta.*
import hep.dataforge.values.ValueType
import hep.dataforge.vis.common.Colors
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.VisualObject3D
import info.laht.threekt.materials.LineBasicMaterial
import info.laht.threekt.materials.Material
import info.laht.threekt.materials.MeshBasicMaterial
@ -37,7 +37,7 @@ object ThreeMaterials {
}
}
fun getMaterial(visualObject3D: VisualObject3D): Material {
fun getMaterial(visualObject3D: VisualObject): Material {
val meta = visualObject3D.getProperty(Material3D.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT
return if (meta[Material3D.SPECULAR_COLOR_KEY] != null) {
MeshPhongMaterial().apply {

View File

@ -25,7 +25,7 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
val propertyName = name.cutFirst()
val proxyChild = obj[childName] as? VisualObject3D ?: error("Proxy child with name '$childName' not found or not a 3D object")
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
val child = object3D.findChild(childName)?: error("Object child with name '$childName' not found")
child.updateProperty(proxyChild, propertyName)
} else {

View File

@ -2,7 +2,7 @@ package hep.dataforge.vis.spatial.three
import hep.dataforge.js.requireJS
import hep.dataforge.vis.js.editor.card
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualGroup3D
import kotlinx.html.InputType
import kotlinx.html.TagConsumer
@ -46,7 +46,7 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
+"Export"
onClickFunction = {
val json = (canvas.content as? VisualGroup3D)?.let { group ->
Visual3DPlugin.json.stringify(
Visual3D.json.stringify(
VisualGroup3D.serializer(),
group
)

View File

@ -0,0 +1,54 @@
package hep.dataforge.vis.spatial.gdml.demo
import scientifik.gdml.*
fun cubes(): GDML = GDML {
val center = define.position("center")
structure {
val air = ref<GDMLMaterial>("G4_AIR")
val tubeMaterial = ref<GDMLMaterial>("tube")
val boxMaterial = ref<GDMLMaterial>("box")
val segment = solids.tube("segment", 20, 5.0) {
rmin = 17
deltaphi = 60
aunit = DEG
}
val worldBox = solids.box("LargeBox", 200, 200, 200)
val smallBox = solids.box("smallBox", 30, 30, 30)
val segmentVolume = volume("segment", tubeMaterial, segment.ref()) {}
val circle = volume("composite", boxMaterial, smallBox.ref()) {
for (i in 0 until 6) {
physVolume(segmentVolume) {
name = "segment$i"
positionref = center.ref()
rotation {
z = 60 * i
unit = DEG
}
}
}
}
world = volume("world", air, worldBox.ref()) {
for (i in 0 until 3) {
for (j in 0 until 3) {
for (k in 0 until 3) {
physVolume(circle) {
name = "composite$i$j$k"
position {
x = (-50 + i * 50)
y = (-50 + j * 50)
z = (-50 + k * 50)
}
rotation {
x = i * 120
y = j * 120
z = 120 * k
}
}
}
}
}
}
}
}

View File

@ -0,0 +1,18 @@
package hep.dataforge.vis.spatial.gdml
import hep.dataforge.meta.string
import hep.dataforge.names.toName
import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.gdml.demo.cubes
import kotlin.test.Test
import kotlin.test.assertEquals
class GDMLVisualTest {
@Test
fun testPrototypeProperty() {
val gdml = cubes()
val visual = gdml.toVisual()
visual["composite000.segment0".toName()]?.setProperty(Material3D.MATERIAL_COLOR_KEY, "red")
assertEquals("red", visual["composite000.segment0".toName()]?.getProperty(Material3D.MATERIAL_COLOR_KEY).string)
}
}

View File

@ -4,7 +4,7 @@ import hep.dataforge.context.Global
import hep.dataforge.vis.fx.editor.VisualObjectEditorFragment
import hep.dataforge.vis.fx.editor.VisualObjectTreeFragment
import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualGroup3D
import hep.dataforge.vis.spatial.fx.FX3DPlugin
import hep.dataforge.vis.spatial.fx.FXCanvas3D
@ -34,11 +34,11 @@ class GDMLView : View() {
override val root: Parent = borderpane {
top {
buttonbar {
button("Load GDML") {
button("Load GDML/json") {
action {
val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull()
?: return@action
val visual: VisualGroup3D = Visual3DPlugin.readFile(file)
val visual: VisualGroup3D = Visual3D.readFile(file)
canvas.render(visual)
}
}

View File

@ -1,7 +1,7 @@
package hep.dataforge.vis.spatial.gdml.demo
import hep.dataforge.vis.spatial.Material3D
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualGroup3D
import hep.dataforge.vis.spatial.gdml.LUnit
import hep.dataforge.vis.spatial.gdml.readFile
@ -11,7 +11,7 @@ import java.io.File
import java.util.zip.GZIPInputStream
import java.util.zip.ZipInputStream
fun Visual3DPlugin.Companion.readFile(file: File): VisualGroup3D = when {
fun Visual3D.Companion.readFile(file: File): VisualGroup3D = when {
file.extension == "gdml" || file.extension == "xml" -> {
GDML.readFile(file.toPath()).toVisual {
lUnit = LUnit.CM
@ -46,4 +46,4 @@ fun Visual3DPlugin.Companion.readFile(file: File): VisualGroup3D = when {
else -> error("Unknown extension ${file.extension}")
}
fun Visual3DPlugin.Companion.readFile(fileName: String): VisualGroup3D = readFile(File(fileName))
fun Visual3D.Companion.readFile(fileName: String): VisualGroup3D = readFile(File(fileName))

View File

@ -1,6 +1,6 @@
package hep.dataforge.vis.spatial.gdml.demo
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualGroup3D
import hep.dataforge.vis.spatial.gdml.LUnit
import hep.dataforge.vis.spatial.gdml.readFile
@ -14,6 +14,6 @@ fun main() {
val visual = gdml.toVisual {
lUnit = LUnit.CM
}
val json = Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)
val json = Visual3D.json.stringify(VisualGroup3D.serializer(), visual)
File("D:\\Work\\Projects\\gdml.kt\\gdml-source\\cubes.json").writeText(json)
}

View File

@ -15,7 +15,7 @@ import hep.dataforge.vis.js.editor.displayPropertyEditor
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vis.spatial.Material3D.Companion.MATERIAL_WIREFRAME_KEY
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import hep.dataforge.vis.spatial.VisualObject3D
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
import hep.dataforge.vis.spatial.three.ThreePlugin
@ -41,7 +41,7 @@ private class MMDemoApp : Application {
private val connection = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(Visual3DPlugin.json)
serializer = KotlinxSerializer(Visual3D.json)
}
}

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor.server
import hep.dataforge.vis.spatial.Visual3DPlugin
import hep.dataforge.vis.spatial.Visual3D
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
@ -35,7 +35,7 @@ fun Application.module() {
install(DefaultHeaders)
install(CallLogging)
install(ContentNegotiation) {
serialization(json = Visual3DPlugin.json)
serialization(json = Visual3D.json)
}
install(Routing) {
get("/event") {