forked from kscience/visionforge
WIP Root object model
This commit is contained in:
parent
a15afb3d52
commit
b79265e8c2
@ -36,7 +36,9 @@ apiValidation {
|
|||||||
ignoredPackages.add("info.laht.threekt")
|
ignoredPackages.add("info.laht.threekt")
|
||||||
}
|
}
|
||||||
|
|
||||||
//workaround for https://youtrack.jetbrains.com/issue/KT-48273
|
|
||||||
rootProject.plugins.withType(org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootPlugin::class.java) {
|
afterEvaluate {
|
||||||
rootProject.the<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension>().versions.webpackDevServer.version = "4.0.0-rc.0"
|
extensions.configure<org.jetbrains.kotlin.gradle.targets.js.nodejs.NodeJsRootExtension> {
|
||||||
|
versions.webpackDevServer.version = "4.0.0"
|
||||||
|
}
|
||||||
}
|
}
|
19
cern-root-loader/build.gradle.kts
Normal file
19
cern-root-loader/build.gradle.kts
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
plugins {
|
||||||
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
|
}
|
||||||
|
|
||||||
|
kscience{
|
||||||
|
useSerialization {
|
||||||
|
json()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
kotlin {
|
||||||
|
sourceSets {
|
||||||
|
val commonMain by getting {
|
||||||
|
dependencies {
|
||||||
|
api(project(":visionforge-solid"))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,25 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlin.properties.PropertyDelegateProvider
|
||||||
|
import kotlin.reflect.KType
|
||||||
|
import kotlin.reflect.typeOf
|
||||||
|
|
||||||
|
public interface RootValueProvider {
|
||||||
|
/**
|
||||||
|
* Provide a member cast or reinterpreted to given type.
|
||||||
|
* Returns null if member with given name/type could not be resolved.
|
||||||
|
*/
|
||||||
|
public fun <T : Any> provideOrNull(name: String, type: KType): T?
|
||||||
|
}
|
||||||
|
|
||||||
|
public interface RootModel {
|
||||||
|
public val provider: RootValueProvider
|
||||||
|
}
|
||||||
|
|
||||||
|
public inline fun <reified T : Any> RootValueProvider.provide(name: String): T =
|
||||||
|
provideOrNull(name, typeOf<T>()) ?: error("A member with type ${T::class} and name $name could not be resolved")
|
||||||
|
|
||||||
|
public inline fun <reified T : Any> RootModel.member(name: String? = null): PropertyDelegateProvider<Any?, Lazy<T>> =
|
||||||
|
PropertyDelegateProvider { _, property ->
|
||||||
|
lazy { provider.provide(name ?: property.name) }
|
||||||
|
}
|
@ -0,0 +1,33 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public sealed class TGeoMatrix : TNamed()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoIdentity : TGeoMatrix()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoHMatrix(
|
||||||
|
public val fTranslation: DoubleArray,
|
||||||
|
public val fRotationMatrix: DoubleArray,
|
||||||
|
public val fScale: DoubleArray
|
||||||
|
) : TGeoMatrix()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoTranslation(
|
||||||
|
public val fTranslation: DoubleArray
|
||||||
|
) : TGeoMatrix()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoRotation(
|
||||||
|
public val fRotationMatrix: DoubleArray
|
||||||
|
): TGeoMatrix()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoCombiTrans(
|
||||||
|
public val fTranslation: DoubleArray,
|
||||||
|
public val fRotation: TGeoRotation? = null,
|
||||||
|
): TGeoMatrix()
|
@ -0,0 +1,30 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import kotlinx.serialization.json.Json
|
||||||
|
import kotlinx.serialization.json.JsonObject
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoManager : TNamed() {
|
||||||
|
|
||||||
|
public val fMatrices: TObjArray = TObjArray.empty
|
||||||
|
public val fShapes: TObjArray = TObjArray.empty
|
||||||
|
public val fVolumes: TObjArray = TObjArray.empty
|
||||||
|
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
public val rootJson: Json = Json {
|
||||||
|
encodeDefaults = true
|
||||||
|
ignoreUnknownKeys = true
|
||||||
|
classDiscriminator = "_typename"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Load Json encoded TGeoManager
|
||||||
|
*/
|
||||||
|
public fun decodeFromJson(jsonObject: JsonObject): TGeoManager = TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
@ -0,0 +1,9 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public open class TGeoMaterial: TNamed()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoMixture: TGeoMaterial()
|
@ -0,0 +1,10 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoMedium(
|
||||||
|
public val fId : Int,
|
||||||
|
public val fMaterial: TGeoMaterial,
|
||||||
|
public val fParams: DoubleArray
|
||||||
|
): TNamed()
|
@ -0,0 +1,17 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoNode : TNamed() {
|
||||||
|
//val fGeoAtt: UInt
|
||||||
|
public val fVolume: TGeoVolume? = null
|
||||||
|
public val fMother: TGeoVolume? = null
|
||||||
|
public val fNumber: Int = 0
|
||||||
|
public val fNovlp: Int = 0
|
||||||
|
public val fOverlaps: IntArray = intArrayOf()
|
||||||
|
}
|
||||||
|
|
||||||
|
public class TGeoNodeMatrix : TGeoMatrix() {
|
||||||
|
public val fMatrix: TGeoMatrix? = null
|
||||||
|
}
|
@ -0,0 +1,80 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public abstract class TGeoShape : TNamed() {
|
||||||
|
public val fShapeBits: UInt = 0u
|
||||||
|
public val fShapeId: Int = 0
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public open class TGeoBBox : TGeoShape() {
|
||||||
|
public val fDX: Double = 0.0
|
||||||
|
public val fDY: Double = 0.0
|
||||||
|
public val fDZ: Double = 0.0
|
||||||
|
public val fOrigin: DoubleArray = doubleArrayOf(0.0, 0.0, 0.0)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public sealed class TGeoBoolNode : TObject() {
|
||||||
|
public abstract val fLeft: TGeoShape
|
||||||
|
public abstract val fLeftMat: TGeoMatrix
|
||||||
|
public abstract val fRight: TGeoShape
|
||||||
|
public abstract val fRightMat: TGeoMatrix
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoUnion(
|
||||||
|
override val fLeft: TGeoShape,
|
||||||
|
override val fLeftMat: TGeoMatrix,
|
||||||
|
override val fRight: TGeoShape,
|
||||||
|
override val fRightMat: TGeoMatrix
|
||||||
|
) : TGeoBoolNode()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoSubtraction(
|
||||||
|
override val fLeft: TGeoShape,
|
||||||
|
override val fLeftMat: TGeoMatrix,
|
||||||
|
override val fRight: TGeoShape,
|
||||||
|
override val fRightMat: TGeoMatrix
|
||||||
|
) : TGeoBoolNode()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoIntersection(
|
||||||
|
override val fLeft: TGeoShape,
|
||||||
|
override val fLeftMat: TGeoMatrix,
|
||||||
|
override val fRight: TGeoShape,
|
||||||
|
override val fRightMat: TGeoMatrix
|
||||||
|
) : TGeoBoolNode()
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoCompositeShape(public val fNode: TGeoBoolNode) : TGeoBBox()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoXtru(
|
||||||
|
public val fNvert: Int,
|
||||||
|
public val fNz: Int,
|
||||||
|
public val fZcurrent: Double,
|
||||||
|
public val fX: DoubleArray,
|
||||||
|
public val fY: DoubleArray,
|
||||||
|
public val fZ: DoubleArray,
|
||||||
|
public val fScale: DoubleArray,
|
||||||
|
public val fX0: DoubleArray,
|
||||||
|
public val fY0: DoubleArray
|
||||||
|
) : TGeoBBox()
|
||||||
|
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoTube(
|
||||||
|
public val fRmin: Double,
|
||||||
|
public val fRmax: Double,
|
||||||
|
public val fDz: Double,
|
||||||
|
) : TGeoBBox()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoShapeAssembly(
|
||||||
|
public val fVolume: TGeoVolumeAssembly,
|
||||||
|
public val fBBoxOK: Boolean = true
|
||||||
|
): TGeoBBox()
|
@ -0,0 +1,22 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public open class TGeoVolume : TNamed(){
|
||||||
|
// "fGeoAtt" : 3084,
|
||||||
|
// "fLineColor" : 3,
|
||||||
|
// "fLineStyle" : 1,
|
||||||
|
// "fLineWidth" : 1,
|
||||||
|
// "fFillColor" : 19,
|
||||||
|
// "fFillStyle" : 1001,
|
||||||
|
public lateinit var fNodes: TObjArray
|
||||||
|
public lateinit var fShape: TGeoShape
|
||||||
|
public lateinit var fMedium: TGeoMedium
|
||||||
|
public val fNumber: Int = 1
|
||||||
|
public val fNtotal: Int = 1
|
||||||
|
public val fRefCount: Int = 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TGeoVolumeAssembly : TGeoVolume()
|
@ -0,0 +1,22 @@
|
|||||||
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public abstract class TObject {
|
||||||
|
public val fUniqueID: UInt = 0u
|
||||||
|
public val fBits: UInt = 0u
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public abstract class TNamed : TObject() {
|
||||||
|
public val fName: String = ""
|
||||||
|
public val fTitle: String = ""
|
||||||
|
}
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class TObjArray(public val arr: List<TObject>){
|
||||||
|
public companion object{
|
||||||
|
public val empty = TObjArray(emptyList())
|
||||||
|
}
|
||||||
|
}
|
@ -6,6 +6,7 @@ import react.RProps
|
|||||||
import react.child
|
import react.child
|
||||||
import react.functionalComponent
|
import react.functionalComponent
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.plotly.layout
|
||||||
import space.kscience.plotly.models.Trace
|
import space.kscience.plotly.models.Trace
|
||||||
import space.kscience.visionforge.markup.VisionOfMarkup
|
import space.kscience.visionforge.markup.VisionOfMarkup
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
@ -91,7 +92,10 @@ val GravityDemo = functionalComponent<DemoProps> { props ->
|
|||||||
height = 50.vh - 50.pt
|
height = 50.vh - 50.pt
|
||||||
}
|
}
|
||||||
plotly {
|
plotly {
|
||||||
traces(velocityTrace)
|
traces(velocityTrace,energyTrace)
|
||||||
|
layout {
|
||||||
|
xaxis.title = "time"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
Markup {
|
Markup {
|
||||||
attrs {
|
attrs {
|
||||||
|
@ -32,7 +32,7 @@ val Markup = functionalComponent<MarkupProps>("Markup") { props ->
|
|||||||
//TODO add new formats via plugins
|
//TODO add new formats via plugins
|
||||||
else -> error("Format ${vision.format} not recognized")
|
else -> error("Format ${vision.format} not recognized")
|
||||||
}
|
}
|
||||||
vision.useProperty(VisionOfMarkup::content) { content ->
|
vision.useProperty(VisionOfMarkup::content) { content: String? ->
|
||||||
element.clear()
|
element.clear()
|
||||||
element.append {
|
element.append {
|
||||||
markdown(flavour) { content ?: "" }
|
markdown(flavour) { content ?: "" }
|
||||||
|
@ -32,6 +32,7 @@ include(
|
|||||||
":visionforge-threejs",
|
":visionforge-threejs",
|
||||||
":visionforge-threejs:visionforge-threejs-server",
|
":visionforge-threejs:visionforge-threejs-server",
|
||||||
":visionforge-gdml",
|
":visionforge-gdml",
|
||||||
|
":cern-root-loader",
|
||||||
":visionforge-server",
|
":visionforge-server",
|
||||||
":visionforge-plotly",
|
":visionforge-plotly",
|
||||||
":visionforge-markdown",
|
":visionforge-markdown",
|
||||||
|
@ -13,9 +13,7 @@ import space.kscience.dataforge.names.Name
|
|||||||
import space.kscience.dataforge.names.NameToken
|
import space.kscience.dataforge.names.NameToken
|
||||||
import space.kscience.dataforge.names.isEmpty
|
import space.kscience.dataforge.names.isEmpty
|
||||||
import space.kscience.dataforge.names.length
|
import space.kscience.dataforge.names.length
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.*
|
||||||
import space.kscience.visionforge.VisionGroup
|
|
||||||
import space.kscience.visionforge.computeProperties
|
|
||||||
import space.kscience.visionforge.react.ThreeCanvasComponent
|
import space.kscience.visionforge.react.ThreeCanvasComponent
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
@ -85,7 +83,9 @@ public val ThreeCanvasWithControls: FunctionComponent<ThreeCanvasWithControlsPro
|
|||||||
|
|
||||||
useEffect {
|
useEffect {
|
||||||
props.context.launch {
|
props.context.launch {
|
||||||
solid = props.builderOfSolid.await()
|
solid = props.builderOfSolid.await().also {
|
||||||
|
it?.root(props.context.visionManager)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,4 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("multiplatform")
|
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("ru.mipt.npm.gradle.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -0,0 +1,95 @@
|
|||||||
|
package space.kscience.visionforge.gdml
|
||||||
|
|
||||||
|
import space.kscience.dataforge.meta.Meta
|
||||||
|
import space.kscience.dataforge.meta.MutableMeta
|
||||||
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.gdml.*
|
||||||
|
import space.kscience.visionforge.solid.Solid
|
||||||
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
|
import space.kscience.visionforge.solid.invoke
|
||||||
|
import space.kscience.visionforge.useStyle
|
||||||
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
public class GdmlLoaderOptions {
|
||||||
|
|
||||||
|
public enum class Action {
|
||||||
|
ADD,
|
||||||
|
REJECT,
|
||||||
|
PROTOTYPE
|
||||||
|
}
|
||||||
|
|
||||||
|
public var lUnit: LUnit = LUnit.MM
|
||||||
|
public var aUnit: AUnit = AUnit.RADIAN
|
||||||
|
|
||||||
|
public var solidAction: (GdmlSolid) -> Action = { Action.PROTOTYPE }
|
||||||
|
public var volumeAction: (GdmlGroup) -> Action = { Action.PROTOTYPE }
|
||||||
|
|
||||||
|
internal val styleCache = HashMap<Name, Meta>()
|
||||||
|
|
||||||
|
public fun Solid.registerAndUseStyle(name: String, builder: MutableMeta.() -> Unit) {
|
||||||
|
styleCache.getOrPut(Name.parse(name)) {
|
||||||
|
Meta(builder)
|
||||||
|
}
|
||||||
|
useStyle(name)
|
||||||
|
}
|
||||||
|
|
||||||
|
public fun Solid.transparent() {
|
||||||
|
registerAndUseStyle("transparent") {
|
||||||
|
SolidMaterial.MATERIAL_OPACITY_KEY put 0.3
|
||||||
|
"edges.enabled" put true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure paint for given solid with given [GdmlMaterial]
|
||||||
|
*/
|
||||||
|
public var configurePaint: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit =
|
||||||
|
{ material, _ -> color(randomColor(material)) }
|
||||||
|
private set
|
||||||
|
|
||||||
|
public fun paint(block: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit) {
|
||||||
|
configurePaint = block
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configure given solid
|
||||||
|
*/
|
||||||
|
public var configureSolid: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit =
|
||||||
|
{ parent, solid, material ->
|
||||||
|
val styleName = "materials.${material.name}"
|
||||||
|
|
||||||
|
if (parent.physVolumes.isNotEmpty()) transparent()
|
||||||
|
|
||||||
|
registerAndUseStyle(styleName) {
|
||||||
|
val vfMaterial = SolidMaterial().apply {
|
||||||
|
configurePaint(material, solid)
|
||||||
|
}
|
||||||
|
SolidMaterial.MATERIAL_KEY put vfMaterial.toMeta()
|
||||||
|
"Gdml.material" put material.name
|
||||||
|
}
|
||||||
|
}
|
||||||
|
private set
|
||||||
|
|
||||||
|
public fun configure(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) {
|
||||||
|
val oldConfigure = configureSolid
|
||||||
|
configureSolid = { parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial ->
|
||||||
|
oldConfigure(parent, solid, material)
|
||||||
|
block(parent, solid, material)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public companion object {
|
||||||
|
private val random: Random = Random(222)
|
||||||
|
|
||||||
|
private val colorCache = HashMap<GdmlMaterial, Int>()
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Use random color and cache it based on the material. Meaning that colors are random, but always the same for the
|
||||||
|
* same material.
|
||||||
|
*/
|
||||||
|
public fun randomColor(material: GdmlMaterial): Int {
|
||||||
|
return colorCache.getOrPut(material) { random.nextInt(16777216) }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,7 +1,5 @@
|
|||||||
package space.kscience.visionforge.gdml
|
package space.kscience.visionforge.gdml
|
||||||
|
|
||||||
import space.kscience.dataforge.meta.Meta
|
|
||||||
import space.kscience.dataforge.meta.MutableMeta
|
|
||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
@ -11,10 +9,8 @@ import space.kscience.gdml.*
|
|||||||
import space.kscience.visionforge.*
|
import space.kscience.visionforge.*
|
||||||
import space.kscience.visionforge.html.VisionOutput
|
import space.kscience.visionforge.html.VisionOutput
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY
|
|
||||||
import kotlin.math.cos
|
import kotlin.math.cos
|
||||||
import kotlin.math.sin
|
import kotlin.math.sin
|
||||||
import kotlin.random.Random
|
|
||||||
|
|
||||||
private val solidsName = "solids".asName()
|
private val solidsName = "solids".asName()
|
||||||
private val volumesName = "volumes".asName()
|
private val volumesName = "volumes".asName()
|
||||||
@ -25,91 +21,7 @@ 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
|
||||||
|
|
||||||
public class GdmlTransformer {
|
private class GdmlLoader(val settings: GdmlLoaderOptions) {
|
||||||
|
|
||||||
public enum class Action {
|
|
||||||
ADD,
|
|
||||||
REJECT,
|
|
||||||
PROTOTYPE
|
|
||||||
}
|
|
||||||
|
|
||||||
public var lUnit: LUnit = LUnit.MM
|
|
||||||
public var aUnit: AUnit = AUnit.RADIAN
|
|
||||||
|
|
||||||
public var solidAction: (GdmlSolid) -> Action = { Action.PROTOTYPE }
|
|
||||||
public var volumeAction: (GdmlGroup) -> Action = { Action.PROTOTYPE }
|
|
||||||
|
|
||||||
internal val styleCache = HashMap<Name, Meta>()
|
|
||||||
|
|
||||||
public fun Solid.registerAndUseStyle(name: String, builder: MutableMeta.() -> Unit) {
|
|
||||||
styleCache.getOrPut(Name.parse(name)) {
|
|
||||||
Meta(builder)
|
|
||||||
}
|
|
||||||
useStyle(name)
|
|
||||||
}
|
|
||||||
|
|
||||||
public fun Solid.transparent() {
|
|
||||||
registerAndUseStyle("transparent") {
|
|
||||||
SolidMaterial.MATERIAL_OPACITY_KEY put 0.3
|
|
||||||
"edges.enabled" put true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure paint for given solid with given [GdmlMaterial]
|
|
||||||
*/
|
|
||||||
public var configurePaint: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit =
|
|
||||||
{ material, _ -> color(randomColor(material)) }
|
|
||||||
private set
|
|
||||||
|
|
||||||
public fun paint(block: SolidMaterial.(material: GdmlMaterial, solid: GdmlSolid) -> Unit) {
|
|
||||||
configurePaint = block
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Configure given solid
|
|
||||||
*/
|
|
||||||
public var configureSolid: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit =
|
|
||||||
{ parent, solid, material ->
|
|
||||||
val styleName = "materials.${material.name}"
|
|
||||||
|
|
||||||
if (parent.physVolumes.isNotEmpty()) transparent()
|
|
||||||
|
|
||||||
registerAndUseStyle(styleName) {
|
|
||||||
val vfMaterial = SolidMaterial().apply {
|
|
||||||
configurePaint(material, solid)
|
|
||||||
}
|
|
||||||
MATERIAL_KEY put vfMaterial.toMeta()
|
|
||||||
"Gdml.material" put material.name
|
|
||||||
}
|
|
||||||
}
|
|
||||||
private set
|
|
||||||
|
|
||||||
public fun configure(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) {
|
|
||||||
val oldConfigure = configureSolid
|
|
||||||
configureSolid = { parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial ->
|
|
||||||
oldConfigure(parent, solid, material)
|
|
||||||
block(parent, solid, material)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public companion object {
|
|
||||||
private val random: Random = Random(222)
|
|
||||||
|
|
||||||
private val colorCache = HashMap<GdmlMaterial, Int>()
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Use random color and cache it based on the material. Meaning that colors are random, but always the same for the
|
|
||||||
* same material.
|
|
||||||
*/
|
|
||||||
public fun randomColor(material: GdmlMaterial): Int {
|
|
||||||
return colorCache.getOrPut(material) { random.nextInt(16777216) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
|
||||||
//private val materialCache = HashMap<GdmlMaterial, Meta>()
|
//private val materialCache = HashMap<GdmlMaterial, Meta>()
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -356,13 +268,13 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
|||||||
): Solid? {
|
): Solid? {
|
||||||
require(name != "") { "Can't use empty solid name. Use null instead." }
|
require(name != "") { "Can't use empty solid name. Use null instead." }
|
||||||
return when (settings.solidAction(solid)) {
|
return when (settings.solidAction(solid)) {
|
||||||
GdmlTransformer.Action.ADD -> {
|
GdmlLoaderOptions.Action.ADD -> {
|
||||||
addSolid(root, solid, name)
|
addSolid(root, solid, name)
|
||||||
}
|
}
|
||||||
GdmlTransformer.Action.PROTOTYPE -> {
|
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||||
proxySolid(root, this, solid, name ?: solid.name)
|
proxySolid(root, this, solid, name ?: solid.name)
|
||||||
}
|
}
|
||||||
GdmlTransformer.Action.REJECT -> {
|
GdmlLoaderOptions.Action.REJECT -> {
|
||||||
//ignore
|
//ignore
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -388,14 +300,14 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
when (settings.volumeAction(volume)) {
|
when (settings.volumeAction(volume)) {
|
||||||
GdmlTransformer.Action.ADD -> {
|
GdmlLoaderOptions.Action.ADD -> {
|
||||||
val group: SolidGroup = volume(root, volume)
|
val group: SolidGroup = volume(root, volume)
|
||||||
this[physVolume.name] = group.withPosition(root, physVolume)
|
this[physVolume.name] = group.withPosition(root, physVolume)
|
||||||
}
|
}
|
||||||
GdmlTransformer.Action.PROTOTYPE -> {
|
GdmlLoaderOptions.Action.PROTOTYPE -> {
|
||||||
proxyVolume(root, this, physVolume, volume)
|
proxyVolume(root, this, physVolume, volume)
|
||||||
}
|
}
|
||||||
GdmlTransformer.Action.REJECT -> {
|
GdmlLoaderOptions.Action.REJECT -> {
|
||||||
//ignore
|
//ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -460,16 +372,16 @@ private class GdmlTransformerEnv(val settings: GdmlTransformer) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public fun Gdml.toVision(block: GdmlTransformer.() -> Unit = {}): SolidGroup {
|
public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup {
|
||||||
val settings = GdmlTransformer().apply(block)
|
val settings = GdmlLoaderOptions().apply(block)
|
||||||
val context = GdmlTransformerEnv(settings)
|
val context = GdmlLoader(settings)
|
||||||
return context.transform(this)
|
return context.transform(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append Gdml node to the group
|
* Append Gdml node to the group
|
||||||
*/
|
*/
|
||||||
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlTransformer.() -> Unit = {}) {
|
public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> 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)
|
@ -9,7 +9,7 @@ public fun SolidGroup.gdml(
|
|||||||
file: Path,
|
file: Path,
|
||||||
key: String = "",
|
key: String = "",
|
||||||
usePreprocessor: Boolean = false,
|
usePreprocessor: Boolean = false,
|
||||||
transformer: GdmlTransformer.() -> Unit = {},
|
transformer: GdmlLoaderOptions.() -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val gdml = Gdml.decodeFromFile(file, usePreprocessor)
|
val gdml = Gdml.decodeFromFile(file, usePreprocessor)
|
||||||
gdml(gdml, key, transformer)
|
gdml(gdml, key, transformer)
|
||||||
|
Loading…
Reference in New Issue
Block a user