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<*>? {
return if (inherit) {
properties?.get(name) ?: parent?.getProperty(name, inherit) ?: actualStyles[name]
properties?.get(name) ?: actualStyles[name] ?: parent?.getProperty(name, inherit)
} else {
properties?.get(name) ?: actualStyles[name]
}

View File

@ -153,7 +153,7 @@ private fun VisualGroup3D.addPhysicalVolume(
//optimizing single child case
if (context.optimizeSingleChild && group.children.size == 1) {
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
//setting offset from physical volume
withPosition(

View File

@ -22,6 +22,11 @@ class Composite(
val second: VisualObject3D
) : AbstractVisualObject(), VisualObject3D {
init {
first.parent = this
second.parent = this
}
override var position: Point3D? = null
override var rotation: 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 kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlin.collections.component1
import kotlin.collections.component2
import kotlin.collections.set
/**
* 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()
fun childPropertyName(childName: Name, propertyName: Name): Name {
return NameToken(PROXY_CHILD_PROPERTY_PREFIX, childName.toString()) + propertyName
}
inner class ProxyChild(val name: Name) : AbstractVisualObject(), VisualGroup {
override val children: Map<NameToken, VisualObject>
@ -89,9 +96,16 @@ class Proxy(val templateName: Name) : AbstractVisualObject(), VisualGroup, Visua
get() = propertyCache[name]
set(value) {
if (value == null) {
propertyCache.remove(name)
propertyCache.remove(name)?.also {
//Removing listener if it is present
removeChangeListener(this@Proxy)
}
} 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.ProxyChild -> prototype
else -> null

View File

@ -42,6 +42,8 @@ interface VisualObject3D : VisualObject {
val DETAIL_KEY = "detail".asName()
val LAYER_KEY = "layer".asName()
val GEOMETRY_KEY = "geometey".asName()
val COLOR_KEY = MATERIAL_KEY + "color"
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) {
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()
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()
val firstCSG = CSG.fromMesh(first)
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.node
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.names.plus
import hep.dataforge.names.startsWith
import hep.dataforge.provider.Type
import hep.dataforge.vis.common.VisualObject
import hep.dataforge.vis.spatial.*
import hep.dataforge.vis.spatial.VisualObject3D.Companion.GEOMETRY_KEY
import hep.dataforge.vis.spatial.three.ThreeFactory.Companion.TYPE
import info.laht.threekt.core.BufferGeometry
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
obj.onPropertyChange(this) { name, _, _ ->
if (name.startsWith(VisualObject3D.MATERIAL_KEY)) {
//updated material
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.updateProperty(obj, name)
if (name.startsWith(GEOMETRY_KEY)) {
mesh.geometry = geometryBuilder(obj)
mesh.material = obj.material.jsMaterial()
}
}
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
*/

View File

@ -58,10 +58,6 @@ class ThreeOutput(val three: ThreePlugin, val meta: Meta = EmptyMeta) : Output<V
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)
animate()

View File

@ -1,8 +1,9 @@
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.spatial.Proxy
import hep.dataforge.vis.spatial.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
import hep.dataforge.vis.spatial.VisualObject3D
import hep.dataforge.vis.spatial.material
import hep.dataforge.vis.spatial.visible
@ -30,18 +31,14 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
object3D.updatePosition(obj)
obj.onPropertyChange(this) { name, _, _ ->
if (object3D is Mesh && name.startsWith(VisualObject3D.MATERIAL_KEY)) {
//updated material
object3D.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
object3D.updatePosition(obj)
} else if (name == VisualObject3D.VISIBLE_KEY) {
object3D.visible = obj.visible ?: true
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] ?: 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 {
object3D.updateProperty(obj, name)
}
}