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

View File

@ -3,6 +3,7 @@ package hep.dataforge.vision.gdml.demo
import hep.dataforge.context.Global
import hep.dataforge.vision.Application
import hep.dataforge.vision.gdml.toVision
import hep.dataforge.vision.solid.three.ThreePlugin
import hep.dataforge.vision.startApplication
import kotlinx.browser.document
import react.child
@ -14,12 +15,16 @@ private class GDMLDemoApp : Application {
override fun start(state: Map<String, Any>) {
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) {
child(GDMLApp) {
val vision = cubes().toVision()
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
attrs {
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
*/
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> {
return styles.asSequence().map {
getStyle(it)
}.map {
it[name]
public fun Vision.getStyleItems(name: Name): Sequence<MetaItem> = styles.asSequence().map {
getStyle(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
get() = Json(defaultJson) {
encodeDefaults = false
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) {
val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref)
val styleName = "material[${material.name}]"
val styleName = "materials.${material.name}"
obj.useStyle(styleName) {
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
obj.onPropertyChange(three.updateScope) { name ->
println("Property $name of mesh ${mesh.name} updated")
when {
name.startsWith(Solid.GEOMETRY_KEY) -> {
val oldGeometry = mesh.geometry as BufferGeometry

View File

@ -197,7 +197,7 @@ public class ThreeCanvas(
}
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) }
val object3D = three.buildObject3D(vision)

View File

@ -7,7 +7,6 @@ import hep.dataforge.values.int
import hep.dataforge.values.string
import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision
import hep.dataforge.vision.allStyles
import hep.dataforge.vision.solid.SolidMaterial
import info.laht.threekt.materials.LineBasicMaterial
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 {
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) {
//val meta = vision.getProperty(SolidMaterial.MATERIAL_KEY, inherit = true).node
val ownMaterialMeta = vision.getOwnProperty(SolidMaterial.MATERIAL_KEY)
val stylesMaterialMeta = vision.allStyles[SolidMaterial.MATERIAL_KEY]
val parentMaterialMeta = vision.parent?.getProperty(
SolidMaterial.MATERIAL_KEY,
inherit = true,
@ -144,16 +128,22 @@ public fun Mesh.updateMaterial(vision: Vision) {
)
material = when {
ownMaterialMeta == null && stylesMaterialMeta == null && parentMaterialMeta == null -> {
//use default is not material properties are defined
ThreeMaterials.DEFAULT
}
ownMaterialMeta == null && parentMaterialMeta == null -> {
//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 -> {
vision.getProperty(SolidMaterial.MATERIAL_KEY).node?.let {
vision.getProperty(
SolidMaterial.MATERIAL_KEY,
inherit = true
).node?.let {
ThreeMaterials.buildMaterial(it)
} ?: ThreeMaterials.DEFAULT
}
@ -182,7 +172,7 @@ public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) {
includeStyles = true,
includeDefaults = false
).double ?: 1.0
material.asDynamic().opacity = opacity
material.opacity = opacity
material.transparent = opacity < 1.0
material.needsUpdate = true
}

View File

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