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
### Changed
- Edges moved to solids module for easier construction
- Visions **must** be rooted in order to subscribe to updates.
- Visions use flows instead of direct subscriptions.
- 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.setChild
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.three.*
import three.core.Object3D
@ -60,7 +61,7 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision
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)
}
}

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_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 {
//must be lazy to avoid initialization bug
MetaDescriptor {
@ -114,4 +119,11 @@ public var Solid.opacity: Number?
get() = properties.getValue(MATERIAL_OPACITY_KEY, inherit = true)?.number
set(value) {
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.solid.Composite
import space.kscience.visionforge.solid.CompositeType
import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY
import three.objects.Mesh
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 fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh {
val first =
three.buildObject3D(vision.first, observe).takeIfMesh() ?: error("First part of composite is not a mesh")
val second =
three.buildObject3D(vision.second, observe).takeIfMesh() ?: error("Second part of composite is not a mesh")
val first = three.buildObject3D(vision.first, observe).takeIfMesh()
?: error("First part of composite is not a mesh")
val second = three.buildObject3D(vision.second, observe).takeIfMesh()
?: error("Second part of composite is not a mesh")
return when (vision.compositeType) {
CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second)
CompositeType.INTERSECT -> CSG.intersect(first, second)
@ -49,11 +50,12 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory
}.apply {
updatePosition(vision)
applyProperties(vision)
if (observe) {
vision.onPropertyChange { name ->
when {
//name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj)
name.startsWith(ThreeMeshFactory.EDGES_KEY) -> applyEdges(vision)
name.startsWith(EDGES_KEY) -> applyEdges(vision)
else -> updateProperty(vision, name)
}
}

View File

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