Final global refactoring

This commit is contained in:
Alexander Nozik 2020-08-08 09:40:07 +03:00
parent 9805c249ad
commit 423b36b3de
262 changed files with 943 additions and 745 deletions

View File

@ -23,7 +23,7 @@ kotlin {
sourceSets {
commonMain {
dependencies {
implementation(project(":visionforge-spatial"))
implementation(project(":visionforge-solid"))
implementation(project(":visionforge-gdml"))
}
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import scientifik.gdml.*

View File

@ -1,11 +1,11 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import hep.dataforge.meta.setItem
import hep.dataforge.meta.string
import hep.dataforge.names.toName
import hep.dataforge.values.asValue
import hep.dataforge.vision.spatial.Material3D
import hep.dataforge.vision.spatial.gdml.demo.cubes
import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.solid.gdml.demo.cubes
import kotlin.test.Test
import kotlin.test.assertEquals
@ -14,7 +14,7 @@ class GDMLVisualTest {
fun testPrototypeProperty() {
val gdml = cubes()
val visual = gdml.toVision()
visual["composite000.segment0".toName()]?.setItem(Material3D.MATERIAL_COLOR_KEY, "red".asValue())
assertEquals("red", visual["composite000.segment0".toName()]?.getItem(Material3D.MATERIAL_COLOR_KEY).string)
visual["composite000.segment0".toName()]?.setItem(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
assertEquals("red", visual["composite000.segment0".toName()]?.getItem(SolidMaterial.MATERIAL_COLOR_KEY).string)
}
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import hep.dataforge.context.Context
import hep.dataforge.names.Name
@ -10,14 +10,14 @@ import hep.dataforge.vision.react.component
import hep.dataforge.vision.react.configEditor
import hep.dataforge.vision.react.flexColumn
import hep.dataforge.vision.react.state
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.spatial.gdml.toVision
import hep.dataforge.vision.spatial.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreeCanvasComponent
import hep.dataforge.vision.spatial.three.canvasControls
import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.solid.gdml.toVision
import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.solid.three.ThreeCanvasComponent
import hep.dataforge.vision.solid.three.canvasControls
import kotlinx.css.FlexBasis
import kotlinx.css.Overflow
import kotlinx.css.flex
@ -62,7 +62,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
val gdml = GDML.parse(data)
gdml.toVision(gdmlConfiguration)
}
name.endsWith(".json") -> VisionGroup3D.parseJson(data)
name.endsWith(".json") -> SolidGroup.parseJson(data)
else -> {
window.alert("File extension is not recognized: $name")
error("File extension is not recognized: $name")
@ -107,7 +107,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
gridColumn(6, maxSize= GridMaxSize.XL, classes = "order-1 order-xl-2") {
//canvas
(visual as? Vision3D)?.let { visual3D ->
(visual as? Solid)?.let { visual3D ->
child(ThreeCanvasComponent::class) {
attrs {
this.context = props.context
@ -143,7 +143,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
else -> (visual as? VisionGroup)?.get(selected)
}
if (selectedObject != null) {
configEditor(selectedObject, default = selectedObject.properties(), key = selected)
configEditor(selectedObject, default = selectedObject.getAllProperties(), key = selected)
}
}
}

View File

@ -1,12 +1,12 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import hep.dataforge.context.Global
import hep.dataforge.js.Application
import hep.dataforge.js.startApplication
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vision.spatial.gdml.GDMLTransformer
import hep.dataforge.vision.spatial.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.toVision
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vision.solid.gdml.GDMLTransformer
import hep.dataforge.vision.solid.gdml.LUnit
import hep.dataforge.vision.solid.gdml.toVision
import kotlinx.css.*
import react.child
import react.dom.render

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import drop.FileDrop
import kotlinx.css.*

View File

@ -1,13 +1,13 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import hep.dataforge.context.Global
import hep.dataforge.vision.editor.VisualObjectEditorFragment
import hep.dataforge.vision.editor.VisualObjectTreeFragment
import hep.dataforge.vision.spatial.Material3D
import hep.dataforge.vision.spatial.SpatialVisionManager
import hep.dataforge.vision.spatial.fx.FX3DPlugin
import hep.dataforge.vision.spatial.fx.FXCanvas3D
import hep.dataforge.vision.spatial.gdml.toVision
import hep.dataforge.vision.solid.SolidManager
import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.solid.fx.FX3DPlugin
import hep.dataforge.vision.solid.fx.FXCanvas3D
import hep.dataforge.vision.solid.gdml.toVision
import javafx.geometry.Orientation
import javafx.scene.Parent
import javafx.stage.FileChooser
@ -24,9 +24,9 @@ class GDMLView : View() {
}
private val propertyEditor = VisualObjectEditorFragment {
it.properties()
it.getAllProperties()
}.apply {
descriptorProperty.set(Material3D.descriptor)
descriptorProperty.set(SolidMaterial.descriptor)
itemProperty.bind(treeFragment.selectedProperty)
}
@ -39,7 +39,7 @@ class GDMLView : View() {
runAsync {
val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull()
?: return@runAsync null
SpatialVisionManager.readFile(file)
SolidManager.readFile(file)
} ui {
if (it != null) {
canvas.render(it)

View File

@ -1,51 +1,51 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import hep.dataforge.meta.setItem
import hep.dataforge.values.asValue
import hep.dataforge.vision.spatial.Material3D
import hep.dataforge.vision.spatial.SpatialVisionManager
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.spatial.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.readFile
import hep.dataforge.vision.spatial.gdml.toVision
import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.solid.SolidManager
import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.solid.gdml.LUnit
import hep.dataforge.vision.solid.gdml.readFile
import hep.dataforge.vision.solid.gdml.toVision
import scientifik.gdml.GDML
import java.io.File
import java.util.zip.GZIPInputStream
import java.util.zip.ZipInputStream
fun SpatialVisionManager.Companion.readFile(file: File): VisionGroup3D = when {
fun SolidManager.Companion.readFile(file: File): SolidGroup = when {
file.extension == "gdml" || file.extension == "xml" -> {
GDML.readFile(file.toPath()).toVision {
lUnit = LUnit.CM
solidConfiguration = { parent, solid ->
if (solid.name == "cave") {
setItem(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue())
setItem(SolidMaterial.MATERIAL_WIREFRAME_KEY, true.asValue())
}
if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") {
Material3D.MATERIAL_OPACITY_KEY put 0.3
SolidMaterial.MATERIAL_OPACITY_KEY put 0.3
}
}
}
}
}
file.extension == "json" -> VisionGroup3D.parseJson(file.readText())
file.extension == "json" -> SolidGroup.parseJson(file.readText())
file.name.endsWith("json.zip") -> {
file.inputStream().use {
val unzip = ZipInputStream(it, Charsets.UTF_8)
val text = unzip.readBytes().decodeToString()
VisionGroup3D.parseJson(text)
SolidGroup.parseJson(text)
}
}
file.name.endsWith("json.gz") -> {
file.inputStream().use {
val unzip = GZIPInputStream(it)
val text = unzip.readBytes().decodeToString()
VisionGroup3D.parseJson(text)
SolidGroup.parseJson(text)
}
}
else -> error("Unknown extension ${file.extension}")
}
fun SpatialVisionManager.Companion.readFile(fileName: String): VisionGroup3D = readFile(File(fileName))
fun SolidManager.Companion.readFile(fileName: String): SolidGroup = readFile(File(fileName))

View File

@ -1,9 +1,9 @@
package hep.dataforge.vision.spatial.gdml.demo
package hep.dataforge.vision.solid.gdml.demo
import hep.dataforge.vision.spatial.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.readFile
import hep.dataforge.vision.spatial.gdml.toVision
import hep.dataforge.vision.spatial.stringify
import hep.dataforge.vision.solid.gdml.LUnit
import hep.dataforge.vision.solid.gdml.readFile
import hep.dataforge.vision.solid.gdml.toVision
import hep.dataforge.vision.solid.stringify
import scientifik.gdml.GDML
import java.io.File
import java.nio.file.Paths

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.names.asName
import org.junit.jupiter.api.Test
@ -9,7 +9,7 @@ class FileSerializationTest {
@Ignore
fun testFileRead(){
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
val visual = VisionGroup3D.parseJson(text)
val visual = SolidGroup.parseJson(text)
visual["composite_001".asName()]
}
}

View File

@ -43,7 +43,7 @@ kotlin {
sourceSets {
commonMain {
dependencies {
implementation(project(":visionforge-spatial"))
implementation(project(":visionforge-solid"))
}
}
jvmMain {

View File

@ -1,8 +1,8 @@
@file:UseSerializers(Point3DSerializer::class)
package ru.mipt.npm.muon.monitor
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.spatial.Point3DSerializer
import hep.dataforge.vision.solid.Point3D
import hep.dataforge.vision.solid.Point3DSerializer
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers

View File

@ -1,17 +1,17 @@
package ru.mipt.npm.muon.monitor
import hep.dataforge.vision.removeAll
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.solid.*
import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z
import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z
import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z
import kotlin.math.PI
class Model {
private val map = HashMap<String, VisionGroup3D>()
private val map = HashMap<String, SolidGroup>()
private val events = HashSet<Event>()
private fun VisionGroup3D.pixel(pixel: SC1) {
private fun SolidGroup.pixel(pixel: SC1) {
val group = group(pixel.name) {
position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z)
box(pixel.xSize, pixel.ySize, pixel.zSize)
@ -23,7 +23,7 @@ class Model {
map[pixel.name] = group
}
private fun VisionGroup3D.detector(detector: SC16) {
private fun SolidGroup.detector(detector: SC16) {
group(detector.name) {
detector.pixels.forEach {
pixel(it)
@ -31,9 +31,9 @@ class Model {
}
}
var tracks: VisionGroup3D
var tracks: SolidGroup
val root: VisionGroup3D = VisionGroup3D().apply {
val root: SolidGroup = SolidGroup().apply {
rotationX = PI / 2
group("bottom") {
Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach {
@ -63,7 +63,7 @@ class Model {
fun reset() {
map.values.forEach {
it.config
it.setItem(Material3D.MATERIAL_COLOR_KEY, null)
it.setItem(SolidMaterial.MATERIAL_COLOR_KEY, null)
}
tracks.removeAll()
}

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.spatial.plus
import hep.dataforge.vision.solid.Point3D
import hep.dataforge.vision.solid.plus
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE

View File

@ -10,11 +10,11 @@ import hep.dataforge.vision.bootstrap.objectTree
import hep.dataforge.vision.react.component
import hep.dataforge.vision.react.configEditor
import hep.dataforge.vision.react.state
import hep.dataforge.vision.spatial.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreeCanvasComponent
import hep.dataforge.vision.spatial.three.canvasControls
import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.solid.three.ThreeCanvasComponent
import hep.dataforge.vision.solid.three.canvasControls
import io.ktor.client.HttpClient
import io.ktor.client.request.get
import kotlinx.coroutines.GlobalScope
@ -155,7 +155,7 @@ val MMApp = component<MMAppProps> { props ->
else -> visual[selected]
}
if (selectedObject != null) {
configEditor(selectedObject, default = selectedObject.properties(), key = selected)
configEditor(selectedObject, default = selectedObject.getAllProperties(), key = selected)
}
}
}

View File

@ -3,7 +3,7 @@ package ru.mipt.npm.muon.monitor
import hep.dataforge.context.Global
import hep.dataforge.js.Application
import hep.dataforge.js.startApplication
import hep.dataforge.vision.spatial.SpatialVisionManager
import hep.dataforge.vision.solid.SolidManager
import io.ktor.client.HttpClient
import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer
@ -19,7 +19,7 @@ private class MMDemoApp : Application {
private val connection = HttpClient {
install(JsonFeature) {
serializer = KotlinxSerializer(Json(context = SpatialVisionManager.serialModule))
serializer = KotlinxSerializer(Json(context = SolidManager.serialModule))
}
}

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor.server
import hep.dataforge.vision.spatial.SpatialVisionManager
import hep.dataforge.vision.solid.SolidManager
import io.ktor.application.Application
import io.ktor.application.call
import io.ktor.application.install
@ -36,7 +36,7 @@ fun Application.module() {
install(DefaultHeaders)
install(CallLogging)
install(ContentNegotiation) {
json(module = SpatialVisionManager.serialModule)
json(module = SolidManager.serialModule)
}
install(Routing) {
get("/event") {

View File

@ -1,6 +1,6 @@
package ru.mipt.npm.muon.monitor.sim
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.solid.Point3D
import org.apache.commons.math3.geometry.euclidean.threed.Line
import org.apache.commons.math3.geometry.euclidean.threed.Plane
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D

View File

@ -19,7 +19,7 @@ kotlin {
sourceSets {
commonMain {
dependencies {
api(project(":visionforge-spatial"))
api(project(":visionforge-solid"))
api(project(":visionforge-gdml"))
}
}
@ -27,5 +27,5 @@ kotlin {
}
application {
mainClassName = "hep.dataforge.vis.spatial.demo.FXDemoAppKt"
mainClassName = "hep.dataforge.vis.solid.demo.FXDemoAppKt"
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.meta.Meta
import hep.dataforge.meta.invoke
@ -6,8 +6,8 @@ import hep.dataforge.names.toName
import hep.dataforge.output.OutputManager
import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import kotlinx.coroutines.*
import kotlin.math.PI
import kotlin.math.cos
@ -15,7 +15,7 @@ import kotlin.math.sin
import kotlin.random.Random
fun OutputManager.demo(name: String, title: String = name, block: VisionGroup3D.() -> Unit) {
fun OutputManager.demo(name: String, title: String = name, block: SolidGroup.() -> Unit) {
val meta = Meta {
"title" put title
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.js.Application
import hep.dataforge.js.startApplication

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.context.Global
import hep.dataforge.meta.Meta
@ -8,9 +8,9 @@ import hep.dataforge.names.Name
import hep.dataforge.output.OutputManager
import hep.dataforge.output.Renderer
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreePlugin
import hep.dataforge.vision.spatial.three.output
import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.solid.three.ThreePlugin
import hep.dataforge.vision.solid.three.output
import kotlinx.html.dom.append
import kotlinx.html.dom.create
import kotlinx.html.h2

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.meta.int
import hep.dataforge.meta.number
@ -10,11 +10,11 @@ import hep.dataforge.names.startsWith
import hep.dataforge.values.asValue
import hep.dataforge.vision.getProperty
import hep.dataforge.vision.set
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.spatial.Vision3D.Companion.GEOMETRY_KEY
import hep.dataforge.vision.spatial.demo.VariableBoxThreeFactory.Z_SIZE_KEY
import hep.dataforge.vision.spatial.three.*
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
import hep.dataforge.vision.solid.demo.VariableBoxThreeFactory.Z_SIZE_KEY
import hep.dataforge.vision.solid.three.*
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.BoxBufferGeometry
@ -23,13 +23,13 @@ import kotlinx.serialization.UseSerializers
import kotlin.math.max
import kotlin.reflect.KClass
internal var Vision3D.variableZSize: Number
internal var Solid.variableZSize: Number
get() = getProperty(Z_SIZE_KEY, false).number ?: 0f
set(value) {
setItem(Z_SIZE_KEY, value.asValue())
}
internal var Vision3D.value: Int
internal var Solid.value: Int
get() = getProperty("value", false).int ?: 0
set(value) {
setItem("value", value.asValue())
@ -43,26 +43,26 @@ internal var Vision3D.value: Int
color(r.toUByte(), g.toUByte(), b.toUByte())
}
fun VisionGroup3D.varBox(
fun SolidGroup.varBox(
xSize: Number,
ySize: Number,
zSize: Number,
name: String = "",
action: Vision3D.() -> Unit = {}
action: Solid.() -> Unit = {}
) = CustomThreeVision(VariableBoxThreeFactory).apply {
scaleX = xSize
scaleY = ySize
scaleZ = zSize
}.apply(action).also { set(name, it) }
private object VariableBoxThreeFactory : ThreeFactory<Vision3D> {
private object VariableBoxThreeFactory : ThreeFactory<Solid> {
val X_SIZE_KEY = GEOMETRY_KEY + "xSize"
val Y_SIZE_KEY = GEOMETRY_KEY + "ySize"
val Z_SIZE_KEY = GEOMETRY_KEY + "zSize"
override val type: KClass<in Vision3D> get() = Vision3D::class
override val type: KClass<in Solid> get() = Solid::class
override fun invoke(obj: Vision3D): Object3D {
override fun invoke(obj: Solid): Object3D {
val xSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0
val ySize = obj.getProperty(Y_SIZE_KEY, false).number?.toDouble() ?: 1.0
val zSize = obj.getProperty(Z_SIZE_KEY, false).number?.toDouble() ?: 1.0
@ -87,7 +87,7 @@ private object VariableBoxThreeFactory : ThreeFactory<Vision3D> {
mesh.scale.set(xSize, ySize, zSize)
//add listener to object properties
obj.onPropertyChange(this) { name, _, _ ->
obj.onPropertyChange(this) { name ->
when {
// name.startsWith(GEOMETRY_KEY) -> {
// val newXSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.vision.spatial.gdml.gdml
import hep.dataforge.vision.solid.gdml.gdml
import javafx.stage.Stage
import tornadofx.*
import java.nio.file.Paths

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.demo
package hep.dataforge.vision.solid.demo
import hep.dataforge.context.Global
import hep.dataforge.meta.Meta
@ -6,8 +6,8 @@ import hep.dataforge.names.Name
import hep.dataforge.output.OutputManager
import hep.dataforge.output.Renderer
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.fx.FX3DPlugin
import hep.dataforge.vision.spatial.fx.FXCanvas3D
import hep.dataforge.vision.solid.fx.FX3DPlugin
import hep.dataforge.vision.solid.fx.FXCanvas3D
import javafx.collections.FXCollections
import javafx.scene.Parent
import javafx.scene.control.Tab

View File

@ -19,7 +19,7 @@ kotlin {
sourceSets {
commonMain {
dependencies {
api(project(":visionforge-spatial"))
api(project(":visionforge-solid"))
api(project(":visionforge-gdml"))
api(project(":ui:bootstrap"))
}

View File

@ -4,12 +4,12 @@ import hep.dataforge.js.startApplication
import hep.dataforge.names.Name
import hep.dataforge.vision.bootstrap.objectTree
import hep.dataforge.vision.bootstrap.visualPropertyEditor
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.spatial.box
import hep.dataforge.vision.spatial.group
import hep.dataforge.vision.spatial.three.ThreePlugin
import hep.dataforge.vision.spatial.three.threeCanvas
import hep.dataforge.vision.solid.Point3D
import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.solid.box
import hep.dataforge.vision.solid.group
import hep.dataforge.vision.solid.three.ThreePlugin
import hep.dataforge.vision.solid.three.threeCanvas
import org.w3c.dom.HTMLElement
import react.dom.div
import react.dom.render
@ -24,7 +24,7 @@ private class PlayGroundApp : Application {
val element =
document.getElementById("app") as? HTMLElement ?: error("Element with id 'canvas' not found on page")
val obj = VisionGroup3D().apply {
val obj = SolidGroup().apply {
box(100, 100, 100, name = "A")
group("B") {
position = Point3D(120, 0, 0)

View File

@ -41,7 +41,7 @@ include(
":ui:material",
":ui:bootstrap",
":visionforge-core",
":visionforge-spatial",
":visionforge-solid",
":visionforge-gdml",
":demo:spatial-showcase",
":demo:gdml",

View File

@ -4,14 +4,13 @@ import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.values.Value
import hep.dataforge.values.ValueType
import hep.dataforge.vision.Vision.Companion.STYLE_KEY
import kotlinx.serialization.Transient
internal data class PropertyListener(
val owner: Any? = null,
val action: (name: Name, oldItem: MetaItem<*>?, newItem: MetaItem<*>?) -> Unit
val action: (name: Name) -> Unit
)
abstract class AbstractVision : Vision {
@ -22,46 +21,42 @@ abstract class AbstractVision : Vision {
/**
* Object own properties excluding styles and inheritance
*/
protected abstract var ownProperties: Config?
final override var styles: List<String>
get() = ownProperties?.get(STYLE_KEY).stringList
set(value) {
setItem(STYLE_KEY, Value.of(value))
updateStyles(value)
}
protected abstract var properties: Config?
protected fun updateStyles(names: List<String>) {
styleCache = null
names.mapNotNull { findStyle(it) }.asSequence()
names.mapNotNull { resolveStyle(it) }.asSequence()
.flatMap { it.items.asSequence() }
.distinctBy { it.key }
.forEach {
propertyChanged(it.key.asName(), null, it.value)
propertyChanged(it.key.asName())
}
}
/**
* The config is initialized and assigned on-demand.
* To avoid unnecessary allocations, one should access [ownProperties] via [getProperty] instead.
* To avoid unnecessary allocations, one should access [getAllProperties] via [getProperty] instead.
*/
override val config: Config
get() = ownProperties ?: Config().also { config ->
ownProperties = config.apply { onChange(this, ::propertyChanged) }
get() = properties ?: Config().also { config ->
properties = config.also {
it.onChange(this) { name, _, _ -> propertyChanged(name) }
}
}
@Transient
private val listeners = HashSet<PropertyListener>()
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
if (before != after) {
for (l in listeners) {
l.action(name, before, after)
}
override fun propertyChanged(name: Name) {
if (name == STYLE_KEY) {
updateStyles(properties?.get(STYLE_KEY)?.stringList ?: emptyList())
}
for (listener in listeners) {
listener.action(name)
}
}
override fun onPropertyChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit) {
override fun onPropertyChange(owner: Any?, action: (Name) -> Unit) {
listeners.add(PropertyListener(owner, action))
}
@ -75,25 +70,25 @@ abstract class AbstractVision : Vision {
* Collect all styles for this object in a single cached meta
*/
protected val mergedStyles: Meta
get() = styleCache ?: findAllStyles().merge().also {
get() = styleCache ?: Laminate(styles.mapNotNull(::resolveStyle)).merge().also {
styleCache = it
}
/**
* All available properties in a layered form
*/
override fun properties(): Laminate = Laminate(ownProperties, mergedStyles, parent?.properties())
override fun getAllProperties(): Laminate = Laminate(properties, mergedStyles, parent?.getAllProperties())
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
yield(parent?.getProperty(name, inherit))
}.merge()
} else {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
}.merge()
}
@ -103,8 +98,8 @@ abstract class AbstractVision : Vision {
* Reset all properties to their default values
*/
fun resetProperties() {
ownProperties?.removeListener(this)
ownProperties = null
properties?.removeListener(this)
properties = null
}
companion object {

View File

@ -1,6 +1,5 @@
package hep.dataforge.vision
import hep.dataforge.meta.MetaItem
import hep.dataforge.names.Name
import hep.dataforge.names.NameToken
import hep.dataforge.names.asName
@ -31,10 +30,10 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
res.block()
}
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) {
super.propertyChanged(name, before, after)
override fun propertyChanged(name: Name) {
super.propertyChanged(name)
for(obj in this) {
obj.propertyChanged(name, before, after)
obj.propertyChanged(name)
}
}

View File

@ -13,7 +13,7 @@ class SimpleVisionGroup : AbstractVisionGroup() {
override var styleSheet: StyleSheet? = null
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var ownProperties: Config? = null
override var properties: Config? = null
@SerialName("children")
private val _children = HashMap<NameToken, Vision>()

View File

@ -5,6 +5,7 @@ package hep.dataforge.vision
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.values.asValue
import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer
@ -23,6 +24,21 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
val items: Map<String, Meta> get() = styleMap
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
if (styles.contains(key)) {
//TODO optimize set concatenation
val tokens: Collection<Name> = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet()))
.map { it.asName() }
tokens.forEach { parent?.propertyChanged(it) }
}
if (this is VisionGroup) {
for (obj in this) {
obj.styleChanged(key, oldStyle, newStyle)
}
}
}
operator fun get(key: String): Meta? {
return styleMap[key] ?: owner?.parent?.styleSheet?.get(key)
}
@ -73,16 +89,19 @@ class StyleSheet private constructor(private val styleMap: MutableMap<String, Me
}
}
private fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) {
if (styles.contains(key)) {
//TODO optimize set concatenation
val tokens: Collection<Name> = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet()))
.map { it.asName() }
tokens.forEach { parent?.propertyChanged(it, oldStyle?.get(it), newStyle?.get(it)) }
}
if (this is VisionGroup) {
for (obj in this) {
obj.styleChanged(key, oldStyle, newStyle)
}
/**
* List of names of styles applied to this object. Order matters. Not inherited
*/
var Vision.styles: List<String>
get() = getItem(Vision.STYLE_KEY).stringList
set(value) {
setItem(Vision.STYLE_KEY,value.map { it.asValue() }.asValue())
}
/**
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
*/
fun Vision.useStyle(name: String) {
styles = styles + name
}

View File

@ -27,10 +27,10 @@ interface Vision : Configurable {
/**
* All properties including styles and prototypes if present, including inherited ones
*/
fun properties(): Laminate
fun getAllProperties(): Laminate
/**
* Get property including or excluding parent properties
* Get property (including styles). [inherit] toggles parent node property lookup
*/
fun getProperty(name: Name, inherit: Boolean): MetaItem<*>?
@ -42,28 +42,18 @@ interface Vision : Configurable {
/**
* Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
*/
fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?): Unit
/**
* Send a signal that property value should be reevaluated
*/
fun propertyInvalidated(name: Name) = propertyChanged(name, null, null)
fun propertyChanged(name: Name): Unit
/**
* Add listener triggering on property change
*/
fun onPropertyChange(owner: Any?, action: (Name, before: MetaItem<*>?, after: MetaItem<*>?) -> Unit): Unit
fun onPropertyChange(owner: Any?, action: (Name) -> Unit): Unit
/**
* Remove change listeners with given owner.
*/
fun removeChangeListener(owner: Any?)
/**
* List of names of styles applied to this object. Order matters. Not inherited
*/
var styles: List<String>
companion object {
const val TYPE = "visual"
val STYLE_KEY = "@style".asName()
@ -81,13 +71,8 @@ fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
getProperty(key.toName(), inherit)
/**
* Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment.
* Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision].
*/
fun Vision.useStyle(name: String) {
styles = styles + name
}
tailrec fun Vision.resolveStyle(name: String): Meta? =
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.resolveStyle(name)
tailrec fun Vision.findStyle(name: String): Meta? =
(this as? VisionGroup)?.styleSheet?.get(name) ?: parent?.findStyle(name)
fun Vision.findAllStyles(): Laminate = Laminate(styles.mapNotNull(::findStyle))

View File

@ -16,7 +16,7 @@ interface VisionGroup : Provider, Vision {
/**
* A stylesheet for this group and its descendants. Stylesheet is not applied directly,
* but instead is just a repository for named configutations
* but instead is just a repository for named configurations.
*/
val styleSheet: StyleSheet?

View File

@ -1,39 +1,127 @@
package hep.dataforge.vision
import hep.dataforge.context.*
import hep.dataforge.meta.Meta
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.names.toName
import kotlinx.serialization.KSerializer
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.modules.SerializersModule
import kotlin.reflect.KClass
interface VisionFactory<T : Vision> : Factory<T> {
val type: KClass<T>
@DFExperimental
interface VisionForm<T : Vision> {
val type: KClass<out T>
val serializer: KSerializer<T>
val name get() = serializer.descriptor.serialName.toName()
/**
* Apply a patch to given [Vision]
*/
fun patch(obj: T, meta: Meta)
companion object {
const val TYPE = "visionForm"
}
}
@DFExperimental
object SimpleGroupForm: VisionForm<SimpleVisionGroup>{
override val type: KClass<out SimpleVisionGroup> = SimpleVisionGroup::class
override val serializer: KSerializer<SimpleVisionGroup> = SimpleVisionGroup.serializer()
override fun patch(obj: SimpleVisionGroup, meta: Meta) {
TODO("Not yet implemented")
}
}
@DFExperimental
fun <T : Vision> VisionForm<T>.visionToMeta(vision: T, module: SerialModule, descriptor: NodeDescriptor? = null): Meta {
val engine = Json(VisionManager.jsonConfiguration, module)
val json = engine.toJson<T>(serializer, vision)
return json.toMetaItem(descriptor).node!!
}
@DFExperimental
fun <T : Vision> VisionForm<T>.buildVision(meta: Meta, module: SerialModule, descriptor: NodeDescriptor? = null): T {
val engine = Json(VisionManager.jsonConfiguration, module)
val json = meta.toJson(descriptor)
return engine.fromJson(serializer, json)
}
@DFExperimental
class VisionManager(meta: Meta) : AbstractPlugin(meta) {
override val tag: PluginTag get() = Companion.tag
/**
* Create a list of factories on first call and cache it
*/
private val factories by lazy {
context.content<VisionFactory<*>>(VISION_FACTORY_TYPE).mapKeys { it.value.type }
private val forms by lazy {
context.content<VisionForm<*>>(VisionForm.TYPE).mapKeys { it.value.type }
}
@Suppress("UNCHECKED_CAST")
fun <T : Vision> resolveVisionFactory(type: KClass<out T>): VisionFactory<T>? =
factories[type] as VisionFactory<T>
inline fun <reified T : Vision> buildVision(parent: VisionGroup?, meta: Meta): T? {
return resolveVisionFactory(T::class)?.invoke(meta, context)?.apply {
this.parent = parent
val visionSerialModule
get() = SerializersModule {
include(defaultSerialModule)
context.content<SerialModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
include(it)
}
}
@Suppress("UNCHECKED_CAST")
fun <T : Vision> resolveVisionForm(type: KClass<out T>): VisionForm<T>? =
forms[type] as VisionForm<T>
inline fun <reified T : Vision> buildSpecificVision(meta: Meta): T {
val factory = resolveVisionForm(T::class) ?: error("Could not resolve a form for ${meta["type"].string}")
return factory.buildVision(meta, visionSerialModule)
}
fun buildVision(meta: Meta): Vision {
val type = meta["type"].string ?: SimpleVisionGroup.serializer().descriptor.serialName
val form = forms.values.find { it.name.toString() == type } ?: error("Could not resolve a form for type $type")
return form.buildVision(meta, visionSerialModule)
}
fun <T : Vision> writeVisionToMeta(vision: T): Meta {
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
val engine = Json(VisionManager.jsonConfiguration, visionSerialModule)
val json = engine.toJson(form.serializer,vision)
return json.toMetaItem().node!!
}
fun patchVision(vision: Vision, meta: Meta) {
val form = resolveVisionForm(vision::class) ?: error("Could not resolve a form for $vision")
form.patch(vision, meta)
}
companion object : PluginFactory<VisionManager> {
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out VisionManager> = VisionManager::class
const val VISION_SERIAL_MODULE_TARGET = "visionSerialModule"
override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta)
const val VISION_FACTORY_TYPE = "vision.factory"
@OptIn(UnstableDefault::class)
val jsonConfiguration = JsonConfiguration(
prettyPrint = true,
useArrayPolymorphism = false,
encodeDefaults = false,
ignoreUnknownKeys = true
)
val defaultSerialModule = SerializersModule {
polymorphic(Vision::class, VisionGroup::class) {
subclass(SimpleVisionGroup.serializer())
}
}
}
}

View File

@ -5,7 +5,8 @@ import hep.dataforge.meta.Meta
import hep.dataforge.meta.descriptors.NodeDescriptor
import hep.dataforge.meta.update
import hep.dataforge.vision.Vision
import hep.dataforge.vision.findStyle
import hep.dataforge.vision.resolveStyle
import hep.dataforge.vision.styles
import javafx.beans.binding.Binding
import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Node
@ -54,7 +55,7 @@ class VisualObjectEditorFragment(val selector: (Vision) -> Meta) : Fragment() {
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() {
VBox().apply {
item?.styles?.forEach { styleName ->
val styleMeta = item?.findStyle(styleName)
val styleMeta = item?.resolveStyle(styleName)
if (styleMeta != null) {
titledpane(styleName, node = MetaViewer(styleMeta).root)
}

View File

@ -6,7 +6,7 @@ kotlin {
sourceSets {
val commonMain by getting {
dependencies {
api(project(":visionforge-spatial"))
api(project(":visionforge-solid"))
api("scientifik:gdml:0.1.8")
}
}

View File

@ -1,12 +1,12 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import hep.dataforge.meta.Meta
import hep.dataforge.meta.MetaBuilder
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.names.toName
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.useStyle
import scientifik.gdml.*
import kotlin.random.Random
@ -24,7 +24,7 @@ class GDMLTransformer(val root: GDML) {
/**
* A special group for local templates
*/
val proto by lazy { VisionGroup3D() }
val proto by lazy { SolidGroup() }
private val styleCache = HashMap<Name, Meta>()
var lUnit: LUnit = LUnit.MM
@ -33,23 +33,23 @@ class GDMLTransformer(val root: GDML) {
var volumeAction: (GDMLGroup) -> Action = { Action.CACHE }
var solidConfiguration: Vision3D.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { parent, _ ->
var solidConfiguration: Solid.(parent: GDMLVolume, solid: GDMLSolid) -> Unit = { parent, _ ->
lUnit = LUnit.CM
if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") {
Material3D.MATERIAL_OPACITY_KEY put 0.3
SolidMaterial.MATERIAL_OPACITY_KEY put 0.3
}
}
}
fun Vision3D.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
fun Solid.useStyle(name: String, builder: MetaBuilder.() -> Unit) {
styleCache.getOrPut(name.toName()) {
Meta(builder)
}
useStyle(name)
}
internal fun configureSolid(obj: Vision3D, parent: GDMLVolume, solid: GDMLSolid) {
internal fun configureSolid(obj: Solid, parent: GDMLVolume, solid: GDMLSolid) {
val material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref)
val styleName = "material[${material.name}]"
@ -68,7 +68,7 @@ class GDMLTransformer(val root: GDML) {
var onFinish: GDMLTransformer.() -> Unit = {}
internal fun finalize(final: VisionGroup3D): VisionGroup3D {
internal fun finalize(final: SolidGroup): SolidGroup {
//final.prototypes = proto
final.prototypes {
proto.children.forEach { (token, item) ->

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import hep.dataforge.names.Name
@ -6,20 +6,20 @@ import hep.dataforge.names.asName
import hep.dataforge.names.plus
import hep.dataforge.vision.get
import hep.dataforge.vision.set
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.spatial.World.ONE
import hep.dataforge.vision.spatial.World.ZERO
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.World.ONE
import hep.dataforge.vision.solid.World.ZERO
import scientifik.gdml.*
import kotlin.math.cos
import kotlin.math.sin
private fun Vision3D.withPosition(
private fun Solid.withPosition(
lUnit: LUnit,
newPos: GDMLPosition? = null,
newRotation: GDMLRotation? = null,
newScale: GDMLScale? = null
): Vision3D = apply {
): Solid = apply {
newPos?.let {
val point = Point3D(it.x(lUnit), it.y(lUnit), it.z(lUnit))
if (position != null || point != ZERO) {
@ -48,12 +48,12 @@ private inline operator fun Number.times(d: Double) = toDouble() * d
@Suppress("NOTHING_TO_INLINE")
private inline operator fun Number.times(f: Float) = toFloat() * f
private fun VisionGroup3D.addSolid(
private fun SolidGroup.addSolid(
context: GDMLTransformer,
solid: GDMLSolid,
name: String = "",
block: Vision3D.() -> Unit = {}
): Vision3D {
block: Solid.() -> Unit = {}
): Solid {
//context.solidAdded(solid)
val lScale = solid.lscale(context.lUnit)
val aScale = solid.ascale()
@ -154,7 +154,7 @@ private fun VisionGroup3D.addSolid(
private val volumesName = "volumes".asName()
private fun VisionGroup3D.addPhysicalVolume(
private fun SolidGroup.addPhysicalVolume(
context: GDMLTransformer,
physVolume: GDMLPhysVolume
) {
@ -194,7 +194,7 @@ private fun VisionGroup3D.addPhysicalVolume(
}
}
private fun VisionGroup3D.addDivisionVolume(
private fun SolidGroup.addDivisionVolume(
context: GDMLTransformer,
divisionVolume: GDMLDivisionVolume
) {
@ -216,8 +216,8 @@ private val solidsName = "solids".asName()
private fun volume(
context: GDMLTransformer,
group: GDMLGroup
): VisionGroup3D {
return VisionGroup3D().apply {
): SolidGroup {
return SolidGroup().apply {
if (group is GDMLVolume) {
val solid = group.solidref.resolve(context.root)
?: error("Solid with tag ${group.solidref.ref} for volume ${group.name} not defined")
@ -253,7 +253,7 @@ private fun volume(
}
}
fun GDML.toVision(block: GDMLTransformer.() -> Unit = {}): VisionGroup3D {
fun GDML.toVision(block: GDMLTransformer.() -> Unit = {}): SolidGroup {
val context = GDMLTransformer(this).apply(block)
return context.finalize(volume(context, world))
}
@ -261,7 +261,7 @@ fun GDML.toVision(block: GDMLTransformer.() -> Unit = {}): VisionGroup3D {
/**
* Append gdml node to the group
*/
fun VisionGroup3D.gdml(gdml: GDML, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
fun SolidGroup.gdml(gdml: GDML, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
val visual = gdml.toVision(transformer)
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
set(key, visual)

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import scientifik.gdml.AUnit
import scientifik.gdml.GDMLPosition

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.solid.SolidGroup
import nl.adaptivity.xmlutil.StAXReader
import scientifik.gdml.GDML
import java.nio.file.Files
@ -11,7 +11,7 @@ fun GDML.Companion.readFile(file: Path): GDML {
return format.parse(GDML.serializer(), xmlReader)
}
fun VisionGroup3D.gdml(file: Path, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
fun SolidGroup.gdml(file: Path, key: String = "", transformer: GDMLTransformer.() -> Unit = {}) {
val gdml = GDML.readFile(file)
gdml(gdml, key, transformer)
}

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.spatial.gdml
package hep.dataforge.vision.solid.gdml
import hep.dataforge.vision.spatial.stringify
import hep.dataforge.vision.solid.stringify
import nl.adaptivity.xmlutil.StAXReader
import org.junit.jupiter.api.Test
import scientifik.gdml.GDML

View File

@ -1,34 +1,29 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
import hep.dataforge.context.Context
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.meta.Meta
import hep.dataforge.meta.float
import hep.dataforge.meta.get
import hep.dataforge.vision.AbstractVision
import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.VisionFactory
import hep.dataforge.vision.set
import hep.dataforge.vision.spatial.Box.Companion.TYPE_NAME
import hep.dataforge.vision.solid.Solid.Companion.solidEquals
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import kotlin.reflect.KClass
@Serializable
@SerialName(TYPE_NAME)
@SerialName("solid.box")
class Box(
val xSize: Float,
val ySize: Float,
val zSize: Float
) : AbstractVision(), Vision3D, Shape {
) : AbstractVision(), GeometrySolid {
override var position: Point3D? = null
override var rotation: Point3D? = null
override var scale: Point3D? = null
override var ownProperties: Config? = null
override var properties: Config? = null
//TODO add helper for color configuration
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
@ -51,19 +46,29 @@ class Box(
geometryBuilder.face4(node8, node5, node6, node7)
}
companion object : VisionFactory<Box> {
override fun equals(other: Any?): Boolean {
if (this === other) return true
if (other == null || this::class != other::class) return false
const val TYPE_NAME = "3d.box"
other as Box
override val type: KClass<Box> get() = Box::class
if (xSize != other.xSize) return false
if (ySize != other.ySize) return false
if (zSize != other.zSize) return false
return solidEquals(this, other)
}
override fun hashCode(): Int {
var result = xSize.hashCode()
result = 31 * result + ySize.hashCode()
result = 31 * result + zSize.hashCode()
return 31 * result + Solid.solidHashCode(this)
}
companion object {
override fun invoke(meta: Meta, context: Context): Box = Box(
meta["xSize"].float!!,
meta["ySize"].float!!,
meta["zSize"].float!!
).apply {
update(meta)
}
}
}

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.meta.update
@ -17,12 +17,12 @@ enum class CompositeType {
}
@Serializable
@SerialName("3d.composite")
@SerialName("solid.composite")
class Composite(
val compositeType: CompositeType,
val first: Vision3D,
val second: Vision3D
) : AbstractVision(), Vision3D, VisionGroup {
val first: Solid,
val second: Solid
) : AbstractVision(), Solid, VisionGroup {
init {
first.parent = this
@ -33,7 +33,7 @@ class Composite(
override var rotation: Point3D? = null
override var scale: Point3D? = null
override var ownProperties: Config? = null
override var properties: Config? = null
override val children: Map<NameToken, Vision>
get() = mapOf(NameToken("first") to first, NameToken("second") to second)
@ -45,10 +45,10 @@ class Composite(
inline fun MutableVisionGroup.composite(
type: CompositeType,
name: String = "",
builder: VisionGroup3D.() -> Unit
builder: SolidGroup.() -> Unit
): Composite {
val group = VisionGroup3D().apply(builder)
val children = group.children.values.filterIsInstance<Vision3D>()
val group = SolidGroup().apply(builder)
val children = group.children.values.filterIsInstance<Solid>()
if (children.size != 2) error("Composite requires exactly two children")
return Composite(type, children[0], children[1]).also {
it.config.update(group.config)
@ -67,11 +67,11 @@ inline fun MutableVisionGroup.composite(
}
}
inline fun MutableVisionGroup.union(name: String = "", builder: VisionGroup3D.() -> Unit) =
inline fun MutableVisionGroup.union(name: String = "", builder: SolidGroup.() -> Unit) =
composite(CompositeType.UNION, name, builder = builder)
inline fun MutableVisionGroup.subtract(name: String = "", builder: VisionGroup3D.() -> Unit) =
inline fun MutableVisionGroup.subtract(name: String = "", builder: SolidGroup.() -> Unit) =
composite(CompositeType.SUBTRACT, name, builder = builder)
inline fun MutableVisionGroup.intersect(name: String = "", builder: VisionGroup3D.() -> Unit) =
inline fun MutableVisionGroup.intersect(name: String = "", builder: SolidGroup.() -> Unit) =
composite(CompositeType.INTERSECT, name, builder = builder)

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -16,16 +16,16 @@ import kotlin.math.sin
* A cylinder or cut cone segment
*/
@Serializable
@SerialName("3d.cone")
@SerialName("solid.cone")
class ConeSegment(
var radius: Float,
var height: Float,
var upperRadius: Float,
var startAngle: Float = 0f,
var angle: Float = PI2
) : AbstractVision(), Vision3D, Shape {
) : AbstractVision(), GeometrySolid {
override var ownProperties: Config? = null
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -11,18 +11,16 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
@Serializable
@SerialName("3d.convex")
class Convex(val points: List<Point3D>) : AbstractVision(), Vision3D {
@SerialName("solid.convex")
class Convex(val points: List<Point3D>) : AbstractVision(), Solid {
override var ownProperties: Config? = null
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null
override var scale: Point3D? = null
companion object {
const val TYPE = "geometry.3d.convex"
}
}
inline fun MutableVisionGroup.convex(name: String = "", action: ConvexBuilder.() -> Unit = {}) =

View File

@ -1,5 +1,5 @@
@file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -39,13 +39,13 @@ fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
@Serializable
@SerialName("3d.extrude")
@SerialName("solid.extrude")
class Extruded(
var shape: List<Point2D> = ArrayList(),
var layers: MutableList<Layer> = ArrayList()
) : AbstractVision(), Vision3D, Shape {
) : AbstractVision(), GeometrySolid {
override var ownProperties: Config? = null
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Meta
@ -31,9 +31,9 @@ fun GeometryBuilder<*>.face4(
}
/**
* [Shape] is a [Vision3D] that can represent its own geometry as a set of polygons.
* [GeometrySolid] is a [Solid] that can represent its own geometry as a set of polygons.
*/
interface Shape : Vision3D {
interface GeometrySolid : Solid {
fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
}

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.meta.number
@ -14,16 +14,16 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
@Serializable
@SerialName("3d.line")
class PolyLine(var points: List<Point3D>) : AbstractVision(), Vision3D {
override var ownProperties: Config? = null
@SerialName("solid.line")
class PolyLine(var points: List<Point3D>) : AbstractVision(), Solid {
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null
override var scale: Point3D? = null
//var lineType by string()
var thickness by number(1.0, key = Material3D.MATERIAL_KEY + THICKNESS_KEY)
var thickness by number(1.0, key = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY)
companion object {
val THICKNESS_KEY = "thickness".asName()

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.meta.Laminate
@ -16,15 +16,15 @@ import kotlinx.serialization.UseSerializers
import kotlin.collections.set
/**
* A proxy [Vision3D] to reuse a template object
* A proxy [Solid] to reuse a template object
*/
@Serializable
@SerialName("3d.proxy")
@SerialName("solid.proxy")
class Proxy private constructor(
val templateName: Name
) : AbstractVision(), VisionGroup, Vision3D {
) : AbstractVision(), VisionGroup, Solid {
constructor(parent: VisionGroup3D, templateName: Name) : this(templateName) {
constructor(parent: SolidGroup, templateName: Name) : this(templateName) {
this.parent = parent
}
@ -32,31 +32,29 @@ class Proxy private constructor(
override var rotation: Point3D? = null
override var scale: Point3D? = null
override var ownProperties: Config? = null
override var properties: Config? = null
/**
* Recursively search for defined template in the parent
*/
val prototype: Vision3D
get() = (parent as? VisionGroup3D)?.getPrototype(templateName)
val prototype: Solid
get() = (parent as? SolidGroup)?.getPrototype(templateName)
?: error("Prototype with name $templateName not found in $parent")
override val styleSheet: StyleSheet
get() = parent?.styleSheet ?: StyleSheet(
this
)
get() = parent?.styleSheet ?: StyleSheet(this)
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
yield(prototype.getItem(name))
yield(parent?.getProperty(name, inherit))
}.merge()
} else {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
yield(prototype.getProperty(name, false))
}.merge()
@ -82,8 +80,8 @@ class Proxy private constructor(
?: error("Prototype with name $name not found in $this")
}
override fun properties(): Laminate =
Laminate(ownProperties, mergedStyles, prototype.properties(), parent?.properties())
override fun getAllProperties(): Laminate =
Laminate(properties, mergedStyles, prototype.getAllProperties(), parent?.getAllProperties())
override fun attachChildren() {
//do nothing
@ -108,7 +106,7 @@ class Proxy private constructor(
)
} ?: emptyMap()
override var ownProperties: Config?
override var properties: Config?
get() = propertyCache[name]
set(value) {
if (value == null) {
@ -118,8 +116,8 @@ class Proxy private constructor(
}
} else {
propertyCache[name] = value.also {
onPropertyChange(this@Proxy) { propertyName, before, after ->
this@Proxy.propertyChanged(childPropertyName(name, propertyName), before, after)
onPropertyChange(this@Proxy) { propertyName ->
this@Proxy.propertyChanged(childPropertyName(name, propertyName))
}
}
}
@ -128,14 +126,14 @@ class Proxy private constructor(
override fun getProperty(name: Name, inherit: Boolean): MetaItem<*>? {
return if (inherit) {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
yield(prototype.getItem(name))
yield(parent?.getProperty(name, inherit))
}.merge()
} else {
sequence {
yield(ownProperties?.get(name))
yield(properties?.get(name))
yield(mergedStyles[name])
yield(prototype.getProperty(name, false))
}.merge()
@ -146,8 +144,8 @@ class Proxy private constructor(
//do nothing
}
override fun properties(): Laminate =
Laminate(ownProperties, mergedStyles, prototype.properties(), parent?.properties())
override fun getAllProperties(): Laminate =
Laminate(properties, mergedStyles, prototype.getAllProperties(), parent?.getAllProperties())
override val descriptor: NodeDescriptor?
@ -169,7 +167,7 @@ val Vision.prototype: Vision
/**
* Create ref for existing prototype
*/
fun VisionGroup3D.ref(
fun SolidGroup.ref(
templateName: Name,
name: String = ""
): Proxy = Proxy(this, templateName).also { set(name, it) }
@ -177,9 +175,9 @@ fun VisionGroup3D.ref(
/**
* Add new proxy wrapping given object and automatically adding it to the prototypes
*/
fun VisionGroup3D.proxy(
fun SolidGroup.proxy(
name: String,
obj: Vision3D,
obj: Solid,
templateName: Name = name.toName()
): Proxy {
val existing = getPrototype(templateName)
@ -193,11 +191,11 @@ fun VisionGroup3D.proxy(
return ref(templateName, name)
}
fun VisionGroup3D.proxyGroup(
fun SolidGroup.proxyGroup(
name: String,
templateName: Name = name.toName(),
block: MutableVisionGroup.() -> Unit
): Proxy {
val group = VisionGroup3D().apply (block)
val group = SolidGroup().apply(block)
return proxy(name, group, templateName)
}

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
@ -11,20 +11,22 @@ import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue
import hep.dataforge.vision.Vision
import hep.dataforge.vision.enum
import hep.dataforge.vision.spatial.Vision3D.Companion.DETAIL_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.IGNORE_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.LAYER_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.VISIBLE_KEY
import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
import hep.dataforge.vision.solid.Solid.Companion.VISIBLE_KEY
import kotlinx.serialization.UseSerializers
/**
* Interface for 3-dimensional [Vision]
*/
interface Vision3D : Vision {
interface Solid : Vision {
var position: Point3D?
var rotation: Point3D?
var scale: Point3D?
val properties: Config?
override val descriptor: NodeDescriptor? get() = Companion.descriptor
companion object {
@ -75,25 +77,41 @@ interface Vision3D : Vision {
multiple = true
}
item(Material3D.MATERIAL_KEY.toString(), Material3D.descriptor)
item(SolidMaterial.MATERIAL_KEY.toString(), SolidMaterial.descriptor)
enum<RotationOrder>(ROTATION_ORDER_KEY,default = RotationOrder.XYZ)
}
}
internal fun solidEquals(first: Solid, second: Solid): Boolean{
if (first.position != second.position) return false
if (first.rotation != second.rotation) return false
if (first.scale != second.scale) return false
if (first.properties != second.properties) return false
return true
}
internal fun solidHashCode(solid: Solid): Int{
var result = + (solid.position?.hashCode() ?: 0)
result = 31 * result + (solid.rotation?.hashCode() ?: 0)
result = 31 * result + (solid.scale?.hashCode() ?: 0)
result = 31 * result + (solid.properties?.hashCode() ?: 0)
return result
}
}
}
/**
* Count number of layers to the top object. Return 1 if this is top layer
*/
var Vision3D.layer: Int
var Solid.layer: Int
get() = getItem(LAYER_KEY).int ?: 0
set(value) {
setItem(LAYER_KEY, value.asValue())
}
fun Renderer<Vision3D>.render(meta: Meta = Meta.EMPTY, action: VisionGroup3D.() -> Unit) =
render(VisionGroup3D().apply(action), meta)
fun Renderer<Solid>.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit) =
render(SolidGroup().apply(action), meta)
// Common properties
@ -109,15 +127,15 @@ enum class RotationOrder {
/**
* Rotation order
*/
var Vision3D.rotationOrder: RotationOrder
get() = getItem(Vision3D.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) = setItem(Vision3D.ROTATION_ORDER_KEY, value.name.asValue())
var Solid.rotationOrder: RotationOrder
get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) = setItem(Solid.ROTATION_ORDER_KEY, value.name.asValue())
/**
* Preferred number of polygons for displaying the object. If not defined, uses shape or renderer default. Not inherited
*/
var Vision3D.detail: Int?
var Solid.detail: Int?
get() = getProperty(DETAIL_KEY, false).int
set(value) = setItem(DETAIL_KEY, value?.asValue())
@ -137,74 +155,74 @@ var Vision.ignore: Boolean?
// get() = getProperty(SELECTED_KEY).boolean
// set(value) = setProperty(SELECTED_KEY, value)
private fun Vision3D.position(): Point3D =
private fun Solid.position(): Point3D =
position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
var Vision3D.x: Number
var Solid.x: Number
get() = position?.x ?: 0f
set(value) {
position().x = value.toDouble()
propertyInvalidated(Vision3D.X_POSITION_KEY)
propertyChanged(Solid.X_POSITION_KEY)
}
var Vision3D.y: Number
var Solid.y: Number
get() = position?.y ?: 0f
set(value) {
position().y = value.toDouble()
propertyInvalidated(Vision3D.Y_POSITION_KEY)
propertyChanged(Solid.Y_POSITION_KEY)
}
var Vision3D.z: Number
var Solid.z: Number
get() = position?.z ?: 0f
set(value) {
position().z = value.toDouble()
propertyInvalidated(Vision3D.Z_POSITION_KEY)
propertyChanged(Solid.Z_POSITION_KEY)
}
private fun Vision3D.rotation(): Point3D =
private fun Solid.rotation(): Point3D =
rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
var Vision3D.rotationX: Number
var Solid.rotationX: Number
get() = rotation?.x ?: 0f
set(value) {
rotation().x = value.toDouble()
propertyInvalidated(Vision3D.X_ROTATION_KEY)
propertyChanged(Solid.X_ROTATION_KEY)
}
var Vision3D.rotationY: Number
var Solid.rotationY: Number
get() = rotation?.y ?: 0f
set(value) {
rotation().y = value.toDouble()
propertyInvalidated(Vision3D.Y_ROTATION_KEY)
propertyChanged(Solid.Y_ROTATION_KEY)
}
var Vision3D.rotationZ: Number
var Solid.rotationZ: Number
get() = rotation?.z ?: 0f
set(value) {
rotation().z = value.toDouble()
propertyInvalidated(Vision3D.Z_ROTATION_KEY)
propertyChanged(Solid.Z_ROTATION_KEY)
}
private fun Vision3D.scale(): Point3D =
private fun Solid.scale(): Point3D =
scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
var Vision3D.scaleX: Number
var Solid.scaleX: Number
get() = scale?.x ?: 1f
set(value) {
scale().x = value.toDouble()
propertyInvalidated(Vision3D.X_SCALE_KEY)
propertyChanged(Solid.X_SCALE_KEY)
}
var Vision3D.scaleY: Number
var Solid.scaleY: Number
get() = scale?.y ?: 1f
set(value) {
scale().y = value.toDouble()
propertyInvalidated(Vision3D.Y_SCALE_KEY)
propertyChanged(Solid.Y_SCALE_KEY)
}
var Vision3D.scaleZ: Number
var Solid.scaleZ: Number
get() = scale?.z ?: 1f
set(value) {
scale().z = value.toDouble()
propertyInvalidated(Vision3D.Z_SCALE_KEY)
propertyChanged(Solid.Z_SCALE_KEY)
}

View File

@ -2,7 +2,7 @@
Point3DSerializer::class
)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.names.Name
@ -23,8 +23,8 @@ interface PrototypeHolder {
* Represents 3-dimensional Visual Group
*/
@Serializable
@SerialName("group.3d")
class VisionGroup3D : AbstractVisionGroup(), Vision3D, PrototypeHolder {
@SerialName("group.solid")
class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder {
override var styleSheet: StyleSheet? = null
@ -46,7 +46,7 @@ class VisionGroup3D : AbstractVisionGroup(), Vision3D, PrototypeHolder {
}
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed
override var ownProperties: Config? = null
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null
@ -75,31 +75,39 @@ class VisionGroup3D : AbstractVisionGroup(), Vision3D, PrototypeHolder {
// */
// override fun addStatic(child: VisualObject) = setChild(NameToken("@static(${child.hashCode()})"), child)
override fun createGroup(): VisionGroup3D = VisionGroup3D()
override fun createGroup(): SolidGroup = SolidGroup()
companion object {
// val PROTOTYPES_KEY = NameToken("@prototypes")
fun parseJson(json: String): VisionGroup3D =
SpatialVisionManager.json.parse(serializer(), json).also { it.attachChildren() }
fun parseJson(json: String): SolidGroup =
SolidManager.jsonForSolids.parse(serializer(), json).also { it.attachChildren() }
}
}
@Suppress("FunctionName")
fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup {
return SolidGroup().apply(block)
}
/**
* Ger a prototype redirecting the request to the parent if prototype is not found
*/
tailrec fun PrototypeHolder.getPrototype(name: Name): Vision3D? =
prototypes?.get(name) as? Vision3D ?: (parent as? PrototypeHolder)?.getPrototype(name)
tailrec fun PrototypeHolder.getPrototype(name: Name): Solid? =
prototypes?.get(name) as? Solid ?: (parent as? PrototypeHolder)?.getPrototype(name)
/**
* Define a group with given [name], attach it to this parent and return it.
*/
fun MutableVisionGroup.group(name: String = "", action: VisionGroup3D.() -> Unit = {}): VisionGroup3D =
VisionGroup3D().apply(action).also {
fun MutableVisionGroup.group(name: String = "", action: SolidGroup.() -> Unit = {}): SolidGroup =
SolidGroup().apply(action).also {
set(name, it)
}
/**
* A special class which works as a holder for prototypes
*/
internal class Prototypes(
override var children: MutableMap<NameToken, Vision> = LinkedHashMap()
) : AbstractVisionGroup(), MutableVisionGroup, PrototypeHolder {
@ -121,7 +129,7 @@ internal class Prototypes(
override fun createGroup() = SimpleVisionGroup()
override var ownProperties: Config?
override var properties: Config?
get() = null
set(_) {
error("Can't define properties for prototypes block")

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -11,9 +11,9 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
@Serializable
@SerialName("3d.label")
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Vision3D {
override var ownProperties: Config? = null
@SerialName("solid.label")
class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Solid {
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null
@ -26,6 +26,6 @@ fun MutableVisionGroup.label(
fontSize: Number = 20,
fontFamily: String = "Arial",
name: String = "",
action: Label3D.() -> Unit = {}
action: SolidLabel.() -> Unit = {}
) =
Label3D(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }
SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) }

View File

@ -0,0 +1,137 @@
package hep.dataforge.vision.solid
import hep.dataforge.context.AbstractPlugin
import hep.dataforge.context.Context
import hep.dataforge.context.PluginFactory
import hep.dataforge.context.PluginTag
import hep.dataforge.meta.*
import hep.dataforge.names.Name
import hep.dataforge.names.toName
import hep.dataforge.vision.SimpleVisionGroup
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionForm
import hep.dataforge.vision.VisionManager
import hep.dataforge.vision.VisionManager.Companion.VISION_SERIAL_MODULE_TARGET
import kotlinx.serialization.KSerializer
import kotlinx.serialization.UnstableDefault
import kotlinx.serialization.json.Json
import kotlinx.serialization.json.JsonConfiguration
import kotlinx.serialization.modules.SerialModule
import kotlinx.serialization.modules.SerialModuleCollector
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import kotlin.reflect.KClass
@DFExperimental
private class SolidForm<T :Solid>(
override val type: KClass<T>,
override val serializer: KSerializer<T>
) : VisionForm<T> {
private fun Solid.update(meta: Meta) {
fun Meta.toVector(default: Float = 0f) = Point3D(
this[Solid.X_KEY].float ?: default,
this[Solid.Y_KEY].float ?: default,
this[Solid.Z_KEY].float ?: default
)
meta[Solid.POSITION_KEY].node?.toVector()?.let { position = it }
meta[Solid.ROTATION].node?.toVector()?.let { rotation = it }
meta[Solid.SCALE_KEY].node?.toVector(1f)?.let { scale = it }
meta["properties"].node?.let { configure(it) }
}
override fun patch(obj: T, meta: Meta) {
TODO("Not yet implemented")
}
}
@DFExperimental
@OptIn(UnstableDefault::class)
private fun SerialModule.extractFactories(): List<SolidForm<*>> {
val list = ArrayList<SolidForm<*>>()
val jsonEngine = Json(
JsonConfiguration(
prettyPrint = true,
useArrayPolymorphism = false,
encodeDefaults = false,
ignoreUnknownKeys = true
),
context = this
)
val collector = object : SerialModuleCollector {
override fun <T : Any> contextual(kClass: KClass<T>, serializer: KSerializer<T>) {
//Do nothing
}
override fun <Base : Any, Sub : Base> polymorphic(
baseClass: KClass<Base>,
actualClass: KClass<Sub>,
actualSerializer: KSerializer<Sub>
) {
if (baseClass == Vision::class) {
@Suppress("UNCHECKED_CAST") val factory = SolidForm<Solid>(
actualClass as KClass<Solid>,
actualSerializer as KSerializer<Solid>
)
val name = actualSerializer.descriptor.serialName.toName()
list.add(factory)
}
}
}
dumpTo(collector)
return list
}
@DFExperimental
class SolidManager(meta: Meta) : AbstractPlugin(meta) {
val visionManager by require(VisionManager)
override val tag: PluginTag get() = Companion.tag
override fun provideTop(target: String): Map<Name, Any> = when (target) {
VisionForm.TYPE -> serialModule.extractFactories().associateBy { it.name }
VISION_SERIAL_MODULE_TARGET -> mapOf(tag.name.toName() to serialModule)
else -> super.provideTop(target)
}
companion object : PluginFactory<SolidManager> {
override val tag: PluginTag = PluginTag(name = "visual.spatial", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out SolidManager> = SolidManager::class
override fun invoke(meta: Meta, context: Context): SolidManager = SolidManager(meta)
val serialModule = SerializersModule {
contextual(Point3DSerializer)
contextual(Point2DSerializer)
polymorphic(Vision::class, Solid::class) {
subclass(SimpleVisionGroup.serializer())
subclass(SolidGroup.serializer())
subclass(Proxy.serializer())
subclass(Composite.serializer())
subclass(Tube.serializer())
subclass(Box.serializer())
subclass(Convex.serializer())
subclass(Extruded.serializer())
subclass(PolyLine.serializer())
subclass(SolidLabel.serializer())
subclass(Sphere.serializer())
}
}
@OptIn(UnstableDefault::class)
val jsonForSolids = Json(
JsonConfiguration(
prettyPrint = true,
useArrayPolymorphism = false,
encodeDefaults = false,
ignoreUnknownKeys = true
),
context = serialModule
)
}
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor
@ -8,12 +8,12 @@ import hep.dataforge.names.plus
import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue
import hep.dataforge.vision.Colors
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_KEY
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY
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
class Material3D : Scheme() {
class SolidMaterial : Scheme() {
/**
* Primary web-color for the material
@ -35,7 +35,7 @@ class Material3D : Scheme() {
*/
var wireframe by boolean(false, WIREFRAME_KEY)
companion object : SchemeSpec<Material3D>(::Material3D) {
companion object : SchemeSpec<SolidMaterial>(::SolidMaterial) {
val MATERIAL_KEY = "material".asName()
internal val COLOR_KEY = "color".asName()
@ -77,18 +77,18 @@ class Material3D : Scheme() {
/**
* Set color as web-color
*/
fun Vision3D.color(webColor: String) {
fun Solid.color(webColor: String) {
setItem(MATERIAL_COLOR_KEY, webColor.asValue())
}
/**
* Set color as integer
*/
fun Vision3D.color(rgb: Int) {
fun Solid.color(rgb: Int) {
setItem(MATERIAL_COLOR_KEY, rgb.asValue())
}
fun Vision3D.color(r: UByte, g: UByte, b: UByte) = setItem(
fun Solid.color(r: UByte, g: UByte, b: UByte) = setItem(
MATERIAL_COLOR_KEY,
Colors.rgbToMeta(r, g, b)
)
@ -96,25 +96,25 @@ fun Vision3D.color(r: UByte, g: UByte, b: UByte) = setItem(
/**
* Web colors representation of the color in `#rrggbb` format or HTML name
*/
var Vision3D.color: String?
var Solid.color: String?
get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
set(value) {
setItem(MATERIAL_COLOR_KEY, value?.asValue())
}
val Vision3D.material: Material3D?
get() = getItem(MATERIAL_KEY).node?.let { Material3D.wrap(it) }
val Solid.material: SolidMaterial?
get() = getItem(MATERIAL_KEY).node?.let { SolidMaterial.wrap(it) }
fun Vision3D.material(builder: Material3D.() -> Unit) {
fun Solid.material(builder: SolidMaterial.() -> Unit) {
val node = config[MATERIAL_KEY].node
if (node != null) {
Material3D.update(node, builder)
SolidMaterial.update(node, builder)
} else {
config[MATERIAL_KEY] = Material3D(builder)
config[MATERIAL_KEY] = SolidMaterial(builder)
}
}
var Vision3D.opacity: Double?
var Solid.opacity: Double?
get() = getItem(MATERIAL_OPACITY_KEY).double
set(value) {
setItem(MATERIAL_OPACITY_KEY, value?.asValue())

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -14,16 +14,16 @@ import kotlin.math.cos
import kotlin.math.sin
@Serializable
@SerialName("3d.sphere")
@SerialName("solid.sphere")
class Sphere(
var radius: Float,
var phiStart: Float = 0f,
var phi: Float = PI2,
var thetaStart: Float = 0f,
var theta: Float = PI.toFloat()
) : AbstractVision(), Vision3D, Shape {
) : AbstractVision(), GeometrySolid {
override var ownProperties: Config? = null
override var properties: Config? = null
override var position: Point3D? = null
override var rotation: Point3D? = null

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
@ -17,20 +17,20 @@ import kotlin.math.sin
* Straight tube segment
*/
@Serializable
@SerialName("3d.tube")
@SerialName("solid.tube")
class Tube(
var radius: Float,
var height: Float,
var innerRadius: Float = 0f,
var startAngle: Float = 0f,
var angle: Float = PI2
) : AbstractVision(), Vision3D, Shape {
) : AbstractVision(), GeometrySolid {
override var position: Point3D? = null
override var rotation: Point3D? = null
override var scale: Point3D? = null
override var ownProperties: Config? = null
override var properties: Config? = null
init {
require(radius > 0)

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.Meta
import hep.dataforge.meta.get
@ -21,8 +21,8 @@ operator fun Point2D.component1() = x
operator fun Point2D.component2() = y
fun Point2D.toMeta() = Meta {
Vision3D.X_KEY put x
Vision3D.Y_KEY put y
Solid.X_KEY put x
Solid.Y_KEY put y
}
fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0)
@ -42,7 +42,7 @@ operator fun Point3D.component3() = z
fun Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
fun Point3D.toMeta() = Meta {
Vision3D.X_KEY put x
Vision3D.Y_KEY put y
Vision3D.Z_KEY put z
Solid.X_KEY put x
Solid.Y_KEY put y
Solid.Z_KEY put z
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.double
import hep.dataforge.names.NameToken
@ -118,9 +118,9 @@ internal object PrototypesSerializer : KSerializer<MutableVisionGroup> {
}
}
fun Vision.stringify(): String = SpatialVisionManager.json.stringify(Vision.serializer(), this)
fun Vision.stringify(): String = SolidManager.jsonForSolids.stringify(Vision.serializer(), this)
fun Vision.Companion.parseJson(str: String) = SpatialVisionManager.json.parse(Vision.serializer(), str).also {
fun Vision.Companion.parseJson(str: String) = SolidManager.jsonForSolids.parse(Vision.serializer(), str).also {
if(it is VisionGroup){
it.attachChildren()
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.specifications
package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.*

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.specifications
package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.Scheme
import hep.dataforge.meta.SchemeSpec

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.specifications
package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.Scheme
import hep.dataforge.meta.SchemeSpec

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.specifications
package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.Scheme
import hep.dataforge.meta.SchemeSpec

View File

@ -1,11 +1,11 @@
package hep.dataforge.vision.spatial.transform
package hep.dataforge.vision.solid.transform
import hep.dataforge.meta.update
import hep.dataforge.names.asName
import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionGroup
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.solid.*
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
return child.apply {
@ -14,7 +14,7 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
//parent.properties?.let { config.update(it) }
if (this is Vision3D && parent is Vision3D) {
if (this is Solid && parent is Solid) {
position = (position ?: World.ZERO) + (parent.position ?: World.ZERO)
rotation = (parent.rotation ?: World.ZERO) + (parent.rotation ?: World.ZERO)
scale = when {
@ -32,9 +32,9 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
}
}
object RemoveSingleChild : VisualTreeTransform<VisionGroup3D>() {
object RemoveSingleChild : VisualTreeTransform<SolidGroup>() {
override fun VisionGroup3D.transformInPlace() {
override fun SolidGroup.transformInPlace() {
fun MutableVisionGroup.replaceChildren() {
children.forEach { (childName, parent) ->
if (parent is Proxy) return@forEach //ignore refs
@ -56,7 +56,7 @@ object RemoveSingleChild : VisualTreeTransform<VisionGroup3D>() {
}
}
override fun VisionGroup3D.clone(): VisionGroup3D {
override fun SolidGroup.clone(): SolidGroup {
TODO()
}
}

View File

@ -1,13 +1,13 @@
package hep.dataforge.vision.spatial.transform
package hep.dataforge.vision.solid.transform
import hep.dataforge.names.Name
import hep.dataforge.names.asName
import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.VisionGroup
import hep.dataforge.vision.spatial.Proxy
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.solid.Proxy
import hep.dataforge.vision.solid.SolidGroup
object UnRef : VisualTreeTransform<VisionGroup3D>() {
object UnRef : VisualTreeTransform<SolidGroup>() {
private fun VisionGroup.countRefs(): Map<Name, Int> {
return children.values.fold(HashMap()) { reducer, obj ->
if (obj is VisionGroup) {
@ -24,7 +24,7 @@ object UnRef : VisualTreeTransform<VisionGroup3D>() {
}
private fun MutableVisionGroup.unref(name: Name) {
(this as? VisionGroup3D)?.prototypes?.set(name, null)
(this as? SolidGroup)?.prototypes?.set(name, null)
children.filter { (it.value as? Proxy)?.templateName == name }.forEach { (key, value) ->
val proxy = value as Proxy
val newChild = mergeChild(proxy, proxy.prototype)
@ -35,14 +35,14 @@ object UnRef : VisualTreeTransform<VisionGroup3D>() {
children.values.filterIsInstance<MutableVisionGroup>().forEach { it.unref(name) }
}
override fun VisionGroup3D.transformInPlace() {
override fun SolidGroup.transformInPlace() {
val counts = countRefs()
counts.filter { it.value <= 1 }.forEach {
this.unref(it.key)
}
}
override fun VisionGroup3D.clone(): VisionGroup3D {
override fun SolidGroup.clone(): SolidGroup {
TODO()
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.transform
package hep.dataforge.vision.solid.transform
import hep.dataforge.vision.Vision

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.getIndexed
@ -11,7 +11,7 @@ class ConvexTest {
@Suppress("UNUSED_VARIABLE")
@Test
fun testConvexBuilder() {
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
convex {
point(50, 50, -50)
point(50, -50, -50)
@ -26,7 +26,7 @@ class ConvexTest {
val convex = group.children.values.first() as Convex
val json = SpatialVisionManager.json.toJson(Convex.serializer(), convex)
val json = SolidManager.jsonForSolids.toJson(Convex.serializer(), convex)
val meta = json.toMetaItem().node!!
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() }

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.vision.Colors
import hep.dataforge.vision.get
@ -9,7 +9,7 @@ import kotlin.test.assertEquals
class GroupTest {
@Test
fun testGroupWithComposite() {
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
union("union") {
box(100, 100, 100) {
z = 100
@ -45,7 +45,7 @@ class GroupTest {
}
assertEquals(3, group.children.count())
assertEquals(300.0, (group["intersect"] as Vision3D).y.toDouble())
assertEquals(-300.0, (group["subtract"] as Vision3D).y.toDouble())
assertEquals(300.0, (group["intersect"] as Solid).y.toDouble())
assertEquals(-300.0, (group["subtract"] as Solid).y.toDouble())
}
}

View File

@ -1,8 +1,9 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.meta.int
import hep.dataforge.meta.set
import hep.dataforge.names.asName
import hep.dataforge.vision.styles
import hep.dataforge.vision.useStyle
import kotlin.test.Test
import kotlin.test.assertEquals
@ -12,7 +13,7 @@ class PropertyTest {
@Test
fun testInheritedProperty() {
var box: Box? = null
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
config["test"] = 22
group {
box = box(100, 100, 100)
@ -24,7 +25,7 @@ class PropertyTest {
@Test
fun testStyleProperty() {
var box: Box? = null
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
styleSheet {
set("testStyle") {
"test" put 22
@ -42,10 +43,10 @@ class PropertyTest {
@Test
fun testColor() {
var box: Box? = null
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
styleSheet {
set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555"
SolidMaterial.MATERIAL_COLOR_KEY put "#555555"
}
}
group {
@ -60,10 +61,10 @@ class PropertyTest {
@Test
fun testProxyStyleProperty() {
var box: Proxy? = null
val group = VisionGroup3D().apply {
val group = SolidGroup().apply {
styleSheet {
set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555"
SolidMaterial.MATERIAL_COLOR_KEY put "#555555"
}
}
prototypes {

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import hep.dataforge.names.toName
import hep.dataforge.vision.Vision
@ -27,7 +27,7 @@ class SerializationTest {
x = 100
z = -100
}
val group = VisionGroup3D().apply {
val group = SolidGroup{
proxy("cube", cube)
proxyGroup("pg", "pg.content".toName()){
sphere(50){
@ -37,7 +37,8 @@ class SerializationTest {
}
val string = group.stringify()
println(string)
val reconstructed = VisionGroup3D.parseJson(string)
val reconstructed = SolidGroup.parseJson(string)
assertEquals(group["cube"]?.config, reconstructed["cube"]?.config)
}
}

View File

@ -0,0 +1,28 @@
package hep.dataforge.vision.solid
import hep.dataforge.context.Global
import hep.dataforge.meta.DFExperimental
import hep.dataforge.vision.get
import kotlin.test.Test
import kotlin.test.assertEquals
class SolidPluginTest {
val vision = SolidGroup {
box(100,100,100, name = "aBox")
sphere(100,name = "aSphere"){
z = 200
}
}
@DFExperimental
@Test
fun testPluginConverter(){
val plugin = Global.plugins.fetch(SolidManager).visionManager
val meta = plugin.writeVisionToMeta(vision)
val reconstructed = plugin.buildSpecificVision<SolidGroup>(meta)
assertEquals(vision["aBox"],reconstructed["aBox"])
}
}

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial
package hep.dataforge.vision.solid
import info.laht.threekt.math.Vector2

View File

@ -1,14 +1,14 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.boolean
import hep.dataforge.meta.node
import hep.dataforge.names.asName
import hep.dataforge.names.plus
import hep.dataforge.names.startsWith
import hep.dataforge.vision.spatial.Material3D
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.spatial.layer
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial
import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.solid.layer
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.EdgesGeometry
import info.laht.threekt.geometries.WireframeGeometry
@ -19,7 +19,7 @@ import kotlin.reflect.KClass
/**
* Basic geometry-based factory
*/
abstract class MeshThreeFactory<in T : Vision3D>(
abstract class MeshThreeFactory<in T : Solid>(
override val type: KClass<in T>
) : ThreeFactory<T> {
/**
@ -50,9 +50,9 @@ abstract class MeshThreeFactory<in T : Vision3D>(
}
//add listener to object properties
obj.onPropertyChange(this) { name, _, _ ->
obj.onPropertyChange(this) { name->
when {
name.startsWith(Vision3D.GEOMETRY_KEY) -> {
name.startsWith(Solid.GEOMETRY_KEY) -> {
val oldGeometry = mesh.geometry as BufferGeometry
val newGeometry = buildGeometry(obj)
oldGeometry.attributes = newGeometry.attributes
@ -73,13 +73,13 @@ abstract class MeshThreeFactory<in T : Vision3D>(
val WIREFRAME_KEY = "wireframe".asName()
val ENABLED_KEY = "enabled".asName()
val EDGES_ENABLED_KEY = EDGES_KEY + ENABLED_KEY
val EDGES_MATERIAL_KEY = EDGES_KEY + Material3D.MATERIAL_KEY
val EDGES_MATERIAL_KEY = EDGES_KEY + SolidMaterial.MATERIAL_KEY
val WIREFRAME_ENABLED_KEY = WIREFRAME_KEY + ENABLED_KEY
val WIREFRAME_MATERIAL_KEY = WIREFRAME_KEY + Material3D.MATERIAL_KEY
val WIREFRAME_MATERIAL_KEY = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY
}
}
fun Mesh.applyEdges(obj: Vision3D) {
fun Mesh.applyEdges(obj: Solid) {
children.find { it.name == "@edges" }?.let {
remove(it)
(it as LineSegments).dispose()
@ -99,7 +99,7 @@ fun Mesh.applyEdges(obj: Vision3D) {
}
}
fun Mesh.applyWireFrame(obj: Vision3D) {
fun Mesh.applyWireFrame(obj: Solid) {
children.find { it.name == "@wireframe" }?.let {
remove(it)
(it as LineSegments).dispose()

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.Box
import hep.dataforge.vision.spatial.detail
import hep.dataforge.vision.solid.Box
import hep.dataforge.vision.solid.detail
import info.laht.threekt.geometries.BoxBufferGeometry
object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) {

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.context.Context
import hep.dataforge.meta.Meta
@ -9,12 +9,12 @@ import hep.dataforge.names.plus
import hep.dataforge.names.toName
import hep.dataforge.output.Renderer
import hep.dataforge.vision.Colors
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.spatial.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.specifications.Controls
import hep.dataforge.vision.spatial.three.ThreeMaterials.HIGHLIGHT_MATERIAL
import hep.dataforge.vision.spatial.three.ThreeMaterials.SELECTED_MATERIAL
import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.solid.specifications.Controls
import hep.dataforge.vision.solid.three.ThreeMaterials.HIGHLIGHT_MATERIAL
import hep.dataforge.vision.solid.three.ThreeMaterials.SELECTED_MATERIAL
import info.laht.threekt.WebGLRenderer
import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.core.BufferGeometry
@ -41,11 +41,11 @@ import kotlin.math.sin
/**
*
*/
class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Canvas3DOptions) : Renderer<Vision3D> {
class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Canvas3DOptions) : Renderer<Solid> {
override val context: Context get() = three.context
var content: Vision3D? = null
var content: Solid? = null
private set
private var root: Object3D? = null
@ -172,7 +172,7 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
}
}
override fun render(obj: Vision3D, meta: Meta) {
override fun render(obj: Solid, meta: Meta) {
//clear old root
clear()
@ -244,5 +244,5 @@ class ThreeCanvas(element: HTMLElement, val three: ThreePlugin, val options: Can
fun ThreePlugin.output(element: HTMLElement, spec: Canvas3DOptions = Canvas3DOptions.empty()): ThreeCanvas =
ThreeCanvas(element, this, spec)
fun ThreePlugin.render(element: HTMLElement, obj: Vision3D, spec: Canvas3DOptions = Canvas3DOptions.empty()): Unit =
fun ThreePlugin.render(element: HTMLElement, obj: Solid, spec: Canvas3DOptions = Canvas3DOptions.empty()): Unit =
output(element, spec).render(obj)

View File

@ -1,9 +1,9 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.context.Context
import hep.dataforge.names.Name
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions
import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
import react.RBuilder
@ -15,7 +15,7 @@ import react.dom.findDOMNode
interface ThreeCanvasProps : RProps {
var context: Context
var obj: Vision3D
var obj: Solid
var options: Canvas3DOptions?
var selected: Name?
var clickCallback: (Name?) -> Unit
@ -61,7 +61,7 @@ class ThreeCanvasComponent : RComponent<ThreeCanvasProps, ThreeCanvasState>() {
}
}
fun RBuilder.threeCanvas(object3D: Vision3D, options: Canvas3DOptions.() -> Unit = {}) {
fun RBuilder.threeCanvas(object3D: Solid, options: Canvas3DOptions.() -> Unit = {}) {
child(ThreeCanvasComponent::class) {
attrs {
this.obj = object3D

View File

@ -1,8 +1,8 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.Label3D
import hep.dataforge.vision.spatial.color
import hep.dataforge.vision.spatial.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG
import hep.dataforge.vision.solid.SolidLabel
import hep.dataforge.vision.solid.color
import hep.dataforge.vision.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG
import info.laht.threekt.DoubleSide
import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.PlaneBufferGeometry
@ -19,10 +19,10 @@ import kotlin.reflect.KClass
/**
* Using example from http://stemkoski.github.io/Three.js/Texture-From-Canvas.html
*/
object ThreeCanvasLabelFactory : ThreeFactory<Label3D> {
override val type: KClass<in Label3D> get() = Label3D::class
object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
override val type: KClass<in SolidLabel> get() = SolidLabel::class
override fun invoke(obj: Label3D): Object3D {
override fun invoke(obj: SolidLabel): Object3D {
val canvas = document.createElement("canvas") as HTMLCanvasElement
val context = canvas.getContext("2d") as CanvasRenderingContext2D
context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}"

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.Composite
import hep.dataforge.vision.spatial.CompositeType
import hep.dataforge.vision.solid.Composite
import hep.dataforge.vision.solid.CompositeType
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.objects.Mesh

View File

@ -1,6 +1,6 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.Convex
import hep.dataforge.vision.solid.Convex
import info.laht.threekt.external.geometries.ConvexBufferGeometry
import info.laht.threekt.math.Vector3

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.ConeSegment
import hep.dataforge.vision.spatial.detail
import hep.dataforge.vision.solid.ConeSegment
import hep.dataforge.vision.solid.detail
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.CylinderBufferGeometry
import kotlin.math.PI

View File

@ -1,13 +1,13 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.names.Name
import hep.dataforge.names.startsWith
import hep.dataforge.provider.Type
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_KEY
import hep.dataforge.vision.spatial.three.ThreeFactory.Companion.TYPE
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial
import hep.dataforge.vision.solid.*
import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D
import info.laht.threekt.objects.Mesh
@ -33,7 +33,7 @@ interface ThreeFactory<in T : Vision> {
*/
fun Object3D.updatePosition(obj: Vision) {
visible = obj.visible ?: true
if(obj is Vision3D) {
if(obj is Solid) {
position.set(obj.x, obj.y, obj.z)
setRotationFromEuler(obj.euler)
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ)
@ -60,13 +60,13 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) {
if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
this.material = getMaterial(source)
} else if (
propertyName.startsWith(Vision3D.POSITION_KEY)
|| propertyName.startsWith(Vision3D.ROTATION)
|| propertyName.startsWith(Vision3D.SCALE_KEY)
propertyName.startsWith(Solid.POSITION_KEY)
|| propertyName.startsWith(Solid.ROTATION)
|| propertyName.startsWith(Solid.SCALE_KEY)
) {
//update position of mesh using this object
updatePosition(source)
} else if (propertyName == Vision3D.VISIBLE_KEY) {
} else if (propertyName == Solid.VISIBLE_KEY) {
visible = source.visible ?: true
}
}
@ -74,8 +74,8 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) {
/**
* Generic factory for elements which provide inside geometry builder
*/
object ThreeShapeFactory : MeshThreeFactory<Shape>(Shape::class) {
override fun buildGeometry(obj: Shape): BufferGeometry {
object ThreeShapeFactory : MeshThreeFactory<GeometrySolid>(GeometrySolid::class) {
override fun buildGeometry(obj: GeometrySolid): BufferGeometry {
return obj.run {
ThreeGeometryBuilder().apply { toGeometry(this) }.build()
}

View File

@ -1,10 +1,10 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.Meta
import hep.dataforge.meta.get
import hep.dataforge.meta.int
import hep.dataforge.vision.spatial.GeometryBuilder
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.solid.GeometryBuilder
import hep.dataforge.vision.solid.Point3D
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Face3
import info.laht.threekt.core.Geometry

View File

@ -0,0 +1,31 @@
package hep.dataforge.vision.solid.three
import hep.dataforge.js.jsObject
import hep.dataforge.vision.solid.SolidLabel
import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.TextBufferGeometry
import info.laht.threekt.objects.Mesh
import kotlin.reflect.KClass
/**
*
*/
object ThreeLabelFactory : ThreeFactory<SolidLabel> {
override val type: KClass<in SolidLabel> get() = SolidLabel::class
override fun invoke(obj: SolidLabel): Object3D {
val textGeo = TextBufferGeometry(obj.text, jsObject {
font = obj.fontFamily
size = 20
height = 1
curveSegments = 1
})
return Mesh(textGeo, getMaterial(obj)).apply {
updatePosition(obj)
obj.onPropertyChange(this@ThreeLabelFactory) { _ ->
//TODO
}
}
}
}

View File

@ -1,9 +1,9 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.node
import hep.dataforge.vision.spatial.PolyLine
import hep.dataforge.vision.spatial.color
import hep.dataforge.vision.spatial.three.ThreeMaterials.DEFAULT_LINE_COLOR
import hep.dataforge.vision.solid.PolyLine
import hep.dataforge.vision.solid.color
import hep.dataforge.vision.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR
import info.laht.threekt.core.Geometry
import info.laht.threekt.core.Object3D
import info.laht.threekt.math.Color
@ -27,7 +27,7 @@ object ThreeLineFactory : ThreeFactory<PolyLine> {
updatePosition(obj)
//layers.enable(obj.layer)
//add listener to object properties
obj.onPropertyChange(this) { propertyName, _, _ ->
obj.onPropertyChange(this) { propertyName->
updateProperty(obj, propertyName)
}
}

View File

@ -1,10 +1,10 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.*
import hep.dataforge.values.ValueType
import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.Material3D
import hep.dataforge.vision.solid.SolidMaterial
import info.laht.threekt.materials.LineBasicMaterial
import info.laht.threekt.materials.Material
import info.laht.threekt.materials.MeshBasicMaterial
@ -36,30 +36,30 @@ object ThreeMaterials {
fun getLineMaterial(meta: Meta?): LineBasicMaterial {
if (meta == null) return DEFAULT_LINE
return LineBasicMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_LINE_COLOR
opacity = meta[Material3D.OPACITY_KEY].double ?: 1.0
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_LINE_COLOR
opacity = meta[SolidMaterial.OPACITY_KEY].double ?: 1.0
transparent = opacity < 1.0
linewidth = meta["thickness"].double ?: 1.0
}
}
fun getMaterial(vision3D: Vision): Material {
val meta = vision3D.getItem(Material3D.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT
return if (meta[Material3D.SPECULAR_COLOR_KEY] != null) {
val meta = vision3D.getItem(SolidMaterial.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT
return if (meta[SolidMaterial.SPECULAR_COLOR_KEY] != null) {
MeshPhongMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
specular = meta[Material3D.SPECULAR_COLOR_KEY]!!.getColor()
opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
specular = meta[SolidMaterial.SPECULAR_COLOR_KEY]!!.getColor()
opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
transparent = opacity < 1.0
wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
needsUpdate = true
}
} else {
MeshBasicMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0
color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
transparent = opacity < 1.0
wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false
wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
needsUpdate = true
}
}

View File

@ -1,10 +1,10 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.context.*
import hep.dataforge.meta.Meta
import hep.dataforge.names.*
import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.solid.*
import info.laht.threekt.core.Object3D
import kotlin.collections.set
import kotlin.reflect.KClass
@ -13,7 +13,7 @@ import info.laht.threekt.objects.Group as ThreeGroup
class ThreePlugin : AbstractPlugin() {
override val tag: PluginTag get() = Companion.tag
private val objectFactories = HashMap<KClass<out Vision3D>, ThreeFactory<*>>()
private val objectFactories = HashMap<KClass<out Solid>, ThreeFactory<*>>()
private val compositeFactory = ThreeCompositeFactory(this)
private val proxyFactory = ThreeProxyFactory(this)
@ -24,24 +24,24 @@ class ThreePlugin : AbstractPlugin() {
objectFactories[Sphere::class] = ThreeSphereFactory
objectFactories[ConeSegment::class] = ThreeCylinderFactory
objectFactories[PolyLine::class] = ThreeLineFactory
objectFactories[Label3D::class] = ThreeCanvasLabelFactory
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
}
@Suppress("UNCHECKED_CAST")
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Vision3D>? {
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? {
return (objectFactories[type]
?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == type })
as ThreeFactory<Vision3D>?
as ThreeFactory<Solid>?
}
fun buildObject3D(obj: Vision3D): Object3D {
fun buildObject3D(obj: Solid): Object3D {
return when (obj) {
is ThreeVision -> obj.toObject3D()
is Proxy -> proxyFactory(obj)
is VisionGroup3D -> {
is SolidGroup -> {
val group = ThreeGroup()
obj.children.forEach { (token, child) ->
if (child is Vision3D && child.ignore != true) {
if (child is Solid && child.ignore != true) {
try {
val object3D = buildObject3D(child)
group[token] = object3D
@ -55,15 +55,15 @@ class ThreePlugin : AbstractPlugin() {
updatePosition(obj)
//obj.onChildrenChange()
obj.onPropertyChange(this) { name, _, _ ->
obj.onPropertyChange(this) { name->
if (
name.startsWith(Vision3D.POSITION_KEY) ||
name.startsWith(Vision3D.ROTATION) ||
name.startsWith(Vision3D.SCALE_KEY)
name.startsWith(Solid.POSITION_KEY) ||
name.startsWith(Solid.ROTATION) ||
name.startsWith(Solid.SCALE_KEY)
) {
//update position of mesh using this object
updatePosition(obj)
} else if (name == Vision3D.VISIBLE_KEY) {
} else if (name == Solid.VISIBLE_KEY) {
visible = obj.visible ?: true
}
}
@ -83,7 +83,7 @@ class ThreePlugin : AbstractPlugin() {
}
//adding new object
if (child != null && child is Vision3D) {
if (child != null && child is Solid) {
try {
val object3D = buildObject3D(child)
set(name, object3D)
@ -97,10 +97,10 @@ class ThreePlugin : AbstractPlugin() {
is Composite -> compositeFactory(obj)
else -> {
//find specialized factory for this type if it is present
val factory: ThreeFactory<Vision3D>? = findObjectFactory(obj::class)
val factory: ThreeFactory<Solid>? = findObjectFactory(obj::class)
when {
factory != null -> factory(obj)
obj is Shape -> ThreeShapeFactory(obj)
obj is GeometrySolid -> ThreeShapeFactory(obj)
else -> error("Renderer for ${obj::class} not found")
}
}

View File

@ -1,13 +1,13 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.names.toName
import hep.dataforge.vision.spatial.Proxy
import hep.dataforge.vision.spatial.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.solid.Proxy
import hep.dataforge.vision.solid.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
import hep.dataforge.vision.solid.Solid
import info.laht.threekt.core.Object3D
class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
private val cache = HashMap<Vision3D, Object3D>()
private val cache = HashMap<Solid, Object3D>()
override val type = Proxy::class
@ -21,7 +21,7 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
val object3D = cachedObject.clone()
object3D.updatePosition(obj)
obj.onPropertyChange(this) { name, _, _ ->
obj.onPropertyChange(this) { name->
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
val propertyName = name.cutFirst()

View File

@ -1,7 +1,7 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.vision.spatial.Sphere
import hep.dataforge.vision.spatial.detail
import hep.dataforge.vision.solid.Sphere
import hep.dataforge.vision.solid.detail
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.SphereBufferGeometry

View File

@ -1,12 +1,12 @@
@file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision
import hep.dataforge.vision.spatial.Point3D
import hep.dataforge.vision.spatial.Point3DSerializer
import hep.dataforge.vision.spatial.Vision3D
import hep.dataforge.vision.solid.Point3D
import hep.dataforge.vision.solid.Point3DSerializer
import hep.dataforge.vision.solid.Solid
import info.laht.threekt.core.Object3D
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
@ -14,18 +14,18 @@ import kotlinx.serialization.UseSerializers
/**
* A custom visual object that has its own Three.js renderer
*/
interface ThreeVision : Vision3D {
interface ThreeVision : Solid {
fun toObject3D(): Object3D
}
@Serializable
class CustomThreeVision(val threeFactory: ThreeFactory<Vision3D>) : AbstractVision(),
class CustomThreeVision(val threeFactory: ThreeFactory<Solid>) : AbstractVision(),
ThreeVision {
override var position: Point3D? = null
override var rotation: Point3D? = null
override var scale: Point3D? = null
override var ownProperties: Config? = null
override var properties: Config? = null
override fun toObject3D(): Object3D = threeFactory(this)

View File

@ -9,7 +9,7 @@
"NESTED_CLASS_IN_EXTERNAL_INTERFACE"
)
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import info.laht.threekt.math.Matrix4

View File

@ -1,10 +1,10 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.js.requireJS
import hep.dataforge.vision.bootstrap.accordion
import hep.dataforge.vision.bootstrap.entry
import hep.dataforge.vision.spatial.SpatialVisionManager
import hep.dataforge.vision.spatial.VisionGroup3D
import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.solid.SolidManager
import kotlinx.html.*
import kotlinx.html.dom.append
import kotlinx.html.js.onChangeFunction
@ -52,9 +52,9 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
+"Export"
attrs {
onClickFunction = {
val json = (canvas.content as? VisionGroup3D)?.let { group ->
SpatialVisionManager.json.stringify(
VisionGroup3D.serializer(),
val json = (canvas.content as? SolidGroup)?.let { group ->
SolidManager.jsonForSolids.stringify(
SolidGroup.serializer(),
group
)
}
@ -116,9 +116,9 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
button {
+"Export"
onClickFunction = {
val json = (canvas.content as? VisionGroup3D)?.let { group ->
SpatialVisionManager.json.stringify(
VisionGroup3D.serializer(),
val json = (canvas.content as? SolidGroup)?.let { group ->
SolidManager.jsonForSolids.stringify(
SolidGroup.serializer(),
group
)
}

View File

@ -1,10 +1,10 @@
package hep.dataforge.vision.spatial.three
package hep.dataforge.vision.solid.three
import hep.dataforge.meta.MetaItem
import hep.dataforge.meta.float
import hep.dataforge.meta.get
import hep.dataforge.meta.node
import hep.dataforge.vision.spatial.*
import hep.dataforge.vision.solid.*
import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.DirectGeometry
import info.laht.threekt.core.Face3
@ -17,7 +17,7 @@ import info.laht.threekt.objects.Mesh
import info.laht.threekt.textures.Texture
import kotlin.math.PI
val Vision3D.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
val Solid.euler get() = Euler(rotationX, rotationY, rotationZ, rotationOrder.name)
val MetaItem<*>.vector get() = Vector3(node["x"].float ?: 0f, node["y"].float ?: 0f, node["z"].float ?: 0f)

Some files were not shown because too many files have changed in this diff Show More