Fix edges for composite

This commit is contained in:
Alexander Nozik 2022-08-24 09:19:13 +03:00
parent 25fc143363
commit 56d577453a
No known key found for this signature in database
GPG Key ID: F7FCF2DD25C71357
5 changed files with 30 additions and 29 deletions

View File

@ -6,6 +6,7 @@
- MeshLine for thick lines - MeshLine for thick lines
### Changed ### Changed
- Edges moved to solids module for easier construction
- Visions **must** be rooted in order to subscribe to updates. - Visions **must** be rooted in order to subscribe to updates.
- Visions use flows instead of direct subscriptions. - Visions use flows instead of direct subscriptions.
- Radical change of inner workings of vision children and properties. - Radical change of inner workings of vision children and properties.

View File

@ -8,6 +8,7 @@ import space.kscience.dataforge.names.startsWith
import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.onPropertyChange
import space.kscience.visionforge.setChild import space.kscience.visionforge.setChild
import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.SolidGroup
import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY
import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.layer
import space.kscience.visionforge.solid.three.* import space.kscience.visionforge.solid.three.*
import three.core.Object3D import three.core.Object3D
@ -60,7 +61,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision
mesh.updateMatrix() mesh.updateMatrix()
} }
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) name.startsWith(EDGES_KEY) -> mesh.applyEdges(this@VariableBox)
else -> mesh.updateProperty(this@VariableBox, name) else -> mesh.updateProperty(this@VariableBox, name)
} }
} }

View File

@ -52,6 +52,11 @@ public class SolidMaterial : Scheme() {
public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY
public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY
public val EDGES_KEY: Name = "edges".asName()
public val ENABLED_KEY: Name = "enabled".asName()
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + MATERIAL_KEY
public override val descriptor: MetaDescriptor by lazy { public override val descriptor: MetaDescriptor by lazy {
//must be lazy to avoid initialization bug //must be lazy to avoid initialization bug
MetaDescriptor { MetaDescriptor {
@ -115,3 +120,10 @@ public var Solid.opacity: Number?
set(value) { set(value) {
properties.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) properties.setValue(MATERIAL_OPACITY_KEY, value?.asValue())
} }
@VisionBuilder
public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) {
properties[SolidMaterial.EDGES_ENABLED_KEY] = enabled
SolidMaterial.write(properties.getProperty(SolidMaterial.EDGES_MATERIAL_KEY)).apply(block)
}

View File

@ -5,6 +5,7 @@ import space.kscience.dataforge.names.startsWith
import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.onPropertyChange
import space.kscience.visionforge.solid.Composite import space.kscience.visionforge.solid.Composite
import space.kscience.visionforge.solid.CompositeType import space.kscience.visionforge.solid.CompositeType
import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY
import three.objects.Mesh import three.objects.Mesh
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -38,10 +39,10 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
override val type: KClass<in Composite> get() = Composite::class override val type: KClass<in Composite> get() = Composite::class
override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { override fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh {
val first = val first = three.buildObject3D(vision.first, observe).takeIfMesh()
three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh") ?: error("First part of composite is not a mesh")
val second = val second = three.buildObject3D(vision.second, observe).takeIfMesh()
three.buildObject3D(vision.second, observe).takeIfMesh() ?: error("Second part of composite is not a mesh") ?: error("Second part of composite is not a mesh")
return when (vision.compositeType) { return when (vision.compositeType) {
CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second) CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second)
CompositeType.INTERSECT -> CSG.intersect(first, second) CompositeType.INTERSECT -> CSG.intersect(first, second)
@ -49,11 +50,12 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
}.apply { }.apply {
updatePosition(vision) updatePosition(vision)
applyProperties(vision) applyProperties(vision)
if (observe) { if (observe) {
vision.onPropertyChange { name -> vision.onPropertyChange { name ->
when { when {
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(vision) name.startsWith(EDGES_KEY) -> applyEdges(vision)
else -> updateProperty(vision, name) else -> updateProperty(vision, name)
} }
} }

View File

@ -1,18 +1,13 @@
package space.kscience.visionforge.solid.three package space.kscience.visionforge.solid.three
import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.boolean
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.plus
import space.kscience.dataforge.names.startsWith import space.kscience.dataforge.names.startsWith
import space.kscience.visionforge.VisionBuilder
import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.onPropertyChange
import space.kscience.visionforge.set
import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_ENABLED_KEY
import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY
import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_MATERIAL_KEY
import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.layer
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_ENABLED_KEY
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_MATERIAL_KEY
import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME
import three.core.BufferGeometry import three.core.BufferGeometry
import three.geometries.EdgesGeometry import three.geometries.EdgesGeometry
@ -43,7 +38,7 @@ public abstract class ThreeMeshFactory<in T : Solid>(
applyProperties(vision) applyProperties(vision)
} }
if(observe) { if (observe) {
//add listener to object properties //add listener to object properties
vision.onPropertyChange(three.context) { name -> vision.onPropertyChange(three.context) { name ->
when { when {
@ -66,24 +61,15 @@ public abstract class ThreeMeshFactory<in T : Solid>(
} }
public companion object { public companion object {
public val EDGES_KEY: Name = "edges".asName()
internal const val EDGES_OBJECT_NAME: String = "@edges" internal const val EDGES_OBJECT_NAME: String = "@edges"
//public val WIREFRAME_KEY: Name = "wireframe".asName() //public val WIREFRAME_KEY: Name = "wireframe".asName()
public val ENABLED_KEY: Name = "enabled".asName()
public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY
public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + SolidMaterial.MATERIAL_KEY
//public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY //public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY
//public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY //public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
} }
} }
@VisionBuilder
public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) {
properties[EDGES_ENABLED_KEY] = enabled
SolidMaterial.write(properties.getProperty(EDGES_MATERIAL_KEY)).apply(block)
}
internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { internal fun Mesh.applyProperties(vision: Solid): Mesh = apply {
setMaterial(vision) setMaterial(vision)
applyEdges(vision) applyEdges(vision)
@ -97,13 +83,12 @@ internal fun Mesh.applyProperties(vision: Solid): Mesh = apply {
public fun Mesh.applyEdges(vision: Solid) { public fun Mesh.applyEdges(vision: Solid) {
val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments
//inherited edges definition, enabled by default //inherited edges definition, enabled by default
if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = false)?.boolean != false) {
val bufferGeometry = geometry as? BufferGeometry ?: return
val material = ThreeMaterials.getLineMaterial(vision.properties.getProperty(EDGES_MATERIAL_KEY), true) val material = ThreeMaterials.getLineMaterial(vision.properties.getProperty(EDGES_MATERIAL_KEY), true)
if (edges == null) { if (edges == null) {
add( add(
LineSegments( LineSegments(
EdgesGeometry(bufferGeometry), EdgesGeometry(geometry),
material material
).apply { ).apply {
name = EDGES_OBJECT_NAME name = EDGES_OBJECT_NAME