Refactored SolidMaterial to use color wrapper
This commit is contained in:
parent
f4970955cb
commit
1ccd45d6c5
@ -58,7 +58,7 @@ class Model {
|
||||
}
|
||||
|
||||
private fun highlight(pixel: String) {
|
||||
map[pixel]?.color("blue")
|
||||
map[pixel]?.color?.invoke("blue")
|
||||
}
|
||||
|
||||
fun reset() {
|
||||
|
@ -4,6 +4,7 @@ package ru.mipt.npm.sat
|
||||
import hep.dataforge.names.toName
|
||||
import hep.dataforge.vision.solid.Solid
|
||||
import hep.dataforge.vision.solid.color
|
||||
import hep.dataforge.vision.solid.invoke
|
||||
import hep.dataforge.vision.three.server.*
|
||||
import kotlinx.coroutines.GlobalScope
|
||||
import kotlinx.coroutines.delay
|
||||
@ -40,7 +41,7 @@ fun main() {
|
||||
val target = "layer[$randomLayer].segment[$randomI,$randomJ]".toName()
|
||||
(sat[target] as? Solid)?.color("red")
|
||||
delay(300)
|
||||
(sat[target] as? Solid)?.color = "green"
|
||||
(sat[target] as? Solid)?.color("green")
|
||||
delay(10)
|
||||
}
|
||||
}
|
||||
|
@ -134,31 +134,39 @@ fun Page<Solid>.showcase() {
|
||||
|
||||
fun Page<Solid>.showcaseCSG() {
|
||||
demo("CSG.simple", "CSG operations") {
|
||||
composite(CompositeType.UNION) {
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50)
|
||||
material {
|
||||
color(Colors.lightgreen)
|
||||
opacity = 0.3f
|
||||
}
|
||||
}
|
||||
composite(CompositeType.INTERSECT) {
|
||||
y = 300
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50)
|
||||
sphere(50){
|
||||
detail = 32
|
||||
}
|
||||
material {
|
||||
color(Colors.red)
|
||||
wireframe = false
|
||||
}
|
||||
}
|
||||
composite(CompositeType.UNION) {
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50){
|
||||
detail = 32
|
||||
}
|
||||
color(Colors.lightgreen)
|
||||
opacity = 0.3
|
||||
}
|
||||
composite(CompositeType.SUBTRACT) {
|
||||
y = -300
|
||||
box(100, 100, 100) {
|
||||
z = 50
|
||||
}
|
||||
sphere(50)
|
||||
color(Colors.blue)
|
||||
sphere(50){
|
||||
detail = 32
|
||||
}
|
||||
color(Colors.teal)
|
||||
opacity = 0.7
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,12 +1,10 @@
|
||||
import hep.dataforge.Application
|
||||
import hep.dataforge.context.Global
|
||||
import hep.dataforge.startApplication
|
||||
import hep.dataforge.vision.bootstrap.visionPropertyEditor
|
||||
import hep.dataforge.vision.react.ThreeCanvasComponent
|
||||
import hep.dataforge.vision.react.objectTree
|
||||
import hep.dataforge.vision.solid.*
|
||||
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
|
||||
import hep.dataforge.vision.solid.three.ThreePlugin
|
||||
import kotlinx.browser.document
|
||||
import org.w3c.dom.HTMLElement
|
||||
import react.RBuilder
|
||||
@ -14,7 +12,7 @@ import react.child
|
||||
import react.dom.div
|
||||
import react.dom.render
|
||||
|
||||
public fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
||||
fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
|
||||
child(ThreeCanvasComponent) {
|
||||
attrs {
|
||||
this.obj = object3D
|
||||
@ -25,8 +23,6 @@ public fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() ->
|
||||
|
||||
private class PlayGroundApp : Application {
|
||||
|
||||
private val three = Global.plugins.fetch(ThreePlugin)
|
||||
|
||||
override fun start(state: Map<String, Any>) {
|
||||
|
||||
val element =
|
||||
|
@ -8,6 +8,10 @@ import hep.dataforge.names.Name
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.asValue
|
||||
|
||||
@DslMarker
|
||||
public annotation class VisionBuilder
|
||||
|
||||
|
||||
public fun Sequence<MetaItem<*>?>.merge(): MetaItem<*>? {
|
||||
return when (val first = firstOrNull { it != null }) {
|
||||
null -> null
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
|
||||
@ -61,6 +62,7 @@ public class Box(
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.box(
|
||||
xSize: Number,
|
||||
ySize: Number,
|
||||
|
@ -3,10 +3,7 @@ package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.meta.update
|
||||
import hep.dataforge.names.NameToken
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.VisionGroup
|
||||
import hep.dataforge.vision.set
|
||||
import hep.dataforge.vision.*
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
|
||||
@ -33,6 +30,7 @@ public class Composite(
|
||||
get() = mapOf(NameToken("first") to first, NameToken("second") to second)
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.composite(
|
||||
type: CompositeType,
|
||||
name: String = "",
|
||||
@ -58,11 +56,14 @@ public inline fun VisionContainerBuilder<Solid>.composite(
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.union(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||
composite(CompositeType.UNION, name, builder = builder)
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.subtract(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||
composite(CompositeType.SUBTRACT, name, builder = builder)
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.intersect(name: String = "", builder: SolidGroup.() -> Unit): Composite =
|
||||
composite(CompositeType.INTERSECT, name, builder = builder)
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
@ -102,5 +103,6 @@ public class Extruded(
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun VisionContainerBuilder<Solid>.extrude(name: String = "", action: Extruded.() -> Unit = {}): Extruded =
|
||||
Extruded().apply(action).also { set(name, it) }
|
@ -4,6 +4,7 @@ import hep.dataforge.meta.number
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.props
|
||||
import hep.dataforge.vision.set
|
||||
@ -23,6 +24,7 @@ public class PolyLine(public var points: List<Point3D>) : SolidBase(), Solid {
|
||||
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun VisionContainerBuilder<Solid>.polyline(
|
||||
vararg points: Point3D,
|
||||
name: String = "",
|
||||
|
@ -9,6 +9,7 @@ import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.vision.Vision
|
||||
import hep.dataforge.vision.Vision.Companion.VISIBLE_KEY
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.enum
|
||||
import hep.dataforge.vision.layout.Output
|
||||
import hep.dataforge.vision.setProperty
|
||||
@ -104,6 +105,7 @@ public var Solid.layer: Int
|
||||
config[LAYER_KEY] = value.asValue()
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun Output<Solid>.solidGroup(builder: SolidGroup.() -> Unit): Unit = render(SolidGroup().apply(builder))
|
||||
|
||||
// Common properties
|
||||
|
@ -86,6 +86,7 @@ public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
|
||||
public tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? =
|
||||
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
|
||||
|
||||
@VisionBuilder
|
||||
public fun VisionContainerBuilder<Vision>.group(name: Name = Name.EMPTY, action: SolidGroup.() -> Unit = {}): SolidGroup =
|
||||
SolidGroup().apply(action).also { set(name, it) }
|
||||
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
@ -13,6 +14,7 @@ public class SolidLabel(
|
||||
public var fontFamily: String,
|
||||
) : SolidBase(), Solid
|
||||
|
||||
@VisionBuilder
|
||||
public fun VisionContainerBuilder<Solid>.label(
|
||||
text: String,
|
||||
fontSize: Number = 20,
|
||||
|
@ -6,26 +6,66 @@ import hep.dataforge.meta.descriptors.attributes
|
||||
import hep.dataforge.names.Name
|
||||
import hep.dataforge.names.asName
|
||||
import hep.dataforge.names.plus
|
||||
import hep.dataforge.values.Value
|
||||
import hep.dataforge.values.ValueType
|
||||
import hep.dataforge.values.asValue
|
||||
import hep.dataforge.values.string
|
||||
import hep.dataforge.vision.Colors
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.setProperty
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
|
||||
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
|
||||
import hep.dataforge.vision.widgetType
|
||||
|
||||
@VisionBuilder
|
||||
public class ColorAccessor(private val parent: MutableItemProvider, private val colorKey: Name) {
|
||||
public var value: Value?
|
||||
get() = parent.getItem(colorKey).value
|
||||
set(value) {
|
||||
parent[colorKey] = value
|
||||
}
|
||||
}
|
||||
|
||||
public var ColorAccessor?.string: String?
|
||||
get() = this?.value?.string
|
||||
set(value) {
|
||||
this?.value = value?.asValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string
|
||||
*/
|
||||
public operator fun ColorAccessor?.invoke(webColor: String) {
|
||||
this?.value = webColor.asValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color as RGB integer
|
||||
*/
|
||||
public operator fun ColorAccessor?.invoke(rgb: Int) {
|
||||
this?.value = rgb.asValue()
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color as RGB
|
||||
*/
|
||||
public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) {
|
||||
this?.value = Colors.rgbToString(r, g, b).asValue()
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public class SolidMaterial : Scheme() {
|
||||
|
||||
/**
|
||||
* Primary web-color for the material
|
||||
*/
|
||||
public var color: String? by string(key = COLOR_KEY)
|
||||
public var color: ColorAccessor = ColorAccessor(config, COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Specular color for phong material
|
||||
*/
|
||||
public var specularColor: String? by string(key = SPECULAR_COLOR_KEY)
|
||||
public var specularColor: ColorAccessor = ColorAccessor(config, SPECULAR_COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Opacity
|
||||
@ -75,37 +115,13 @@ public class SolidMaterial : Scheme() {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Set color as web-color
|
||||
*/
|
||||
public fun Solid.color(webColor: String) {
|
||||
setProperty(MATERIAL_COLOR_KEY, webColor.asValue())
|
||||
}
|
||||
public val Solid.color: ColorAccessor get() = ColorAccessor(config, MATERIAL_COLOR_KEY)
|
||||
|
||||
/**
|
||||
* Set color as integer
|
||||
*/
|
||||
public fun Solid.color(rgb: Int) {
|
||||
setProperty(MATERIAL_COLOR_KEY, rgb.asValue())
|
||||
}
|
||||
|
||||
public fun Solid.color(r: UByte, g: UByte, b: UByte): Unit = setProperty(
|
||||
MATERIAL_COLOR_KEY,
|
||||
Colors.rgbToString(r, g, b).asValue()
|
||||
)
|
||||
|
||||
/**
|
||||
* Web colors representation of the color in `#rrggbb` format or HTML name
|
||||
*/
|
||||
public var Solid.color: String?
|
||||
get() = getProperty(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
|
||||
set(value) {
|
||||
setProperty(MATERIAL_COLOR_KEY, value?.asValue())
|
||||
}
|
||||
|
||||
public val Solid.material: SolidMaterial?
|
||||
public var Solid.material: SolidMaterial?
|
||||
get() = getProperty(MATERIAL_KEY).node?.let { SolidMaterial.read(it) }
|
||||
set(value) = setProperty(MATERIAL_KEY, value?.config)
|
||||
|
||||
@VisionBuilder
|
||||
public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
||||
val node = config[MATERIAL_KEY].node
|
||||
if (node != null) {
|
||||
@ -115,8 +131,8 @@ public fun Solid.material(builder: SolidMaterial.() -> Unit) {
|
||||
}
|
||||
}
|
||||
|
||||
public var Solid.opacity: Double?
|
||||
get() = getProperty(MATERIAL_OPACITY_KEY).double
|
||||
public var Solid.opacity: Number?
|
||||
get() = getProperty(MATERIAL_OPACITY_KEY).number
|
||||
set(value) {
|
||||
setProperty(MATERIAL_OPACITY_KEY, value?.asValue())
|
||||
}
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
@ -50,6 +51,7 @@ public class Sphere(
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.sphere(
|
||||
radius: Number,
|
||||
phi: Number = 2 * PI,
|
||||
|
@ -1,5 +1,6 @@
|
||||
package hep.dataforge.vision.solid
|
||||
|
||||
import hep.dataforge.vision.VisionBuilder
|
||||
import hep.dataforge.vision.VisionContainerBuilder
|
||||
import hep.dataforge.vision.set
|
||||
import kotlinx.serialization.SerialName
|
||||
@ -118,6 +119,7 @@ public class Tube(
|
||||
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public inline fun VisionContainerBuilder<Solid>.tube(
|
||||
r: Number,
|
||||
height: Number,
|
||||
|
@ -55,7 +55,7 @@ class PropertyTest {
|
||||
}
|
||||
}
|
||||
}
|
||||
assertEquals("#555555", box?.color)
|
||||
assertEquals("#555555", box?.color.string)
|
||||
}
|
||||
|
||||
@Test
|
||||
@ -76,6 +76,6 @@ class PropertyTest {
|
||||
box = ref("box".asName())
|
||||
}
|
||||
}
|
||||
assertEquals("#555555", box?.color)
|
||||
assertEquals("#555555", box?.color.string)
|
||||
}
|
||||
}
|
@ -28,8 +28,8 @@ class VisionUpdateTest {
|
||||
}
|
||||
targetVision.update(dif)
|
||||
assertTrue { targetVision["top"] is SolidGroup }
|
||||
assertEquals("red", (targetVision["origin"] as Solid).color) // Should work
|
||||
assertEquals("#00007b", (targetVision["top"] as SolidGroup).color) // new item always takes precedence
|
||||
assertEquals("red", (targetVision["origin"] as Solid).color.string) // Should work
|
||||
assertEquals("#00007b", (targetVision["top"] as SolidGroup).color.string) // new item always takes precedence
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -9,5 +9,5 @@ kscience {
|
||||
dependencies {
|
||||
api(project(":visionforge-solid"))
|
||||
implementation(npm("three", "0.122.0"))
|
||||
implementation(npm("three-csg-ts", "1.0.6"))
|
||||
implementation(npm("three-csg-ts", "2.0.0"))
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ package hep.dataforge.vision.solid.three
|
||||
import hep.dataforge.meta.node
|
||||
import hep.dataforge.vision.solid.PolyLine
|
||||
import hep.dataforge.vision.solid.color
|
||||
import hep.dataforge.vision.solid.string
|
||||
import hep.dataforge.vision.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR
|
||||
import info.laht.threekt.core.Geometry
|
||||
import info.laht.threekt.core.Object3D
|
||||
@ -21,7 +22,7 @@ public object ThreeLineFactory : ThreeFactory<PolyLine> {
|
||||
val material = ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.EDGES_MATERIAL_KEY).node, true)
|
||||
|
||||
material.linewidth = obj.thickness.toDouble()
|
||||
material.color = obj.color?.let { Color(it) } ?: DEFAULT_LINE_COLOR
|
||||
material.color = obj.color.string?.let { Color(it) } ?: DEFAULT_LINE_COLOR
|
||||
|
||||
return LineSegments(geometry, material).apply {
|
||||
updatePosition(obj)
|
||||
|
Loading…
Reference in New Issue
Block a user