Fix style material bug

This commit is contained in:
Alexander Nozik 2021-01-12 19:41:17 +03:00
parent 5eb9925d35
commit 18828e87f2
9 changed files with 31 additions and 44 deletions

View File

@ -29,7 +29,7 @@ import styled.styledDiv
external interface GDMLAppProps : RProps { external interface GDMLAppProps : RProps {
var context: Context var context: Context
var rootObject: Vision? var rootVision: Vision?
var selected: Name? var selected: Name?
} }
@ -45,7 +45,7 @@ external interface GDMLAppProps : RProps {
val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props -> val GDMLApp = functionalComponent<GDMLAppProps>("GDMLApp") { props ->
var selected by useState { props.selected } var selected by useState { props.selected }
var canvas: ThreeCanvas? by useState { null } var canvas: ThreeCanvas? by useState { null }
var vision: Vision? by useState { props.rootObject } var vision: Vision? by useState { props.rootVision }
val onSelect: (Name?) -> Unit = { val onSelect: (Name?) -> Unit = {
selected = it selected = it

View File

@ -3,6 +3,7 @@ package hep.dataforge.vision.gdml.demo
import hep.dataforge.context.Global import hep.dataforge.context.Global
import hep.dataforge.vision.Application import hep.dataforge.vision.Application
import hep.dataforge.vision.gdml.toVision import hep.dataforge.vision.gdml.toVision
import hep.dataforge.vision.solid.three.ThreePlugin
import hep.dataforge.vision.startApplication import hep.dataforge.vision.startApplication
import kotlinx.browser.document import kotlinx.browser.document
import react.child import react.child
@ -14,12 +15,16 @@ private class GDMLDemoApp : Application {
override fun start(state: Map<String, Any>) { override fun start(state: Map<String, Any>) {
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page") val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
val context = Global.context("demo") {} val context = Global.context("demo") .apply{
plugins.fetch(ThreePlugin)
}
render(element) { render(element) {
child(GDMLApp) { child(GDMLApp) {
val vision = cubes().toVision()
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
attrs { attrs {
this.context = context this.context = context
this.rootObject = cubes().toVision() this.rootVision = vision
} }
} }
} }

View File

@ -99,17 +99,8 @@ public tailrec fun Vision.getStyle(name: String): Meta? =
/** /**
* Resolve an item in all style layers * Resolve an item in all style layers
*/ */
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> { public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> = styles.asSequence().map {
return styles.asSequence().map { getStyle(it)[name]
getStyle(it) }.filterNotNull()
}.map {
it[name]
}.filterNotNull()
}
/**
* Collect all styles for this object in a single laminate
*/
public val Vision.allStyles: Laminate get() = Laminate(styles.mapNotNull(::getStyle))

View File

@ -29,6 +29,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) {
public val jsonFormat: Json public val jsonFormat: Json
get() = Json(defaultJson) { get() = Json(defaultJson) {
encodeDefaults = false
serializersModule = this@VisionManager.serializersModule serializersModule = this@VisionManager.serializersModule
} }

View File

@ -97,7 +97,7 @@ private class GDMLTransformer(val settings: GDMLTransformerSettings) {
fun configureSolid(root: GDML, obj: Solid, parent: GDMLVolume, solid: GDMLSolid) { fun configureSolid(root: GDML, obj: Solid, parent: GDMLVolume, solid: GDMLSolid) {
val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref) val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref)
val styleName = "material[${material.name}]" val styleName = "materials.${material.name}"
obj.useStyle(styleName) { obj.useStyle(styleName) {
MATERIAL_COLOR_KEY put random.nextInt(16777216) MATERIAL_COLOR_KEY put random.nextInt(16777216)

View File

@ -42,6 +42,7 @@ public abstract class MeshThreeFactory<in T : Solid>(
//add listener to object properties //add listener to object properties
obj.onPropertyChange(three.updateScope) { name -> obj.onPropertyChange(three.updateScope) { name ->
println("Property $name of mesh ${mesh.name} updated")
when { when {
name.startsWith(Solid.GEOMETRY_KEY) -> { name.startsWith(Solid.GEOMETRY_KEY) -> {
val oldGeometry = mesh.geometry as BufferGeometry val oldGeometry = mesh.geometry as BufferGeometry

View File

@ -197,7 +197,7 @@ public class ThreeCanvas(
} }
public fun render(vision: Solid) { public fun render(vision: Solid) {
three.logger.info { "Replacing root node in $this" } three.logger.info { "Replacing root node in three canvas" }
scene.findChild("@root".asName())?.let { scene.remove(it) } scene.findChild("@root".asName())?.let { scene.remove(it) }
val object3D = three.buildObject3D(vision) val object3D = three.buildObject3D(vision)

View File

@ -7,7 +7,6 @@ import hep.dataforge.values.int
import hep.dataforge.values.string import hep.dataforge.values.string
import hep.dataforge.vision.Colors import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.allStyles
import hep.dataforge.vision.solid.SolidMaterial import hep.dataforge.vision.solid.SolidMaterial
import info.laht.threekt.materials.LineBasicMaterial import info.laht.threekt.materials.LineBasicMaterial
import info.laht.threekt.materials.Material import info.laht.threekt.materials.Material
@ -83,26 +82,12 @@ public object ThreeMaterials {
} }
} }
internal fun cacheMeta(meta: Meta): Material = materialCache.getOrPut(meta) { internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) {
buildMaterial(meta).apply { buildMaterial(meta).apply {
cached = true cached = true
} }
} }
// internal fun getMaterial(vision: Vision, cache: Boolean): Material {
// val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node ?: return DEFAULT
// return if (cache) {
// materialCache.getOrPut(meta) {
// buildMaterial(meta).apply {
// cached = true
// }
// }
// } else {
// buildMaterial(meta)
// }
// }
} }
/** /**
@ -135,7 +120,6 @@ private var Material.cached: Boolean
public fun Mesh.updateMaterial(vision: Vision) { public fun Mesh.updateMaterial(vision: Vision) {
//val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node //val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node
val ownMaterialMeta = vision.getOwnProperty(SolidMaterial.MATERIAL_KEY) val ownMaterialMeta = vision.getOwnProperty(SolidMaterial.MATERIAL_KEY)
val stylesMaterialMeta = vision.allStyles[SolidMaterial.MATERIAL_KEY]
val parentMaterialMeta = vision.parent?.getProperty( val parentMaterialMeta = vision.parent?.getProperty(
SolidMaterial.MATERIAL_KEY, SolidMaterial.MATERIAL_KEY,
inherit = true, inherit = true,
@ -144,16 +128,22 @@ public fun Mesh.updateMaterial(vision: Vision) {
) )
material = when { material = when {
ownMaterialMeta == null && stylesMaterialMeta == null && parentMaterialMeta == null -> {
//use default is not material properties are defined
ThreeMaterials.DEFAULT
}
ownMaterialMeta == null && parentMaterialMeta == null -> { ownMaterialMeta == null && parentMaterialMeta == null -> {
//If material is style-based, use cached //If material is style-based, use cached
ThreeMaterials.cacheMeta(stylesMaterialMeta.node ?: Meta.EMPTY) vision.getProperty(
SolidMaterial.MATERIAL_KEY,
inherit = false,
includeStyles = true,
includeDefaults = false
).node?.let {
ThreeMaterials.cacheMaterial(it)
} ?: ThreeMaterials.DEFAULT
} }
else -> { else -> {
vision.getProperty(SolidMaterial.MATERIAL_KEY).node?.let { vision.getProperty(
SolidMaterial.MATERIAL_KEY,
inherit = true
).node?.let {
ThreeMaterials.buildMaterial(it) ThreeMaterials.buildMaterial(it)
} ?: ThreeMaterials.DEFAULT } ?: ThreeMaterials.DEFAULT
} }
@ -182,7 +172,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
includeStyles = true, includeStyles = true,
includeDefaults = false includeDefaults = false
).double ?: 1.0 ).double ?: 1.0
material.asDynamic().opacity = opacity material.opacity = opacity
material.transparent = opacity < 1.0 material.transparent = opacity < 1.0
material.needsUpdate = true material.needsUpdate = true
} }

View File

@ -1,11 +1,9 @@
package hep.dataforge.vision.solid.three package hep.dataforge.vision.solid.three
import hep.dataforge.meta.node
import hep.dataforge.names.cutFirst import hep.dataforge.names.cutFirst
import hep.dataforge.names.firstOrNull import hep.dataforge.names.firstOrNull
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.vision.solid.Solid import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.solid.SolidReferenceGroup import hep.dataforge.vision.solid.SolidReferenceGroup
import hep.dataforge.vision.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX import hep.dataforge.vision.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
@ -49,6 +47,7 @@ public object ThreeReferenceFactory : ThreeFactory<SolidReferenceGroup> {
//TODO apply child properties //TODO apply child properties
obj.onPropertyChange(three.updateScope) { name-> obj.onPropertyChange(three.updateScope) { name->
println("Property $name of reference ${object3D.name} updated")
if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) {
val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for reference child property: '$name'") val childName = name.firstOrNull()?.index?.toName() ?: error("Wrong syntax for reference child property: '$name'")
val propertyName = name.cutFirst() val propertyName = name.cutFirst()