Clean up factories

This commit is contained in:
Alexander Nozik 2019-10-03 11:37:48 +03:00
parent 255261e789
commit 73d45ddbe4
9 changed files with 69 additions and 43 deletions

View File

@ -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]
} }

View File

@ -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(

View File

@ -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

View File

@ -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,13 +122,18 @@ 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?
is Proxy -> prototype get() = when (this) {
is Proxy.ProxyChild -> prototype is Proxy -> prototype
else -> null is Proxy.ProxyChild -> prototype
} else -> null
}
inline fun VisualGroup3D.ref( inline fun VisualGroup3D.ref(
templateName: Name, templateName: Name,

View File

@ -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"

View File

@ -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)

View File

@ -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
*/ */

View File

@ -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()

View File

@ -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
} }
} }