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 { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
implementation(project(":visionforge-spatial")) implementation(project(":visionforge-solid"))
implementation(project(":visionforge-gdml")) 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.* 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.setItem
import hep.dataforge.meta.string import hep.dataforge.meta.string
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vision.spatial.Material3D import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.spatial.gdml.demo.cubes import hep.dataforge.vision.solid.gdml.demo.cubes
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -14,7 +14,7 @@ class GDMLVisualTest {
fun testPrototypeProperty() { fun testPrototypeProperty() {
val gdml = cubes() val gdml = cubes()
val visual = gdml.toVision() val visual = gdml.toVision()
visual["composite000.segment0".toName()]?.setItem(Material3D.MATERIAL_COLOR_KEY, "red".asValue()) visual["composite000.segment0".toName()]?.setItem(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
assertEquals("red", visual["composite000.segment0".toName()]?.getItem(Material3D.MATERIAL_COLOR_KEY).string) 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.context.Context
import hep.dataforge.names.Name 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.configEditor
import hep.dataforge.vision.react.flexColumn import hep.dataforge.vision.react.flexColumn
import hep.dataforge.vision.react.state import hep.dataforge.vision.react.state
import hep.dataforge.vision.spatial.Vision3D import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.spatial.VisionGroup3D import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.spatial.gdml.toVision import hep.dataforge.vision.solid.gdml.toVision
import hep.dataforge.vision.spatial.specifications.Camera import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.three.ThreeCanvas import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreeCanvasComponent import hep.dataforge.vision.solid.three.ThreeCanvasComponent
import hep.dataforge.vision.spatial.three.canvasControls import hep.dataforge.vision.solid.three.canvasControls
import kotlinx.css.FlexBasis import kotlinx.css.FlexBasis
import kotlinx.css.Overflow import kotlinx.css.Overflow
import kotlinx.css.flex import kotlinx.css.flex
@ -62,7 +62,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
val gdml = GDML.parse(data) val gdml = GDML.parse(data)
gdml.toVision(gdmlConfiguration) gdml.toVision(gdmlConfiguration)
} }
name.endsWith(".json") -> VisionGroup3D.parseJson(data) name.endsWith(".json") -> SolidGroup.parseJson(data)
else -> { else -> {
window.alert("File extension is not recognized: $name") window.alert("File extension is not recognized: $name")
error("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") { gridColumn(6, maxSize= GridMaxSize.XL, classes = "order-1 order-xl-2") {
//canvas //canvas
(visual as? Vision3D)?.let { visual3D -> (visual as? Solid)?.let { visual3D ->
child(ThreeCanvasComponent::class) { child(ThreeCanvasComponent::class) {
attrs { attrs {
this.context = props.context this.context = props.context
@ -143,7 +143,7 @@ val GDMLApp = component<GDMLAppProps> { props ->
else -> (visual as? VisionGroup)?.get(selected) else -> (visual as? VisionGroup)?.get(selected)
} }
if (selectedObject != null) { 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.context.Global
import hep.dataforge.js.Application import hep.dataforge.js.Application
import hep.dataforge.js.startApplication import hep.dataforge.js.startApplication
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vision.spatial.gdml.GDMLTransformer import hep.dataforge.vision.solid.gdml.GDMLTransformer
import hep.dataforge.vision.spatial.gdml.LUnit import hep.dataforge.vision.solid.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.toVision import hep.dataforge.vision.solid.gdml.toVision
import kotlinx.css.* import kotlinx.css.*
import react.child import react.child
import react.dom.render 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 drop.FileDrop
import kotlinx.css.* 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.context.Global
import hep.dataforge.vision.editor.VisualObjectEditorFragment import hep.dataforge.vision.editor.VisualObjectEditorFragment
import hep.dataforge.vision.editor.VisualObjectTreeFragment import hep.dataforge.vision.editor.VisualObjectTreeFragment
import hep.dataforge.vision.spatial.Material3D import hep.dataforge.vision.solid.SolidManager
import hep.dataforge.vision.spatial.SpatialVisionManager import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.spatial.fx.FX3DPlugin import hep.dataforge.vision.solid.fx.FX3DPlugin
import hep.dataforge.vision.spatial.fx.FXCanvas3D import hep.dataforge.vision.solid.fx.FXCanvas3D
import hep.dataforge.vision.spatial.gdml.toVision import hep.dataforge.vision.solid.gdml.toVision
import javafx.geometry.Orientation import javafx.geometry.Orientation
import javafx.scene.Parent import javafx.scene.Parent
import javafx.stage.FileChooser import javafx.stage.FileChooser
@ -24,9 +24,9 @@ class GDMLView : View() {
} }
private val propertyEditor = VisualObjectEditorFragment { private val propertyEditor = VisualObjectEditorFragment {
it.properties() it.getAllProperties()
}.apply { }.apply {
descriptorProperty.set(Material3D.descriptor) descriptorProperty.set(SolidMaterial.descriptor)
itemProperty.bind(treeFragment.selectedProperty) itemProperty.bind(treeFragment.selectedProperty)
} }
@ -39,7 +39,7 @@ class GDMLView : View() {
runAsync { runAsync {
val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull() val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull()
?: return@runAsync null ?: return@runAsync null
SpatialVisionManager.readFile(file) SolidManager.readFile(file)
} ui { } ui {
if (it != null) { if (it != null) {
canvas.render(it) 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.meta.setItem
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vision.spatial.Material3D import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.spatial.SpatialVisionManager import hep.dataforge.vision.solid.SolidManager
import hep.dataforge.vision.spatial.VisionGroup3D import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.spatial.gdml.LUnit import hep.dataforge.vision.solid.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.readFile import hep.dataforge.vision.solid.gdml.readFile
import hep.dataforge.vision.spatial.gdml.toVision import hep.dataforge.vision.solid.gdml.toVision
import scientifik.gdml.GDML import scientifik.gdml.GDML
import java.io.File import java.io.File
import java.util.zip.GZIPInputStream import java.util.zip.GZIPInputStream
import java.util.zip.ZipInputStream 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" -> { file.extension == "gdml" || file.extension == "xml" -> {
GDML.readFile(file.toPath()).toVision { GDML.readFile(file.toPath()).toVision {
lUnit = LUnit.CM lUnit = LUnit.CM
solidConfiguration = { parent, solid -> solidConfiguration = { parent, solid ->
if (solid.name == "cave") { if (solid.name == "cave") {
setItem(Material3D.MATERIAL_WIREFRAME_KEY, true.asValue()) setItem(SolidMaterial.MATERIAL_WIREFRAME_KEY, true.asValue())
} }
if (parent.physVolumes.isNotEmpty()) { if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") { 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.name.endsWith("json.zip") -> {
file.inputStream().use { file.inputStream().use {
val unzip = ZipInputStream(it, Charsets.UTF_8) val unzip = ZipInputStream(it, Charsets.UTF_8)
val text = unzip.readBytes().decodeToString() val text = unzip.readBytes().decodeToString()
VisionGroup3D.parseJson(text) SolidGroup.parseJson(text)
} }
} }
file.name.endsWith("json.gz") -> { file.name.endsWith("json.gz") -> {
file.inputStream().use { file.inputStream().use {
val unzip = GZIPInputStream(it) val unzip = GZIPInputStream(it)
val text = unzip.readBytes().decodeToString() val text = unzip.readBytes().decodeToString()
VisionGroup3D.parseJson(text) SolidGroup.parseJson(text)
} }
} }
else -> error("Unknown extension ${file.extension}") 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.solid.gdml.LUnit
import hep.dataforge.vision.spatial.gdml.readFile import hep.dataforge.vision.solid.gdml.readFile
import hep.dataforge.vision.spatial.gdml.toVision import hep.dataforge.vision.solid.gdml.toVision
import hep.dataforge.vision.spatial.stringify import hep.dataforge.vision.solid.stringify
import scientifik.gdml.GDML import scientifik.gdml.GDML
import java.io.File import java.io.File
import java.nio.file.Paths 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 hep.dataforge.names.asName
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
@ -9,7 +9,7 @@ class FileSerializationTest {
@Ignore @Ignore
fun testFileRead(){ fun testFileRead(){
val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString() val text = this::class.java.getResourceAsStream("/cubes.json").readBytes().decodeToString()
val visual = VisionGroup3D.parseJson(text) val visual = SolidGroup.parseJson(text)
visual["composite_001".asName()] visual["composite_001".asName()]
} }
} }

View File

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

View File

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

View File

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

View File

@ -1,7 +1,7 @@
package ru.mipt.npm.muon.monitor package ru.mipt.npm.muon.monitor
import hep.dataforge.vision.spatial.Point3D import hep.dataforge.vision.solid.Point3D
import hep.dataforge.vision.spatial.plus import hep.dataforge.vision.solid.plus
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_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.component
import hep.dataforge.vision.react.configEditor import hep.dataforge.vision.react.configEditor
import hep.dataforge.vision.react.state import hep.dataforge.vision.react.state
import hep.dataforge.vision.spatial.specifications.Camera import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.three.ThreeCanvas import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreeCanvasComponent import hep.dataforge.vision.solid.three.ThreeCanvasComponent
import hep.dataforge.vision.spatial.three.canvasControls import hep.dataforge.vision.solid.three.canvasControls
import io.ktor.client.HttpClient import io.ktor.client.HttpClient
import io.ktor.client.request.get import io.ktor.client.request.get
import kotlinx.coroutines.GlobalScope import kotlinx.coroutines.GlobalScope
@ -155,7 +155,7 @@ val MMApp = component<MMAppProps> { props ->
else -> visual[selected] else -> visual[selected]
} }
if (selectedObject != null) { 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.context.Global
import hep.dataforge.js.Application import hep.dataforge.js.Application
import hep.dataforge.js.startApplication 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.HttpClient
import io.ktor.client.features.json.JsonFeature import io.ktor.client.features.json.JsonFeature
import io.ktor.client.features.json.serializer.KotlinxSerializer import io.ktor.client.features.json.serializer.KotlinxSerializer
@ -19,7 +19,7 @@ private class MMDemoApp : Application {
private val connection = HttpClient { private val connection = HttpClient {
install(JsonFeature) { 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 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.Application
import io.ktor.application.call import io.ktor.application.call
import io.ktor.application.install import io.ktor.application.install
@ -36,7 +36,7 @@ fun Application.module() {
install(DefaultHeaders) install(DefaultHeaders)
install(CallLogging) install(CallLogging)
install(ContentNegotiation) { install(ContentNegotiation) {
json(module = SpatialVisionManager.serialModule) json(module = SolidManager.serialModule)
} }
install(Routing) { install(Routing) {
get("/event") { get("/event") {

View File

@ -1,6 +1,6 @@
package ru.mipt.npm.muon.monitor.sim 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.Line
import org.apache.commons.math3.geometry.euclidean.threed.Plane import org.apache.commons.math3.geometry.euclidean.threed.Plane
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D import org.apache.commons.math3.geometry.euclidean.threed.Vector3D

View File

@ -19,7 +19,7 @@ kotlin {
sourceSets { sourceSets {
commonMain { commonMain {
dependencies { dependencies {
api(project(":visionforge-spatial")) api(project(":visionforge-solid"))
api(project(":visionforge-gdml")) api(project(":visionforge-gdml"))
} }
} }
@ -27,5 +27,5 @@ kotlin {
} }
application { 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.Meta
import hep.dataforge.meta.invoke import hep.dataforge.meta.invoke
@ -6,8 +6,8 @@ import hep.dataforge.names.toName
import hep.dataforge.output.OutputManager import hep.dataforge.output.OutputManager
import hep.dataforge.vision.Colors import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.cos import kotlin.math.cos
@ -15,7 +15,7 @@ import kotlin.math.sin
import kotlin.random.Random 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 { val meta = Meta {
"title" put title "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.Application
import hep.dataforge.js.startApplication 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.context.Global
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
@ -8,9 +8,9 @@ import hep.dataforge.names.Name
import hep.dataforge.output.OutputManager import hep.dataforge.output.OutputManager
import hep.dataforge.output.Renderer import hep.dataforge.output.Renderer
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.three.ThreeCanvas import hep.dataforge.vision.solid.three.ThreeCanvas
import hep.dataforge.vision.spatial.three.ThreePlugin import hep.dataforge.vision.solid.three.ThreePlugin
import hep.dataforge.vision.spatial.three.output import hep.dataforge.vision.solid.three.output
import kotlinx.html.dom.append import kotlinx.html.dom.append
import kotlinx.html.dom.create import kotlinx.html.dom.create
import kotlinx.html.h2 import kotlinx.html.h2

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class) @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.int
import hep.dataforge.meta.number import hep.dataforge.meta.number
@ -10,11 +10,11 @@ import hep.dataforge.names.startsWith
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vision.getProperty import hep.dataforge.vision.getProperty
import hep.dataforge.vision.set import hep.dataforge.vision.set
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import hep.dataforge.vision.spatial.Vision3D.Companion.GEOMETRY_KEY import hep.dataforge.vision.solid.Solid.Companion.GEOMETRY_KEY
import hep.dataforge.vision.spatial.demo.VariableBoxThreeFactory.Z_SIZE_KEY import hep.dataforge.vision.solid.demo.VariableBoxThreeFactory.Z_SIZE_KEY
import hep.dataforge.vision.spatial.three.* import hep.dataforge.vision.solid.three.*
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.BoxBufferGeometry import info.laht.threekt.geometries.BoxBufferGeometry
@ -23,13 +23,13 @@ import kotlinx.serialization.UseSerializers
import kotlin.math.max import kotlin.math.max
import kotlin.reflect.KClass import kotlin.reflect.KClass
internal var Vision3D.variableZSize: Number internal var Solid.variableZSize: Number
get() = getProperty(Z_SIZE_KEY, false).number ?: 0f get() = getProperty(Z_SIZE_KEY, false).number ?: 0f
set(value) { set(value) {
setItem(Z_SIZE_KEY, value.asValue()) setItem(Z_SIZE_KEY, value.asValue())
} }
internal var Vision3D.value: Int internal var Solid.value: Int
get() = getProperty("value", false).int ?: 0 get() = getProperty("value", false).int ?: 0
set(value) { set(value) {
setItem("value", value.asValue()) setItem("value", value.asValue())
@ -43,26 +43,26 @@ internal var Vision3D.value: Int
color(r.toUByte(), g.toUByte(), b.toUByte()) color(r.toUByte(), g.toUByte(), b.toUByte())
} }
fun VisionGroup3D.varBox( fun SolidGroup.varBox(
xSize: Number, xSize: Number,
ySize: Number, ySize: Number,
zSize: Number, zSize: Number,
name: String = "", name: String = "",
action: Vision3D.() -> Unit = {} action: Solid.() -> Unit = {}
) = CustomThreeVision(VariableBoxThreeFactory).apply { ) = CustomThreeVision(VariableBoxThreeFactory).apply {
scaleX = xSize scaleX = xSize
scaleY = ySize scaleY = ySize
scaleZ = zSize scaleZ = zSize
}.apply(action).also { set(name, it) } }.apply(action).also { set(name, it) }
private object VariableBoxThreeFactory : ThreeFactory<Vision3D> { private object VariableBoxThreeFactory : ThreeFactory<Solid> {
val X_SIZE_KEY = GEOMETRY_KEY + "xSize" val X_SIZE_KEY = GEOMETRY_KEY + "xSize"
val Y_SIZE_KEY = GEOMETRY_KEY + "ySize" val Y_SIZE_KEY = GEOMETRY_KEY + "ySize"
val Z_SIZE_KEY = GEOMETRY_KEY + "zSize" 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 xSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0
val ySize = obj.getProperty(Y_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 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) mesh.scale.set(xSize, ySize, zSize)
//add listener to object properties //add listener to object properties
obj.onPropertyChange(this) { name, _, _ -> obj.onPropertyChange(this) { name ->
when { when {
// name.startsWith(GEOMETRY_KEY) -> { // name.startsWith(GEOMETRY_KEY) -> {
// val newXSize = obj.getProperty(X_SIZE_KEY, false).number?.toDouble() ?: 1.0 // 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 javafx.stage.Stage
import tornadofx.* import tornadofx.*
import java.nio.file.Paths 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.context.Global
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
@ -6,8 +6,8 @@ import hep.dataforge.names.Name
import hep.dataforge.output.OutputManager import hep.dataforge.output.OutputManager
import hep.dataforge.output.Renderer import hep.dataforge.output.Renderer
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.fx.FX3DPlugin import hep.dataforge.vision.solid.fx.FX3DPlugin
import hep.dataforge.vision.spatial.fx.FXCanvas3D import hep.dataforge.vision.solid.fx.FXCanvas3D
import javafx.collections.FXCollections import javafx.collections.FXCollections
import javafx.scene.Parent import javafx.scene.Parent
import javafx.scene.control.Tab import javafx.scene.control.Tab

View File

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

View File

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

View File

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

View File

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

View File

@ -1,6 +1,5 @@
package hep.dataforge.vision package hep.dataforge.vision
import hep.dataforge.meta.MetaItem
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.NameToken import hep.dataforge.names.NameToken
import hep.dataforge.names.asName import hep.dataforge.names.asName
@ -31,10 +30,10 @@ abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup {
res.block() res.block()
} }
override fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?) { override fun propertyChanged(name: Name) {
super.propertyChanged(name, before, after) super.propertyChanged(name)
for(obj in this) { 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 override var styleSheet: StyleSheet? = null
//FIXME to be lifted to AbstractVisualGroup after https://github.com/Kotlin/kotlinx.serialization/issues/378 is fixed //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") @SerialName("children")
private val _children = HashMap<NameToken, Vision>() private val _children = HashMap<NameToken, Vision>()

View File

@ -5,6 +5,7 @@ package hep.dataforge.vision
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.values.asValue
import kotlinx.serialization.* import kotlinx.serialization.*
import kotlinx.serialization.builtins.MapSerializer import kotlinx.serialization.builtins.MapSerializer
import kotlinx.serialization.builtins.serializer 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 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? { operator fun get(key: String): Meta? {
return styleMap[key] ?: owner?.parent?.styleSheet?.get(key) 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 * List of names of styles applied to this object. Order matters. Not inherited
val tokens: Collection<Name> = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet())) */
.map { it.asName() } var Vision.styles: List<String>
tokens.forEach { parent?.propertyChanged(it, oldStyle?.get(it), newStyle?.get(it)) } get() = getItem(Vision.STYLE_KEY).stringList
} set(value) {
if (this is VisionGroup) { setItem(Vision.STYLE_KEY,value.map { it.asValue() }.asValue())
for (obj in this) {
obj.styleChanged(key, oldStyle, newStyle)
}
} }
/**
* 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 * 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<*>? 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 * Trigger property invalidation event. If [name] is empty, notify that the whole object is changed
*/ */
fun propertyChanged(name: Name, before: MetaItem<*>?, after: MetaItem<*>?): Unit fun propertyChanged(name: Name): Unit
/**
* Send a signal that property value should be reevaluated
*/
fun propertyInvalidated(name: Name) = propertyChanged(name, null, null)
/** /**
* Add listener triggering on property change * 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. * Remove change listeners with given owner.
*/ */
fun removeChangeListener(owner: Any?) fun removeChangeListener(owner: Any?)
/**
* List of names of styles applied to this object. Order matters. Not inherited
*/
var styles: List<String>
companion object { companion object {
const val TYPE = "visual" const val TYPE = "visual"
val STYLE_KEY = "@style".asName() val STYLE_KEY = "@style".asName()
@ -81,13 +71,8 @@ fun Vision.getProperty(key: String, inherit: Boolean = true): MetaItem<*>? =
getProperty(key.toName(), inherit) 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) { tailrec fun Vision.resolveStyle(name: String): Meta? =
styles = styles + name (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, * 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? val styleSheet: StyleSheet?

View File

@ -1,39 +1,127 @@
package hep.dataforge.vision package hep.dataforge.vision
import hep.dataforge.context.* 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 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) { class VisionManager(meta: Meta) : AbstractPlugin(meta) {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
/** /**
* Create a list of factories on first call and cache it * Create a list of factories on first call and cache it
*/ */
private val factories by lazy { private val forms by lazy {
context.content<VisionFactory<*>>(VISION_FACTORY_TYPE).mapKeys { it.value.type } context.content<VisionForm<*>>(VisionForm.TYPE).mapKeys { it.value.type }
}
val visionSerialModule
get() = SerializersModule {
include(defaultSerialModule)
context.content<SerialModule>(VISION_SERIAL_MODULE_TARGET).values.forEach {
include(it)
}
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
fun <T : Vision> resolveVisionFactory(type: KClass<out T>): VisionFactory<T>? = fun <T : Vision> resolveVisionForm(type: KClass<out T>): VisionForm<T>? =
factories[type] as VisionFactory<T> forms[type] as VisionForm<T>
inline fun <reified T : Vision> buildVision(parent: VisionGroup?, meta: Meta): T? { inline fun <reified T : Vision> buildSpecificVision(meta: Meta): T {
return resolveVisionFactory(T::class)?.invoke(meta, context)?.apply { val factory = resolveVisionForm(T::class) ?: error("Could not resolve a form for ${meta["type"].string}")
this.parent = parent 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> { companion object : PluginFactory<VisionManager> {
override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP) override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP)
override val type: KClass<out VisionManager> = VisionManager::class 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) 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.descriptors.NodeDescriptor
import hep.dataforge.meta.update import hep.dataforge.meta.update
import hep.dataforge.vision.Vision 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.binding.Binding
import javafx.beans.property.SimpleObjectProperty import javafx.beans.property.SimpleObjectProperty
import javafx.scene.Node import javafx.scene.Node
@ -54,7 +55,7 @@ class VisualObjectEditorFragment(val selector: (Vision) -> Meta) : Fragment() {
private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() { private val styleBoxProperty: Binding<Node?> = configProperty.objectBinding() {
VBox().apply { VBox().apply {
item?.styles?.forEach { styleName -> item?.styles?.forEach { styleName ->
val styleMeta = item?.findStyle(styleName) val styleMeta = item?.resolveStyle(styleName)
if (styleMeta != null) { if (styleMeta != null) {
titledpane(styleName, node = MetaViewer(styleMeta).root) titledpane(styleName, node = MetaViewer(styleMeta).root)
} }

View File

@ -6,7 +6,7 @@ kotlin {
sourceSets { sourceSets {
val commonMain by getting { val commonMain by getting {
dependencies { dependencies {
api(project(":visionforge-spatial")) api(project(":visionforge-solid"))
api("scientifik:gdml:0.1.8") 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.Meta
import hep.dataforge.meta.MetaBuilder import hep.dataforge.meta.MetaBuilder
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_COLOR_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.useStyle import hep.dataforge.vision.useStyle
import scientifik.gdml.* import scientifik.gdml.*
import kotlin.random.Random import kotlin.random.Random
@ -24,7 +24,7 @@ class GDMLTransformer(val root: GDML) {
/** /**
* A special group for local templates * A special group for local templates
*/ */
val proto by lazy { VisionGroup3D() } val proto by lazy { SolidGroup() }
private val styleCache = HashMap<Name, Meta>() private val styleCache = HashMap<Name, Meta>()
var lUnit: LUnit = LUnit.MM var lUnit: LUnit = LUnit.MM
@ -33,23 +33,23 @@ class GDMLTransformer(val root: GDML) {
var volumeAction: (GDMLGroup) -> Action = { Action.CACHE } 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 lUnit = LUnit.CM
if (parent.physVolumes.isNotEmpty()) { if (parent.physVolumes.isNotEmpty()) {
useStyle("opaque") { 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()) { styleCache.getOrPut(name.toName()) {
Meta(builder) Meta(builder)
} }
useStyle(name) 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 material = parent.materialref.resolve(root) ?: GDMLElement(parent.materialref.ref)
val styleName = "material[${material.name}]" val styleName = "material[${material.name}]"
@ -68,7 +68,7 @@ class GDMLTransformer(val root: GDML) {
var onFinish: GDMLTransformer.() -> Unit = {} var onFinish: GDMLTransformer.() -> Unit = {}
internal fun finalize(final: VisionGroup3D): VisionGroup3D { internal fun finalize(final: SolidGroup): SolidGroup {
//final.prototypes = proto //final.prototypes = proto
final.prototypes { final.prototypes {
proto.children.forEach { (token, item) -> 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 import hep.dataforge.names.Name
@ -6,20 +6,20 @@ import hep.dataforge.names.asName
import hep.dataforge.names.plus import hep.dataforge.names.plus
import hep.dataforge.vision.get import hep.dataforge.vision.get
import hep.dataforge.vision.set import hep.dataforge.vision.set
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import hep.dataforge.vision.spatial.World.ONE import hep.dataforge.vision.solid.World.ONE
import hep.dataforge.vision.spatial.World.ZERO import hep.dataforge.vision.solid.World.ZERO
import scientifik.gdml.* import scientifik.gdml.*
import kotlin.math.cos import kotlin.math.cos
import kotlin.math.sin import kotlin.math.sin
private fun Vision3D.withPosition( private fun Solid.withPosition(
lUnit: LUnit, lUnit: LUnit,
newPos: GDMLPosition? = null, newPos: GDMLPosition? = null,
newRotation: GDMLRotation? = null, newRotation: GDMLRotation? = null,
newScale: GDMLScale? = null newScale: GDMLScale? = null
): Vision3D = apply { ): Solid = apply {
newPos?.let { newPos?.let {
val point = Point3D(it.x(lUnit), it.y(lUnit), it.z(lUnit)) val point = Point3D(it.x(lUnit), it.y(lUnit), it.z(lUnit))
if (position != null || point != ZERO) { if (position != null || point != ZERO) {
@ -48,12 +48,12 @@ private inline operator fun Number.times(d: Double) = toDouble() * d
@Suppress("NOTHING_TO_INLINE") @Suppress("NOTHING_TO_INLINE")
private inline operator fun Number.times(f: Float) = toFloat() * f private inline operator fun Number.times(f: Float) = toFloat() * f
private fun VisionGroup3D.addSolid( private fun SolidGroup.addSolid(
context: GDMLTransformer, context: GDMLTransformer,
solid: GDMLSolid, solid: GDMLSolid,
name: String = "", name: String = "",
block: Vision3D.() -> Unit = {} block: Solid.() -> Unit = {}
): Vision3D { ): Solid {
//context.solidAdded(solid) //context.solidAdded(solid)
val lScale = solid.lscale(context.lUnit) val lScale = solid.lscale(context.lUnit)
val aScale = solid.ascale() val aScale = solid.ascale()
@ -154,7 +154,7 @@ private fun VisionGroup3D.addSolid(
private val volumesName = "volumes".asName() private val volumesName = "volumes".asName()
private fun VisionGroup3D.addPhysicalVolume( private fun SolidGroup.addPhysicalVolume(
context: GDMLTransformer, context: GDMLTransformer,
physVolume: GDMLPhysVolume physVolume: GDMLPhysVolume
) { ) {
@ -194,7 +194,7 @@ private fun VisionGroup3D.addPhysicalVolume(
} }
} }
private fun VisionGroup3D.addDivisionVolume( private fun SolidGroup.addDivisionVolume(
context: GDMLTransformer, context: GDMLTransformer,
divisionVolume: GDMLDivisionVolume divisionVolume: GDMLDivisionVolume
) { ) {
@ -216,8 +216,8 @@ private val solidsName = "solids".asName()
private fun volume( private fun volume(
context: GDMLTransformer, context: GDMLTransformer,
group: GDMLGroup group: GDMLGroup
): VisionGroup3D { ): SolidGroup {
return VisionGroup3D().apply { return SolidGroup().apply {
if (group is GDMLVolume) { if (group is GDMLVolume) {
val solid = group.solidref.resolve(context.root) val solid = group.solidref.resolve(context.root)
?: error("Solid with tag ${group.solidref.ref} for volume ${group.name} not defined") ?: 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) val context = GDMLTransformer(this).apply(block)
return context.finalize(volume(context, world)) return context.finalize(volume(context, world))
} }
@ -261,7 +261,7 @@ fun GDML.toVision(block: GDMLTransformer.() -> Unit = {}): VisionGroup3D {
/** /**
* Append gdml node to the group * 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) val visual = gdml.toVision(transformer)
//println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)) //println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual))
set(key, 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.AUnit
import scientifik.gdml.GDMLPosition 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 nl.adaptivity.xmlutil.StAXReader
import scientifik.gdml.GDML import scientifik.gdml.GDML
import java.nio.file.Files import java.nio.file.Files
@ -11,7 +11,7 @@ fun GDML.Companion.readFile(file: Path): GDML {
return format.parse(GDML.serializer(), xmlReader) 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) val gdml = GDML.readFile(file)
gdml(gdml, key, transformer) 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 nl.adaptivity.xmlutil.StAXReader
import org.junit.jupiter.api.Test import org.junit.jupiter.api.Test
import scientifik.gdml.GDML import scientifik.gdml.GDML

View File

@ -1,34 +1,29 @@
@file:UseSerializers(Point3DSerializer::class) @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.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.AbstractVision
import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.VisionFactory
import hep.dataforge.vision.set 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.SerialName
import kotlinx.serialization.Serializable import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
import kotlin.reflect.KClass
@Serializable @Serializable
@SerialName(TYPE_NAME) @SerialName("solid.box")
class Box( class Box(
val xSize: Float, val xSize: Float,
val ySize: Float, val ySize: Float,
val zSize: Float val zSize: Float
) : AbstractVision(), Vision3D, Shape { ) : AbstractVision(), GeometrySolid {
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var ownProperties: Config? = null override var properties: Config? = null
//TODO add helper for color configuration //TODO add helper for color configuration
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) { override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
@ -51,19 +46,29 @@ class Box(
geometryBuilder.face4(node8, node5, node6, node7) 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
override fun invoke(meta: Meta, context: Context): Box = Box( return solidEquals(this, other)
meta["xSize"].float!!,
meta["ySize"].float!!,
meta["zSize"].float!!
).apply {
update(meta)
} }
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 {
} }
} }

View File

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

View File

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

View File

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

View File

@ -1,5 +1,5 @@
@file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class) @file:UseSerializers(Point2DSerializer::class, Point3DSerializer::class)
package hep.dataforge.vision.spatial package hep.dataforge.vision.solid
import hep.dataforge.meta.Config import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision 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) data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
@Serializable @Serializable
@SerialName("3d.extrude") @SerialName("solid.extrude")
class Extruded( class Extruded(
var shape: List<Point2D> = ArrayList(), var shape: List<Point2D> = ArrayList(),
var layers: MutableList<Layer> = 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 position: Point3D? = null
override var rotation: 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 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>) fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
} }

View File

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

View File

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

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class) @file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial package hep.dataforge.vision.solid
import hep.dataforge.meta.* import hep.dataforge.meta.*
import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor
@ -11,20 +11,22 @@ import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.enum import hep.dataforge.vision.enum
import hep.dataforge.vision.spatial.Vision3D.Companion.DETAIL_KEY import hep.dataforge.vision.solid.Solid.Companion.DETAIL_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.IGNORE_KEY import hep.dataforge.vision.solid.Solid.Companion.IGNORE_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.LAYER_KEY import hep.dataforge.vision.solid.Solid.Companion.LAYER_KEY
import hep.dataforge.vision.spatial.Vision3D.Companion.VISIBLE_KEY import hep.dataforge.vision.solid.Solid.Companion.VISIBLE_KEY
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
/** /**
* Interface for 3-dimensional [Vision] * Interface for 3-dimensional [Vision]
*/ */
interface Vision3D : Vision { interface Solid : Vision {
var position: Point3D? var position: Point3D?
var rotation: Point3D? var rotation: Point3D?
var scale: Point3D? var scale: Point3D?
val properties: Config?
override val descriptor: NodeDescriptor? get() = Companion.descriptor override val descriptor: NodeDescriptor? get() = Companion.descriptor
companion object { companion object {
@ -75,25 +77,41 @@ interface Vision3D : Vision {
multiple = true multiple = true
} }
item(Material3D.MATERIAL_KEY.toString(), Material3D.descriptor) item(SolidMaterial.MATERIAL_KEY.toString(), SolidMaterial.descriptor)
enum<RotationOrder>(ROTATION_ORDER_KEY,default = RotationOrder.XYZ) 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 * 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 get() = getItem(LAYER_KEY).int ?: 0
set(value) { set(value) {
setItem(LAYER_KEY, value.asValue()) setItem(LAYER_KEY, value.asValue())
} }
fun Renderer<Vision3D>.render(meta: Meta = Meta.EMPTY, action: VisionGroup3D.() -> Unit) = fun Renderer<Solid>.render(meta: Meta = Meta.EMPTY, action: SolidGroup.() -> Unit) =
render(VisionGroup3D().apply(action), meta) render(SolidGroup().apply(action), meta)
// Common properties // Common properties
@ -109,15 +127,15 @@ enum class RotationOrder {
/** /**
* Rotation order * Rotation order
*/ */
var Vision3D.rotationOrder: RotationOrder var Solid.rotationOrder: RotationOrder
get() = getItem(Vision3D.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ get() = getItem(Solid.ROTATION_ORDER_KEY).enum<RotationOrder>() ?: RotationOrder.XYZ
set(value) = setItem(Vision3D.ROTATION_ORDER_KEY, value.name.asValue()) 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 * 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 get() = getProperty(DETAIL_KEY, false).int
set(value) = setItem(DETAIL_KEY, value?.asValue()) set(value) = setItem(DETAIL_KEY, value?.asValue())
@ -137,74 +155,74 @@ var Vision.ignore: Boolean?
// get() = getProperty(SELECTED_KEY).boolean // get() = getProperty(SELECTED_KEY).boolean
// set(value) = setProperty(SELECTED_KEY, value) // 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 } position ?: Point3D(0.0, 0.0, 0.0).also { position = it }
var Vision3D.x: Number var Solid.x: Number
get() = position?.x ?: 0f get() = position?.x ?: 0f
set(value) { set(value) {
position().x = value.toDouble() 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 get() = position?.y ?: 0f
set(value) { set(value) {
position().y = value.toDouble() 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 get() = position?.z ?: 0f
set(value) { set(value) {
position().z = value.toDouble() 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 } rotation ?: Point3D(0.0, 0.0, 0.0).also { rotation = it }
var Vision3D.rotationX: Number var Solid.rotationX: Number
get() = rotation?.x ?: 0f get() = rotation?.x ?: 0f
set(value) { set(value) {
rotation().x = value.toDouble() 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 get() = rotation?.y ?: 0f
set(value) { set(value) {
rotation().y = value.toDouble() 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 get() = rotation?.z ?: 0f
set(value) { set(value) {
rotation().z = value.toDouble() 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 } scale ?: Point3D(1.0, 1.0, 1.0).also { scale = it }
var Vision3D.scaleX: Number var Solid.scaleX: Number
get() = scale?.x ?: 1f get() = scale?.x ?: 1f
set(value) { set(value) {
scale().x = value.toDouble() 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 get() = scale?.y ?: 1f
set(value) { set(value) {
scale().y = value.toDouble() 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 get() = scale?.z ?: 1f
set(value) { set(value) {
scale().z = value.toDouble() scale().z = value.toDouble()
propertyInvalidated(Vision3D.Z_SCALE_KEY) propertyChanged(Solid.Z_SCALE_KEY)
} }

View File

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

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class) @file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial package hep.dataforge.vision.solid
import hep.dataforge.meta.Config import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.AbstractVision
@ -11,9 +11,9 @@ import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers import kotlinx.serialization.UseSerializers
@Serializable @Serializable
@SerialName("3d.label") @SerialName("solid.label")
class Label3D(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Vision3D { class SolidLabel(var text: String, var fontSize: Double, var fontFamily: String) : AbstractVision(), Solid {
override var ownProperties: Config? = null override var properties: Config? = null
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null
@ -26,6 +26,6 @@ fun MutableVisionGroup.label(
fontSize: Number = 20, fontSize: Number = 20,
fontFamily: String = "Arial", fontFamily: String = "Arial",
name: String = "", 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.*
import hep.dataforge.meta.descriptors.NodeDescriptor import hep.dataforge.meta.descriptors.NodeDescriptor
@ -8,12 +8,12 @@ import hep.dataforge.names.plus
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.values.asValue import hep.dataforge.values.asValue
import hep.dataforge.vision.Colors import hep.dataforge.vision.Colors
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_COLOR_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_OPACITY_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY
import hep.dataforge.vision.widgetType import hep.dataforge.vision.widgetType
class Material3D : Scheme() { class SolidMaterial : Scheme() {
/** /**
* Primary web-color for the material * Primary web-color for the material
@ -35,7 +35,7 @@ class Material3D : Scheme() {
*/ */
var wireframe by boolean(false, WIREFRAME_KEY) var wireframe by boolean(false, WIREFRAME_KEY)
companion object : SchemeSpec<Material3D>(::Material3D) { companion object : SchemeSpec<SolidMaterial>(::SolidMaterial) {
val MATERIAL_KEY = "material".asName() val MATERIAL_KEY = "material".asName()
internal val COLOR_KEY = "color".asName() internal val COLOR_KEY = "color".asName()
@ -77,18 +77,18 @@ class Material3D : Scheme() {
/** /**
* Set color as web-color * Set color as web-color
*/ */
fun Vision3D.color(webColor: String) { fun Solid.color(webColor: String) {
setItem(MATERIAL_COLOR_KEY, webColor.asValue()) setItem(MATERIAL_COLOR_KEY, webColor.asValue())
} }
/** /**
* Set color as integer * Set color as integer
*/ */
fun Vision3D.color(rgb: Int) { fun Solid.color(rgb: Int) {
setItem(MATERIAL_COLOR_KEY, rgb.asValue()) 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, MATERIAL_COLOR_KEY,
Colors.rgbToMeta(r, g, b) 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 * 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) } get() = getItem(MATERIAL_COLOR_KEY)?.let { Colors.fromMeta(it) }
set(value) { set(value) {
setItem(MATERIAL_COLOR_KEY, value?.asValue()) setItem(MATERIAL_COLOR_KEY, value?.asValue())
} }
val Vision3D.material: Material3D? val Solid.material: SolidMaterial?
get() = getItem(MATERIAL_KEY).node?.let { Material3D.wrap(it) } 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 val node = config[MATERIAL_KEY].node
if (node != null) { if (node != null) {
Material3D.update(node, builder) SolidMaterial.update(node, builder)
} else { } 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 get() = getItem(MATERIAL_OPACITY_KEY).double
set(value) { set(value) {
setItem(MATERIAL_OPACITY_KEY, value?.asValue()) setItem(MATERIAL_OPACITY_KEY, value?.asValue())

View File

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

View File

@ -1,6 +1,6 @@
@file:UseSerializers(Point3DSerializer::class) @file:UseSerializers(Point3DSerializer::class)
package hep.dataforge.vision.spatial package hep.dataforge.vision.solid
import hep.dataforge.meta.Config import hep.dataforge.meta.Config
import hep.dataforge.vision.AbstractVision import hep.dataforge.vision.AbstractVision
@ -17,20 +17,20 @@ import kotlin.math.sin
* Straight tube segment * Straight tube segment
*/ */
@Serializable @Serializable
@SerialName("3d.tube") @SerialName("solid.tube")
class Tube( class Tube(
var radius: Float, var radius: Float,
var height: Float, var height: Float,
var innerRadius: Float = 0f, var innerRadius: Float = 0f,
var startAngle: Float = 0f, var startAngle: Float = 0f,
var angle: Float = PI2 var angle: Float = PI2
) : AbstractVision(), Vision3D, Shape { ) : AbstractVision(), GeometrySolid {
override var position: Point3D? = null override var position: Point3D? = null
override var rotation: Point3D? = null override var rotation: Point3D? = null
override var scale: Point3D? = null override var scale: Point3D? = null
override var ownProperties: Config? = null override var properties: Config? = null
init { init {
require(radius > 0) 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.Meta
import hep.dataforge.meta.get import hep.dataforge.meta.get
@ -21,8 +21,8 @@ operator fun Point2D.component1() = x
operator fun Point2D.component2() = y operator fun Point2D.component2() = y
fun Point2D.toMeta() = Meta { fun Point2D.toMeta() = Meta {
Vision3D.X_KEY put x Solid.X_KEY put x
Vision3D.Y_KEY put y Solid.Y_KEY put y
} }
fun Meta.point2D() = Point2D(this["x"].number ?: 0, this["y"].number ?: 0) 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 Meta.point3D() = Point3D(this["x"].number ?: 0, this["y"].number ?: 0, this["y"].number ?: 0)
fun Point3D.toMeta() = Meta { fun Point3D.toMeta() = Meta {
Vision3D.X_KEY put x Solid.X_KEY put x
Vision3D.Y_KEY put y Solid.Y_KEY put y
Vision3D.Z_KEY put z 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.meta.double
import hep.dataforge.names.NameToken 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){ if(it is VisionGroup){
it.attachChildren() it.attachChildren()
} }

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.specifications package hep.dataforge.vision.solid.specifications
import hep.dataforge.meta.* 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.Scheme
import hep.dataforge.meta.SchemeSpec 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.Scheme
import hep.dataforge.meta.SchemeSpec 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.Scheme
import hep.dataforge.meta.SchemeSpec 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.meta.update
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.VisionGroup import hep.dataforge.vision.VisionGroup
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
internal fun mergeChild(parent: VisionGroup, child: Vision): Vision { internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
return child.apply { return child.apply {
@ -14,7 +14,7 @@ internal fun mergeChild(parent: VisionGroup, child: Vision): Vision {
//parent.properties?.let { config.update(it) } //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) position = (position ?: World.ZERO) + (parent.position ?: World.ZERO)
rotation = (parent.rotation ?: World.ZERO) + (parent.rotation ?: World.ZERO) rotation = (parent.rotation ?: World.ZERO) + (parent.rotation ?: World.ZERO)
scale = when { 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() { fun MutableVisionGroup.replaceChildren() {
children.forEach { (childName, parent) -> children.forEach { (childName, parent) ->
if (parent is Proxy) return@forEach //ignore refs 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() 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.Name
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.vision.MutableVisionGroup import hep.dataforge.vision.MutableVisionGroup
import hep.dataforge.vision.VisionGroup import hep.dataforge.vision.VisionGroup
import hep.dataforge.vision.spatial.Proxy import hep.dataforge.vision.solid.Proxy
import hep.dataforge.vision.spatial.VisionGroup3D import hep.dataforge.vision.solid.SolidGroup
object UnRef : VisualTreeTransform<VisionGroup3D>() { object UnRef : VisualTreeTransform<SolidGroup>() {
private fun VisionGroup.countRefs(): Map<Name, Int> { private fun VisionGroup.countRefs(): Map<Name, Int> {
return children.values.fold(HashMap()) { reducer, obj -> return children.values.fold(HashMap()) { reducer, obj ->
if (obj is VisionGroup) { if (obj is VisionGroup) {
@ -24,7 +24,7 @@ object UnRef : VisualTreeTransform<VisionGroup3D>() {
} }
private fun MutableVisionGroup.unref(name: Name) { 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) -> children.filter { (it.value as? Proxy)?.templateName == name }.forEach { (key, value) ->
val proxy = value as Proxy val proxy = value as Proxy
val newChild = mergeChild(proxy, proxy.prototype) val newChild = mergeChild(proxy, proxy.prototype)
@ -35,14 +35,14 @@ object UnRef : VisualTreeTransform<VisionGroup3D>() {
children.values.filterIsInstance<MutableVisionGroup>().forEach { it.unref(name) } children.values.filterIsInstance<MutableVisionGroup>().forEach { it.unref(name) }
} }
override fun VisionGroup3D.transformInPlace() { override fun SolidGroup.transformInPlace() {
val counts = countRefs() val counts = countRefs()
counts.filter { it.value <= 1 }.forEach { counts.filter { it.value <= 1 }.forEach {
this.unref(it.key) this.unref(it.key)
} }
} }
override fun VisionGroup3D.clone(): VisionGroup3D { override fun SolidGroup.clone(): SolidGroup {
TODO() TODO()
} }

View File

@ -1,4 +1,4 @@
package hep.dataforge.vision.spatial.transform package hep.dataforge.vision.solid.transform
import hep.dataforge.vision.Vision 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.MetaItem
import hep.dataforge.meta.getIndexed import hep.dataforge.meta.getIndexed
@ -11,7 +11,7 @@ class ConvexTest {
@Suppress("UNUSED_VARIABLE") @Suppress("UNUSED_VARIABLE")
@Test @Test
fun testConvexBuilder() { fun testConvexBuilder() {
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
convex { convex {
point(50, 50, -50) point(50, 50, -50)
point(50, -50, -50) point(50, -50, -50)
@ -26,7 +26,7 @@ class ConvexTest {
val convex = group.children.values.first() as Convex 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 meta = json.toMetaItem().node!!
val points = meta.getIndexed("points").values.map { (it as MetaItem.NodeItem<*>).node.point3D() } 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.Colors
import hep.dataforge.vision.get import hep.dataforge.vision.get
@ -9,7 +9,7 @@ import kotlin.test.assertEquals
class GroupTest { class GroupTest {
@Test @Test
fun testGroupWithComposite() { fun testGroupWithComposite() {
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
union("union") { union("union") {
box(100, 100, 100) { box(100, 100, 100) {
z = 100 z = 100
@ -45,7 +45,7 @@ class GroupTest {
} }
assertEquals(3, group.children.count()) assertEquals(3, group.children.count())
assertEquals(300.0, (group["intersect"] as Vision3D).y.toDouble()) assertEquals(300.0, (group["intersect"] as Solid).y.toDouble())
assertEquals(-300.0, (group["subtract"] as Vision3D).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.int
import hep.dataforge.meta.set import hep.dataforge.meta.set
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.vision.styles
import hep.dataforge.vision.useStyle import hep.dataforge.vision.useStyle
import kotlin.test.Test import kotlin.test.Test
import kotlin.test.assertEquals import kotlin.test.assertEquals
@ -12,7 +13,7 @@ class PropertyTest {
@Test @Test
fun testInheritedProperty() { fun testInheritedProperty() {
var box: Box? = null var box: Box? = null
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
config["test"] = 22 config["test"] = 22
group { group {
box = box(100, 100, 100) box = box(100, 100, 100)
@ -24,7 +25,7 @@ class PropertyTest {
@Test @Test
fun testStyleProperty() { fun testStyleProperty() {
var box: Box? = null var box: Box? = null
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
styleSheet { styleSheet {
set("testStyle") { set("testStyle") {
"test" put 22 "test" put 22
@ -42,10 +43,10 @@ class PropertyTest {
@Test @Test
fun testColor() { fun testColor() {
var box: Box? = null var box: Box? = null
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
styleSheet { styleSheet {
set("testStyle") { set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555" SolidMaterial.MATERIAL_COLOR_KEY put "#555555"
} }
} }
group { group {
@ -60,10 +61,10 @@ class PropertyTest {
@Test @Test
fun testProxyStyleProperty() { fun testProxyStyleProperty() {
var box: Proxy? = null var box: Proxy? = null
val group = VisionGroup3D().apply { val group = SolidGroup().apply {
styleSheet { styleSheet {
set("testStyle") { set("testStyle") {
Material3D.MATERIAL_COLOR_KEY put "#555555" SolidMaterial.MATERIAL_COLOR_KEY put "#555555"
} }
} }
prototypes { 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.names.toName
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
@ -27,7 +27,7 @@ class SerializationTest {
x = 100 x = 100
z = -100 z = -100
} }
val group = VisionGroup3D().apply { val group = SolidGroup{
proxy("cube", cube) proxy("cube", cube)
proxyGroup("pg", "pg.content".toName()){ proxyGroup("pg", "pg.content".toName()){
sphere(50){ sphere(50){
@ -37,7 +37,8 @@ class SerializationTest {
} }
val string = group.stringify() val string = group.stringify()
println(string) println(string)
val reconstructed = VisionGroup3D.parseJson(string) val reconstructed = SolidGroup.parseJson(string)
assertEquals(group["cube"]?.config, reconstructed["cube"]?.config) 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 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.boolean
import hep.dataforge.meta.node import hep.dataforge.meta.node
import hep.dataforge.names.asName import hep.dataforge.names.asName
import hep.dataforge.names.plus import hep.dataforge.names.plus
import hep.dataforge.names.startsWith import hep.dataforge.names.startsWith
import hep.dataforge.vision.spatial.Material3D import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.spatial.Vision3D import hep.dataforge.vision.solid.SolidMaterial
import hep.dataforge.vision.spatial.layer import hep.dataforge.vision.solid.layer
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.EdgesGeometry import info.laht.threekt.geometries.EdgesGeometry
import info.laht.threekt.geometries.WireframeGeometry import info.laht.threekt.geometries.WireframeGeometry
@ -19,7 +19,7 @@ import kotlin.reflect.KClass
/** /**
* Basic geometry-based factory * Basic geometry-based factory
*/ */
abstract class MeshThreeFactory<in T : Vision3D>( abstract class MeshThreeFactory<in T : Solid>(
override val type: KClass<in T> override val type: KClass<in T>
) : ThreeFactory<T> { ) : ThreeFactory<T> {
/** /**
@ -50,9 +50,9 @@ abstract class MeshThreeFactory<in T : Vision3D>(
} }
//add listener to object properties //add listener to object properties
obj.onPropertyChange(this) { name, _, _ -> obj.onPropertyChange(this) { name->
when { when {
name.startsWith(Vision3D.GEOMETRY_KEY) -> { name.startsWith(Solid.GEOMETRY_KEY) -> {
val oldGeometry = mesh.geometry as BufferGeometry val oldGeometry = mesh.geometry as BufferGeometry
val newGeometry = buildGeometry(obj) val newGeometry = buildGeometry(obj)
oldGeometry.attributes = newGeometry.attributes oldGeometry.attributes = newGeometry.attributes
@ -73,13 +73,13 @@ abstract class MeshThreeFactory<in T : Vision3D>(
val WIREFRAME_KEY = "wireframe".asName() val WIREFRAME_KEY = "wireframe".asName()
val ENABLED_KEY = "enabled".asName() val ENABLED_KEY = "enabled".asName()
val EDGES_ENABLED_KEY = EDGES_KEY + ENABLED_KEY 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_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 { children.find { it.name == "@edges" }?.let {
remove(it) remove(it)
(it as LineSegments).dispose() (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 { children.find { it.name == "@wireframe" }?.let {
remove(it) remove(it)
(it as LineSegments).dispose() (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.solid.Box
import hep.dataforge.vision.spatial.detail import hep.dataforge.vision.solid.detail
import info.laht.threekt.geometries.BoxBufferGeometry import info.laht.threekt.geometries.BoxBufferGeometry
object ThreeBoxFactory : MeshThreeFactory<Box>(Box::class) { 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.context.Context
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
@ -9,12 +9,12 @@ import hep.dataforge.names.plus
import hep.dataforge.names.toName import hep.dataforge.names.toName
import hep.dataforge.output.Renderer import hep.dataforge.output.Renderer
import hep.dataforge.vision.Colors import hep.dataforge.vision.Colors
import hep.dataforge.vision.spatial.Vision3D import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.spatial.specifications.Camera import hep.dataforge.vision.solid.specifications.Camera
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import hep.dataforge.vision.spatial.specifications.Controls import hep.dataforge.vision.solid.specifications.Controls
import hep.dataforge.vision.spatial.three.ThreeMaterials.HIGHLIGHT_MATERIAL import hep.dataforge.vision.solid.three.ThreeMaterials.HIGHLIGHT_MATERIAL
import hep.dataforge.vision.spatial.three.ThreeMaterials.SELECTED_MATERIAL import hep.dataforge.vision.solid.three.ThreeMaterials.SELECTED_MATERIAL
import info.laht.threekt.WebGLRenderer import info.laht.threekt.WebGLRenderer
import info.laht.threekt.cameras.PerspectiveCamera import info.laht.threekt.cameras.PerspectiveCamera
import info.laht.threekt.core.BufferGeometry 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 override val context: Context get() = three.context
var content: Vision3D? = null var content: Solid? = null
private set private set
private var root: Object3D? = null 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 old root
clear() 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 = fun ThreePlugin.output(element: HTMLElement, spec: Canvas3DOptions = Canvas3DOptions.empty()): ThreeCanvas =
ThreeCanvas(element, this, spec) 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) 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.context.Context
import hep.dataforge.names.Name import hep.dataforge.names.Name
import hep.dataforge.vision.spatial.Vision3D import hep.dataforge.vision.solid.Solid
import hep.dataforge.vision.spatial.specifications.Canvas3DOptions import hep.dataforge.vision.solid.specifications.Canvas3DOptions
import org.w3c.dom.Element import org.w3c.dom.Element
import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLElement
import react.RBuilder import react.RBuilder
@ -15,7 +15,7 @@ import react.dom.findDOMNode
interface ThreeCanvasProps : RProps { interface ThreeCanvasProps : RProps {
var context: Context var context: Context
var obj: Vision3D var obj: Solid
var options: Canvas3DOptions? var options: Canvas3DOptions?
var selected: Name? var selected: Name?
var clickCallback: (Name?) -> Unit 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) { child(ThreeCanvasComponent::class) {
attrs { attrs {
this.obj = object3D 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.solid.SolidLabel
import hep.dataforge.vision.spatial.color import hep.dataforge.vision.solid.color
import hep.dataforge.vision.spatial.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG import hep.dataforge.vision.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG
import info.laht.threekt.DoubleSide import info.laht.threekt.DoubleSide
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.geometries.PlaneBufferGeometry 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 * Using example from http://stemkoski.github.io/Three.js/Texture-From-Canvas.html
*/ */
object ThreeCanvasLabelFactory : ThreeFactory<Label3D> { object ThreeCanvasLabelFactory : ThreeFactory<SolidLabel> {
override val type: KClass<in Label3D> get() = Label3D::class 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 canvas = document.createElement("canvas") as HTMLCanvasElement
val context = canvas.getContext("2d") as CanvasRenderingContext2D val context = canvas.getContext("2d") as CanvasRenderingContext2D
context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" 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.solid.Composite
import hep.dataforge.vision.spatial.CompositeType import hep.dataforge.vision.solid.CompositeType
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.objects.Mesh 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.external.geometries.ConvexBufferGeometry
import info.laht.threekt.math.Vector3 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.solid.ConeSegment
import hep.dataforge.vision.spatial.detail import hep.dataforge.vision.solid.detail
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.CylinderBufferGeometry import info.laht.threekt.geometries.CylinderBufferGeometry
import kotlin.math.PI 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.Name
import hep.dataforge.names.startsWith import hep.dataforge.names.startsWith
import hep.dataforge.provider.Type import hep.dataforge.provider.Type
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import hep.dataforge.vision.spatial.Material3D.Companion.MATERIAL_KEY import hep.dataforge.vision.solid.SolidMaterial.Companion.MATERIAL_KEY
import hep.dataforge.vision.spatial.three.ThreeFactory.Companion.TYPE import hep.dataforge.vision.solid.three.ThreeFactory.Companion.TYPE
import hep.dataforge.vision.spatial.three.ThreeMaterials.getMaterial import hep.dataforge.vision.solid.three.ThreeMaterials.getMaterial
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.objects.Mesh import info.laht.threekt.objects.Mesh
@ -33,7 +33,7 @@ interface ThreeFactory<in T : Vision> {
*/ */
fun Object3D.updatePosition(obj: Vision) { fun Object3D.updatePosition(obj: Vision) {
visible = obj.visible ?: true visible = obj.visible ?: true
if(obj is Vision3D) { if(obj is Solid) {
position.set(obj.x, obj.y, obj.z) position.set(obj.x, obj.y, obj.z)
setRotationFromEuler(obj.euler) setRotationFromEuler(obj.euler)
scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) 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)) { if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) {
this.material = getMaterial(source) this.material = getMaterial(source)
} else if ( } else if (
propertyName.startsWith(Vision3D.POSITION_KEY) propertyName.startsWith(Solid.POSITION_KEY)
|| propertyName.startsWith(Vision3D.ROTATION) || propertyName.startsWith(Solid.ROTATION)
|| propertyName.startsWith(Vision3D.SCALE_KEY) || propertyName.startsWith(Solid.SCALE_KEY)
) { ) {
//update position of mesh using this object //update position of mesh using this object
updatePosition(source) updatePosition(source)
} else if (propertyName == Vision3D.VISIBLE_KEY) { } else if (propertyName == Solid.VISIBLE_KEY) {
visible = source.visible ?: true visible = source.visible ?: true
} }
} }
@ -74,8 +74,8 @@ fun Object3D.updateProperty(source: Vision, propertyName: Name) {
/** /**
* Generic factory for elements which provide inside geometry builder * Generic factory for elements which provide inside geometry builder
*/ */
object ThreeShapeFactory : MeshThreeFactory<Shape>(Shape::class) { object ThreeShapeFactory : MeshThreeFactory<GeometrySolid>(GeometrySolid::class) {
override fun buildGeometry(obj: Shape): BufferGeometry { override fun buildGeometry(obj: GeometrySolid): BufferGeometry {
return obj.run { return obj.run {
ThreeGeometryBuilder().apply { toGeometry(this) }.build() 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.Meta
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.int import hep.dataforge.meta.int
import hep.dataforge.vision.spatial.GeometryBuilder import hep.dataforge.vision.solid.GeometryBuilder
import hep.dataforge.vision.spatial.Point3D import hep.dataforge.vision.solid.Point3D
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.core.Face3 import info.laht.threekt.core.Face3
import info.laht.threekt.core.Geometry 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.meta.node
import hep.dataforge.vision.spatial.PolyLine import hep.dataforge.vision.solid.PolyLine
import hep.dataforge.vision.spatial.color import hep.dataforge.vision.solid.color
import hep.dataforge.vision.spatial.three.ThreeMaterials.DEFAULT_LINE_COLOR import hep.dataforge.vision.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR
import info.laht.threekt.core.Geometry import info.laht.threekt.core.Geometry
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import info.laht.threekt.math.Color import info.laht.threekt.math.Color
@ -27,7 +27,7 @@ object ThreeLineFactory : ThreeFactory<PolyLine> {
updatePosition(obj) updatePosition(obj)
//layers.enable(obj.layer) //layers.enable(obj.layer)
//add listener to object properties //add listener to object properties
obj.onPropertyChange(this) { propertyName, _, _ -> obj.onPropertyChange(this) { propertyName->
updateProperty(obj, 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.meta.*
import hep.dataforge.values.ValueType import hep.dataforge.values.ValueType
import hep.dataforge.vision.Colors import hep.dataforge.vision.Colors
import hep.dataforge.vision.Vision 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.LineBasicMaterial
import info.laht.threekt.materials.Material import info.laht.threekt.materials.Material
import info.laht.threekt.materials.MeshBasicMaterial import info.laht.threekt.materials.MeshBasicMaterial
@ -36,30 +36,30 @@ object ThreeMaterials {
fun getLineMaterial(meta: Meta?): LineBasicMaterial { fun getLineMaterial(meta: Meta?): LineBasicMaterial {
if (meta == null) return DEFAULT_LINE if (meta == null) return DEFAULT_LINE
return LineBasicMaterial().apply { return LineBasicMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_LINE_COLOR color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_LINE_COLOR
opacity = meta[Material3D.OPACITY_KEY].double ?: 1.0 opacity = meta[SolidMaterial.OPACITY_KEY].double ?: 1.0
transparent = opacity < 1.0 transparent = opacity < 1.0
linewidth = meta["thickness"].double ?: 1.0 linewidth = meta["thickness"].double ?: 1.0
} }
} }
fun getMaterial(vision3D: Vision): Material { fun getMaterial(vision3D: Vision): Material {
val meta = vision3D.getItem(Material3D.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT val meta = vision3D.getItem(SolidMaterial.MATERIAL_KEY).node ?: return ThreeMaterials.DEFAULT
return if (meta[Material3D.SPECULAR_COLOR_KEY] != null) { return if (meta[SolidMaterial.SPECULAR_COLOR_KEY] != null) {
MeshPhongMaterial().apply { MeshPhongMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
specular = meta[Material3D.SPECULAR_COLOR_KEY]!!.getColor() specular = meta[SolidMaterial.SPECULAR_COLOR_KEY]!!.getColor()
opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0 opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
transparent = opacity < 1.0 transparent = opacity < 1.0
wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
needsUpdate = true needsUpdate = true
} }
} else { } else {
MeshBasicMaterial().apply { MeshBasicMaterial().apply {
color = meta[Material3D.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR color = meta[SolidMaterial.COLOR_KEY]?.getColor() ?: DEFAULT_COLOR
opacity = meta[Material3D.OPACITY_KEY]?.double ?: 1.0 opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0
transparent = opacity < 1.0 transparent = opacity < 1.0
wireframe = meta[Material3D.WIREFRAME_KEY].boolean ?: false wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false
needsUpdate = true 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.context.*
import hep.dataforge.meta.Meta import hep.dataforge.meta.Meta
import hep.dataforge.names.* import hep.dataforge.names.*
import hep.dataforge.vision.Vision import hep.dataforge.vision.Vision
import hep.dataforge.vision.spatial.* import hep.dataforge.vision.solid.*
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
import kotlin.collections.set import kotlin.collections.set
import kotlin.reflect.KClass import kotlin.reflect.KClass
@ -13,7 +13,7 @@ import info.laht.threekt.objects.Group as ThreeGroup
class ThreePlugin : AbstractPlugin() { class ThreePlugin : AbstractPlugin() {
override val tag: PluginTag get() = Companion.tag 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 compositeFactory = ThreeCompositeFactory(this)
private val proxyFactory = ThreeProxyFactory(this) private val proxyFactory = ThreeProxyFactory(this)
@ -24,24 +24,24 @@ class ThreePlugin : AbstractPlugin() {
objectFactories[Sphere::class] = ThreeSphereFactory objectFactories[Sphere::class] = ThreeSphereFactory
objectFactories[ConeSegment::class] = ThreeCylinderFactory objectFactories[ConeSegment::class] = ThreeCylinderFactory
objectFactories[PolyLine::class] = ThreeLineFactory objectFactories[PolyLine::class] = ThreeLineFactory
objectFactories[Label3D::class] = ThreeCanvasLabelFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
} }
@Suppress("UNCHECKED_CAST") @Suppress("UNCHECKED_CAST")
private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Vision3D>? { private fun findObjectFactory(type: KClass<out Vision>): ThreeFactory<Solid>? {
return (objectFactories[type] return (objectFactories[type]
?: context.content<ThreeFactory<*>>(ThreeFactory.TYPE).values.find { it.type == 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) { return when (obj) {
is ThreeVision -> obj.toObject3D() is ThreeVision -> obj.toObject3D()
is Proxy -> proxyFactory(obj) is Proxy -> proxyFactory(obj)
is VisionGroup3D -> { is SolidGroup -> {
val group = ThreeGroup() val group = ThreeGroup()
obj.children.forEach { (token, child) -> obj.children.forEach { (token, child) ->
if (child is Vision3D && child.ignore != true) { if (child is Solid && child.ignore != true) {
try { try {
val object3D = buildObject3D(child) val object3D = buildObject3D(child)
group[token] = object3D group[token] = object3D
@ -55,15 +55,15 @@ class ThreePlugin : AbstractPlugin() {
updatePosition(obj) updatePosition(obj)
//obj.onChildrenChange() //obj.onChildrenChange()
obj.onPropertyChange(this) { name, _, _ -> obj.onPropertyChange(this) { name->
if ( if (
name.startsWith(Vision3D.POSITION_KEY) || name.startsWith(Solid.POSITION_KEY) ||
name.startsWith(Vision3D.ROTATION) || name.startsWith(Solid.ROTATION) ||
name.startsWith(Vision3D.SCALE_KEY) name.startsWith(Solid.SCALE_KEY)
) { ) {
//update position of mesh using this object //update position of mesh using this object
updatePosition(obj) updatePosition(obj)
} else if (name == Vision3D.VISIBLE_KEY) { } else if (name == Solid.VISIBLE_KEY) {
visible = obj.visible ?: true visible = obj.visible ?: true
} }
} }
@ -83,7 +83,7 @@ class ThreePlugin : AbstractPlugin() {
} }
//adding new object //adding new object
if (child != null && child is Vision3D) { if (child != null && child is Solid) {
try { try {
val object3D = buildObject3D(child) val object3D = buildObject3D(child)
set(name, object3D) set(name, object3D)
@ -97,10 +97,10 @@ class ThreePlugin : AbstractPlugin() {
is Composite -> compositeFactory(obj) is Composite -> compositeFactory(obj)
else -> { else -> {
//find specialized factory for this type if it is present //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 { when {
factory != null -> factory(obj) factory != null -> factory(obj)
obj is Shape -> ThreeShapeFactory(obj) obj is GeometrySolid -> ThreeShapeFactory(obj)
else -> error("Renderer for ${obj::class} not found") 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.names.toName
import hep.dataforge.vision.spatial.Proxy import hep.dataforge.vision.solid.Proxy
import hep.dataforge.vision.spatial.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX import hep.dataforge.vision.solid.Proxy.Companion.PROXY_CHILD_PROPERTY_PREFIX
import hep.dataforge.vision.spatial.Vision3D import hep.dataforge.vision.solid.Solid
import info.laht.threekt.core.Object3D import info.laht.threekt.core.Object3D
class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> { class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
private val cache = HashMap<Vision3D, Object3D>() private val cache = HashMap<Solid, Object3D>()
override val type = Proxy::class override val type = Proxy::class
@ -21,7 +21,7 @@ class ThreeProxyFactory(val three: ThreePlugin) : ThreeFactory<Proxy> {
val object3D = cachedObject.clone() val object3D = cachedObject.clone()
object3D.updatePosition(obj) object3D.updatePosition(obj)
obj.onPropertyChange(this) { name, _, _ -> obj.onPropertyChange(this) { name->
if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) { if (name.first()?.body == PROXY_CHILD_PROPERTY_PREFIX) {
val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'") val childName = name.first()?.index?.toName() ?: error("Wrong syntax for proxy child property: '$name'")
val propertyName = name.cutFirst() 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.solid.Sphere
import hep.dataforge.vision.spatial.detail import hep.dataforge.vision.solid.detail
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.SphereBufferGeometry import info.laht.threekt.geometries.SphereBufferGeometry

View File

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

View File

@ -9,7 +9,7 @@
"NESTED_CLASS_IN_EXTERNAL_INTERFACE" "NESTED_CLASS_IN_EXTERNAL_INTERFACE"
) )
package hep.dataforge.vision.spatial.three package hep.dataforge.vision.solid.three
import info.laht.threekt.math.Matrix4 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.js.requireJS
import hep.dataforge.vision.bootstrap.accordion import hep.dataforge.vision.bootstrap.accordion
import hep.dataforge.vision.bootstrap.entry import hep.dataforge.vision.bootstrap.entry
import hep.dataforge.vision.spatial.SpatialVisionManager import hep.dataforge.vision.solid.SolidGroup
import hep.dataforge.vision.spatial.VisionGroup3D import hep.dataforge.vision.solid.SolidManager
import kotlinx.html.* import kotlinx.html.*
import kotlinx.html.dom.append import kotlinx.html.dom.append
import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onChangeFunction
@ -52,9 +52,9 @@ fun RBuilder.canvasControls(canvas: ThreeCanvas) = accordion("controls") {
+"Export" +"Export"
attrs { attrs {
onClickFunction = { onClickFunction = {
val json = (canvas.content as? VisionGroup3D)?.let { group -> val json = (canvas.content as? SolidGroup)?.let { group ->
SpatialVisionManager.json.stringify( SolidManager.jsonForSolids.stringify(
VisionGroup3D.serializer(), SolidGroup.serializer(),
group group
) )
} }
@ -116,9 +116,9 @@ fun Element.displayCanvasControls(canvas: ThreeCanvas, block: TagConsumer<HTMLEl
button { button {
+"Export" +"Export"
onClickFunction = { onClickFunction = {
val json = (canvas.content as? VisionGroup3D)?.let { group -> val json = (canvas.content as? SolidGroup)?.let { group ->
SpatialVisionManager.json.stringify( SolidManager.jsonForSolids.stringify(
VisionGroup3D.serializer(), SolidGroup.serializer(),
group 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.MetaItem
import hep.dataforge.meta.float import hep.dataforge.meta.float
import hep.dataforge.meta.get import hep.dataforge.meta.get
import hep.dataforge.meta.node 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.BufferGeometry
import info.laht.threekt.core.DirectGeometry import info.laht.threekt.core.DirectGeometry
import info.laht.threekt.core.Face3 import info.laht.threekt.core.Face3
@ -17,7 +17,7 @@ import info.laht.threekt.objects.Mesh
import info.laht.threekt.textures.Texture import info.laht.threekt.textures.Texture
import kotlin.math.PI 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) 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