Clean up factories
This commit is contained in:
parent
255261e789
commit
73d45ddbe4
@ -74,7 +74,7 @@ abstract class AbstractVisualObject : VisualObject {
|
|||||||
|
|
||||||
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
|
||||||
return if (inherit) {
|
return if (inherit) {
|
||||||
properties?.get(name) ?: parent?.getProperty(name, inherit) ?: actualStyles[name]
|
properties?.get(name) ?: actualStyles[name] ?: parent?.getProperty(name, inherit)
|
||||||
} else {
|
} else {
|
||||||
properties?.get(name) ?: actualStyles[name]
|
properties?.get(name) ?: actualStyles[name]
|
||||||
}
|
}
|
||||||
|
@ -153,7 +153,7 @@ private fun VisualGroup3D.addPhysicalVolume(
|
|||||||
//optimizing single child case
|
//optimizing single child case
|
||||||
if (context.optimizeSingleChild && group.children.size == 1) {
|
if (context.optimizeSingleChild && group.children.size == 1) {
|
||||||
this[physVolume.name ?: ""] = group.children.values.first().apply {
|
this[physVolume.name ?: ""] = group.children.values.first().apply {
|
||||||
//Must ser this to avoid parent reset error
|
//Must set this to avoid parent reset error
|
||||||
parent = null
|
parent = null
|
||||||
//setting offset from physical volume
|
//setting offset from physical volume
|
||||||
withPosition(
|
withPosition(
|
||||||
|
@ -22,6 +22,11 @@ class Composite(
|
|||||||
val second: VisualObject3D
|
val second: VisualObject3D
|
||||||
) : AbstractVisualObject(), VisualObject3D {
|
) : AbstractVisualObject(), VisualObject3D {
|
||||||
|
|
||||||
|
init {
|
||||||
|
first.parent = this
|
||||||
|
second.parent = this
|
||||||
|
}
|
||||||
|
|
||||||
override var position: Point3D? = null
|
override var position: Point3D? = null
|
||||||
override var rotation: Point3D? = null
|
override var rotation: Point3D? = null
|
||||||
override var scale: Point3D? = null
|
override var scale: Point3D? = null
|
||||||
|
@ -15,6 +15,9 @@ import hep.dataforge.vis.common.VisualGroup
|
|||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.common.VisualObject
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import kotlinx.serialization.UseSerializers
|
import kotlinx.serialization.UseSerializers
|
||||||
|
import kotlin.collections.component1
|
||||||
|
import kotlin.collections.component2
|
||||||
|
import kotlin.collections.set
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A proxy [VisualObject3D] to reuse a template object
|
* A proxy [VisualObject3D] to reuse a template object
|
||||||
@ -63,6 +66,10 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
|
|
||||||
private val propertyCache: HashMap<Name, Config> = HashMap()
|
private val propertyCache: HashMap<Name, Config> = HashMap()
|
||||||
|
|
||||||
|
fun childPropertyName(childName: Name, propertyName: Name): Name {
|
||||||
|
return NameToken(PROXY_CHILD_PROPERTY_PREFIX, childName.toString()) + propertyName
|
||||||
|
}
|
||||||
|
|
||||||
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
|
||||||
|
|
||||||
override val children: Map<NameToken, VisualObject>
|
override val children: Map<NameToken, VisualObject>
|
||||||
@ -89,9 +96,16 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
get() = propertyCache[name]
|
get() = propertyCache[name]
|
||||||
set(value) {
|
set(value) {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
propertyCache.remove(name)
|
propertyCache.remove(name)?.also {
|
||||||
|
//Removing listener if it is present
|
||||||
|
removeChangeListener(this@Proxy)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
propertyCache[name] = value
|
propertyCache[name] = value.also {
|
||||||
|
onPropertyChange(this@Proxy) { propertyName, before, after ->
|
||||||
|
this@Proxy.propertyChanged(childPropertyName(name, propertyName), before, after)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -108,9 +122,14 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
const val PROXY_CHILD_PROPERTY_PREFIX = "@child"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val VisualObject.prototype: VisualObject? get() = when(this){
|
val VisualObject.prototype: VisualObject?
|
||||||
|
get() = when (this) {
|
||||||
is Proxy -> prototype
|
is Proxy -> prototype
|
||||||
is Proxy.ProxyChild -> prototype
|
is Proxy.ProxyChild -> prototype
|
||||||
else -> null
|
else -> null
|
||||||
|
@ -42,6 +42,8 @@ interface VisualObject3D : VisualObject {
|
|||||||
val DETAIL_KEY = "detail".asName()
|
val DETAIL_KEY = "detail".asName()
|
||||||
val LAYER_KEY = "layer".asName()
|
val LAYER_KEY = "layer".asName()
|
||||||
|
|
||||||
|
val GEOMETRY_KEY = "geometey".asName()
|
||||||
|
|
||||||
val COLOR_KEY = MATERIAL_KEY + "color"
|
val COLOR_KEY = MATERIAL_KEY + "color"
|
||||||
val OPACITY_KEY = MATERIAL_KEY + "opacity"
|
val OPACITY_KEY = MATERIAL_KEY + "opacity"
|
||||||
|
|
||||||
|
@ -11,9 +11,9 @@ import info.laht.threekt.objects.Mesh
|
|||||||
class ThreeCompositeFactory(val three: ThreePlugin) : MeshThreeFactory<Composite>(Composite::class) {
|
class ThreeCompositeFactory(val three: ThreePlugin) : MeshThreeFactory<Composite>(Composite::class) {
|
||||||
|
|
||||||
override fun buildGeometry(obj: Composite): BufferGeometry {
|
override fun buildGeometry(obj: Composite): BufferGeometry {
|
||||||
val first = three.buildObject3D(obj.first.apply { parent = obj.parent }) as? Mesh ?: error("First part of composite is not a mesh")
|
val first = three.buildObject3D(obj.first) as? Mesh ?: error("First part of composite is not a mesh")
|
||||||
first.updateMatrix()
|
first.updateMatrix()
|
||||||
val second = three.buildObject3D(obj.second.apply { parent = obj.parent }) as? Mesh ?: error("Second part of composite is not a mesh")
|
val second = three.buildObject3D(obj.second) as? Mesh ?: error("Second part of composite is not a mesh")
|
||||||
second.updateMatrix()
|
second.updateMatrix()
|
||||||
val firstCSG = CSG.fromMesh(first)
|
val firstCSG = CSG.fromMesh(first)
|
||||||
val secondCSG = CSG.fromMesh(second)
|
val secondCSG = CSG.fromMesh(second)
|
||||||
|
@ -2,11 +2,14 @@ package hep.dataforge.vis.spatial.three
|
|||||||
|
|
||||||
import hep.dataforge.meta.boolean
|
import hep.dataforge.meta.boolean
|
||||||
import hep.dataforge.meta.node
|
import hep.dataforge.meta.node
|
||||||
|
import hep.dataforge.names.Name
|
||||||
import hep.dataforge.names.asName
|
import hep.dataforge.names.asName
|
||||||
import hep.dataforge.names.plus
|
import hep.dataforge.names.plus
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.startsWith
|
||||||
import hep.dataforge.provider.Type
|
import hep.dataforge.provider.Type
|
||||||
|
import hep.dataforge.vis.common.VisualObject
|
||||||
import hep.dataforge.vis.spatial.*
|
import hep.dataforge.vis.spatial.*
|
||||||
|
import hep.dataforge.vis.spatial.VisualObject3D.Companion.GEOMETRY_KEY
|
||||||
import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.TYPE
|
import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.TYPE
|
||||||
import info.laht.threekt.core.BufferGeometry
|
import info.laht.threekt.core.BufferGeometry
|
||||||
import info.laht.threekt.core.Object3D
|
import info.laht.threekt.core.Object3D
|
||||||
@ -115,22 +118,9 @@ abstract class MeshThreeFactory<T : VisualObject3D>(override val type: KClass<ou
|
|||||||
|
|
||||||
//add listener to object properties
|
//add listener to object properties
|
||||||
obj.onPropertyChange(this) { name, _, _ ->
|
obj.onPropertyChange(this) { name, _, _ ->
|
||||||
if (name.startsWith(VisualObject3D.MATERIAL_KEY)) {
|
mesh.updateProperty(obj, name)
|
||||||
//updated material
|
if (name.startsWith(GEOMETRY_KEY)) {
|
||||||
mesh.material = obj.material.jsMaterial()
|
|
||||||
} else if (
|
|
||||||
name.startsWith(VisualObject3D.position) ||
|
|
||||||
name.startsWith(VisualObject3D.rotation) ||
|
|
||||||
name.startsWith(VisualObject3D.scale)
|
|
||||||
) {
|
|
||||||
//update position of mesh using this object
|
|
||||||
mesh.updatePosition(obj)
|
|
||||||
} else if (name == VisualObject3D.VISIBLE_KEY) {
|
|
||||||
mesh.visible = obj.visible ?: true
|
|
||||||
} else {
|
|
||||||
//full update
|
|
||||||
mesh.geometry = geometryBuilder(obj)
|
mesh.geometry = geometryBuilder(obj)
|
||||||
mesh.material = obj.material.jsMaterial()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return mesh
|
return mesh
|
||||||
@ -138,6 +128,23 @@ abstract class MeshThreeFactory<T : VisualObject3D>(override val type: KClass<ou
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fun Object3D.updateProperty(source: VisualObject, propertyName: Name) {
|
||||||
|
if (this is Mesh && propertyName.startsWith(VisualObject3D.MATERIAL_KEY)) {
|
||||||
|
//updated material
|
||||||
|
material = source.material.jsMaterial()
|
||||||
|
} else if (
|
||||||
|
source is VisualObject3D &&
|
||||||
|
(propertyName.startsWith(VisualObject3D.position)
|
||||||
|
|| propertyName.startsWith(VisualObject3D.rotation)
|
||||||
|
|| propertyName.startsWith(VisualObject3D.scale))
|
||||||
|
) {
|
||||||
|
//update position of mesh using this object
|
||||||
|
updatePosition(source)
|
||||||
|
} else if (propertyName == VisualObject3D.VISIBLE_KEY) {
|
||||||
|
visible = source.visible ?: true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generic factory for elements which provide inside geometry builder
|
* Generic factory for elements which provide inside geometry builder
|
||||||
*/
|
*/
|
||||||
|
@ -58,10 +58,6 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<V
|
|||||||
camera.updateProjectionMatrix()
|
camera.updateProjectionMatrix()
|
||||||
}
|
}
|
||||||
|
|
||||||
// val width by meta.number(element.offsetWidth).int
|
|
||||||
// val height by meta.number(element.offsetHeight).int
|
|
||||||
// val size = min(width, height)
|
|
||||||
// renderer.setSize(size, size)
|
|
||||||
renderer.setSize(element.offsetWidth, element.offsetWidth)
|
renderer.setSize(element.offsetWidth, element.offsetWidth)
|
||||||
|
|
||||||
animate()
|
animate()
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
package hep.dataforge.vis.spatial.three
|
package hep.dataforge.vis.spatial.three
|
||||||
|
|
||||||
import hep.dataforge.names.startsWith
|
import hep.dataforge.names.toName
|
||||||
import hep.dataforge.vis.common.VisualObject
|
import hep.dataforge.vis.common.VisualObject
|
||||||
import hep.dataforge.vis.spatial.Proxy
|
import hep.dataforge.vis.spatial.Proxy
|
||||||
|
import hep.dataforge.vis.spatial.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
|
||||||
import hep.dataforge.vis.spatial.VisualObject3D
|
import hep.dataforge.vis.spatial.VisualObject3D
|
||||||
import hep.dataforge.vis.spatial.material
|
import hep.dataforge.vis.spatial.material
|
||||||
import hep.dataforge.vis.spatial.visible
|
import hep.dataforge.vis.spatial.visible
|
||||||
@ -30,18 +31,14 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
|
|||||||
object3D.updatePosition(obj)
|
object3D.updatePosition(obj)
|
||||||
|
|
||||||
obj.onPropertyChange(this) { name, _, _ ->
|
obj.onPropertyChange(this) { name, _, _ ->
|
||||||
if (object3D is Mesh && name.startsWith(VisualObject3D.MATERIAL_KEY)) {
|
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
|
||||||
//updated material
|
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
|
||||||
object3D.material = obj.material.jsMaterial()
|
val propertyName = name.cutFirst()
|
||||||
} else if (
|
val proxyChild = obj[childName] ?: error("Proxy child with name '$childName' not found")
|
||||||
name.startsWith(VisualObject3D.position) ||
|
val child = object3D.findChild(childName)?: error("Object child with name '$childName' not found")
|
||||||
name.startsWith(VisualObject3D.rotation) ||
|
child.updateProperty(proxyChild, propertyName)
|
||||||
name.startsWith(VisualObject3D.scale)
|
} else {
|
||||||
) {
|
object3D.updateProperty(obj, name)
|
||||||
//update position of mesh using this object
|
|
||||||
object3D.updatePosition(obj)
|
|
||||||
} else if (name == VisualObject3D.VISIBLE_KEY) {
|
|
||||||
object3D.visible = obj.visible ?: true
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user