Fixed after migration to new Group structure
This commit is contained in:
parent
589afaa9b8
commit
8f1dcac6cd
@ -54,10 +54,24 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
//
|
||||
// }
|
||||
|
||||
/**
|
||||
* Remove a child with given name token
|
||||
*/
|
||||
protected abstract fun removeChild(token: NameToken)
|
||||
|
||||
/**
|
||||
* Add, remove or replace child with given name
|
||||
*/
|
||||
protected abstract fun setChild(token: NameToken, child: VisualObject?)
|
||||
|
||||
/**
|
||||
* Add a static child. Statics could not be found by name, removed or replaced
|
||||
*/
|
||||
protected abstract fun addStatic(child: VisualObject)
|
||||
|
||||
/**
|
||||
* Recursively create a child group
|
||||
*/
|
||||
protected abstract fun createGroup(name: Name): VisualGroup
|
||||
|
||||
/**
|
||||
@ -66,17 +80,16 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
*/
|
||||
override fun set(name: Name, child: VisualObject?) {
|
||||
when {
|
||||
name.isEmpty() -> error("")
|
||||
name.isEmpty() -> {
|
||||
if (child != null) {
|
||||
addStatic(child)
|
||||
}
|
||||
}
|
||||
name.length == 1 -> {
|
||||
val token = name.first()!!
|
||||
if (child == null) {
|
||||
removeChild(token)
|
||||
} else {
|
||||
if (child.parent == null) {
|
||||
child.parent = this
|
||||
} else {
|
||||
error("Can't reassign existing parent for $child")
|
||||
}
|
||||
setChild(token, child)
|
||||
}
|
||||
}
|
||||
@ -89,7 +102,13 @@ abstract class AbstractVisualGroup : AbstractVisualObject(), VisualGroup {
|
||||
listeners.forEach { it.callback(name, child) }
|
||||
}
|
||||
|
||||
operator fun set(key: String, child: VisualObject?) = set(key.asName(), child)
|
||||
operator fun set(key: String, child: VisualObject?) = if (key.isBlank()) {
|
||||
child?.let { addStatic(child) }
|
||||
} else {
|
||||
set(key.asName(), child)
|
||||
}
|
||||
|
||||
operator fun set(key: String?, child: VisualObject?) = set(key ?: "", child)
|
||||
|
||||
protected fun MetaBuilder.updateChildren() {
|
||||
//adding named children
|
||||
|
@ -34,8 +34,7 @@ abstract class AbstractVisualObject : VisualObject {
|
||||
abstract var properties: Config?
|
||||
override val config: Config
|
||||
get() = properties ?: Config().also { config ->
|
||||
properties = config
|
||||
config.onChange(this, ::propertyChanged)
|
||||
properties = config.apply { onChange(this, ::propertyChanged) }
|
||||
}
|
||||
|
||||
override fun setProperty(name: Name, value: Any?) {
|
||||
|
@ -50,4 +50,4 @@ interface VisualGroup : VisualObject, Provider, Iterable<VisualObject> {
|
||||
operator fun set(name: Name, child: VisualObject?)
|
||||
}
|
||||
|
||||
operator fun VisualGroup.get(str: String) = get(str.toName())
|
||||
operator fun VisualGroup.get(str: String?) = get(str?.toName() ?: EmptyName)
|
@ -1,8 +1,10 @@
|
||||
package hep.dataforge.vis.spatial.gdml
|
||||
|
||||
import hep.dataforge.meta.Meta
|
||||
import hep.dataforge.names.EmptyName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vis.common.asName
|
||||
import hep.dataforge.vis.common.get
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import scientifik.gdml.*
|
||||
import kotlin.math.cos
|
||||
@ -42,7 +44,7 @@ private inline operator fun Number.times(f: Float) = toFloat() * f
|
||||
private fun VisualGroup3D.addSolid(
|
||||
context: GDMLTransformer,
|
||||
solid: GDMLSolid,
|
||||
name: String? = null,
|
||||
name: String = "",
|
||||
block: VisualObject3D.() -> Unit = {}
|
||||
): VisualObject3D {
|
||||
context.solidAdded(solid)
|
||||
@ -185,7 +187,8 @@ private fun VisualGroup3D.addDivisionVolume(
|
||||
?: error("Volume with ref ${divisionVolume.volumeref.ref} could not be resolved")
|
||||
|
||||
//TODO add divisions
|
||||
add(
|
||||
set(
|
||||
EmptyName,
|
||||
volume(
|
||||
context,
|
||||
volume
|
||||
@ -217,7 +220,7 @@ private fun volume(
|
||||
}
|
||||
}
|
||||
GDMLTransformer.Action.CACHE -> {
|
||||
if (context.templates[solid.name] == null) {
|
||||
if (context.templates.get(solid.name) == null) {
|
||||
context.templates.addSolid(context, solid, solid.name) {
|
||||
this.material = context.resolveColor(group, material, solid)
|
||||
}
|
||||
|
@ -12,7 +12,7 @@ import kotlinx.serialization.UseSerializers
|
||||
import kotlin.reflect.KClass
|
||||
|
||||
@Serializable
|
||||
data class Box(
|
||||
class Box(
|
||||
val xSize: Float,
|
||||
val ySize: Float,
|
||||
val zSize: Float
|
||||
|
@ -3,12 +3,16 @@ package hep.dataforge.vis.spatial
|
||||
import hep.dataforge.context.AbstractPlugin
|
||||
import hep.dataforge.context.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.io.MetaSerializer
|
||||
import hep.dataforge.io.NameSerializer
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
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) {
|
||||
@ -28,6 +32,12 @@ class Visual3DPlugin(meta: Meta) : AbstractPlugin(meta) {
|
||||
override fun invoke(meta: Meta): Visual3DPlugin = Visual3DPlugin(meta)
|
||||
|
||||
val serialModule = SerializersModule {
|
||||
contextual(Point3DSerializer)
|
||||
contextual(Point2DSerializer)
|
||||
contextual(NameSerializer)
|
||||
contextual(NameTokenSerializer)
|
||||
contextual(MetaSerializer)
|
||||
contextual(ConfigSerializer)
|
||||
polymorphic(VisualObject3D::class) {
|
||||
VisualGroup3D::class with VisualGroup3D.serializer()
|
||||
Proxy::class with Proxy.serializer()
|
||||
|
@ -0,0 +1,92 @@
|
||||
@file:UseSerializers(Point3DSerializer::class, ConfigSerializer::class, NameTokenSerializer::class)
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.meta.Config
|
||||
import hep.dataforge.meta.Configurable
|
||||
import hep.dataforge.meta.MetaBuilder
|
||||
import hep.dataforge.meta.set
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.vis.common.AbstractVisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
|
||||
@Serializable
|
||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, Configurable {
|
||||
/**
|
||||
* A container for templates visible inside this group
|
||||
*/
|
||||
var templates: VisualGroup3D? = null
|
||||
set(value) {
|
||||
value?.parent = this
|
||||
field = value
|
||||
}
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
override var position: Point3D? = null
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
private val _children = HashMap<NameToken, VisualObject>()
|
||||
override val children: Map<NameToken, VisualObject> get() = _children
|
||||
|
||||
override fun removeChild(token: NameToken) {
|
||||
_children.remove(token)
|
||||
}
|
||||
|
||||
override fun setChild(token: NameToken, child: VisualObject?) {
|
||||
if (child == null) {
|
||||
_children.remove(token)
|
||||
} else {
|
||||
if (child.parent == null) {
|
||||
child.parent = this
|
||||
} else {
|
||||
error("Can't reassign existing parent for $child")
|
||||
}
|
||||
_children[token] = child
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* TODO add special static group to hold statics without propagation
|
||||
*/
|
||||
override fun addStatic(child: VisualObject) = setChild(NameToken(child.hashCode().toString()), child)
|
||||
|
||||
override fun createGroup(name: Name): VisualGroup3D {
|
||||
return when {
|
||||
name.isEmpty() -> error("Should be unreachable")
|
||||
name.length == 1 -> {
|
||||
val token = name.first()!!
|
||||
when (val current = children[token]) {
|
||||
null -> VisualGroup3D().also { setChild(token, it) }
|
||||
is VisualGroup3D -> current
|
||||
else -> error("Can't create group with name $name because it exists and not a group")
|
||||
}
|
||||
}
|
||||
else -> createGroup(name.first()!!.asName()).createGroup(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
||||
fun getTemplate(name: Name): VisualObject3D? =
|
||||
templates?.get(name) as? VisualObject3D
|
||||
?: (parent as? VisualGroup3D)?.getTemplate(name)
|
||||
|
||||
override fun MetaBuilder.updateMeta() {
|
||||
set(TEMPLATES_KEY, templates?.toMeta())
|
||||
updatePosition()
|
||||
updateChildren()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TEMPLATES_KEY = "templates"
|
||||
}
|
||||
}
|
||||
|
||||
fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
|
||||
VisualGroup3D().apply(action).also { set(key, it) }
|
@ -2,18 +2,15 @@
|
||||
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.io.ConfigSerializer
|
||||
import hep.dataforge.io.NameSerializer
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.*
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.output.Output
|
||||
import hep.dataforge.vis.common.AbstractVisualGroup
|
||||
import hep.dataforge.vis.common.VisualObject
|
||||
import hep.dataforge.vis.common.asName
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.DETAIL_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.MATERIAL_KEY
|
||||
import hep.dataforge.vis.spatial.VisualObject3D.Companion.VISIBLE_KEY
|
||||
import kotlinx.serialization.Serializable
|
||||
import kotlinx.serialization.UseSerializers
|
||||
|
||||
interface VisualObject3D : VisualObject {
|
||||
@ -64,71 +61,6 @@ interface VisualObject3D : VisualObject {
|
||||
}
|
||||
}
|
||||
|
||||
@Serializable
|
||||
class VisualGroup3D : AbstractVisualGroup(), VisualObject3D, Configurable {
|
||||
/**
|
||||
* A container for templates visible inside this group
|
||||
*/
|
||||
var templates: VisualGroup3D? = null
|
||||
set(value) {
|
||||
value?.parent = this
|
||||
field = value
|
||||
}
|
||||
|
||||
@Serializable(ConfigSerializer::class)
|
||||
override var properties: Config? = null
|
||||
|
||||
override var position: Point3D? = null
|
||||
override var rotation: Point3D? = null
|
||||
override var scale: Point3D? = null
|
||||
|
||||
private val _children = HashMap<NameToken, VisualObject>()
|
||||
override val children: Map<NameToken, VisualObject> get() = _children
|
||||
|
||||
override fun removeChild(token: NameToken) {
|
||||
_children.remove(token)
|
||||
}
|
||||
|
||||
override fun setChild(token: NameToken, child: VisualObject?) {
|
||||
if (child == null) {
|
||||
_children.remove(token)
|
||||
} else {
|
||||
_children[token] = child
|
||||
}
|
||||
}
|
||||
|
||||
override fun createGroup(name: Name): VisualGroup3D {
|
||||
return when{
|
||||
name.isEmpty() -> error("Should be unreachable")
|
||||
name.length == 1 -> {
|
||||
val token = name.first()!!
|
||||
when (val current = children[token]) {
|
||||
null -> VisualGroup3D().also { setChild(token, it) }
|
||||
is VisualGroup3D -> current
|
||||
else -> error("Can't create group with name $name because it exists and not a group")
|
||||
}
|
||||
}
|
||||
else -> createGroup(name.first()!!.asName()).createGroup(name.cutFirst())
|
||||
}
|
||||
}
|
||||
|
||||
fun getTemplate(name: Name): VisualObject3D? =
|
||||
templates?.get(name) as? VisualGroup3D ?: (parent as? VisualGroup3D)?.getTemplate(name)
|
||||
|
||||
override fun MetaBuilder.updateMeta() {
|
||||
set(TEMPLATES_KEY, templates?.toMeta())
|
||||
updatePosition()
|
||||
updateChildren()
|
||||
}
|
||||
|
||||
companion object {
|
||||
const val TEMPLATES_KEY = "templates"
|
||||
}
|
||||
}
|
||||
|
||||
fun VisualGroup3D.group(key: String = "", action: VisualGroup3D.() -> Unit = {}): VisualGroup3D =
|
||||
VisualGroup3D().apply(action).also { set(key, it) }
|
||||
|
||||
fun Output<VisualObject3D>.render(meta: Meta = EmptyMeta, action: VisualGroup3D.() -> Unit) =
|
||||
render(VisualGroup3D().apply(action), meta)
|
||||
|
||||
|
@ -1,7 +1,9 @@
|
||||
package hep.dataforge.vis.spatial
|
||||
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.names.toName
|
||||
import kotlinx.serialization.*
|
||||
import kotlinx.serialization.internal.StringDescriptor
|
||||
|
||||
@Serializable
|
||||
private data class Point2DSerial(val x: Double, val y: Double)
|
||||
@ -10,7 +12,7 @@ private data class Point2DSerial(val x: Double, val y: Double)
|
||||
private data class Point3DSerial(val x: Double, val y: Double, val z: Double)
|
||||
|
||||
@Serializer(Point3D::class)
|
||||
object Point3DSerializer : KSerializer<Point3D>{
|
||||
object Point3DSerializer : KSerializer<Point3D> {
|
||||
private val serializer = Point3DSerial.serializer()
|
||||
override val descriptor: SerialDescriptor get() = serializer.descriptor
|
||||
|
||||
@ -26,7 +28,7 @@ object Point3DSerializer : KSerializer<Point3D>{
|
||||
}
|
||||
|
||||
@Serializer(Point2D::class)
|
||||
object Point2DSerializer : KSerializer<Point2D>{
|
||||
object Point2DSerializer : KSerializer<Point2D> {
|
||||
private val serializer = Point2DSerial.serializer()
|
||||
override val descriptor: SerialDescriptor get() = serializer.descriptor
|
||||
|
||||
@ -42,4 +44,14 @@ object Point2DSerializer : KSerializer<Point2D>{
|
||||
}
|
||||
|
||||
@Serializer(NameToken::class)
|
||||
object NameTokenSerializer : KSerializer<NameToken>
|
||||
object NameTokenSerializer : KSerializer<NameToken> {
|
||||
override val descriptor: SerialDescriptor = StringDescriptor.withName("NameToken")
|
||||
|
||||
override fun deserialize(decoder: Decoder): NameToken {
|
||||
return decoder.decodeString().toName().first()!!
|
||||
}
|
||||
|
||||
override fun serialize(encoder: Encoder, obj: NameToken) {
|
||||
encoder.encodeString(obj.toString())
|
||||
}
|
||||
}
|
@ -56,7 +56,7 @@ fun Meta?.jsMaterial(): Material {
|
||||
opacity = get("opacity")?.double ?: 1.0
|
||||
transparent = get("transparent").boolean ?: (opacity < 1.0)
|
||||
//node["specularColor"]?.let { specular = it.color() }
|
||||
side = 2
|
||||
//side = 2
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -90,7 +90,7 @@ abstract class MeshThreeFactory<T : VisualObject3D>(override val type: KClass<ou
|
||||
|
||||
override fun invoke(obj: T): Mesh {
|
||||
//create mesh from geometry
|
||||
return buildMesh<T>(obj) { buildGeometry(it) }
|
||||
return buildMesh(obj) { buildGeometry(it) }
|
||||
}
|
||||
|
||||
companion object {
|
||||
|
@ -5,6 +5,9 @@ import hep.dataforge.context.PluginFactory
|
||||
import hep.dataforge.context.PluginTag
|
||||
import hep.dataforge.context.content
|
||||
import hep.dataforge.meta.*
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.isEmpty
|
||||
import hep.dataforge.vis.spatial.*
|
||||
import info.laht.threekt.cameras.Camera
|
||||
import info.laht.threekt.cameras.PerspectiveCamera
|
||||
@ -46,7 +49,7 @@ class ThreePlugin : AbstractPlugin() {
|
||||
object3D.name = name.toString()
|
||||
group.add(object3D)
|
||||
} catch (ex: Throwable) {
|
||||
console.error(ex)
|
||||
// console.error(ex)
|
||||
logger.error(ex) { "Failed to render $name" }
|
||||
}
|
||||
}
|
||||
@ -97,4 +100,12 @@ class ThreePlugin : AbstractPlugin() {
|
||||
override val type = ThreePlugin::class
|
||||
override fun invoke(meta: Meta) = ThreePlugin()
|
||||
}
|
||||
}
|
||||
|
||||
fun Object3D.findChild(name: Name): Object3D? {
|
||||
return when {
|
||||
name.isEmpty() -> this
|
||||
name.length == 1 -> this.children.find { it.name == name.first()!!.toString() }
|
||||
else -> findChild(name.first()!!.asName())?.findChild(name.cutFirst())
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user