diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 8c73f7d9..4b57e1c0 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -8,15 +8,15 @@ on: jobs: build: runs-on: ubuntu-latest - timeout-minutes: 40 + timeout-minutes: 30 steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v3.5.3 - name: Set up JDK 11 - uses: actions/setup-java@v2.5.0 + uses: actions/setup-java@v3.12.0 with: java-version: 11 distribution: liberica - name: execute build - uses: gradle/gradle-build-action@v2 + uses: gradle/gradle-build-action@v2.7.1 with: arguments: build diff --git a/.gitignore b/.gitignore index 7fab40d3..6d07da58 100644 --- a/.gitignore +++ b/.gitignore @@ -7,3 +7,5 @@ build/ data/ !gradle-wrapper.jar + +/kotlin-js-store/yarn.lock diff --git a/CHANGELOG.md b/CHANGELOG.md index 2ffcb3c9..bf2c3478 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,14 +2,27 @@ ## [Unreleased] ### Added +- Context receivers flag +- MeshLine for thick lines +- Custom client-side events and thier processing in VisionServer ### Changed +- Color accessor property is now `colorProperty`. Color uses non-nullable `invoke` instead of `set`. +- API update for server and pages +- Edges moved to solids module for easier construction +- Visions **must** be rooted in order to subscribe to updates. +- Visions use flows instead of direct subscriptions. +- Radical change of inner workings of vision children and properties. +- Three package changed to `three`. +- Naming of Canvas3D options. +- Lights are added to the scene instead of 3D options. ### Deprecated ### Removed ### Fixed +- Jupyter integration for IDEA and Jupyter lab. ### Security diff --git a/build.gradle.kts b/build.gradle.kts index 0f892c76..b578696d 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,29 +1,50 @@ +import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile +import space.kscience.gradle.useApache2Licence +import space.kscience.gradle.useSPCTeam + plugins { - id("ru.mipt.npm.gradle.project") - id("org.jetbrains.kotlinx.kover") version "0.5.0-RC" + id("space.kscience.gradle.project") +// id("org.jetbrains.kotlinx.kover") version "0.5.0" } -val dataforgeVersion by extra("0.5.2") +val dataforgeVersion by extra("0.7.1") val fxVersion by extra("11") -allprojects{ +allprojects { group = "space.kscience" - version = "0.2.0" + version = "0.3.0-dev-17" } subprojects { if (name.startsWith("visionforge")) apply() repositories { + mavenLocal() maven("https://repo.kotlin.link") mavenCentral() maven("https://maven.jzy3d.org/releases") + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") + } + + tasks.withType { + kotlinOptions { + freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers" + } + } + + tasks.withType{ + kotlinOptions{ + useEsClasses = true + } } } ksciencePublish { - github("visionforge") - space() + pom("https://github.com/SciProgCentre/visionforge") { + useApache2Licence() + useSPCTeam() + } + repository("spc","https://maven.sciprog.center/kscience") sonatype() } diff --git a/cern-root-loader/build.gradle.kts b/cern-root-loader/build.gradle.kts index fa26fab5..fb787187 100644 --- a/cern-root-loader/build.gradle.kts +++ b/cern-root-loader/build.gradle.kts @@ -1,19 +1,14 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } kscience{ + jvm() + js() + dependencies { + api(projects.visionforgeSolid) + } useSerialization { json() } -} - -kotlin { - sourceSets { - val commonMain by getting { - dependencies { - api(project(":visionforge-solid")) - } - } - } } \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt new file mode 100644 index 00000000..5ae1671c --- /dev/null +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/BMN.kt @@ -0,0 +1,53 @@ +package ru.mipt.npm.root + +import kotlinx.serialization.Serializable +import kotlinx.serialization.builtins.ListSerializer +import kotlinx.serialization.json.Json +import kotlinx.serialization.json.JsonArray +import space.kscience.visionforge.solid.Float32Vector3D + + +@Serializable +public data class FairTrackParam( + val fX: Double, + val fY: Double, + val fZ: Double, + val fTx: Double, + val fTy: Double, + val fQp: Double, +) + +public fun FairTrackParam.toVector(): Float32Vector3D = Float32Vector3D(fX,fY,fZ) + +@Serializable +public data class CbmStsTrack( + val fParamFirst: FairTrackParam, + val fParamLast: FairTrackParam, +) + +@Serializable +public data class BmnGlobalTrack( + val fParamFirst: FairTrackParam, + val fParamLast: FairTrackParam, +) + +public class BmnEventContainer( + public val cbmTracks: List, + public val bmnGlobalTracks: List, +) + +public object BMN { + public val json: Json = Json { + ignoreUnknownKeys = true + classDiscriminator = "_typename" + } + + public fun readEventJson(string: String): BmnEventContainer { + val jsonArray = json.parseToJsonElement(string) as JsonArray + val cbmTracks: List = + json.decodeFromJsonElement(ListSerializer(CbmStsTrack.serializer()), jsonArray[0]) + val bmnGlobalTracks: List = + json.decodeFromJsonElement(ListSerializer(BmnGlobalTrack.serializer()), jsonArray[1]) + return BmnEventContainer(cbmTracks, bmnGlobalTracks) + } +} \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt index 5af50c3f..6d959f4f 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/DObject.kt @@ -5,7 +5,6 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.Named import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.doubleArray import kotlin.properties.ReadOnlyProperty public fun MetaProvider.doubleArray( @@ -43,7 +42,7 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac } internal fun tObjectArray( - builder: (Meta, DObjectCache) -> T + builder: (Meta, DObjectCache) -> T, ): ReadOnlyProperty> = ReadOnlyProperty { _, property -> meta.getIndexed(Name.of(property.name, "arr")).values.mapNotNull { resolve(builder, it) @@ -52,9 +51,9 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac internal fun dObject( builder: (Meta, DObjectCache) -> T, - key: Name? = null + key: Name? = null, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> - meta[key ?: property.name.asName()]?.let { resolve(builder, it) } + meta[key ?: property.name.asName()]?.takeIf { it.value != Null }?.let { resolve(builder, it) } } } @@ -63,8 +62,7 @@ public open class DNamed(meta: Meta, refCache: DObjectCache) : DObject(meta, ref public val fTitle: String by meta.string("") } -public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { -} +public class DGeoMaterial(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) public class DGeoMedium(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { public val fMaterial: DGeoMaterial? by dObject(::DGeoMaterial) @@ -91,27 +89,69 @@ public class DGeoNode(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCach public val fVolume: DGeoVolume? by dObject(::DGeoVolume) } -public open class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) +public sealed class DGeoMatrix(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) -public open class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { +public class DGeoIdentity(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) + +public class DGeoScale(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { public val fScale: DoubleArray by meta.doubleArray(1.0, 1.0, 1.0) public val x: Double get() = fScale[0] public val y: Double get() = fScale[1] public val z: Double get() = fScale[2] } +public class DGeoRotation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotationMatrix: DoubleArray by meta.doubleArray() +} + +public class DGeoTranslation(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fTranslation: DoubleArray by meta.doubleArray() +} + +public open class DGeoCombiTrans(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotation: DGeoRotation? by dObject(::DGeoRotation) + public val fTranslation: DoubleArray by meta.doubleArray() +} + +public class DGeoGenTrans(meta: Meta, refCache: DObjectCache) : DGeoCombiTrans(meta, refCache) { + public val fScale: DoubleArray by meta.doubleArray() +} + +public class DGeoHMatrix(meta: Meta, refCache: DObjectCache) : DGeoMatrix(meta, refCache) { + public val fRotation: DGeoRotation? by dObject(::DGeoRotation) + public val fTranslation: DoubleArray by meta.doubleArray() + public val fScale: DoubleArray by meta.doubleArray() +} + +/** + * Create a specialized version of [DGeoMatrix] + */ +internal fun dGeoMatrix( + meta: Meta, + refCache: DObjectCache, +): DGeoMatrix = when (val typename = meta["_typename"].string) { + null -> error("Type name is undefined") + "TGeoIdentity" -> DGeoIdentity(meta, refCache) + "TGeoScale" -> DGeoScale(meta, refCache) + "TGeoRotation" -> DGeoRotation(meta, refCache) + "TGeoTranslation" -> DGeoTranslation(meta, refCache) + "TGeoCombiTrans" -> DGeoCombiTrans(meta, refCache) + "TGeoGenTrans" -> DGeoGenTrans(meta, refCache) + "TGeoHMatrix" -> DGeoHMatrix(meta, refCache) + else -> error("$typename is not a member of TGeoMatrix") +} public class DGeoBoolNode(meta: Meta, refCache: DObjectCache) : DObject(meta, refCache) { public val fLeft: DGeoShape? by dObject(::DGeoShape) - public val fLeftMat: DGeoMatrix? by dObject(::DGeoMatrix) + public val fLeftMat: DGeoMatrix? by dObject(::dGeoMatrix) public val fRight: DGeoShape? by dObject(::DGeoShape) - public val fRightMat: DGeoMatrix? by dObject(::DGeoMatrix) + public val fRightMat: DGeoMatrix? by dObject(::dGeoMatrix) } public class DGeoManager(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) { - public val fMatrices: List by tObjectArray(::DGeoMatrix) + public val fMatrices: List by tObjectArray(::dGeoMatrix) public val fShapes: List by tObjectArray(::DGeoShape) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt index 7c345dd4..2c501fd7 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/dRootToSolid.kt @@ -1,13 +1,23 @@ package ru.mipt.npm.root -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.doubleArray +import space.kscience.dataforge.names.withIndex +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.geometry.fromRotationMatrix +import space.kscience.kmath.linear.VirtualMatrix +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.isEmpty import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY -import kotlin.math.* +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin private val volumesName = Name.EMPTY //"volumes".asName() @@ -20,51 +30,48 @@ private fun degToRad(d: Double) = d * PI / 180.0 private data class RootToSolidContext( val prototypeHolder: PrototypeHolder, val currentLayer: Int = 0, - val maxLayer: Int = 5 + val maxLayer: Int = 5, + val ignoreRootColors: Boolean = false, + val colorCache: MutableMap = mutableMapOf(), ) -// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix +// apply rotation from a matrix private fun Solid.rotate(rot: DoubleArray) { - val xAngle = atan2(-rot[5], rot[8]) - val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) - val zAngle = atan2(-rot[1], rot[0]) - rotation = Point3D(xAngle, yAngle, zAngle) + val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] } + quaternion = Quaternion.fromRotationMatrix(matrix) } private fun Solid.translate(trans: DoubleArray) { val (x, y, z) = trans - position = Point3D(x, y, z) + position = Float32Vector3D(x, y, z) } -private fun Solid.useMatrix(matrix: DGeoMatrix?) { - if (matrix == null) return - when (matrix.typename) { - "TGeoIdentity" -> { - //do nothing - } - "TGeoTranslation" -> { - val fTranslation by matrix.meta.doubleArray() - translate(fTranslation) - } - "TGeoRotation" -> { - val fRotationMatrix by matrix.meta.doubleArray() - rotate(fRotationMatrix) - } - "TGeoCombiTrans" -> { - val fTranslation by matrix.meta.doubleArray() +private fun Solid.scale(s: DoubleArray) { + scale = Float32Vector3D(s[0], s[1], s[2]) +} - translate(fTranslation) - matrix.meta["fRotation.fRotationMatrix"]?.value?.let { - rotate(it.doubleArray) - } +private fun Solid.useMatrix(matrix: DGeoMatrix?): Unit { + when (matrix) { + null -> {} + is DGeoIdentity -> {} + is DGeoTranslation -> translate(matrix.fTranslation) + is DGeoRotation -> rotate(matrix.fRotationMatrix) + is DGeoScale -> scale(matrix.fScale) + is DGeoGenTrans -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + scale(matrix.fScale) } - "TGeoHMatrix" -> { - val fTranslation by matrix.meta.doubleArray() - val fRotationMatrix by matrix.meta.doubleArray() - val fScale by matrix.meta.doubleArray() - translate(fTranslation) - rotate(fRotationMatrix) - scale = Point3D(fScale[0], fScale[1], fScale[2]) + + is DGeoCombiTrans -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + } + + is DGeoHMatrix -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + scale(matrix.fScale) } } } @@ -73,7 +80,7 @@ private fun SolidGroup.addShape( shape: DGeoShape, context: RootToSolidContext, name: String? = shape.fName.ifEmpty { null }, - block: Solid.() -> Unit = {} + block: Solid.() -> Unit = {}, ) { when (shape.typename) { "TGeoCompositeShape" -> { @@ -87,13 +94,14 @@ private fun SolidGroup.addShape( } smartComposite(compositeType, name = name) { addShape(node.fLeft!!, context, null) { - this.useMatrix(node.fLeftMat) + useMatrix(node.fLeftMat) } addShape(node.fRight!!, context, null) { - this.useMatrix(node.fRightMat) + useMatrix(node.fRightMat) } }.apply(block) } + "TGeoXtru" -> { val fNvert by shape.meta.int(0) val fX by shape.meta.doubleArray() @@ -105,8 +113,8 @@ private fun SolidGroup.addShape( val fScale by shape.meta.doubleArray() extruded(name = name) { - (0 until fNvert).forEach { index -> - shape { + shape { + (0 until fNvert).forEach { index -> point(fX[index], fY[index]) } } @@ -121,6 +129,7 @@ private fun SolidGroup.addShape( } }.apply(block) } + "TGeoTube" -> { val fRmax by shape.meta.double(0.0) val fDz by shape.meta.double(0.0) @@ -134,6 +143,7 @@ private fun SolidGroup.addShape( block = block ) } + "TGeoTubeSeg" -> { val fRmax by shape.meta.double(0.0) val fDz by shape.meta.double(0.0) @@ -151,6 +161,7 @@ private fun SolidGroup.addShape( block = block ) } + "TGeoPcon" -> { val fDphi by shape.meta.double(0.0) val fNz by shape.meta.int(2) @@ -170,14 +181,14 @@ private fun SolidGroup.addShape( name = name, ) { z = (fZ[1] + fZ[0]) / 2 - }.apply(block) } else { - TODO() + TODO("Polycone is not implemented") } } + "TGeoPgon" -> { - //TODO add a inner polygone layer + val fDphi by shape.meta.double(0.0) val fNz by shape.meta.int(2) val fPhi1 by shape.meta.double(360.0) @@ -190,31 +201,41 @@ private fun SolidGroup.addShape( val startphi = degToRad(fPhi1) val deltaphi = degToRad(fDphi) - extruded(name) { + fun Shape2DBuilder.pGon(radius: Double){ + (0.. 1) { "The polyhedron geometry requires at least two planes" } - val baseRadius = fRmax[0] - shape { - (0..fNedges).forEach { - val phi = deltaphi * fNedges * it + startphi - (baseRadius * cos(phi) to baseRadius * sin(phi)) - } - } - (0 until fNz).forEach { index -> - //scaling all radii relative to first layer radius - layer(fZ[index], scale = fRmax[index] / baseRadius) + for (index in 0 until fNz){ + layer( + fZ[index], + innerBuilder = { + pGon(fRmin[index]) + }, + outerBuilder = { + pGon(fRmax[index]) + } + ) } }.apply(block) } + "TGeoShapeAssembly" -> { val fVolume by shape.dObject(::DGeoVolume) fVolume?.let { volume -> - addRootVolume(volume, context, block = block) + addRootVolume(volume, context, name = volume.fName.ifEmpty { null }, block = block) } } + "TGeoBBox" -> { box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name, block = block) } + "TGeoTrap" -> { val fTheta by shape.meta.double(0.0) val fPhi by shape.meta.double(0.0) @@ -232,27 +253,67 @@ private fun SolidGroup.addShape( val fDz by shape.meta.double(0.0) //TODO check proper node order - val node1 = Point3D(-fBl1, -fH1, -fDz) - val node2 = Point3D(fBl1, -fH1, -fDz) - val node3 = Point3D(fTl1, fH1, -fDz) - val node4 = Point3D(-fTl1, fH1, -fDz) - val node5 = Point3D(-fBl2, -fH2, fDz) - val node6 = Point3D(fBl2, -fH2, fDz) - val node7 = Point3D(fTl2, fH2, fDz) - val node8 = Point3D(-fTl2, fH2, fDz) + val node1 = Float32Vector3D(-fBl1, -fH1, -fDz) + val node2 = Float32Vector3D(fBl1, -fH1, -fDz) + val node3 = Float32Vector3D(fTl1, fH1, -fDz) + val node4 = Float32Vector3D(-fTl1, fH1, -fDz) + val node5 = Float32Vector3D(-fBl2, -fH2, fDz) + val node6 = Float32Vector3D(fBl2, -fH2, fDz) + val node7 = Float32Vector3D(fTl2, fH2, fDz) + val node8 = Float32Vector3D(-fTl2, fH2, fDz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } + "TGeoScaledShape" -> { val fShape by shape.dObject(::DGeoShape) val fScale by shape.dObject(::DGeoScale) fShape?.let { scaledShape -> - group(name?.let { Name.parse(it) }) { - scale = Point3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0) + solidGroup(name?.let { Name.parse(it) }) { + scale = Float32Vector3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0) addShape(scaledShape, context) apply(block) } } } + + "TGeoCone" -> { + val fDz by shape.meta.double(0.0) + val fRmin1 by shape.meta.double(0.0) + val fRmax1 by shape.meta.double(0.0) + val fRmin2 by shape.meta.double(0.0) + val fRmax2 by shape.meta.double(0.0) + + coneSurface( + bottomOuterRadius = fRmax1, + bottomInnerRadius = fRmin1, + height = fDz * 2.0, + topOuterRadius = fRmax2, + topInnerRadius = fRmin2, + name = name, + ) + } + + "TGeoCtub" -> { + val fRmin by shape.meta.double(0.0) + val fRmax by shape.meta.double(0.0) + val fDz by shape.meta.double(0.0) + val fPhi1 by shape.meta.double(0.0) + val fPhi2 by shape.meta.double(PI2.toDouble()) + val fNlow by shape.meta.doubleArray() + val fNhigh by shape.meta.doubleArray() + + cutTube( + outerRadius = fRmax, + innerRadius = fRmin, + height = fDz * 2.0, + startAngle = degToRad(fPhi1), + angle = degToRad(fPhi2 - fPhi1), + topNormal = Float32Vector3D(fNhigh[0], fNhigh[1], fNhigh[2]), + bottomNormal = Float32Vector3D(fNlow[0], fNlow[1], fNlow[2]), + name = name, + ) + } + else -> { TODO("A shape with type ${shape.typename} not implemented") } @@ -264,9 +325,10 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) { addRootVolume(volume, context, obj.fName) { when (obj.typename) { "TGeoNodeMatrix" -> { - val fMatrix by obj.dObject(::DGeoMatrix) + val fMatrix by obj.dObject(::dGeoMatrix) this.useMatrix(fMatrix) } + "TGeoNodeOffset" -> { val fOffset by obj.meta.double(0.0) x = fOffset @@ -276,12 +338,12 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) { } private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? { - val group = SolidGroup { + val group = SolidGroup().apply { //set current layer layer = context.currentLayer val nodes = volume.fNodes - if (nodes.isEmpty() || context.currentLayer >= context.maxLayer) { + if (volume.typename != "TGeoVolumeAssembly" && (nodes.isEmpty() || context.currentLayer >= context.maxLayer)) { //TODO add smart filter volume.fShape?.let { shape -> addShape(shape, context) @@ -301,12 +363,22 @@ private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? } } } - return if (group.isEmpty()) { + return if (group.children.isEmpty()) { null - } else if (group.children.size == 1 && group.meta.isEmpty()) { - (group.children.values.first() as Solid).apply { parent = null } + } else if (group.items.size == 1 && group.properties.own == null) { + group.items.values.first().apply { parent = null } } else { group + }.apply { + volume.fMedium?.let { medium -> + color(context.colorCache.getOrPut(medium.meta) { RootColors[11 + context.colorCache.size] }) + } + + if (!context.ignoreRootColors) { + volume.fFillColor?.let { + properties[MATERIAL_COLOR_KEY] = RootColors[it] + } + } } } @@ -317,46 +389,42 @@ private fun SolidGroup.addRootVolume( context: RootToSolidContext, name: String? = null, cache: Boolean = true, - block: Solid.() -> Unit = {} + block: Solid.() -> Unit = {}, ) { - val combinedName = if (volume.fName.isEmpty()) { - name - } else if (name == null) { - volume.fName - } else { - "${name}_${volume.fName}" + val combinedName = name?.parseAsName()?.let { + // this fix is required to work around malformed root files with duplicated node names + if (get(it) != null) { + it.withIndex(volume.hashCode().toString(16)) + } else { + it + } } if (!cache) { - val group = buildVolume(volume, context)?.apply { - volume.fFillColor?.let { - meta[MATERIAL_COLOR_KEY] = RootColors[it] - } - block() - } - set(combinedName?.let { Name.parse(it) }, group) + val group = buildVolume(volume, context)?.apply(block) ?: return + setChild(combinedName, group) } else { val templateName = volumesName + volume.name - val existing = getPrototype(templateName) + val existing = context.prototypeHolder.getPrototype(templateName) if (existing == null) { context.prototypeHolder.prototypes { - val group = buildVolume(volume, context) - set(templateName, group) + val group = buildVolume(volume, context) ?: return@prototypes + setChild(templateName, group) } } - ref(templateName, name).apply { - volume.fFillColor?.let { - meta[MATERIAL_COLOR_KEY] = RootColors[it] - } - block() - } + ref(templateName, combinedName).apply(block) } } -public fun DGeoManager.toSolid(): SolidGroup = SolidGroup { - val context = RootToSolidContext(this) - fNodes.forEach { node -> +public fun MutableVisionContainer.rootGeo( + dGeoManager: DGeoManager, + name: String? = null, + maxLayer: Int = 5, + ignoreRootColors: Boolean = false, +): SolidGroup = solidGroup(name = name?.parseAsName()) { + val context = RootToSolidContext(this, maxLayer = maxLayer, ignoreRootColors = ignoreRootColors) + dGeoManager.fNodes.forEach { node -> addRootNode(node, context) } } \ No newline at end of file diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt index 9ea9c040..9f06125e 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/rootColor.kt @@ -1,7 +1,7 @@ package ru.mipt.npm.root public object RootColors { - private val colorMap = Array(924) { "white" } + private val colorMap = MutableList(924) { "white" } //colorMap[110] = "white" diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt index 5d338394..e3cf446c 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/jsonToRoot.kt @@ -12,9 +12,10 @@ import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass +@Suppress("UNUSED_PARAMETER") private fun jsonRootDeserializer( tSerializer: KSerializer, - builder: (JsonElement) -> T + builder: (JsonElement) -> T, ): DeserializationStrategy = object : DeserializationStrategy { private val jsonElementSerializer = JsonElement.serializer() @@ -46,6 +47,7 @@ private object RootDecoder { private val refCache: List, ) : KSerializer by tSerializer { + @OptIn(ExperimentalSerializationApi::class) @Suppress("UNCHECKED_CAST") override fun deserialize(decoder: Decoder): T { val input = decoder as JsonDecoder @@ -82,7 +84,7 @@ private object RootDecoder { return ref.getOrPutValue { // println("Decoding $it") - val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content +// val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content input.json.decodeFromJsonElement(tSerializer, it) } } @@ -90,9 +92,8 @@ private object RootDecoder { private fun KSerializer.unref(refCache: List): KSerializer = RootUnrefSerializer(this, refCache) - @OptIn(ExperimentalSerializationApi::class) fun unrefSerializersModule( - refCache: List + refCache: List, ): SerializersModule = SerializersModule { contextual(TObjArray::class) { @@ -118,7 +119,7 @@ private object RootDecoder { subclass(TGeoCompositeShape.serializer().unref(refCache)) subclass(TGeoShapeAssembly.serializer().unref(refCache)) - default { + defaultDeserializer { if (it == null) { TGeoShape.serializer().unref(refCache) } else { @@ -136,7 +137,7 @@ private object RootDecoder { val unrefed = TGeoMatrix.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { @@ -149,7 +150,7 @@ private object RootDecoder { subclass(TGeoVolumeAssembly.serializer().unref(refCache)) val unrefed = TGeoVolume.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { @@ -163,7 +164,7 @@ private object RootDecoder { subclass(TGeoNodeOffset.serializer().unref(refCache)) val unrefed = TGeoNode.serializer().unref(refCache) - default { + defaultDeserializer { if (it == null) { unrefed } else { @@ -197,11 +198,13 @@ private object RootDecoder { fillCache(it) } } + is JsonArray -> { element.forEach { fillCache(it) } } + else -> { //ignore primitives } @@ -216,6 +219,7 @@ private object RootDecoder { var value: Any? = null + @Suppress("UNCHECKED_CAST") fun getOrPutValue(builder: (JsonElement) -> T): T { if (value == null) { value = builder(element) diff --git a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt index 117e51b3..eb39b8e7 100644 --- a/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt +++ b/cern-root-loader/src/commonMain/kotlin/ru/mipt/npm/root/serialization/rootToSolid.kt @@ -3,6 +3,7 @@ package ru.mipt.npm.root.serialization import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.solid.* import kotlin.math.PI import kotlin.math.atan2 @@ -24,12 +25,12 @@ private fun Solid.rotate(rot: DoubleArray) { val xAngle = atan2(-rot[5], rot[8]) val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2))) val zAngle = atan2(-rot[1], rot[0]) - rotation = Point3D(xAngle, yAngle, zAngle) + rotation = Float32Vector3D(xAngle, yAngle, zAngle) } private fun Solid.translate(trans: DoubleArray) { val (x, y, z) = trans - position = Point3D(x, y, z) + position = Float32Vector3D(x, y, z) } private fun Solid.useMatrix(matrix: TGeoMatrix?) { @@ -51,7 +52,7 @@ private fun Solid.useMatrix(matrix: TGeoMatrix?) { translate(matrix.fTranslation) rotate(matrix.fRotationMatrix) val (xScale, yScale, zScale) = matrix.fScale - scale = Point3D(xScale, yScale, zScale) + scale = Float32Vector3D(xScale, yScale, zScale) } } } @@ -132,7 +133,7 @@ private fun buildGroup(volume: TGeoVolume): SolidGroup { return if (volume is TGeoVolumeAssemblyRef) { buildGroup(volume.value) } else { - SolidGroup { + SolidGroup().apply { volume.fShape?.let { addShape(it) } volume.fNodes?.let { it.arr.forEach { obj -> @@ -160,7 +161,7 @@ private fun SolidGroup.volume(volume: TGeoVolume, name: String? = null, cache: B name = combinedName, obj = group, prototypeHolder = rootPrototypes, - templateName = volumesName + Name.parse(combinedName ?: "volume[${group.hashCode()}]") + prototypeName = volumesName + Name.parse(combinedName ?: "volume[${group.hashCode()}]") ) } @@ -180,8 +181,8 @@ private fun SolidGroup.volume(volume: TGeoVolume, name: String? = null, cache: B // } -public fun TGeoManager.toSolid(): SolidGroup = SolidGroup { - fNodes.arr.forEach { +public fun MutableVisionContainer.rootGeo(tGeoManager: TGeoManager): SolidGroup = solidGroup { + tGeoManager.fNodes.arr.forEach { node(it) } } \ No newline at end of file diff --git a/demo/build.gradle.kts b/demo/build.gradle.kts new file mode 100644 index 00000000..49476bc7 --- /dev/null +++ b/demo/build.gradle.kts @@ -0,0 +1,11 @@ +import org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode +import org.jetbrains.kotlin.gradle.dsl.KotlinProjectExtension +import org.jetbrains.kotlin.gradle.plugin.KotlinPluginWrapper + +subprojects { + plugins.withType { + configure { + explicitApi = ExplicitApiMode.Disabled + } + } +} \ No newline at end of file diff --git a/demo/gdml/build.gradle.kts b/demo/gdml/build.gradle.kts index a6c3fb0a..4cccf686 100644 --- a/demo/gdml/build.gradle.kts +++ b/demo/gdml/build.gradle.kts @@ -1,60 +1,68 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule - plugins { - id("ru.mipt.npm.gradle.mpp") - application + id("space.kscience.gradle.mpp") } +group = "demo" + kscience { - val fxVersion: String by rootProject.extra - useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) - application() -} - -kotlin { - jvm { - withJava() - } - + jvm() js { useCommonJs() browser { + binaries.executable() commonWebpackConfig { - cssSupport.enabled = false + cssSupport { + enabled.set(false) + } } } } - - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) - implementation(project(":visionforge-gdml")) - } - } - jvmMain { - dependencies { - implementation(project(":visionforge-fx")) - implementation("ch.qos.logback:logback-classic:1.2.5") - } - } - jsMain { - dependencies { - implementation(project(":ui:ring")) - implementation(project(":visionforge-threejs")) - implementation(npm("react-file-drop", "3.0.6")) - } - } + dependencies { + implementation(projects.visionforgeSolid) + implementation(projects.visionforgeGdml) + } + jvmMain { +// implementation(project(":visionforge-fx")) + implementation(spclibs.logback.classic) + } + jsMain { + implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) + implementation(npm("react-file-drop", "3.0.6")) } } -application { - mainClass.set("space.kscience.visionforge.gdml.demo.GdmlFxDemoAppKt") +kotlin { + explicitApi = null } -val convertGdmlToJson by tasks.creating(JavaExec::class) { - group = "application" - classpath = sourceSets["main"].runtimeClasspath - mainClass.set("space.kscience.dataforge.vis.spatial.gdml.demo.SaveToJsonKt") -} \ No newline at end of file +//kotlin { +// +// sourceSets { +// commonMain { +// dependencies { +// implementation(project(":visionforge-solid")) +// implementation(project(":visionforge-gdml")) +// } +// } +// jvmMain { +// dependencies { +//// implementation(project(":visionforge-fx")) +// implementation("ch.qos.logback:logback-classic:1.2.11") +// } +// } +// jsMain { +// dependencies { +// implementation(project(":ui:ring")) +// implementation(project(":visionforge-threejs")) +// implementation(npm("react-file-drop", "3.0.6")) +// } +// } +// } +//} + +//val convertGdmlToJson by tasks.creating(JavaExec::class) { +// group = "application" +// classpath = sourceSets["main"].runtimeClasspath +// mainClass.set("space.kscience.dataforge.vis.spatial.gdml.demo.SaveToJsonKt") +//} \ No newline at end of file diff --git a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt index 12918532..6ade4ec8 100644 --- a/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt +++ b/demo/gdml/src/commonTest/kotlin/space/kscience/visionforge/gdml/GDMLVisionTest.kt @@ -1,13 +1,11 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties -import space.kscience.visionforge.get -import space.kscience.visionforge.setProperty +import space.kscience.visionforge.getChild import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.material @@ -20,8 +18,8 @@ class GDMLVisionTest { @Test fun testCubesStyles(){ - val segment = cubes["composite-000.segment-0"] as Solid - println(segment.computeProperties().getValue(Vision.STYLE_KEY)) + val segment = cubes.children.getChild("composite-000.segment-0") as Solid + println(segment.properties.getValue(Vision.STYLE_KEY)) // println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY)) // println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY)) @@ -35,7 +33,7 @@ class GDMLVisionTest { fun testPrototypeProperty() { val child = cubes[Name.of("composite-000","segment-0")] assertNotNull(child) - child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) - assertEquals("red", child.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.string) + child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue()) + assertEquals("red", child.properties[SolidMaterial.MATERIAL_COLOR_KEY].string) } } \ No newline at end of file diff --git a/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt b/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt index 635c4580..5116155b 100644 --- a/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt +++ b/demo/gdml/src/jsMain/kotlin/drop/FileDrop.kt @@ -9,30 +9,38 @@ import react.Component import react.Props import react.State -external enum class DropEffects { - copy, - move, - link, - none +sealed external class DropEffects { + @JsName("copy") + object Copy : DropEffects + + @JsName("move") + object Move : DropEffects + + @JsName("link") + object Link : DropEffects + + @JsName("none") + object None : DropEffects } -external interface FileDropProps: Props { +external interface FileDropProps : Props { var className: String? var targetClassName: String? var draggingOverFrameClassName: String? var draggingOverTargetClassName: String? -// var frame?: Exclude | HTMLDocument; + // var frame?: Exclude | HTMLDocument; var onFrameDragEnter: ((event: DragEvent) -> Unit)? var onFrameDragLeave: ((event: DragEvent) -> Unit)? var onFrameDrop: ((event: DragEvent) -> Unit)? -// var onDragOver: ReactDragEventHandler? + + // var onDragOver: ReactDragEventHandler? // var onDragLeave: ReactDragEventHandler? var onDrop: ((files: FileList?, event: dynamic) -> Unit)?//event:DragEvent) var dropEffect: DropEffects? } -external interface FileDropState: State { +external interface FileDropState : State { var draggingOverFrame: Boolean var draggingOverTarget: Boolean } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt index 823297ec..37c178f4 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GDMLAppComponent.kt @@ -10,13 +10,11 @@ import org.w3c.files.get import react.Props import react.dom.h2 import react.fc -import react.useMemo import react.useState -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch import space.kscience.dataforge.names.Name import space.kscience.gdml.Gdml import space.kscience.gdml.decodeFromString +import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.markLayers import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.ring.ThreeCanvasWithControls @@ -24,18 +22,19 @@ import space.kscience.visionforge.ring.tab import space.kscience.visionforge.setAsRoot import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke import styled.css import styled.styledDiv external interface GDMLAppProps : Props { - var context: Context + var solids: Solids var vision: Solid? var selected: Name? } @JsExport val GDMLApp = fc("GDMLApp") { props -> - val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager } var deferredVision: Deferred by useState { CompletableDeferred(props.vision) } @@ -50,12 +49,15 @@ val GDMLApp = fc("GDMLApp") { props -> name.endsWith(".gdml") || name.endsWith(".xml") -> { val gdml = Gdml.decodeFromString(data) gdml.toVision().apply { - setAsRoot(visionManager) + setAsRoot(props.solids.visionManager) console.info("Marking layers for file $name") markLayers() + ambientLight { + color(Colors.white) + } } } - name.endsWith(".json") -> visionManager.decodeFromString(data) + name.endsWith(".json") -> props.solids.visionManager.decodeFromString(data) else -> { window.alert("File extension is not recognized: $name") error("File extension is not recognized: $name") @@ -76,7 +78,7 @@ val GDMLApp = fc("GDMLApp") { props -> } child(ThreeCanvasWithControls) { attrs { - this.context = props.context + this.solids = props.solids this.builderOfSolid = deferredVision this.selected = props.selected tab("Load") { diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt index 74246432..7c6514bf 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlJsDemoApp.kt @@ -1,12 +1,18 @@ package space.kscience.visionforge.gdml.demo -import kotlinx.browser.document import kotlinx.css.* -import react.dom.render +import org.w3c.dom.Document import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.request import space.kscience.gdml.GdmlShowCase import space.kscience.visionforge.Application +import space.kscience.visionforge.Colors import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.react.createRoot +import space.kscience.visionforge.react.render +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication import styled.injectGlobal @@ -14,7 +20,7 @@ import styled.injectGlobal private class GDMLDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val context = Context("gdml-demo"){ plugin(ThreePlugin) } @@ -39,12 +45,16 @@ private class GDMLDemoApp : Application { val element = document.getElementById("application") ?: error("Element with id 'application' not found on page") - render(element) { + createRoot(element).render { child(GDMLApp) { - val vision = GdmlShowCase.cubes().toVision() + val vision = GdmlShowCase.cubes().toVision().apply { + ambientLight { + color(Colors.white) + } + } //println(context.plugins.fetch(VisionManager).encodeToString(vision)) attrs { - this.context = context + this.solids = context.request(Solids) this.vision = vision } } diff --git a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt index e91fedee..2478c3af 100644 --- a/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt +++ b/demo/gdml/src/jsMain/kotlin/space/kscience/visionforge/gdml/demo/fileDrop.kt @@ -2,7 +2,6 @@ package space.kscience.visionforge.gdml.demo import drop.FileDrop import kotlinx.css.* -import kotlinx.css.properties.border import org.w3c.files.FileList import react.RBuilder import styled.css @@ -13,7 +12,7 @@ import styled.styledDiv fun RBuilder.fileDrop(title: String, action: (files: FileList?) -> Unit) { styledDiv { css { - border(style = BorderStyle.dashed, width = 1.px, color = Color.orange) + border = Border(style = BorderStyle.dashed, width = 1.px, color = Color.orange) flexGrow = 0.0 alignContent = Align.center } diff --git a/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt b/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt index 83e750ba..92cc69aa 100644 --- a/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt +++ b/demo/gdml/src/jvmMain/kotlin/space/kscience/visionforge/gdml/demo/GdmlFxDemoApp.kt @@ -1,83 +1,83 @@ -package space.kscience.visionforge.gdml.demo - -import javafx.geometry.Orientation -import javafx.scene.Parent -import javafx.stage.FileChooser -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch -import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.editor.VisionEditorFragment -import space.kscience.visionforge.editor.VisionTreeFragment -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.solid.FX3DPlugin -import space.kscience.visionforge.solid.FXCanvas3D -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidMaterial -import tornadofx.* - -class GDMLDemoApp : App(GDMLView::class) - -class GDMLView : View() { - private val context = Context { - plugin(FX3DPlugin) - } - - private val fx3d = context.fetch(FX3DPlugin) - private val visionManager = context.fetch(VisionManager) - private val canvas = FXCanvas3D(fx3d) - - private val treeFragment = VisionTreeFragment().apply { - this.itemProperty.bind(canvas.rootObjectProperty) - } - - private val propertyEditor = VisionEditorFragment().apply { - descriptorProperty.set(SolidMaterial.descriptor) - visionProperty.bind(treeFragment.selectedProperty) - } - - override val root: Parent = borderpane { - top { - buttonbar { - button("Load GDML/json") { - action { - val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull() - if (file != null) { - runAsync { - visionManager.readFile(file) as Solid - } ui { - canvas.render(it) - } - } - } - } - } - } - center { - splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) { - setDividerPositions(0.2, 0.6, 0.2) - } - } - } - - init { - runAsync { - GdmlShowCase.cubes().toVision() - } ui { - canvas.render(it) - } - } - - companion object { - private val fileNameFilter = arrayOf( - FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"), - FileChooser.ExtensionFilter("JSON", "*.json"), - FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"), - FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz") - ) - } -} - -fun main() { - launch() -} \ No newline at end of file +//package space.kscience.visionforge.gdml.demo +// +//import javafx.geometry.Orientation +//import javafx.scene.Parent +//import javafx.stage.FileChooser +//import space.kscience.dataforge.context.Context +//import space.kscience.dataforge.context.fetch +//import space.kscience.gdml.GdmlShowCase +//import space.kscience.visionforge.VisionManager +//import space.kscience.visionforge.editor.VisionEditorFragment +//import space.kscience.visionforge.editor.VisionTreeFragment +//import space.kscience.visionforge.gdml.toVision +//import space.kscience.visionforge.solid.FX3DPlugin +//import space.kscience.visionforge.solid.FXCanvas3D +//import space.kscience.visionforge.solid.Solid +//import space.kscience.visionforge.solid.SolidMaterial +//import tornadofx.* +// +//class GDMLDemoApp : App(GDMLView::class) +// +//class GDMLView : View() { +// private val context = Context { +// plugin(FX3DPlugin) +// } +// +// private val fx3d = context.fetch(FX3DPlugin) +// private val visionManager = context.fetch(VisionManager) +// private val canvas = FXCanvas3D(fx3d) +// +// private val treeFragment = VisionTreeFragment().apply { +// this.itemProperty.bind(canvas.rootObjectProperty) +// } +// +// private val propertyEditor = VisionEditorFragment().apply { +// descriptorProperty.set(SolidMaterial.descriptor) +// visionProperty.bind(treeFragment.selectedProperty) +// } +// +// override val root: Parent = borderpane { +// top { +// buttonbar { +// button("Load GDML/json") { +// action { +// val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull() +// if (file != null) { +// runAsync { +// visionManager.readFile(file) as Solid +// } ui { +// canvas.render(it) +// } +// } +// } +// } +// } +// } +// center { +// splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) { +// setDividerPositions(0.2, 0.6, 0.2) +// } +// } +// } +// +// init { +// runAsync { +// GdmlShowCase.cubes().toVision() +// } ui { +// canvas.render(it) +// } +// } +// +// companion object { +// private val fileNameFilter = arrayOf( +// FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"), +// FileChooser.ExtensionFilter("JSON", "*.json"), +// FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"), +// FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz") +// ) +// } +//} +// +//fun main() { +// launch() +//} \ No newline at end of file diff --git a/demo/js-playground/build.gradle.kts b/demo/js-playground/build.gradle.kts index ccec7015..eca736e4 100644 --- a/demo/js-playground/build.gradle.kts +++ b/demo/js-playground/build.gradle.kts @@ -1,28 +1,35 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.mpp") } -kscience{ +kscience { useCoroutines() - application() } -kotlin{ - js(IR){ +kotlin { + explicitApi = null + js { useCommonJs() browser { + binaries.executable() commonWebpackConfig { - cssSupport.enabled = false + cssSupport { + enabled.set(false) + } } } } } +kscience { -dependencies{ - implementation(projects.visionforge.visionforgeGdml) - implementation(projects.visionforge.visionforgePlotly) - implementation(projects.visionforge.visionforgeMarkdown) - implementation(projects.visionforge.visionforgeThreejs) - implementation(projects.ui.ring) + dependencies { + implementation(projects.visionforge.visionforgeGdml) + implementation(projects.visionforge.visionforgePlotly) + implementation(projects.visionforge.visionforgeMarkdown) + implementation(projects.visionforge.visionforgeThreejs) + } + jsMain { + implementation(projects.ui.ring) + } } \ No newline at end of file diff --git a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt similarity index 81% rename from demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt rename to demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt index a1ffa4ff..dd0d0b26 100644 --- a/demo/js-playground/src/main/kotlin/JsPlaygroundApp.kt +++ b/demo/js-playground/src/jsMain/kotlin/JsPlaygroundApp.kt @@ -1,15 +1,17 @@ -import kotlinx.browser.document import kotlinx.css.* -import react.child -import react.dom.render +import org.w3c.dom.Document import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.request import space.kscience.plotly.models.Trace import space.kscience.plotly.scatter import space.kscience.visionforge.Application -import space.kscience.visionforge.VisionClient +import space.kscience.visionforge.Colors +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.react.createRoot +import space.kscience.visionforge.react.render import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.ring.solid @@ -28,29 +30,29 @@ fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number? private class JsPlaygroundApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val playgroundContext = Context { plugin(ThreeWithControlsPlugin) - plugin(VisionClient) + plugin(JsVisionClient) plugin(PlotlyPlugin) } val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page") - render(element) { + createRoot(element).render { styledDiv { css { - padding(0.pt) - margin(0.pt) + padding = Padding(0.pt) + margin = Margin(0.pt) height = 100.vh width = 100.vw } SmartTabs("gravity") { Tab("gravity") { - GravityDemo{ + GravityDemo { attrs { - this.context = playgroundContext + this.solids = playgroundContext.request(Solids) } } } @@ -71,8 +73,11 @@ private class JsPlaygroundApp : Application { child(ThreeCanvasWithControls) { val random = Random(112233) attrs { - context = playgroundContext + solids = playgroundContext.request(Solids) solid { + ambientLight { + color(Colors.white) + } repeat(100) { sphere(5, name = "sphere[$it]") { x = random.nextDouble(-300.0, 300.0) diff --git a/demo/js-playground/src/main/kotlin/gravityDemo.kt b/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt similarity index 87% rename from demo/js-playground/src/main/kotlin/gravityDemo.kt rename to demo/js-playground/src/jsMain/kotlin/gravityDemo.kt index 716cc2c3..a4bc9057 100644 --- a/demo/js-playground/src/main/kotlin/gravityDemo.kt +++ b/demo/js-playground/src/jsMain/kotlin/gravityDemo.kt @@ -4,9 +4,9 @@ import kotlinx.coroutines.launch import kotlinx.css.* import react.Props import react.fc -import space.kscience.dataforge.context.Context import space.kscience.plotly.layout import space.kscience.plotly.models.Trace +import space.kscience.visionforge.Colors import space.kscience.visionforge.markup.VisionOfMarkup import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls @@ -17,14 +17,14 @@ import styled.styledDiv import kotlin.math.sqrt external interface DemoProps : Props { - var context: Context + var solids: Solids } val GravityDemo = fc { props -> - val velocityTrace = Trace{ + val velocityTrace = Trace { name = "velocity" } - val energyTrace = Trace{ + val energyTrace = Trace { name = "energy" } val markup = VisionOfMarkup() @@ -39,14 +39,19 @@ val GravityDemo = fc { props -> } child(ThreeCanvasWithControls) { attrs { - context = props.context + solids = props.solids solid { + pointLight(200, 200, 200, name = "light"){ + color(Colors.white) + } + ambientLight() + sphere(5.0, "ball") { detail = 16 color("red") val h = 100.0 y = h - context.launch { + solids.context.launch { val g = 10.0 val dt = 0.1 var time = 0.0 @@ -91,7 +96,7 @@ val GravityDemo = fc { props -> height = 50.vh - 50.pt } plotly { - traces(velocityTrace,energyTrace) + traces(velocityTrace, energyTrace) layout { xaxis.title = "time" } diff --git a/demo/js-playground/src/main/kotlin/markupComponent.kt b/demo/js-playground/src/jsMain/kotlin/markupComponent.kt similarity index 91% rename from demo/js-playground/src/main/kotlin/markupComponent.kt rename to demo/js-playground/src/jsMain/kotlin/markupComponent.kt index 4bbe4b80..a47c28cf 100644 --- a/demo/js-playground/src/main/kotlin/markupComponent.kt +++ b/demo/js-playground/src/jsMain/kotlin/markupComponent.kt @@ -1,5 +1,4 @@ import kotlinx.css.* -import kotlinx.css.properties.border import kotlinx.dom.clear import kotlinx.html.dom.append import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor @@ -45,10 +44,10 @@ val Markup = fc("Markup") { props -> css { width = 100.pct height = 100.pct - border(2.pt, BorderStyle.solid, Color.blue) - padding(left = 8.pt) + border= Border(2.pt, BorderStyle.solid, Color.blue) + padding = Padding(left = 8.pt) backgroundColor = Color.white - flex(1.0) + flex = Flex(1.0) zIndex = 10000 } ref = elementRef diff --git a/demo/js-playground/src/main/kotlin/plotlyComponent.kt b/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt similarity index 83% rename from demo/js-playground/src/main/kotlin/plotlyComponent.kt rename to demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt index 5a2c6a81..80417dde 100644 --- a/demo/js-playground/src/main/kotlin/plotlyComponent.kt +++ b/demo/js-playground/src/jsMain/kotlin/plotlyComponent.kt @@ -1,5 +1,4 @@ import kotlinx.css.* -import kotlinx.css.properties.border import org.w3c.dom.Element import org.w3c.dom.HTMLElement import react.* @@ -20,9 +19,9 @@ val Plotly = fc("Plotly") { props -> useEffect(props.plot, elementRef) { val element = elementRef.current as? HTMLElement ?: error("Plotly element not found") props.plot?.let { - element.plot(it, PlotlyConfig { + element.plot(PlotlyConfig { responsive = true - }) + }, it) } } @@ -30,8 +29,8 @@ val Plotly = fc("Plotly") { props -> css { width = 100.pct height = 100.pct - border(2.pt, BorderStyle.solid, Color.blue) - flex(1.0) + border = Border(2.pt, BorderStyle.solid, Color.blue) + flex = Flex(1.0) } ref = elementRef } diff --git a/demo/js-playground/src/main/resources/index.html b/demo/js-playground/src/jsMain/resources/index.html similarity index 100% rename from demo/js-playground/src/main/resources/index.html rename to demo/js-playground/src/jsMain/resources/index.html diff --git a/demo/muon-monitor/build.gradle.kts b/demo/muon-monitor/build.gradle.kts index d33cd455..d01b9dc9 100644 --- a/demo/muon-monitor/build.gradle.kts +++ b/demo/muon-monitor/build.gradle.kts @@ -1,64 +1,47 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") application } group = "ru.mipt.npm" -val ktorVersion: String = npmlibs.versions.ktor.get() +val ktorVersion: String = spclibs.versions.ktor.get() kscience { useCoroutines() useSerialization() - application() -} - -kotlin { - jvm { - withJava() - } - js { - useCommonJs() - browser { - commonWebpackConfig { - cssSupport.enabled = false + useKtor() + fullStack( + "muon-monitor.js", + jvmConfig = { withJava() }, + jsConfig = { useCommonJs() } + ) { + commonWebpackConfig { + cssSupport { + enabled.set(false) } } } - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - duplicatesStrategy = DuplicatesStrategy.EXCLUDE - from(jsBrowserDistribution) - } + commonMain { + implementation(projects.visionforgeSolid) } - - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) - } - } - jvmMain { - dependencies { - implementation("org.apache.commons:commons-math3:3.6.1") - implementation(npmlibs.ktor.server.cio) - implementation(npmlibs.ktor.serialization) - } - } - jsMain { - dependencies { - implementation(project(":ui:ring")) - implementation(project(":visionforge-threejs")) - //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) - } - } + jvmMain { + implementation("org.apache.commons:commons-math3:3.6.1") + implementation("io.ktor:ktor-server-cio:${ktorVersion}") + implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}") + implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}") + implementation("ch.qos.logback:logback-classic:1.2.11") + } + jsMain { + implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) + //implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) } } +kotlin.explicitApi = null + application { mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt") } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt index b47c2b66..22a9d2e1 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Event.kt @@ -1,9 +1,9 @@ package ru.mipt.npm.muon.monitor import kotlinx.serialization.Serializable -import space.kscience.visionforge.solid.Point3D +import space.kscience.visionforge.solid.Float32Vector3D -typealias Track = List +typealias Track = List /** * diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt index 2dab49a2..34b750e9 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Model.kt @@ -3,20 +3,21 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.UPPER_LAYER_Z +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.removeAll import space.kscience.visionforge.setAsRoot -import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.* +import kotlin.collections.set import kotlin.math.PI class Model(val manager: VisionManager) { private val map = HashMap() private val events = HashSet() - private fun SolidGroup.pixel(pixel: SC1) { - val group = group(pixel.name) { - position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z) + private fun MutableVisionContainer.pixel(pixel: SC1) { + val group = solidGroup(pixel.name) { + position = Float32Vector3D(pixel.center.x, pixel.center.y, pixel.center.z) box(pixel.xSize, pixel.ySize, pixel.zSize) label(pixel.name) { z = -Monitor.PIXEL_Z_SIZE / 2 - 5 @@ -27,52 +28,52 @@ class Model(val manager: VisionManager) { } private fun SolidGroup.detector(detector: SC16) { - group(detector.name) { + solidGroup(detector.name) { detector.pixels.forEach { pixel(it) } } } - var tracks: SolidGroup + val tracks: SolidGroup = SolidGroup() val root: SolidGroup = SolidGroup().apply { setAsRoot(this@Model.manager) material { - wireframe color("darkgreen") } rotationX = PI / 2 - group("bottom") { + solidGroup("bottom") { Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach { detector(it) } } - group("middle") { + solidGroup("middle") { Monitor.detectors.filter { it.center.z == CENTRAL_LAYER_Z }.forEach { detector(it) } } - group("top") { + solidGroup("top") { Monitor.detectors.filter { it.center.z == UPPER_LAYER_Z }.forEach { detector(it) } } - tracks = group("tracks") + + setChild("tracks".asName(), tracks) } private fun highlight(pixel: String) { println("highlight $pixel") - map[pixel]?.color?.invoke("blue") + map[pixel]?.color("blue") } fun reset() { map.values.forEach { - it.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, null) + it.properties[SolidMaterial.MATERIAL_COLOR_KEY] = null } - tracks.removeAll() + tracks.children.clear() } fun displayEvent(event: Event) { @@ -83,7 +84,6 @@ class Model(val manager: VisionManager) { } event.track?.let { tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") { - thickness = 4 color("red") } } diff --git a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt index 3e1db5bc..48fe83d1 100644 --- a/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt +++ b/demo/muon-monitor/src/commonMain/kotlin/ru/mipt/npm/muon/monitor/Monitor.kt @@ -2,21 +2,21 @@ package ru.mipt.npm.muon.monitor import ru.mipt.npm.muon.monitor.Monitor.PIXEL_XY_SIZE import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE -import space.kscience.visionforge.solid.Point3D -import space.kscience.visionforge.solid.plus +import space.kscience.visionforge.solid.Float32Euclidean3DSpace +import space.kscience.visionforge.solid.Float32Vector3D /** * A single pixel */ class SC1( val name: String, - val center: Point3D, - val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE + val center: Float32Vector3D, + val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE, ) class SC16( val name: String, - val center: Point3D + val center: Float32Vector3D, ) { /** @@ -28,77 +28,90 @@ class SC16( val y: Double when (index) { 7 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 4 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 6 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } + 5 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } 3 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 0 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = 1.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = 1.5 * Monitor.PIXEL_XY_SPACING } + 2 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } + 1 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = 0.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = 0.5 * Monitor.PIXEL_XY_SPACING } 11 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 8 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 10 -> { - x = -1.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = -1.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } + 9 -> { - x = -0.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = -0.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } 15 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 12 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = -1.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = -1.5 * Monitor.PIXEL_XY_SPACING } + 14 -> { - x = 1.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = 1.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } + 13 -> { - x = 0.5 * Monitor.PIXEL_XY_SPACING; - y = -0.5 * Monitor.PIXEL_XY_SPACING; + x = 0.5 * Monitor.PIXEL_XY_SPACING + y = -0.5 * Monitor.PIXEL_XY_SPACING } - else -> throw Error(); + + else -> throw Error() } - val offset = Point3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0)); + val offset = Float32Vector3D(-y, x, 0)//rotateDetector(Point3D(x, y, 0.0)); val pixelName = "${name}_${index}" - SC1(pixelName, offset + center) + SC1(pixelName, with(Float32Euclidean3DSpace) { offset + center }) } } } @@ -137,11 +150,11 @@ object Monitor { .mapNotNull { line -> if (line.startsWith(" ")) { val split = line.trim().split("\\s+".toRegex()) - val detectorName = split[1]; + val detectorName = split[1] val x = split[4].toDouble() - 500 val y = split[5].toDouble() - 500 val z = 180 - split[6].toDouble() - SC16(detectorName, Point3D(x, y, z)) + SC16(detectorName, Float32Vector3D(x, y, z)) } else { null } diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt index 558317cb..07dc7c7c 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMAppComponent.kt @@ -16,15 +16,18 @@ import react.dom.p import react.fc import react.useMemo import react.useState -import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Colors import space.kscience.visionforge.react.flexColumn import space.kscience.visionforge.react.flexRow import space.kscience.visionforge.ring.ThreeCanvasWithControls import space.kscience.visionforge.ring.tab -import space.kscience.visionforge.solid.specifications.Camera +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.edges +import space.kscience.visionforge.solid.invoke import space.kscience.visionforge.solid.specifications.Canvas3DOptions -import space.kscience.visionforge.solid.three.edges import styled.css import styled.styledDiv import styled.styledSpan @@ -32,7 +35,7 @@ import kotlin.math.PI external interface MMAppProps : Props { var model: Model - var context: Context + var solids: Solids var selected: Name? } @@ -42,17 +45,21 @@ val MMApp = fc("Muon monitor") { props -> val mmOptions = useMemo { Canvas3DOptions { - camera = Camera { + camera { distance = 2100.0 latitude = PI / 6 azimuth = PI + PI / 6 } + } } val root = useMemo(props.model) { props.model.root.apply { edges() + ambientLight{ + color(Colors.white) + } } } @@ -64,7 +71,7 @@ val MMApp = fc("Muon monitor") { props -> } child(ThreeCanvasWithControls) { attrs { - this.context = props.context + this.solids = props.solids this.builderOfSolid = CompletableDeferred(root) this.selected = props.selected this.options = mmOptions @@ -75,7 +82,7 @@ val MMApp = fc("Muon monitor") { props -> +"Next" attrs { onClickFunction = { - context.launch { + solids.context.launch { val event = window.fetch( "http://localhost:8080/event", RequestInit("GET") diff --git a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt index 6b611146..afc9ce80 100644 --- a/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt +++ b/demo/muon-monitor/src/jsMain/kotlin/ru/mipt/npm/muon/monitor/MMDemoApp.kt @@ -1,31 +1,34 @@ package ru.mipt.npm.muon.monitor -import kotlinx.browser.document -import react.dom.render +import org.w3c.dom.Document import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.visionforge.Application import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.react.createRoot +import space.kscience.visionforge.react.render +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreePlugin import space.kscience.visionforge.startApplication private class MMDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val context = Context("MM-demo") { plugin(ThreePlugin) } - val visionManager = context.fetch(VisionManager) + + val visionManager = context.request(VisionManager) val model = Model(visionManager) val element = document.getElementById("app") ?: error("Element with id 'app' not found on page") - render(element) { + createRoot(element).render { child(MMApp) { attrs { this.model = model - this.context = context + this.solids = context.request(Solids) } } } diff --git a/demo/muon-monitor/src/jsMain/resources/index.html b/demo/muon-monitor/src/jsMain/resources/index.html index dbca2406..f9dee8bd 100644 --- a/demo/muon-monitor/src/jsMain/resources/index.html +++ b/demo/muon-monitor/src/jsMain/resources/index.html @@ -5,7 +5,6 @@ Three js demo for particle physics -
diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt index 29abd7ca..d3d50c5b 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/MMServer.kt @@ -1,31 +1,28 @@ package ru.mipt.npm.muon.monitor.server -import io.ktor.application.Application -import io.ktor.application.call -import io.ktor.application.install -import io.ktor.application.log -import io.ktor.features.CallLogging -import io.ktor.features.ContentNegotiation -import io.ktor.features.DefaultHeaders import io.ktor.http.ContentType import io.ktor.http.HttpStatusCode -import io.ktor.http.content.resources -import io.ktor.http.content.static -import io.ktor.response.respond -import io.ktor.response.respondText -import io.ktor.routing.Routing -import io.ktor.routing.get -import io.ktor.serialization.json +import io.ktor.serialization.kotlinx.json.json +import io.ktor.server.application.Application +import io.ktor.server.application.call +import io.ktor.server.application.install +import io.ktor.server.application.log import io.ktor.server.cio.CIO import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.staticResources +import io.ktor.server.plugins.contentnegotiation.ContentNegotiation +import io.ktor.server.response.respond +import io.ktor.server.response.respondText +import io.ktor.server.routing.Routing +import io.ktor.server.routing.get import org.apache.commons.math3.random.JDKRandomGenerator import ru.mipt.npm.muon.monitor.Model import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator import ru.mipt.npm.muon.monitor.sim.simulateOne import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.solid.Solids import java.awt.Desktop @@ -38,10 +35,8 @@ private val generator = Cos2TrackGenerator(JDKRandomGenerator(223)) fun Application.module(context: Context = Global) { val currentDir = File(".").absoluteFile environment.log.info("Current directory: $currentDir") - val solidManager = context.fetch(Solids) + val solidManager = context.request(Solids) - install(DefaultHeaders) - install(CallLogging) install(ContentNegotiation) { json() } @@ -57,9 +52,7 @@ fun Application.module(context: Context = Global) { status = HttpStatusCode.OK ) } - static("/") { - resources() - } + staticResources("/", null) } try { Desktop.getDesktop().browse(URI("http://localhost:8080/index.html")) diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt index c2578783..d9492a74 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/line.kt @@ -5,7 +5,7 @@ import org.apache.commons.math3.geometry.euclidean.threed.Plane import org.apache.commons.math3.geometry.euclidean.threed.Vector3D import ru.mipt.npm.muon.monitor.Monitor.CENTRAL_LAYER_Z import ru.mipt.npm.muon.monitor.Monitor.GEOMETRY_TOLERANCE -import space.kscience.visionforge.solid.Point3D +import space.kscience.visionforge.solid.Float32Vector3D /** * Created by darksnake on 11-May-16. @@ -50,12 +50,12 @@ fun makeTrack(x: Double, y: Double, theta: Double, phi: Double): Line { ) } -fun Vector3D.toPoint() = Point3D(x, y, z) +fun Vector3D.toKMathVector() = Float32Vector3D(x, y, z) -fun Line.toPoints(): List { +fun Line.toKMathVectors(): List { val basePoint = basePlane.intersection(this) val bottom = basePoint.subtract(2000.0, direction) val top = basePoint.add(2000.0, direction) - return listOf(bottom.toPoint(), top.toPoint()) + return listOf(bottom.toKMathVector(), top.toKMathVector()) } diff --git a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt index d2ec7235..e55b74db 100644 --- a/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt +++ b/demo/muon-monitor/src/jvmMain/kotlin/ru/mipt/npm/muon/monitor/sim/monitor.kt @@ -43,7 +43,7 @@ fun readEffs(): Map { fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection = defaultHitResolver): Event { - return Event(index, track.toPoints(), hitResolver(track).map { it.name }) + return Event(index, track.toKMathVectors(), hitResolver(track).map { it.name }) } val defaultHitResolver: (Line) -> Collection = { track: Line -> diff --git a/demo/playground/build.gradle.kts b/demo/playground/build.gradle.kts index 61f4e033..c51f6691 100644 --- a/demo/playground/build.gradle.kts +++ b/demo/playground/build.gradle.kts @@ -2,6 +2,7 @@ plugins { kotlin("multiplatform") kotlin("jupyter.api") id("com.github.johnrengelman.shadow") version "7.1.2" +// application } repositories { @@ -16,23 +17,25 @@ kotlin { useCommonJs() browser { webpackTask { - this.outputFileName = "js/visionforge-playground.js" + mainOutputFileName.set("js/visionforge-playground.js") } commonWebpackConfig { sourceMaps = true - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } binaries.executable() } jvm { - withJava() +// withJava() compilations.all { kotlinOptions { jvmTarget = "11" freeCompilerArgs = - freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + freeCompilerArgs + "-Xjvm-default=all" + "-Xopt-in=kotlin.RequiresOptIn" + "-Xlambdas=indy" + "-Xcontext-receivers" } } testRuns["test"].executionTask.configure { @@ -44,12 +47,11 @@ kotlin { val commonMain by getting { dependencies { implementation(projects.visionforgeSolid) - implementation(projects.visionforgeGdml) implementation(projects.visionforgePlotly) implementation(projects.visionforgeMarkdown) implementation(projects.visionforgeTables) implementation(projects.cernRootLoader) - implementation(projects.jupyter) + api(projects.visionforgeJupyter.visionforgeJupyterCommon) } } @@ -63,8 +65,10 @@ kotlin { val jvmMain by getting { dependencies { + implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}") + implementation(projects.visionforgeGdml) implementation(projects.visionforgeServer) - implementation("ch.qos.logback:logback-classic:1.2.3") + implementation(spclibs.logback.classic) implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6") } } @@ -87,4 +91,8 @@ val processJupyterApiResources by tasks.getting(org.jetbrains.kotlinx.jupyter.ap libraryProducers = listOf("space.kscience.visionforge.examples.VisionForgePlayGroundForJupyter") } -tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources) \ No newline at end of file +tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources) + +//application{ +// mainClass.set("space.kscience.visionforge.examples.ShapesKt") +//} \ No newline at end of file diff --git a/demo/playground/notebooks/common-demo.ipynb b/demo/playground/notebooks/common-demo.ipynb new file mode 100644 index 00000000..caa7306f --- /dev/null +++ b/demo/playground/notebooks/common-demo.ipynb @@ -0,0 +1,98 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "@file:Repository(\"*mavenLocal\")\n", + "@file:Repository(\"https://repo.kotlin.link\")\n", + "@file:Repository(\"https://maven.pkg.jetbrains.space/spc/p/sci/dev\")\n", + "@file:DependsOn(\"space.kscience:visionforge-jupyter-common-jvm:0.3.0-dev-12\")\n", + "//import space.kscience.visionforge.jupyter.JupyterCommonIntegration\n", + "//\n", + "//val integration = JupyterCommonIntegration()\n", + "//USE(integration.getDefinitions(notebook).first())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "vf.fragment {\n", + " h1 { +\"AAA\" }\n", + " vision {\n", + " solid {\n", + " ambientLight()\n", + " box(100, 100, 200)\n", + "\n", + " sphere(100) {\n", + " x = 300\n", + " }\n", + " }\n", + " }\n", + "\n", + " vision {\n", + " plotly {\n", + " scatter {\n", + " x(1, 2, 3, 1)\n", + " y(1, 2, 3, 4)\n", + " }\n", + " }\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [] + }, + "outputs": [], + "source": [ + "Plotly.plot { \n", + " scatter{\n", + " x(1,2,3)\n", + " y(1,2,3)\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "codemirror_mode": "text/x-kotlin", + "file_extension": ".kt", + "mimetype": "text/x-kotlin", + "name": "kotlin", + "nbconvert_exporter": "", + "pygments_lexer": "kotlin", + "version": "1.8.20" + }, + "ktnbPluginMetadata": { + "projectLibraries": [] + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/demo/playground/notebooks/controls.ipynb b/demo/playground/notebooks/controls.ipynb new file mode 100644 index 00000000..8552a178 --- /dev/null +++ b/demo/playground/notebooks/controls.ipynb @@ -0,0 +1,45 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "USE(JupyterCommonIntegration())" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "outputs": [], + "source": [], + "metadata": { + "collapsed": false + } + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "name": "kotlin", + "version": "1.9.0", + "mimetype": "text/x-kotlin", + "file_extension": ".kt", + "pygments_lexer": "kotlin", + "codemirror_mode": "text/x-kotlin", + "nbconvert_exporter": "" + }, + "ktnbPluginMetadata": { + "projectDependencies": true + } + }, + "nbformat": 4, + "nbformat_minor": 0 +} diff --git a/demo/playground/notebooks/dynamic-demo.ipynb b/demo/playground/notebooks/dynamic-demo.ipynb new file mode 100644 index 00000000..3fcd31e3 --- /dev/null +++ b/demo/playground/notebooks/dynamic-demo.ipynb @@ -0,0 +1,89 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "tags": [], + "pycharm": { + "is_executing": true + } + }, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf.startServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": { + "collapsed": false + }, + "outputs": [], + "source": [ + "import kotlinx.coroutines.*\n", + "import kotlin.random.Random\n", + "\n", + "Plotly.plot{\n", + " scatter{\n", + " x(1,2,3)\n", + " y(1,2,3)\n", + " if(vf.isServerRunning()){\n", + " vf.launch{\n", + " while(isActive){\n", + " delay(500)\n", + " y(Random.nextDouble(), Random.nextDouble(), Random.nextDouble())\n", + " }\n", + " }\n", + " }\n", + " }\n", + "}" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "vf.stopServer()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Kotlin", + "language": "kotlin", + "name": "kotlin" + }, + "language_info": { + "codemirror_mode": "text/x-kotlin", + "file_extension": ".kt", + "mimetype": "text/x-kotlin", + "name": "kotlin", + "nbconvert_exporter": "", + "pygments_lexer": "kotlin", + "version": "1.8.0-dev-3517" + }, + "ktnbPluginMetadata": { + "projectLibraries": [] + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/demo/playground/src/jsMain/kotlin/playgroundMain.kt b/demo/playground/src/jsMain/kotlin/playgroundMain.kt index 3ad34867..feff4de1 100644 --- a/demo/playground/src/jsMain/kotlin/playgroundMain.kt +++ b/demo/playground/src/jsMain/kotlin/playgroundMain.kt @@ -1,4 +1,5 @@ import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.jupyter.VFNotebookClient import space.kscience.visionforge.markup.MarkupPlugin import space.kscience.visionforge.plotly.PlotlyPlugin import space.kscience.visionforge.ring.ThreeWithControlsPlugin @@ -11,4 +12,5 @@ fun main() = runVisionClient { plugin(PlotlyPlugin) plugin(MarkupPlugin) plugin(TableVisionJsPlugin) + plugin(VFNotebookClient) } \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/BmnDemo.kt b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt new file mode 100644 index 00000000..295701fa --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/BmnDemo.kt @@ -0,0 +1,83 @@ +package space.kscience.visionforge.examples + +import ru.mipt.npm.root.BMN +import ru.mipt.npm.root.DGeoManager +import ru.mipt.npm.root.rootGeo +import ru.mipt.npm.root.serialization.TGeoManager +import ru.mipt.npm.root.toVector +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.isLeaf +import space.kscience.dataforge.meta.string +import space.kscience.visionforge.Colors +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.* +import java.util.zip.ZipInputStream +import kotlin.io.path.Path +import kotlin.io.path.createDirectories +import kotlin.io.path.writeText + + +private fun Meta.countTypes(): Sequence = sequence { + if (!isLeaf) { + get("_typename")?.value?.let { yield(it.string) } + items.forEach { yieldAll(it.value.countTypes()) } + } +} + +fun main() { + Path("data").createDirectories() + + val string = ZipInputStream(TGeoManager::class.java.getResourceAsStream("/root/geometry_run_7-2076.zip")!!).use { + it.nextEntry + it.readAllBytes().decodeToString() + } + + val geo = DGeoManager.parse(string) + + + val sizes = geo.meta.countTypes().groupBy { it }.mapValues { it.value.size } + sizes.forEach { + println(it) + } + + val events = BMN.readEventJson(TGeoManager::class.java.getResourceAsStream("/root/event_0.json")!!.bufferedReader().readText()) + + makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) { + vision("canvas") { + requirePlugin(Solids) + solid { + ambientLight { + color(Colors.white) + } + rootGeo(geo,"BM@N", ignoreRootColors = true).also { + Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it)) + } + + solidGroup("cbmStsTracks") { + events.cbmTracks.forEach { track -> + polyline( + track.fParamFirst.toVector(), + track.fParamLast.toVector() + ) { + thickness = 2.0 + color(Colors.blue) + } + } + } + + solidGroup("bmnGlobalTracks") { + events.bmnGlobalTracks.forEach { track -> + polyline( + track.fParamFirst.toVector(), + track.fParamLast.toVector() + ) { + thickness = 2.0 + color(Colors.red) + } + } + } + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt b/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt deleted file mode 100644 index 651b580d..00000000 --- a/demo/playground/src/jvmMain/kotlin/VisionForgePlayGroundForJupyter.kt +++ /dev/null @@ -1,50 +0,0 @@ -package space.kscience.visionforge.examples - -import org.jetbrains.kotlinx.jupyter.api.libraries.resources -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.gdml.Gdml -import space.kscience.plotly.Plot -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.JupyterPluginBase -import space.kscience.visionforge.plotly.PlotlyPlugin -import space.kscience.visionforge.plotly.asVision -import space.kscience.visionforge.solid.Solids - -@DFExperimental -internal class VisionForgePlayGroundForJupyter : JupyterPluginBase( - Context("VisionForge") { - plugin(Solids) - plugin(PlotlyPlugin) - } -) { - - override fun Builder.afterLoaded() { - resources { - js("VisionForge") { - classPath("js/visionforge-playground.js") - } - } - - import( - "space.kscience.gdml.*", - "space.kscience.plotly.*", - "space.kscience.plotly.models.*", - "space.kscience.visionforge.solid.*", - ) - - - render { gdmlModel -> - handler.produceHtml { - vision { gdmlModel.toVision() } - } - } - - render { plot -> - handler.produceHtml { - vision { plot.asVision() } - } - } - } - -} diff --git a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt index 23b73af4..5b272b72 100644 --- a/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt +++ b/demo/playground/src/jvmMain/kotlin/allThingsDemo.kt @@ -1,7 +1,8 @@ package space.kscience.visionforge.examples import kotlinx.html.h2 -import space.kscience.dataforge.values.ValueType +import space.kscience.dataforge.meta.ValueType +import space.kscience.dataforge.meta.invoke import space.kscience.plotly.layout import space.kscience.plotly.models.ScatterMode import space.kscience.plotly.models.TextPosition @@ -12,13 +13,14 @@ import space.kscience.visionforge.markup.markdown import space.kscience.visionforge.plotly.plotly import space.kscience.visionforge.solid.box import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.z import space.kscience.visionforge.tables.columnTable -import java.nio.file.Paths +import kotlin.io.path.Path fun main() = makeVisionFile( - Paths.get("VisionForgeDemo.html"), + Path("VisionForgeDemo.html"), resourceLocation = ResourceLocation.EMBED ) { markdown { @@ -32,8 +34,15 @@ fun main() = makeVisionFile( h2 { +"3D visualization with Three-js" } vision("3D") { - solid { - box(100, 100, 100, name = "aBox"){ + solid( + Canvas3DOptions { + axes { + size = 200.0 + visible = true + } + } + ) { + box(100, 100, 100, name = "aBox") { z = 50.0 } } diff --git a/demo/playground/src/jvmMain/kotlin/antenna.kt b/demo/playground/src/jvmMain/kotlin/antenna.kt new file mode 100644 index 00000000..5080e939 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/antenna.kt @@ -0,0 +1,102 @@ +package space.kscience.visionforge.examples + +import kotlinx.coroutines.delay +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import space.kscience.dataforge.meta.configure +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.complex.QuaternionField +import space.kscience.kmath.complex.conjugate +import space.kscience.kmath.geometry.* +import space.kscience.visionforge.solid.* +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +fun main() = serve { + +// val azimuth = 60.degrees +// val inclination = 15.degrees + +// val direction = with(QuaternionField) { +// Quaternion.fromRotation(-azimuth, Euclidean3DSpace.zAxis) * +// Quaternion.fromRotation(Angle.piDiv2 - inclination, Euclidean3DSpace.yAxis) +// } + + //val direction2 = Quaternion.fromEuler(Angle.zero, Angle.piDiv2 - inclination, -azimuth, RotationOrder.ZYX) + + val target = Quaternion.fromEuler((-45).degrees, 45.degrees, Angle.zero, RotationOrder.XYZ) + + + vision("canvas") { + requirePlugin(Solids) + + solid(options = { + configure { "controls.enabled" put false } + }) { + rotationX = -PI / 2 + rotationZ = PI + //axes(200) + ambientLight() + val platform = solidGroup("platform") { + cylinder(50, 5, name = "base") + solidGroup("frame") { + z = 60 + + solidGroup("antenna") { + axes(200) + tube(40, 10, 30) + sphereLayer(100, 95, theta = PI / 6) { + z = 100 + rotationX = -PI / 2 + } + cylinder(5, 30) { + z = 15 + } + + sphereLayer(101, 94, phi = PI / 32, theta = PI / 6) { + z = 100 + rotationX = -PI / 2 + color("red") + } + + quaternion = target + } + } + } + + val frame = platform["frame"] as SolidGroup + + val antenna = frame["antenna"] as SolidGroup + + val xPeriod = 5000 //ms + val yPeriod = 7000 //ms + + val incRot = Quaternion.fromRotation(30.degrees, Euclidean3DSpace.zAxis) + + + context.launch { + var time: Long = 0L + while (isActive) { + with(QuaternionField) { + delay(200) + platform.quaternion = Quaternion.fromRotation( + 15.degrees * sin(time.toDouble() * 2 * PI / xPeriod), + Euclidean3DSpace.xAxis + ) * Quaternion.fromRotation( + 15.degrees * cos(time * 2 * PI / yPeriod), + Euclidean3DSpace.yAxis + ) + + val qi = platform.quaternion * incRot + + antenna.quaternion = qi.conjugate * incRot.conjugate * target + + time += 200 + //antenna.quaternion = Quaternion.fromRotation(5.degrees, Euclidean3DSpace.zAxis) * antenna.quaternion + } + } + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/axes.kt b/demo/playground/src/jvmMain/kotlin/axes.kt new file mode 100644 index 00000000..b8178887 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/axes.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.examples + +import space.kscience.kmath.geometry.Euclidean3DSpace +import space.kscience.kmath.geometry.radians +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.* +import kotlin.math.PI + +fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { + vision("canvas") { + requirePlugin(Solids) + solid { + axes(100, "root-axes") + solidGroup("group") { + z = 100 + rotate((PI / 4).radians, Euclidean3DSpace.vector(1, 1, 1)) + axes(100, "local-axes") + box(50, 50, 50, "box") + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/extruded.kt b/demo/playground/src/jvmMain/kotlin/extruded.kt new file mode 100644 index 00000000..c45b2564 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/extruded.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.examples + +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.extruded +import space.kscience.visionforge.solid.polygon +import space.kscience.visionforge.solid.solid + +fun main() = makeVisionFile { + vision("canvas") { + solid { + ambientLight() + extruded("extruded") { + shape{ + polygon(8, 100) + } + layer(-30) + layer(0, x = 10, y = 10) + layer(30) + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/formServer.kt b/demo/playground/src/jvmMain/kotlin/formServer.kt index 7397b6b6..21d2d4a7 100644 --- a/demo/playground/src/jvmMain/kotlin/formServer.kt +++ b/demo/playground/src/jvmMain/kotlin/formServer.kt @@ -1,22 +1,42 @@ package space.kscience.visionforge.examples +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.staticResources +import io.ktor.server.routing.routing import kotlinx.html.* import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.html.Page -import space.kscience.visionforge.html.formFragment +import space.kscience.visionforge.html.VisionOfHtmlForm +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.bindForm import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser -import space.kscience.visionforge.server.serve +import space.kscience.visionforge.server.visionPage +@Suppress("ExtractKtorModule") fun main() { - val visionManager = Global.fetch(VisionManager) + val visionManager = Global.request(VisionManager) - val server = visionManager.serve { - page(header = Page.scriptHeader("js/visionforge-playground.js")) { - val form = formFragment("form") { + val server = embeddedServer(CIO) { + + routing { + staticResources("/", null) + } + + val form = VisionOfHtmlForm("form").apply { + onPropertyChange(visionManager.context) { + println(values) + } + } + + visionPage( + visionManager, + VisionPage.scriptHeader("js/visionforge-playground.js"), + ) { + bindForm(form) { label { htmlFor = "fname" +"First name:" @@ -47,17 +67,15 @@ fun main() { value = "Submit" } } - - vision("form") { form } - form.onPropertyChange { - println(this) - } + println(form.values) + vision(form) } - } + + }.start(false) server.openInBrowser() - while (readln() != "exit") { + while (readlnOrNull() != "exit") { } diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt index d5d483bc..3e5b0475 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCubes.kt @@ -5,7 +5,7 @@ import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.Solids -fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){ +fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { vision("canvas") { requirePlugin(Solids) GdmlShowCase.cubes().toVision() diff --git a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt index 70827a2d..4cac02b1 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlCurve.kt @@ -223,7 +223,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL } } }.toVision { - configure { _, solid, _ -> + solids { _, solid, _ -> //disable visibility for the world box if(solid.name == "world"){ visible = false diff --git a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt index 6ee718a2..954a30c9 100644 --- a/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt +++ b/demo/playground/src/jvmMain/kotlin/gdmlIaxo.kt @@ -1,12 +1,15 @@ package space.kscience.visionforge.examples import space.kscience.gdml.GdmlShowCase -import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.gdml.gdml import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.solid fun main() = makeVisionFile { vision("canvas") { requirePlugin(Solids) - GdmlShowCase.babyIaxo().toVision() + solid { + gdml(GdmlShowCase.babyIaxo(), "D0") + } } } \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/generateSchema.kt b/demo/playground/src/jvmMain/kotlin/generateSchema.kt index 8331ac62..672cd0b3 100644 --- a/demo/playground/src/jvmMain/kotlin/generateSchema.kt +++ b/demo/playground/src/jvmMain/kotlin/generateSchema.kt @@ -6,6 +6,7 @@ import kotlinx.serialization.json.Json import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.Solids +@OptIn(ExperimentalSerializationApi::class) private val json = Json { serializersModule = Solids.serializersModuleForSolids prettyPrintIndent = " " diff --git a/demo/playground/src/jvmMain/kotlin/plotlyVision.kt b/demo/playground/src/jvmMain/kotlin/plotlyVision.kt index 4b91c352..c1ef18a8 100644 --- a/demo/playground/src/jvmMain/kotlin/plotlyVision.kt +++ b/demo/playground/src/jvmMain/kotlin/plotlyVision.kt @@ -1,15 +1,92 @@ package space.kscience.visionforge.examples -import space.kscience.plotly.scatter +import space.kscience.dataforge.meta.Value +import space.kscience.plotly.layout +import space.kscience.plotly.models.* import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.plotly.plotly fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) { vision { + val trace1 = Violin { + text("sample length: 32") + marker { + line { + width = 2 + color("#bebada") + } + symbol = Symbol.valueOf("line-ns") + } + orientation = Orientation.h + hoveron = ViolinHoveron.`points+kde` + meanline { + visible = true + } + legendgroup = "F" + scalegroup = "F" + points = ViolinPoints.all + pointpos = 1.2 + jitter = 0 + box { + visible = true + } + scalemode = ViolinScaleMode.count + showlegend = false + side = ViolinSide.positive + y0 = Value.of(0) + line { + color("#bebada") + } + name = "F" + + x(10.07, 34.83, 10.65, 12.43, 24.08, 13.42, 12.48, 29.8, 14.52, 11.38, + 20.27, 11.17, 12.26, 18.26, 8.51, 10.33, 14.15, 13.16, 17.47, 27.05, 16.43, + 8.35, 18.64, 11.87, 19.81, 43.11, 13.0, 12.74, 13.0, 16.4, 16.47, 18.78) + } + + val trace2 = Violin { + text("sample length: 32") + marker { + line { + width = 2 + color("#8dd3c7") + } + symbol = Symbol.valueOf("line-ns") + } + orientation = Orientation.h + hoveron = ViolinHoveron.`points+kde` + meanline { + visible = true + } + legendgroup = "M" + scalegroup = "M" + points = ViolinPoints.all + pointpos = -1.2 + jitter = 0 + box { + visible = true + } + scalemode = ViolinScaleMode.count + showlegend = false + side = ViolinSide.negative + y0 = Value.of(0) + + line { + color("#8dd3c7") + } + name = "M" + + x(27.2, 22.76, 17.29, 19.44, 16.66, 32.68, 15.98, 13.03, 18.28, 24.71, + 21.16, 11.69, 14.26, 15.95, 8.52, 22.82, 19.08, 16.0, 34.3, 41.19, 9.78, + 7.51, 28.44, 15.48, 16.58, 7.56, 10.34, 13.51, 18.71, 20.53) + } + plotly { - scatter { - x(1, 2, 3) - y(5, 8, 7) + traces(trace1, trace2) + layout { + width = 800 + height = 800 + title = "Advanced Violin Plot" } } } diff --git a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt index 2d9a5f05..fd1b9865 100644 --- a/demo/playground/src/jvmMain/kotlin/randomSpheres.kt +++ b/demo/playground/src/jvmMain/kotlin/randomSpheres.kt @@ -2,6 +2,7 @@ package space.kscience.visionforge.examples import kotlinx.html.div import kotlinx.html.h1 +import space.kscience.visionforge.Colors import space.kscience.visionforge.html.ResourceLocation import space.kscience.visionforge.solid.* import java.nio.file.Paths @@ -17,6 +18,9 @@ fun main() = makeVisionFile( div { vision { solid { + ambientLight { + color(Colors.white) + } repeat(100) { sphere(5, name = "sphere[$it]") { x = random.nextDouble(-300.0, 300.0) diff --git a/demo/playground/src/jvmMain/kotlin/rootParser.kt b/demo/playground/src/jvmMain/kotlin/rootParser.kt deleted file mode 100644 index 184557da..00000000 --- a/demo/playground/src/jvmMain/kotlin/rootParser.kt +++ /dev/null @@ -1,106 +0,0 @@ -package space.kscience.visionforge.examples - -import ru.mipt.npm.root.DGeoManager -import ru.mipt.npm.root.serialization.TGeoManager -import ru.mipt.npm.root.toSolid -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.isLeaf -import space.kscience.dataforge.values.string -import space.kscience.visionforge.solid.Solids -import java.nio.file.Paths -import java.util.zip.ZipInputStream -import kotlin.io.path.writeText - - -private fun Meta.countTypes(): Sequence = sequence { - if (!isLeaf) { - get("_typename")?.value?.let { yield(it.string) } - items.forEach { yieldAll(it.value.countTypes()) } - } -} - -fun main() { - val string = ZipInputStream(TGeoManager::class.java.getResourceAsStream("/root/BM@N_geometry.zip")!!).use { - it.nextEntry - it.readAllBytes().decodeToString() - } - - val geo = DGeoManager.parse(string) - - - val sizes = geo.meta.countTypes().groupBy { it }.mapValues { it.value.size } - sizes.forEach { - println(it) - } - - val solid = geo.toSolid() - - Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid)) - //println(Solids.encodeToString(solid)) - - makeVisionFile { - vision("canvas") { - requirePlugin(Solids) - solid - } - } -} - - -/* SolidGroup { - set( - "Coil", - solid.getPrototype("Coil".asName())!!.apply { - parent = null - } - ) - *//* group("Shade") { - y = 200 - color("red") - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(79.6, 0, -122.1) - rotation = Point3D(-1.5707964, 0, 0) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(-79.6, 0, -122.1) - rotation = Point3D(1.5707964, 0, -3.1415927) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(79.6, 0, 122.1) - rotation = Point3D(1.5707964, 0, 0) - } - coneSurface( - bottomOuterRadius = 135, - bottomInnerRadius = 25, - height = 50, - topOuterRadius = 135, - topInnerRadius = 25, - angle = 1.5707964 - ) { - position = Point3D(-79.6, 0, 122.1) - rotation = Point3D(-1.5707964, 0, -3.1415927) - } - }*//* - }*/ diff --git a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt index e8be7112..c20f27c7 100644 --- a/demo/playground/src/jvmMain/kotlin/serverExtensions.kt +++ b/demo/playground/src/jvmMain/kotlin/serverExtensions.kt @@ -1,14 +1,24 @@ package space.kscience.visionforge.examples +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.staticResources +import io.ktor.server.routing.routing +import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Global -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.Page -import space.kscience.visionforge.html.ResourceLocation -import space.kscience.visionforge.html.importScriptHeader -import space.kscience.visionforge.makeFile +import space.kscience.visionforge.html.* +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.server.close +import space.kscience.visionforge.server.openInBrowser +import space.kscience.visionforge.server.visionPage +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.tables.TableVisionPlugin +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path + public fun makeVisionFile( path: Path? = null, title: String = "VisionForge page", @@ -16,15 +26,58 @@ public fun makeVisionFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = Page(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( - "title" to Page.title(title), - "playground" to Page.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath), + "title" to VisionPage.title(title), + "playground" to VisionPage.importScriptHeader( + "js/visionforge-playground.js", + resourceLocation, + actualPath + ), ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) } +public fun serve( + title: String = "VisionForge page", + show: Boolean = true, + content: HtmlVisionFragment, +) { + val context = Context("playground") { + plugin(Solids) + plugin(PlotlyPlugin) + plugin(MarkupPlugin) + plugin(TableVisionPlugin) + } + + val server = embeddedServer(CIO, port = 7779) { + routing { + staticResources("", null, null) + } + + visionPage( + context.visionManager, + VisionPage.scriptHeader("js/visionforge-playground.js") { + defer = true + }, + VisionPage.title(title), + visionFragment = content + ) + }.start(false) + + if (show) { + server.openInBrowser() + } + + println("Enter 'exit' to close server") + while (readlnOrNull() != "exit") { + // + } + + server.close() +} + //@DFExperimental //public fun Context.makeVisionFile( // vision: Vision, diff --git a/demo/playground/src/jvmMain/kotlin/shapes.kt b/demo/playground/src/jvmMain/kotlin/shapes.kt new file mode 100644 index 00000000..55ce28d5 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/shapes.kt @@ -0,0 +1,40 @@ +package space.kscience.visionforge.examples + +import space.kscience.visionforge.Colors +import space.kscience.visionforge.solid.* +import kotlin.math.PI + +fun main() = makeVisionFile { + vision("canvas") { + solid { + ambientLight() + box(100.0, 100.0, 100.0) { + z = -110.0 + color("teal") + } + sphere(50.0) { + x = 110 + detail = 16 + color("red") + } + tube(50, height = 10, innerRadius = 25, angle = PI) { + y = 110 + detail = 16 + rotationX = PI / 4 + color("blue") + } + sphereLayer(50, 40, theta = PI / 2) { + rotationX = -PI * 3 / 4 + z = 110 + color(Colors.pink) + } + + + cylinder(30,20, name = "cylinder"){ + detail = 31 + y = -220 + z = 15 + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/surface.kt b/demo/playground/src/jvmMain/kotlin/surface.kt new file mode 100644 index 00000000..01fbfb50 --- /dev/null +++ b/demo/playground/src/jvmMain/kotlin/surface.kt @@ -0,0 +1,19 @@ +package space.kscience.visionforge.examples + +import space.kscience.visionforge.solid.ambientLight +import space.kscience.visionforge.solid.polygon +import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.solid.surface + +fun main() = makeVisionFile { + vision("canvas") { + solid { + ambientLight() + surface("surface") { + layer(0, { polygon(8, 10) }, { polygon(8, 20) }) + layer(10, { polygon(8, 20) }, { polygon(8, 30) }) + layer(20, { polygon(8, 10) }, { polygon(8, 20) }) + } + } + } +} \ No newline at end of file diff --git a/demo/playground/src/jvmMain/kotlin/tables.kt b/demo/playground/src/jvmMain/kotlin/tables.kt index 46cad89d..ab27ebdf 100644 --- a/demo/playground/src/jvmMain/kotlin/tables.kt +++ b/demo/playground/src/jvmMain/kotlin/tables.kt @@ -1,6 +1,6 @@ package space.kscience.visionforge.examples -import space.kscience.dataforge.values.ValueType +import space.kscience.dataforge.meta.ValueType import space.kscience.tables.ColumnHeader import space.kscience.tables.valueRow import space.kscience.visionforge.html.ResourceLocation diff --git a/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip b/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip index 47701be0..e69de29b 100644 Binary files a/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip and b/demo/playground/src/jvmMain/resources/root/BM@N_geometry.zip differ diff --git a/demo/playground/src/jvmMain/resources/root/event_0.json b/demo/playground/src/jvmMain/resources/root/event_0.json new file mode 100644 index 00000000..6ed9451b --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_0.json @@ -0,0 +1,7912 @@ +[ + [ + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 974, + 1006, + 24, + 90, + 180, + 313, + 362, + 632, + 779 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.5345516204834, + "fY": 1.250044465065, + "fZ": 36.8064994812012, + "fTx": -0.0872875526547432, + "fTy": 0.0181172806769609, + "fQp": 0.171960204839706, + "fCovMatrix": [ + 1.27937266370282e-4, + -4.85821627080441e-4, + -3.7555223570962e-6, + 3.6864985304419e-6, + 1.01499799711746e-5, + 0.0232641790062189, + 1.69457871379564e-5, + -1.66413359693252e-4, + -6.65305415168405e-5, + 4.00254350552132e-7, + -1.53248109313608e-7, + -9.94260062725516e-7, + 1.80128506599431e-6, + 7.03108355537552e-7, + 7.72671501181321e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -12.6429347991943, + "fY": 5.05208110809326, + "fZ": 253.266006469727, + "fTx": 7.01297190971673e-4, + "fTy": 0.0169959291815758, + "fQp": 0.172035798430443, + "fCovMatrix": [ + 0.00105739186983556, + 0.00144061620812863, + 1.79473590833368e-5, + 1.12270981844631e-5, + 4.8466074076714e-5, + 0.0194979812949896, + 2.82164965028642e-5, + 1.43817713251337e-4, + 8.1607504398562e-5, + 5.34483035607991e-7, + 2.24166527118541e-7, + 1.38559039442043e-6, + 1.63161871569173e-6, + 6.84420911056804e-7, + 7.74139425629983e-6 + ] + }, + "fFlag": 0, + "fChi2": 12.2162303924561, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 961, + 991, + 6, + 75, + 178, + 247, + 350, + 430, + 741 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.51734781265259, + "fY": 3.06508040428162, + "fZ": 36.8764991760254, + "fTx": 0.217250749468803, + "fTy": 0.0643623322248459, + "fQp": 0.205487444996834, + "fCovMatrix": [ + 1.31504551973194e-4, + 5.73850178625435e-4, + -3.47611194229103e-6, + -3.85523071599891e-6, + 8.39247604744742e-6, + 0.0246394574642181, + -2.53617758971814e-6, + -1.77185094798915e-4, + -1.41971704579191e-5, + 3.95388326523971e-7, + -8.45878389554855e-9, + -1.00948807357781e-6, + 1.90104719877127e-6, + 3.02061550883082e-7, + 8.24428207124583e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.0765991210938, + "fY": 17.0353946685791, + "fZ": 253.266006469727, + "fTx": 0.331152737140656, + "fTy": 0.0661555081605911, + "fQp": 0.206363037228584, + "fCovMatrix": [ + 0.00106893514748663, + 0.00143959815613925, + 1.87995410669828e-5, + 1.16089695438859e-5, + 4.3531610572245e-5, + 0.0197235085070133, + 2.83265908365138e-5, + 1.49970132042654e-4, + 5.78232829866465e-5, + 6.29673479579651e-7, + 2.26611533094001e-7, + 1.31542185499711e-6, + 1.82977680651675e-6, + 4.36535003700556e-7, + 8.22780566522852e-6 + ] + }, + "fFlag": 0, + "fChi2": 41.6662788391113, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509940368, + "fStsHits": [ + 1016, + 38, + 120, + 220, + 317, + 371, + 633, + 863 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 6.3819899559021, + "fY": -4.55210590362549, + "fZ": 42.3520011901855, + "fTx": 0.186407506465912, + "fTy": -0.114231139421463, + "fQp": 0.564049184322357, + "fCovMatrix": [ + 2.09370467928238e-4, + -7.88959383498877e-4, + -4.99387397212558e-6, + 7.36422498448519e-6, + 9.89626551017864e-6, + 0.0280679222196341, + 1.20942240755539e-6, + -2.68892734311521e-4, + -5.33221191290068e-6, + 1.47621835822065e-6, + -3.43512951417324e-8, + -2.07013545150403e-6, + 5.11011558046448e-6, + 1.62103575007677e-7, + 3.53423638443928e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 78.3410491943359, + "fY": -30.1586742401123, + "fZ": 248.565994262695, + "fTx": 0.519947171211243, + "fTy": -0.138447120785713, + "fQp": 0.568591356277466, + "fCovMatrix": [ + 0.00111755426041782, + -0.00150139129254967, + 3.1857311114436e-5, + -1.81215455086203e-5, + 5.22565605933778e-5, + 0.0204639304429293, + -6.45808249828406e-5, + 2.0539241086226e-4, + -8.36852050269954e-5, + 2.64465393229329e-6, + -8.06947014098114e-7, + 2.75229331236915e-6, + 4.93603874929249e-6, + -1.25252370253293e-6, + 3.4731492633e-5 + ] + }, + "fFlag": 0, + "fChi2": 48.1372489929199, + "fNDF": 11, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509936688, + "fStsHits": [ + 893, + 938, + 971, + 1001, + 17, + 86, + 163, + 254, + 339, + 429 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.88969993591309, + "fY": 1.39906001091003, + "fZ": 19.2385005950928, + "fTx": -0.166057333350182, + "fTy": 0.081357829272747, + "fQp": 1.93327069282532, + "fCovMatrix": [ + 1.96733133634552e-4, + -0.0016653569182381, + -1.310913648922e-5, + 2.73616478807526e-5, + 2.41490324697224e-5, + 0.0733450576663017, + 3.03498036373639e-5, + -0.0012214258313179, + 1.01110737887211e-4, + 3.97112444261438e-6, + -8.57961822475772e-7, + -7.769801413815e-6, + 3.36613557010423e-5, + 7.30538772586442e-7, + 3.78385477233678e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.4413909912109, + "fY": 18.4549140930176, + "fZ": 217.451995849609, + "fTx": 1.14467430114746, + "fTy": 0.122764363884926, + "fQp": 1.95217978954315, + "fCovMatrix": [ + 0.00171380024403334, + -0.00418118108063936, + 1.0429337999085e-4, + -7.7113312727306e-5, + 1.41469237860292e-4, + 0.0365858227014542, + -3.63614817615598e-4, + 6.59077544696629e-4, + -4.98083070851862e-4, + 2.47048610617639e-5, + -2.76183914138528e-6, + 2.36326213780558e-5, + 3.55777374352328e-5, + -4.08496134696179e-6, + 3.6235831794329e-4 + ] + }, + "fFlag": 0, + "fChi2": 26.7674999237061, + "fNDF": 15, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509936688, + "fStsHits": [ + 899, + 940, + 973, + 1004, + 20, + 188, + 287, + 337, + 434, + 715 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -2.68070912361145, + "fY": 2.10225534439087, + "fZ": 19.2385005950928, + "fTx": -0.121914230287075, + "fTy": 0.0926407650113106, + "fQp": 0.867175340652466, + "fCovMatrix": [ + 1.68846847373061e-4, + -0.00122805847786367, + -8.67153812578181e-6, + 1.14171198219992e-5, + 1.75226996361744e-5, + 0.0474106967449188, + 3.05320900224615e-5, + -4.7915696632117e-4, + -7.76774395490065e-5, + 1.27255077586597e-6, + -3.17726517096162e-7, + -2.61566196968488e-6, + 9.19102785701398e-6, + 7.4841182140517e-7, + 7.94506777310744e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.3584899902344, + "fY": 23.1596603393555, + "fZ": 253.266006469727, + "fTx": 0.386137813329697, + "fTy": 0.0894111171364784, + "fQp": 0.872905194759369, + "fCovMatrix": [ + 0.00141222530510277, + 0.00261890306137502, + 4.1884839447448e-5, + 3.52654060407076e-5, + 6.37184057268314e-5, + 0.026132557541132, + 1.03059472166933e-4, + 3.20465071126819e-4, + 1.36897549964488e-4, + 3.59388832293916e-6, + 1.2825257726945e-6, + 4.27736631536391e-6, + 8.88297381607117e-6, + 1.62169681061641e-6, + 7.93475410318933e-5 + ] + }, + "fFlag": 0, + "fChi2": 36.3777732849121, + "fNDF": 15, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509938528, + "fStsHits": [ + 957, + 986, + 52, + 159, + 230, + 327, + 409, + 694, + 872 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.74364900588989, + "fY": -2.54444789886475, + "fZ": 25.0970001220703, + "fTx": -0.142562881112099, + "fTy": -0.107907794415951, + "fQp": 0.321766316890717, + "fCovMatrix": [ + 1.39540192321874e-4, + 6.25495449639857e-4, + -5.4858128351043e-6, + -4.96140728500905e-6, + 8.31528905109735e-6, + 0.028283754363656, + -2.80246349575464e-5, + -2.21876412979327e-4, + 6.13260344834998e-5, + 7.6472900900626e-7, + 2.21928303290042e-7, + -8.54944346428965e-7, + 3.13729537992913e-6, + -5.67445340493578e-7, + 1.44416608236497e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -15.6737995147705, + "fY": -26.5016078948975, + "fZ": 248.565994262695, + "fTx": 0.0339683443307877, + "fTy": -0.106621921062469, + "fQp": 0.322487384080887, + "fCovMatrix": [ + 9.68566455412656e-4, + -0.00108841923065484, + 1.94350541278254e-5, + -9.72522593656322e-6, + 4.41747761215083e-5, + 0.0180964469909668, + -2.95923709927592e-5, + 1.45901823998429e-4, + -6.44115061732009e-5, + 9.45050828704552e-7, + -2.62571404618939e-7, + 1.67258588135155e-6, + 2.29809893426136e-6, + -6.07894776294415e-7, + 1.44884925248334e-5 + ] + }, + "fFlag": 0, + "fChi2": 18.3176460266113, + "fNDF": 13, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509940368, + "fStsHits": [ + 895, + 939, + 972, + 1003, + 27, + 84, + 174, + 250 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.42452311515808, + "fY": 1.31336784362793, + "fZ": 19.2385005950928, + "fTx": -0.139086008071899, + "fTy": 0.0885453298687935, + "fQp": 2.47033476829529, + "fCovMatrix": [ + 2.12573911994696e-4, + -0.00202700681984425, + -1.55479410750559e-5, + 3.68334476661403e-5, + 4.15232061641291e-5, + 0.0915368050336838, + 3.206187102478e-5, + -0.00166892097331583, + 5.4530892521143e-4, + 6.06955200055381e-6, + -1.22259484669485e-6, + -1.8674476450542e-5, + 5.09153614984825e-5, + -4.35777155871619e-6, + 0.00107842439319938 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 35.9676246643066, + "fY": 14.2686767578125, + "fZ": 154.856994628906, + "fTx": 0.896000862121582, + "fTy": 0.118299603462219, + "fQp": 2.51388120651245, + "fCovMatrix": [ + 0.001817143172957, + -0.00485007045790553, + 1.14804308395833e-4, + -9.64944920269772e-5, + 2.9752537375316e-4, + 0.0413326025009155, + -4.27107122959569e-4, + 7.91111495345831e-4, + -0.00113374111242592, + 2.6783502107719e-5, + -3.85322800866561e-6, + 5.09271048940718e-5, + 4.6236724301707e-5, + -1.47345344885252e-5, + 0.00102324690669775 + ] + }, + "fFlag": 0, + "fChi2": 40.4142456054688, + "fNDF": 11, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 1033, + 48, + 160, + 331, + 407, + 697, + 870 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -13.5733032226562, + "fY": -2.11779046058655, + "fZ": 41.3269996643066, + "fTx": -0.303289979696274, + "fTy": -0.0571999363601208, + "fQp": 0.409863412380219, + "fCovMatrix": [ + 1.92375795450062e-4, + 3.54970485204831e-4, + -6.03487251282786e-6, + -3.4954239254148e-6, + 1.08150279629626e-5, + 0.0272667352110147, + -3.07323098240886e-5, + -2.24761650315486e-4, + 1.51475287566427e-5, + 2.28913427235966e-6, + 3.55021910536379e-7, + -1.29986210595234e-6, + 5.10126847075298e-6, + -6.66355504108651e-7, + 2.43799313466297e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -53.5613479614258, + "fY": -13.3742799758911, + "fZ": 248.565994262695, + "fTx": -0.0919805094599724, + "fTy": -0.051100492477417, + "fQp": 0.409756720066071, + "fCovMatrix": [ + 0.00102374202106148, + -0.00121821509674191, + 2.25714866246562e-5, + -9.65455365076195e-6, + 5.50462027604226e-5, + 0.0189228896051645, + -3.68259061360732e-5, + 1.56089285155758e-4, + -8.76016565598547e-5, + 1.22756193832174e-6, + -2.51058338562871e-7, + 2.36619644056191e-6, + 2.87100806417584e-6, + -4.09444822935257e-7, + 2.46403506025672e-5 + ] + }, + "fFlag": 0, + "fChi2": 22.5092430114746, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 1023, + 71, + 242, + 332, + 411, + 691, + 874 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.793833792209625, + "fY": -5.07560539245605, + "fZ": 41.2070007324219, + "fTx": -0.00528146233409643, + "fTy": -0.0801199078559875, + "fQp": 0.212064072489738, + "fCovMatrix": [ + 2.20483358134516e-4, + -0.00113531132228673, + -2.9238908609841e-6, + 7.47520653021638e-6, + 6.19972524873447e-6, + 0.0372364558279514, + -2.69870015472407e-5, + -2.56144820014015e-4, + 9.13071853574365e-5, + 9.30207363580848e-7, + 1.75039787109199e-7, + -1.16978264941281e-6, + 2.98273744192556e-6, + -6.90119065893668e-7, + 1.02850199255045e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.50048065185547, + "fY": -21.8310127258301, + "fZ": 248.565994262695, + "fTx": 0.10227494686842, + "fTy": -0.0813720002770424, + "fQp": 0.212042018771172, + "fCovMatrix": [ + 9.97935771010816e-4, + -0.00117292185314, + 1.91287272173213e-5, + -1.25147380458657e-5, + 5.18714150530286e-5, + 0.0186820216476917, + -2.78511197393527e-5, + 1.57315167598426e-4, + -6.73831964377314e-5, + 7.11255154328683e-7, + -3.22366929594864e-7, + 1.75655213752179e-6, + 2.28617523134744e-6, + -8.3049457089146e-7, + 1.02555823104922e-5 + ] + }, + "fFlag": 0, + "fChi2": 24.935546875, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509942208, + "fStsHits": [ + 71, + 156, + 231, + 329, + 408, + 696, + 869 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.829330503940582, + "fY": -6.16100406646729, + "fZ": 60.8950004577637, + "fTx": -0.0424437262117863, + "fTy": -0.0929087698459625, + "fQp": -1.00865876674652, + "fCovMatrix": [ + 0.00144624512176961, + -0.00277250865474343, + -4.15815084124915e-5, + 3.73268521798309e-5, + 8.46372786327265e-5, + 0.0276215653866529, + 1.01451587397605e-4, + -3.41085076797754e-4, + -1.64008262800053e-4, + 3.33984257849806e-6, + -1.22679557534866e-6, + -7.20000844012247e-6, + 8.97274912858848e-6, + 2.28002954827389e-6, + 1.18834454042371e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -58.270393371582, + "fY": -24.5115928649902, + "fZ": 248.565994262695, + "fTx": -0.582086145877838, + "fTy": -0.102219641208649, + "fQp": -1.00568675994873, + "fCovMatrix": [ + 0.00128551793750376, + -0.00207453384064138, + 4.9034886615118e-5, + -2.93046323349699e-5, + 8.9734407083597e-5, + 0.0242247544229031, + -1.19483127491549e-4, + 3.08274960843846e-4, + -2.00828450033441e-4, + 5.85356519877678e-6, + -1.18506238777627e-6, + 6.76520085107768e-6, + 1.06499564935802e-5, + -3.04863306155312e-6, + 1.18108830065466e-4 + ] + }, + "fFlag": 0, + "fChi2": 32.4650840759277, + "fNDF": 9, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 906, + 945, + 977, + 42, + 107, + 211 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 5.86967897415161, + "fY": -1.55108439922333, + "fZ": 16.2285003662109, + "fTx": 0.393072992563248, + "fTy": -0.102556817233562, + "fQp": 0.870569229125977, + "fCovMatrix": [ + 1.81187831913121e-4, + -0.00166891247499734, + -9.88784813671373e-6, + 2.22598482650938e-5, + 2.58275067608338e-5, + 0.0929074883460999, + -3.55086922354531e-5, + -0.00123381358571351, + 5.46134833712131e-4, + 1.74404340214096e-6, + 3.28533360516303e-7, + -7.56158124204376e-6, + 2.22407834371552e-5, + -9.71335612121038e-6, + 2.2154524049256e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 64.4297180175781, + "fY": -13.9177446365356, + "fZ": 123.677001953125, + "fTx": 0.72672039270401, + "fTy": -0.134330794215202, + "fQp": 0.878399670124054, + "fCovMatrix": [ + 0.00160757114645094, + -0.00398816168308258, + 7.29574530851096e-5, + -8.36182516650297e-5, + 2.40785084315576e-4, + 0.0378738828003407, + -2.46375158894807e-4, + 6.83184887748212e-4, + -7.99094792455435e-4, + 7.44503131500096e-6, + -5.03312639921205e-6, + 2.31208141485695e-5, + 2.11625283554895e-5, + -1.67757134477142e-5, + 2.12662940612063e-4 + ] + }, + "fFlag": 0, + "fChi2": 4.79613256454468, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 80, + 169, + 252, + 353, + 449, + 777 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.38197612762451, + "fY": 1.63796663284302, + "fZ": 92.3769989013672, + "fTx": 0.13623172044754, + "fTy": 0.0324348509311676, + "fQp": 0.174530282616615, + "fCovMatrix": [ + 0.00136274169199169, + -0.00250188261270523, + -3.33625248458702e-5, + 2.60251836152747e-5, + 1.30423548398539e-4, + 0.0255636107176542, + 7.64829601394013e-5, + -2.38627530052327e-4, + -3.43920895829797e-4, + 1.30118041852256e-6, + -8.77133004451025e-7, + -5.70030306334957e-6, + 3.12928341372753e-6, + 4.27608256359235e-6, + 3.17654630634934e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 36.9998054504395, + "fY": 6.80868768692017, + "fZ": 253.266006469727, + "fTx": 0.204165861010551, + "fTy": 0.0321086347103119, + "fQp": 0.174466639757156, + "fCovMatrix": [ + 0.00132604071404785, + 0.00240976945497096, + 3.02924581774278e-5, + 2.5230410756194e-5, + 1.25503007438965e-4, + 0.025324797257781, + 6.86817729729228e-5, + 2.36949999816716e-4, + 3.32722527673468e-4, + 1.11861686491466e-6, + 7.92246112268913e-7, + 5.05562411490246e-6, + 3.14955241265125e-6, + 4.21537333750166e-6, + 3.16932710120454e-5 + ] + }, + "fFlag": 0, + "fChi2": 8.98170948028564, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 154, + 238, + 333, + 420, + 700, + 883 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.4566935300827, + "fY": -5.42157125473022, + "fZ": 97.0770034790039, + "fTx": 0.0110252797603607, + "fTy": -0.0553293600678444, + "fQp": 0.26590359210968, + "fCovMatrix": [ + 0.00118249095976353, + 0.00176220992580056, + -3.13560085487552e-5, + -1.92533934750827e-5, + 1.27977749798447e-4, + 0.0225056633353233, + -6.29064234090038e-5, + -2.16538173845038e-4, + 2.94552708510309e-4, + 1.49477023114741e-6, + 7.45524857848068e-7, + -6.63162018099683e-6, + 3.22147957376728e-6, + -3.78141567125567e-6, + 4.35887268395163e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.82009363174438, + "fY": -13.8860502243042, + "fZ": 248.565994262695, + "fTx": 0.107870183885098, + "fTy": -0.0562192648649216, + "fQp": 0.266337841749191, + "fCovMatrix": [ + 0.00115839694626629, + -0.00171898689586669, + 2.91786582238274e-5, + -1.94178428500891e-5, + 1.24229423818178e-4, + 0.0224172528833151, + -5.91218558838591e-5, + 2.1739570365753e-4, + -2.88082315819338e-4, + 1.38089103529637e-6, + -7.26864755051793e-7, + 5.93746290178387e-6, + 3.33536263497081e-6, + -3.93559366784757e-6, + 4.36123991676141e-5 + ] + }, + "fFlag": 0, + "fChi2": 13.1549520492554, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509944048, + "fStsHits": [ + 987, + 1030, + 49, + 137, + 222, + 330 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -4.15340709686279, + "fY": -6.02573776245117, + "fZ": 33.6940002441406, + "fTx": -0.147238731384277, + "fTy": -0.201069056987762, + "fQp": -0.562814176082611, + "fCovMatrix": [ + 1.60062161739916e-4, + 9.04108746908605e-4, + -8.78184346220223e-6, + -1.01532896223944e-5, + 3.31195587932598e-5, + 0.0440464429557323, + -3.74387273041066e-5, + -5.32485079020262e-4, + 2.48558444582159e-5, + 1.46108300214109e-6, + 2.84713451037533e-7, + -6.11977429798571e-6, + 9.40160316531546e-6, + 1.8087304169967e-6, + 9.25581334740855e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -34.5075836181641, + "fY": -31.8353710174561, + "fZ": 159.557006835938, + "fTx": -0.346722215414047, + "fTy": -0.21097306907177, + "fQp": -0.572068274021149, + "fCovMatrix": [ + 0.00153660564683378, + 0.00338289677165449, + 4.58140784758143e-5, + 4.59371112810913e-5, + 1.61742660566233e-4, + 0.0334698744118214, + 1.14889880933333e-4, + 4.34220593888313e-4, + 3.44392232364044e-4, + 2.73831551567127e-6, + 1.49882725963835e-6, + 1.05627932498464e-5, + 8.82463154994184e-6, + 3.68091014024685e-6, + 9.21655009733513e-5 + ] + }, + "fFlag": 0, + "fChi2": 50.0074996948242, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 841823542, + "fStsHits": [ + 918, + 950, + 982, + 1027, + 112, + 202 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.11198008060455, + "fY": -3.55741095542908, + "fZ": 15.018500328064, + "fTx": -0.0508718937635422, + "fTy": -0.263699769973755, + "fQp": 2.05216598510742, + "fCovMatrix": [ + 2.28203454753384e-4, + -0.00292489072307944, + -1.44636278491816e-5, + 3.46158849424683e-5, + 7.70416154409759e-5, + 0.13354517519474, + 3.51274684362579e-5, + -0.00166058784816414, + -6.19782193098217e-4, + 4.62498428532854e-6, + -5.25030770859303e-7, + -1.74180840986082e-5, + 3.94191229133867e-5, + 1.19795095088193e-6, + 9.7273662686348e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.8955745697021, + "fY": -33.7819709777832, + "fZ": 123.677001953125, + "fTx": 0.604310631752014, + "fTy": -0.315734297037125, + "fQp": 2.09776401519775, + "fCovMatrix": [ + 0.00176150107290596, + -0.00480693858116865, + 1.03912498161662e-4, + -1.12679801532067e-4, + 2.87616538116708e-4, + 0.042500589042902, + -4.01500758016482e-4, + 8.34156293421984e-4, + -9.35784832108766e-4, + 1.83507636393188e-5, + -7.35896674086689e-6, + 5.00350506627001e-5, + 4.53848879260477e-5, + -1.4240275049815e-5, + 9.32074501179159e-4 + ] + }, + "fFlag": 0, + "fChi2": 66.7220230102539, + "fNDF": 7, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 2045861141, + "fStsHits": [ + 212, + 323, + 384, + 682, + 867 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.17882251739502, + "fY": -4.51064395904541, + "fZ": 123.647003173828, + "fTx": 0.0928313285112381, + "fTy": -0.0324885919690132, + "fQp": 0.203487545251846, + "fCovMatrix": [ + 0.00148212176281959, + -0.00283645675517619, + -4.24430181737989e-5, + 2.94141318590846e-5, + 1.98712878045626e-4, + 0.0291197914630175, + 8.29956625238992e-5, + -3.13738972181454e-4, + -3.60756297595799e-4, + 2.1217551875452e-6, + -6.54201699035184e-7, + -1.1963853467023e-5, + 4.89495641886606e-6, + 1.76691435171961e-6, + 8.14418744994327e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.739673614502, + "fY": -8.64188003540039, + "fZ": 248.565994262695, + "fTx": 0.153393998742104, + "fTy": -0.0334637500345707, + "fQp": 0.203488066792488, + "fCovMatrix": [ + 0.00120611628517509, + -0.00176589959301054, + 3.30342554661911e-5, + -1.81667473952984e-5, + 1.64499200764112e-4, + 0.0246628411114216, + -4.92055478389375e-5, + 2.77021696092561e-4, + -1.80929011548869e-4, + 1.72334603121271e-6, + -2.53595430876885e-7, + 1.0244283657812e-5, + 4.93520428790362e-6, + 1.19064839054772e-6, + 8.14808299764991e-5 + ] + }, + "fFlag": 0, + "fChi2": 2.79397416114807, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 780009769, + "fStsHits": [ + 950, + 983, + 46, + 133, + 228 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.33684980869293, + "fY": -5.68583679199219, + "fZ": 23.8120002746582, + "fTx": -0.046341560781002, + "fTy": -0.264156848192215, + "fQp": 0.47034752368927, + "fCovMatrix": [ + 1.77758207428269e-4, + -0.00167154613882303, + -7.95815140008926e-6, + 2.09124373213854e-5, + 4.17731207562611e-5, + 0.097347117960453, + -1.18779353215359e-4, + -0.00133563904091716, + 0.0013626089785248, + 2.10728740057675e-6, + 1.98282441488118e-6, + -1.53840901475633e-5, + 2.21159116335912e-5, + -2.405090162938e-5, + 2.14614119613543e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.12681382894516, + "fY": -32.1258316040039, + "fZ": 123.677001953125, + "fTx": 0.0742319375276566, + "fTy": -0.26606622338295, + "fQp": 0.47090420126915, + "fCovMatrix": [ + 0.00158424722030759, + -0.00395862851291895, + 6.28770649200305e-5, + -8.84528126334772e-5, + 3.37789009790868e-4, + 0.0385282747447491, + -2.04121737624519e-4, + 7.34325964003801e-4, + -0.00110242667142302, + 4.39162113252678e-6, + -4.81559709442081e-6, + 2.59254975389922e-5, + 2.14575829886599e-5, + -2.56246821663808e-5, + 2.14337997022085e-4 + ] + }, + "fFlag": 0, + "fChi2": 3.55766558647156, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1783775740, + "fStsHits": [ + 94, + 185, + 309, + 460, + 771 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.756911277771, + "fY": 6.0902042388916, + "fZ": 92.3769989013672, + "fTx": 0.0795530304312706, + "fTy": 0.0387041419744492, + "fQp": 0.383857846260071, + "fCovMatrix": [ + 0.00146504561416805, + -0.00267798593267798, + -4.07527695642784e-5, + 3.33584466716275e-5, + 1.62895128596574e-4, + 0.0262860096991062, + 8.85876797838137e-5, + -2.59445048868656e-4, + -3.90272907679901e-4, + 1.9929259451601e-6, + -1.31975889416935e-6, + -8.48969739308814e-6, + 4.3192999328312e-6, + 6.5653002820909e-6, + 6.07283327553887e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.5165977478027, + "fY": 12.2913675308228, + "fZ": 253.266006469727, + "fTx": 0.229917138814926, + "fTy": 0.0385008491575718, + "fQp": 0.383702665567398, + "fCovMatrix": [ + 0.00140638451557606, + 0.0031376676633954, + 3.78932563762646e-5, + 3.06943329633214e-5, + 1.49175975820981e-4, + 0.0336156375706196, + 1.34585134219378e-4, + 2.975782554131e-4, + 6.11140800174326e-4, + 2.04978573492554e-6, + 1.21983202916454e-6, + 7.85819793236442e-6, + 4.30095087722293e-6, + 5.96624204263208e-6, + 6.05825152888428e-5 + ] + }, + "fFlag": 0, + "fChi2": 4.29511213302612, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1753091105, + "fStsHits": [ + 952, + 984, + 44, + 136, + 226 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.62948191165924, + "fY": -5.86752128601074, + "fZ": 23.8120002746582, + "fTx": -0.0600441806018353, + "fTy": -0.26595738530159, + "fQp": 0.319428592920303, + "fCovMatrix": [ + 1.76074434421025e-4, + -0.00165681610815227, + -7.5707353062171e-6, + 2.02684732357739e-5, + 4.31656080763787e-5, + 0.0970297381281853, + -1.21578275866341e-4, + -0.00131977954879403, + 0.00141425943002105, + 1.95939787772659e-6, + 2.08528990697232e-6, + -1.57428039528895e-5, + 2.11153437703615e-5, + -2.46925937972264e-5, + 1.80507020559162e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.65879273414612, + "fY": -32.4332733154297, + "fZ": 123.677001953125, + "fTx": 0.021767932921648, + "fTy": -0.266411513090134, + "fQp": 0.319602519273758, + "fCovMatrix": [ + 0.00156673660967499, + -0.00387575500644743, + 6.05840032221749e-5, + -8.63880923134275e-5, + 3.30092705553398e-4, + 0.0381363146007061, + -1.93470521480776e-4, + 7.24260287825018e-4, + -0.0010770196095109, + 3.9610790736333e-6, + -4.63677679363173e-6, + 2.43303911702242e-5, + 2.08122073672712e-5, + -2.54360911640106e-5, + 1.80816088686697e-4 + ] + }, + "fFlag": 0, + "fChi2": 5.04423904418945, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1727319917, + "fStsHits": [ + 196, + 284, + 364, + 617, + 838 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0453771762549877, + "fY": 7.03937816619873, + "fZ": 128.34700012207, + "fTx": 0.00845559220761061, + "fTy": 0.047437522560358, + "fQp": 0.107237465679646, + "fCovMatrix": [ + 0.00123450730461627, + 0.00183064327575266, + -3.61626989615615e-5, + -1.8157712474931e-5, + 1.78052068804391e-4, + 0.0247203707695007, + -5.3579336963594e-5, + -2.74032790912315e-4, + 2.21665206481703e-4, + 1.94701146938314e-6, + 2.26964857574785e-7, + -1.18611933430657e-5, + 4.69406131742289e-6, + 9.15381235699897e-7, + 8.15421881270595e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.12280011177063, + "fY": 12.9418659210205, + "fZ": 253.266006469727, + "fTx": 0.0393691956996918, + "fTy": 0.0470872633159161, + "fQp": 0.107262767851353, + "fCovMatrix": [ + 0.00143866648431867, + 0.00267561944201589, + 3.81068348360714e-5, + 2.64393638644833e-5, + 1.97235814994201e-4, + 0.0286122001707554, + 7.03344339854084e-5, + 3.05421301163733e-4, + 3.22181411320344e-4, + 1.72607190052076e-6, + 4.73346517537721e-7, + 1.10340961327893e-5, + 4.70324175694259e-6, + 7.17808632089145e-7, + 8.15572566352785e-5 + ] + }, + "fFlag": 0, + "fChi2": 5.80071449279785, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -570815414, + "fStsHits": [ + 71, + 152, + 324, + 412, + 688 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.803397238254547, + "fY": -6.56422710418701, + "fZ": 60.8950004577637, + "fTx": -0.00771209271624684, + "fTy": -0.108717255294323, + "fQp": 0.300887942314148, + "fCovMatrix": [ + 0.00141080969478935, + -0.0031610825099051, + -3.76598727598321e-5, + 3.06488036585506e-5, + 1.47927450598218e-4, + 0.0337333455681801, + 1.34264904772863e-4, + -2.94755038339645e-4, + -6.17008830886334e-4, + 1.84850216555787e-6, + -1.25635426684312e-6, + -7.9250839917222e-6, + 3.78815661861154e-6, + 6.15704539086437e-6, + 4.82227878819685e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.91399574279785, + "fY": -24.2552947998047, + "fZ": 222.151992797852, + "fTx": 0.11579817533493, + "fTy": -0.110671669244766, + "fQp": 0.300759524106979, + "fCovMatrix": [ + 0.00144522078335285, + 0.00259754969738424, + 3.88384942198172e-5, + 3.15018660330679e-5, + 1.55900037498213e-4, + 0.0258977226912975, + 8.17190230009146e-5, + 2.48358410317451e-4, + 3.75826784875244e-4, + 1.75587786088727e-6, + 1.22047936201852e-6, + 7.71112809161423e-6, + 3.81520703740534e-6, + 6.17916612100089e-6, + 4.81271272292361e-5 + ] + }, + "fFlag": 0, + "fChi2": 9.90100955963135, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1256349111, + "fStsHits": [ + 88, + 182, + 364, + 610, + 762 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -7.7644305229187, + "fY": 4.62638235092163, + "fZ": 92.3769989013672, + "fTx": 0.05038708075881, + "fTy": 0.0621802993118763, + "fQp": 0.322648286819458, + "fCovMatrix": [ + 0.00143061450216919, + -0.00323629332706332, + -3.96349423681386e-5, + 3.10439791064709e-5, + 1.59761097165756e-4, + 0.034010075032711, + 1.41817727126181e-4, + -2.96661688480526e-4, + -6.54383446089923e-4, + 2.02863679987786e-6, + -1.29700083562057e-6, + -8.92197112989379e-6, + 3.86577039535041e-6, + 6.31388365945895e-6, + 5.65568916499615e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 10.7545213699341, + "fY": 14.619312286377, + "fZ": 253.266006469727, + "fTx": 0.175300538539886, + "fTy": 0.0621379911899567, + "fQp": 0.323985666036606, + "fCovMatrix": [ + 0.00143892969936132, + 0.0025955606251955, + 3.82889738830272e-5, + 3.2501597161172e-5, + 1.61684947670437e-4, + 0.0259502083063126, + 8.20754066808149e-5, + 2.53723876085132e-4, + 3.79059580154717e-4, + 1.79275116352073e-6, + 1.24236237297737e-6, + 7.63735897635343e-6, + 4.16995817431598e-6, + 6.60814203001792e-6, + 5.67811584915034e-5 + ] + }, + "fFlag": 0, + "fChi2": 13.0799026489258, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 1631218441, + "fStsHits": [ + 214, + 320, + 365, + 644, + 845 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 12.9226551055908, + "fY": -13.7240266799927, + "fZ": 123.647003173828, + "fTx": 0.130619913339615, + "fTy": -0.108535282313824, + "fQp": 0.209555685520172, + "fCovMatrix": [ + 0.00148277322296053, + -0.00284381420351565, + -4.21922559326049e-5, + 2.9940787499072e-5, + 1.88498030183837e-4, + 0.0291615109890699, + 8.29962300485931e-5, + -3.15275421598926e-4, + -3.49751790054142e-4, + 2.09275822271593e-6, + -6.84486224145076e-7, + -1.12324069050374e-5, + 4.92670187668409e-6, + 1.95221741705609e-6, + 7.34898276277818e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.516040802002, + "fY": -27.4323062896729, + "fZ": 248.565994262695, + "fTx": 0.196304440498352, + "fTy": -0.110583245754242, + "fQp": 0.210500478744507, + "fCovMatrix": [ + 0.00120895623695105, + -0.00177905173040926, + 3.32296367560048e-5, + -1.8623793948791e-5, + 1.56467198394239e-4, + 0.0247090216726065, + -5.03061746712774e-5, + 2.78040184639394e-4, + -1.6888887330424e-4, + 1.74129593233374e-6, + -2.8823438924519e-7, + 9.76290812104708e-6, + 4.95667654831777e-6, + 1.07869789189863e-6, + 7.42414413252845e-5 + ] + }, + "fFlag": 0, + "fChi2": 14.8659296035767, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1089573783, + "fStsHits": [ + 98, + 192, + 283, + 351, + 456 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.8950252532959, + "fY": 6.66752052307129, + "fZ": 92.3769989013672, + "fTx": 0.134052261710167, + "fTy": 0.0280783623456955, + "fQp": 0.193836763501167, + "fCovMatrix": [ + 0.00146598450373858, + -0.00278011965565383, + -4.09681779274251e-5, + 2.82712917396566e-5, + 1.85466415132396e-4, + 0.028964975848794, + 7.84197472967207e-5, + -3.11124749714509e-4, + -3.21005441946909e-4, + 2.00165459318669e-6, + -5.77290904857364e-7, + -1.10228729681694e-5, + 4.85223381474498e-6, + 1.17897820928192e-6, + 7.34671484678984e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 11.7369527816772, + "fY": 10.1584901809692, + "fZ": 217.451995849609, + "fTx": 0.195405215024948, + "fTy": 0.0278738830238581, + "fQp": 0.193810537457466, + "fCovMatrix": [ + 0.00122305878903717, + -0.00181355641689152, + 3.46680826623924e-5, + -1.83849115273915e-5, + 1.60300332936458e-4, + 0.0247811619192362, + -5.19911627634428e-5, + 2.76879087323323e-4, + -1.93408704944886e-4, + 1.84531995728321e-6, + -2.47711994916244e-7, + 1.04186356111313e-5, + 4.85624241264304e-6, + 9.14421434572432e-7, + 7.33600318199024e-5 + ] + }, + "fFlag": 0, + "fChi2": 15.9439134597778, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -572594012, + "fStsHits": [ + 1000, + 26, + 179, + 277, + 360 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.45930767059326, + "fY": 6.92299270629883, + "fZ": 46.757999420166, + "fTx": -0.0997228920459747, + "fTy": 0.126160323619843, + "fQp": -1.08766162395477, + "fCovMatrix": [ + 2.355308533879e-4, + 0.00165701541118324, + -3.18914771924028e-6, + -1.781737228157e-5, + 2.42890519075445e-6, + 0.0631281286478043, + 1.61764794029295e-4, + -7.06360558979213e-4, + -6.62483798805624e-4, + 5.00110809298349e-6, + -1.24003827295383e-6, + -9.39585697778966e-6, + 1.63867207447765e-5, + 7.21116703061853e-6, + 2.10776037420146e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -45.8982467651367, + "fY": 26.5154438018799, + "fZ": 190.85400390625, + "fTx": -0.550392150878906, + "fTy": 0.153908878564835, + "fQp": -1.0933438539505, + "fCovMatrix": [ + 0.0016527270199731, + 0.00375722139142454, + 5.61533379368484e-5, + 5.73905490455218e-5, + 1.73844207893126e-4, + 0.0337851718068123, + 1.5984958736226e-4, + 4.66885743662715e-4, + 5.14892512001097e-4, + 5.31236173628713e-6, + 1.87523312433768e-6, + 1.50291079989984e-5, + 1.36366652441211e-5, + 7.82930146669969e-6, + 2.06039971089922e-4 + ] + }, + "fFlag": 0, + "fChi2": 17.9824352264404, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1619730797, + "fStsHits": [ + 165, + 258, + 338, + 431, + 716 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 12.3870306015015, + "fY": 11.0686092376709, + "fZ": 128.34700012207, + "fTx": 0.131722062826157, + "fTy": 0.0759622156620026, + "fQp": 0.261173069477081, + "fCovMatrix": [ + 0.00124171550851315, + 0.00187338155228645, + -3.69237168342806e-5, + -1.9492090359563e-5, + 1.73412641743198e-4, + 0.0249464139342308, + -5.82418651902117e-5, + -2.8073534485884e-4, + 2.31354613788426e-4, + 2.10472785511229e-6, + 3.32169463490573e-7, + -1.17652871267637e-5, + 5.04569197801175e-6, + 4.14970998008357e-7, + 8.72551318025216e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.9409980773926, + "fY": 20.5864219665527, + "fZ": 253.266006469727, + "fTx": 0.210582479834557, + "fTy": 0.0765761435031891, + "fQp": 0.26235419511795, + "fCovMatrix": [ + 0.00145445531234145, + 0.00275185145437717, + 3.95754941564519e-5, + 2.84991037915461e-5, + 1.90182065125555e-4, + 0.0289667211472988, + 7.69189500715584e-5, + 3.15010925987735e-4, + 3.13600699882954e-4, + 1.93685445992742e-6, + 5.99234567744134e-7, + 1.08821486719535e-5, + 5.13304030391737e-6, + 9.56498297455255e-7, + 8.76150515978225e-5 + ] + }, + "fFlag": 0, + "fChi2": 19.2227821350098, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 317411667, + "fStsHits": [ + 891, + 933, + 969, + 26, + 103 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.118693307042122, + "fY": 3.28726029396057, + "fZ": 20.4885005950928, + "fTx": -0.0277622360736132, + "fTy": 0.111176677048206, + "fQp": -1.19562482833862, + "fCovMatrix": [ + 2.35528306802735e-4, + 0.00313890515826643, + -1.5442321455339e-5, + -6.0346610553097e-5, + 1.6858137678355e-4, + 0.148759827017784, + -5.5129228712758e-5, + -0.00262891850434244, + 4.23989520641044e-4, + 2.86749855149537e-6, + 2.28715475714125e-6, + -4.02842524636071e-5, + 5.76369639020413e-5, + -3.13870623358525e-5, + 0.001336490502581 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.37472343444824, + "fY": 11.430046081543, + "fZ": 92.4069976806641, + "fTx": -0.238975748419762, + "fTy": 0.116884142160416, + "fQp": -1.2022613286972, + "fCovMatrix": [ + 0.00181734294164926, + -0.00530816009268165, + 7.91477577877231e-5, + -1.48450635606423e-4, + 5.27066120412201e-4, + 0.047173984348774, + -2.73892597761005e-4, + 0.00118228862993419, + -0.00185405183583498, + 8.10304391052341e-6, + -5.2895188673574e-6, + 6.60147197777405e-5, + 5.66577327845152e-5, + -3.31722803821322e-5, + 0.00132040248718113 + ] + }, + "fFlag": 0, + "fChi2": 22.2989349365234, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1938391410, + "fStsHits": [ + 990, + 1034, + 43, + 138, + 225 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -13.7463674545288, + "fY": -8.49878787994385, + "fZ": 32.5089988708496, + "fTx": -0.353216707706451, + "fTy": -0.281654328107834, + "fQp": 2.23452591896057, + "fCovMatrix": [ + 2.40419758483768e-4, + 0.00225452845916152, + -2.05391843337566e-5, + -4.39578507211991e-5, + 9.27949513425119e-5, + 0.0848906114697456, + -1.73469685250893e-4, + -0.00167269050143659, + 0.00111202069092542, + 6.10797815170372e-6, + 3.83878614229616e-6, + -3.20881226798519e-5, + 5.32719241164159e-5, + -3.73771363229025e-5, + 0.00151395157445222 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -20.3196315765381, + "fY": -32.7212295532227, + "fZ": 123.677001953125, + "fTx": 0.20149177312851, + "fTy": -0.26336732506752, + "fQp": 2.23557496070862, + "fCovMatrix": [ + 0.00191347696818411, + -0.00565362721681595, + 1.08587002614513e-4, + -1.2761885591317e-4, + 5.17589738592505e-4, + 0.0476216077804565, + -4.27084742113948e-4, + 9.8123773932457e-4, + -0.00190889881923795, + 1.62221658683848e-5, + -8.1552079791436e-6, + 6.61053418298252e-5, + 4.30222571594641e-5, + -3.38782410835847e-5, + 0.00154678162652999 + ] + }, + "fFlag": 0, + "fChi2": 23.6136322021484, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": -1148839103, + "fStsHits": [ + 1015, + 40, + 110, + 210, + 316 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 15.3931322097778, + "fY": -5.86246490478516, + "fZ": 41.1969985961914, + "fTx": 0.425355613231659, + "fTy": -0.167463481426239, + "fQp": 0.66620284318924, + "fCovMatrix": [ + 2.32632548431866e-4, + -0.00139971077442169, + -7.05169713910436e-6, + 1.88414396689041e-5, + 3.04557925119298e-5, + 0.0488575883209705, + 1.53349592437735e-5, + -6.44137908238918e-4, + -3.31959425238892e-4, + 2.50099969889561e-6, + -5.98936765072722e-7, + -6.69307655698503e-6, + 1.28128649521386e-5, + 8.02432987256907e-6, + 9.66489169513807e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 81.8046035766602, + "fY": -27.8622398376465, + "fZ": 159.557006835938, + "fTx": 0.712900757789612, + "fTy": -0.214687287807465, + "fQp": 0.6629798412323, + "fCovMatrix": [ + 0.00161223881877959, + 0.00377275561913848, + 5.2143404900562e-5, + 4.81264833069872e-5, + 1.53602843056433e-4, + 0.0361070893704891, + 1.45044105011038e-4, + 4.82708710478619e-4, + 4.52368607511744e-4, + 3.82798089049174e-6, + 1.44914736210922e-6, + 1.09584916572203e-5, + 1.07873020169791e-5, + 3.82571352020022e-6, + 9.4176190032158e-5 + ] + }, + "fFlag": 0, + "fChi2": 29.0788040161133, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 334, + 416, + 702, + 878 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.35294222831726, + "fY": -2.94638586044312, + "fZ": 159.526992797852, + "fTx": -0.00160328403580934, + "fTy": -0.0169267207384109, + "fQp": 0.10196129232645, + "fCovMatrix": [ + 0.00179960147943348, + 0.00482485769316554, + -9.23326733754948e-5, + -9.07427238416858e-5, + 7.38598289899528e-4, + 0.0417420007288456, + -3.3866785815917e-4, + -7.00218544807285e-4, + 0.00302853807806969, + 7.63753359933617e-6, + 7.02233910487848e-6, + -6.8635301431641e-5, + 1.55159104906488e-5, + -6.57245327602141e-5, + 6.4580439357087e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.532455503940582, + "fY": -4.46498012542725, + "fZ": 248.565994262695, + "fTx": 0.0189191028475761, + "fTy": -0.0171638447791338, + "fQp": 0.101984426379204, + "fCovMatrix": [ + 0.00173512159381062, + -0.00453752232715487, + 8.09849516372196e-5, + -8.93523174454458e-5, + 7.11599015630782e-4, + 0.040440745651722, + -2.90200347080827e-4, + 6.92508299835026e-4, + -0.00289812195114791, + 6.1066607486282e-6, + -6.37889570498373e-6, + 6.09674789302517e-5, + 1.58358107000822e-5, + -6.72492606099695e-5, + 6.46489846985787e-4 + ] + }, + "fFlag": 0, + "fChi2": 0.246076673269272, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 299, + 363, + 631, + 835 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.876356244087219, + "fY": 4.59287118911743, + "fZ": 154.826995849609, + "fTx": 0.0117781879380345, + "fTy": 0.0225483179092407, + "fQp": 0.158706292510033, + "fCovMatrix": [ + 0.00191981764510274, + -0.00540495757013559, + -7.71153063396923e-5, + 9.03008331079036e-5, + 5.39929606020451e-4, + 0.0448320657014847, + 2.76860781013966e-4, + -6.93060865160078e-4, + -0.00220356229692698, + 4.92713297717273e-6, + -5.18905198987341e-6, + -3.95706665585749e-5, + 1.40935781018925e-5, + 4.43687822553329e-5, + 3.44185682479292e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.1041431427002, + "fY": 6.79212951660156, + "fZ": 253.266006469727, + "fTx": 0.0468702279031277, + "fTy": 0.0221596695482731, + "fQp": 0.158737048506737, + "fCovMatrix": [ + 0.00187287107110023, + 0.00517367757856846, + 6.87778447172605e-5, + 8.69970317580737e-5, + 5.25635492522269e-4, + 0.0436974242329597, + 2.40288529312238e-4, + 6.76476571243256e-4, + 0.00211965525522828, + 3.98110887545045e-6, + 4.53476877737558e-6, + 3.50696209352463e-5, + 1.39108415169176e-5, + 4.35302827099804e-5, + 3.44250904163346e-4 + ] + }, + "fFlag": 0, + "fChi2": 0.626406669616699, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 0, + "fStsHits": [ + 60, + 157, + 234, + 419 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.18759298324585, + "fY": -0.0998069643974304, + "fZ": 60.8950004577637, + "fTx": 0.0214630328118801, + "fTy": -0.033104483038187, + "fQp": 0.2199397534132, + "fCovMatrix": [ + 0.00159321434330195, + -0.00335911754518747, + -4.65064476884436e-5, + 4.81843162560835e-5, + 1.99641872313805e-4, + 0.0316577106714249, + 1.0396541620139e-4, + -4.05301689170301e-4, + -3.7617507041432e-4, + 2.28655767386954e-6, + -1.41693453770131e-6, + -1.16198334580986e-5, + 8.46501461637672e-6, + 2.66416714111983e-6, + 7.98600594862364e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.81798672676086, + "fY": -4.31223726272583, + "fZ": 186.154006958008, + "fTx": 0.0906062945723534, + "fTy": -0.0340937301516533, + "fQp": 0.220142289996147, + "fCovMatrix": [ + 0.00228732591494918, + -0.00766046345233917, + 4.16833136114292e-5, + -7.82218339736573e-5, + 1.34086134494282e-4, + 0.0586880035698414, + -9.49596069403924e-5, + 6.17937359493226e-4, + -8.07608885224909e-5, + 1.95375764633354e-6, + -6.85975749092904e-7, + 1.08221520349616e-5, + 8.30812223284738e-6, + 2.07624725589994e-6, + 7.99878544057719e-5 + ] + }, + "fFlag": 0, + "fChi2": 9.89065361022949, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 200, + 280, + 625, + 819 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.28802347183228, + "fY": 6.78667116165161, + "fZ": 128.34700012207, + "fTx": -0.00295145390555263, + "fTy": 0.066863514482975, + "fQp": -0.0631726533174515, + "fCovMatrix": [ + 0.00143133662641048, + 0.00306019233539701, + -6.01537140028086e-5, + -1.5882706065895e-5, + 3.39286430971697e-4, + 0.0325751826167107, + -2.009497693507e-4, + -2.5962368818e-4, + 0.00121131900232285, + 4.89485682919621e-6, + -3.542085380559e-8, + -3.16990190185606e-5, + 4.67263043901767e-6, + 2.65530707110884e-6, + 2.13194463867694e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.728297472000122, + "fY": 15.1543607711792, + "fZ": 253.266006469727, + "fTx": -0.0212028790265322, + "fTy": 0.0670934021472931, + "fQp": -0.0630813986063004, + "fCovMatrix": [ + 0.00170980067923665, + 0.00438810000196099, + 6.43509774818085e-5, + 2.79260748357046e-5, + 3.84177605155855e-4, + 0.0395979657769203, + 2.32808495638892e-4, + 3.1552481232211e-4, + 0.00148620537947863, + 4.30931640948984e-6, + 6.17797468294157e-7, + 2.9539532988565e-5, + 4.65721086584381e-6, + 1.86477541319618e-6, + 2.11488266359083e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.0721521377563, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 200, + 278, + 457, + 769 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.22705960273743, + "fY": 6.41402244567871, + "fZ": 128.34700012207, + "fTx": 0.0584860555827618, + "fTy": 0.0308030731976032, + "fQp": 0.264887034893036, + "fCovMatrix": [ + 0.0014375695027411, + 0.00309103447943926, + -6.08879199717194e-5, + -1.67893485922832e-5, + 3.37220088113099e-4, + 0.0327315106987953, + -2.04334617592394e-4, + -2.64919508481398e-4, + 0.00120495993178338, + 5.05339949086192e-6, + 3.06302361252619e-8, + -3.16862751787994e-5, + 5.05134403283591e-6, + 2.47289267463202e-6, + 2.21960639464669e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.576849937439, + "fY": 10.2098379135132, + "fZ": 253.266006469727, + "fTx": 0.135617300868034, + "fTy": 0.0301221162080765, + "fQp": 0.264727205038071, + "fCovMatrix": [ + 0.00171579921152443, + 0.00442134169861674, + 6.48677450953983e-5, + 2.92732129310025e-5, + 3.80714831408113e-4, + 0.0397795774042606, + 2.3569269978907e-4, + 3.22912295814604e-4, + 0.00147179246414453, + 4.43919816461857e-6, + 7.01510657563631e-7, + 2.92453114525415e-5, + 5.09910523760482e-6, + 1.95571692529484e-6, + 2.21771551878192e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.6950998306274, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 79, + 177, + 354, + 435 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.6889057159424, + "fY": 1.59998142719269, + "fZ": 92.3769989013672, + "fTx": 0.188801899552345, + "fTy": 0.0019485397497192, + "fQp": 0.193691298365593, + "fCovMatrix": [ + 0.00175668124575168, + -0.00460470886901021, + -7.0030233473517e-5, + 3.18565325869713e-5, + 3.55471536749974e-4, + 0.040591511875391, + 2.57493113167584e-4, + -3.32050200086087e-4, + -0.00139040977228433, + 4.9586401473789e-6, + -9.23504728689295e-7, + -2.84806355921319e-5, + 4.88101841256139e-6, + 3.32723448082106e-6, + 1.75820154254325e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 42.284595489502, + "fY": 1.7777191400528, + "fZ": 217.451995849609, + "fTx": 0.251348227262497, + "fTy": 0.00114794040564448, + "fQp": 0.193487912416458, + "fCovMatrix": [ + 0.00140010926406831, + -0.0029458578210324, + 5.59846776013728e-5, + -1.63711501954822e-5, + 2.90705327643082e-4, + 0.0321751311421394, + -1.85875440365635e-4, + 2.63134745182469e-4, + -0.00103027222212404, + 4.47622051069629e-6, + -9.90499948727575e-9, + 2.62509583990322e-5, + 5.04389936395455e-6, + 2.64827554019575e-6, + 1.75261535332538e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.7743577957153, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789398544, + "fStsHits": [ + 173, + 256, + 450, + 764 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.3037147521973, + "fY": 8.18320560455322, + "fZ": 128.34700012207, + "fTx": 0.0485100857913494, + "fTy": 0.0269599035382271, + "fQp": -0.464794427156448, + "fCovMatrix": [ + 0.00144951173570007, + 0.00314678833819926, + -6.25289030722342e-5, + -1.83544307219563e-5, + 3.45025095157325e-4, + 0.0330061092972755, + -2.11471997317858e-4, + -2.74737540166825e-4, + 0.0012352877529338, + 5.42095585842617e-6, + 1.29005059079645e-7, + -3.29223839798942e-5, + 5.89166847930755e-6, + 2.42049827647861e-6, + 2.57838779361919e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 13.6117811203003, + "fY": 11.6619310379028, + "fZ": 253.266006469727, + "fTx": -0.0849352851510048, + "fTy": 0.0285291355103254, + "fQp": -0.465198427438736, + "fCovMatrix": [ + 0.00172228959854692, + 0.00445574428886175, + 6.58447606838308e-5, + 3.0620507459389e-5, + 3.84085607947782e-4, + 0.0399787276983261, + 2.39864952163771e-4, + 3.32715193508193e-4, + 0.00148236250970513, + 4.74132048111642e-6, + 7.53851111312542e-7, + 2.96433372568572e-5, + 6.02678755967645e-6, + 1.60450338171358e-6, + 2.58154206676409e-4 + ] + }, + "fFlag": 0, + "fChi2": 12.822455406189, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 509945888, + "fStsHits": [ + 924, + 956, + 989, + 47, + 144 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -4.1777400970459, + "fY": -1.59111475944519, + "fZ": 16.4085006713867, + "fTx": -0.303603857755661, + "fTy": -0.146884217858315, + "fQp": -2.63142681121826, + "fCovMatrix": [ + 2.53685546340421e-4, + 0.00353788468055427, + -1.72874388226774e-5, + -7.87809622124769e-5, + 7.9515295510646e-5, + 0.158824130892754, + -1.12649591756053e-4, + -0.00375775853171945, + 0.00218742550350726, + 6.11713994658203e-6, + 1.87641842330777e-6, + -5.18201413797215e-5, + 1.49448547745124e-4, + 4.5176362618804e-5, + 0.00313072255812585 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -65.9978485107422, + "fY": -15.9892063140869, + "fZ": 97.1070022583008, + "fTx": -1.69931781291962, + "fTy": -0.28000882267952, + "fQp": -2.60817050933838, + "fCovMatrix": [ + 0.0023685097694397, + 0.0083130206912756, + 2.14044077438302e-4, + 2.21727692405693e-4, + 4.34383895481005e-4, + 0.0642749667167664, + 9.29289672058076e-4, + 0.00157989992294461, + 0.00178945402149111, + 2.0627336925827e-4, + 3.11331641569268e-5, + 5.96506637521088e-4, + 9.46382278925739e-5, + 6.35135511402041e-5, + 0.00276731047779322 + ] + }, + "fFlag": 0, + "fChi2": 26.2706127166748, + "fNDF": 5, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827840, + "fStsHits": [ + 902, + 943, + 976, + 29 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.53912496566772, + "fY": -3.89659118652344, + "fZ": 16.2285003662109, + "fTx": 0.522825419902802, + "fTy": -0.288690507411957, + "fQp": 2.22434949874878, + "fCovMatrix": [ + 2.76199105428532e-4, + -0.00450697494670749, + -2.23749011638574e-5, + 1.09772387077101e-4, + 2.49009346589446e-4, + 0.206538245081902, + 1.02680598502047e-4, + -0.00498864334076643, + -0.00146092427894473, + 8.5196879808791e-6, + -3.43298597726971e-6, + -9.17924553505145e-5, + 1.66340614669025e-4, + 2.30491968977731e-5, + 0.00361455837264657 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 39.5060920715332, + "fY": -18.5408248901367, + "fZ": 60.9249992370605, + "fTx": 0.971311092376709, + "fTy": -0.388391822576523, + "fQp": 2.23315715789795, + "fCovMatrix": [ + 0.00245717912912369, + -0.00909164734184742, + 1.58361988724209e-4, + -2.69030395429581e-4, + 6.81250647176057e-4, + 0.070623591542244, + -5.55392180103809e-4, + 0.00196365104056895, + -0.00189403316471726, + 2.47496318479534e-5, + -2.33925493375864e-5, + 8.39190033730119e-5, + 1.84656732017174e-4, + -5.43450478289742e-5, + 0.00324276322498918 + ] + }, + "fFlag": 0, + "fChi2": 0.0160078462213278, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827792, + "fStsHits": [ + 900, + 942, + 975, + 36 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.39200782775879, + "fY": -3.32475161552429, + "fZ": 16.2285003662109, + "fTx": 0.564900398254395, + "fTy": -0.282062292098999, + "fQp": 1.66170346736908, + "fCovMatrix": [ + 2.7359023806639e-4, + -0.00449520535767078, + -2.11336046049837e-5, + 1.08181659015827e-4, + 2.12581900996156e-4, + 0.206206426024437, + 9.8862117738463e-5, + -0.00494109373539686, + -8.965625311248e-4, + 6.43738349026535e-6, + -2.70707801064418e-6, + -6.69419459882192e-5, + 1.58320981427096e-4, + -8.06868501967983e-6, + 0.00214459444396198 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 40.114372253418, + "fY": -17.2033081054688, + "fZ": 60.9249992370605, + "fTx": 0.89084392786026, + "fTy": -0.348761737346649, + "fQp": 1.6664445400238, + "fCovMatrix": [ + 0.00244997604750097, + -0.0090667437762022, + 1.51414395077154e-4, + -2.62064364505932e-4, + 7.42975214961916e-4, + 0.0705385282635689, + -5.31124067492783e-4, + 0.00194119138177484, + -0.002225091913715, + 1.75859604496509e-5, + -1.97827012016205e-5, + 6.81519377394579e-5, + 1.69458886375651e-4, + -5.7736957387533e-5, + 0.00198274431750178 + ] + }, + "fFlag": 0, + "fChi2": 0.132077515125275, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827936, + "fStsHits": [ + 100, + 167, + 248, + 343 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.1610107421875, + "fY": 9.85746097564697, + "fZ": 92.3769989013672, + "fTx": 0.480140268802643, + "fTy": 0.0600208789110184, + "fQp": 1.93609797954559, + "fCovMatrix": [ + 0.00200024293735623, + -0.00600277772173285, + -8.04242372396402e-5, + 1.13586029328872e-4, + 1.76585090230219e-4, + 0.0491588152945042, + 3.09234921587631e-4, + -8.73124052304775e-4, + -6.78855925798416e-4, + 1.28341525851283e-5, + -3.947150617023e-6, + -2.85571586573496e-5, + 3.27500929415692e-5, + 1.43330807986786e-5, + 5.38995489478111e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 86.7152557373047, + "fY": 17.499963760376, + "fZ": 190.85400390625, + "fTx": 1.84347748756409, + "fTy": 0.138669148087502, + "fQp": 1.97133362293243, + "fCovMatrix": [ + 0.00211035180836916, + 0.00650257663801312, + 1.25869875773787e-4, + 1.28308791317977e-4, + 1.88947567949072e-4, + 0.05129624158144, + 5.15072897542268e-4, + 9.42497921641916e-4, + 7.66049546655267e-4, + 4.11660621466581e-5, + 9.57041356741684e-6, + 5.5888343922561e-5, + 3.89481283491477e-5, + 1.91698745766189e-5, + 3.72251815861091e-4 + ] + }, + "fFlag": 0, + "fChi2": 5.01583194732666, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 0, + "fStsHits": [ + 892, + 932, + 966, + 995 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.163538798689842, + "fY": 6.58575916290283, + "fZ": 20.4885005950928, + "fTx": 0.0469133891165257, + "fTy": 0.296761155128479, + "fQp": 2.95029425621033, + "fCovMatrix": [ + 3.33037634845823e-4, + 0.00646359380334616, + -3.08881171804387e-5, + -3.15742305247113e-4, + 7.95795174781233e-4, + 0.296464592218399, + -3.12631047563627e-4, + -0.0144908409565687, + 0.0118488008156419, + 1.09513002826134e-5, + 2.37099629885051e-5, + -2.41712361457758e-4, + 0.00110194727312773, + -8.97166435606778e-4, + 0.0108545478433371 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.45915913581848, + "fY": 14.4354619979858, + "fZ": 46.7879981994629, + "fTx": 0.234864756464958, + "fTy": 0.301912605762482, + "fQp": 2.95631885528564, + "fCovMatrix": [ + 3.31636285409331e-4, + 0.00638530729338527, + 3.2258660212392e-5, + 3.13805445330217e-4, + 3.01188760204241e-4, + 0.292764902114868, + 3.11581214191392e-4, + 0.0143494522199035, + -0.0112698068842292, + 1.21231414595968e-5, + 2.43910999415675e-5, + 2.18840417801403e-4, + 0.0011020228266716, + -8.5128570208326e-4, + 0.0106315473094583 + ] + }, + "fFlag": 0, + "fChi2": 7.6029896736145, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 789827936, + "fStsHits": [ + 187, + 312, + 454, + 776 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.29122018814087, + "fY": 1.11909639835358, + "fZ": 128.34700012207, + "fTx": 0.0679009631276131, + "fTy": 0.0531249344348907, + "fQp": 1.1774697303772, + "fCovMatrix": [ + 0.00155779195483774, + 0.0037622582167387, + -7.18135343049653e-5, + -4.57157075288706e-5, + 3.0329727451317e-4, + 0.0367696546018124, + -2.54258746281266e-4, + -4.71434817882255e-4, + 0.0010841793846339, + 8.51774257171201e-6, + 8.95118319022004e-7, + -5.39621942152735e-5, + 2.08546880458016e-5, + 2.92173058369372e-6, + 0.00107021443545818 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.9697799682617, + "fY": 8.39235782623291, + "fZ": 253.266006469727, + "fTx": 0.444779872894287, + "fTy": 0.0642979964613914, + "fQp": 1.18556535243988, + "fCovMatrix": [ + 0.00186509417835623, + 0.00526912836357951, + 8.09190751169808e-5, + 6.40154685243033e-5, + 3.54248360963538e-4, + 0.0448441095650196, + 3.1117265461944e-4, + 5.57739695068449e-4, + 0.0013737817062065, + 9.65948038356146e-6, + 1.98274415197375e-6, + 5.237402729108e-5, + 2.17948781937594e-5, + 2.6742793579615e-6, + 0.00105986534617841 + ] + }, + "fFlag": 0, + "fChi2": 9.60446739196777, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + }, + { + "_typename": "CbmStsTrack", + "fUniqueID": 0, + "fBits": 0, + "ststrk": 909258038, + "fStsHits": [ + 181, + 281, + 443, + 758 + ], + "fMvdHits": [], + "fPidHypo": 211, + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.51529216766357, + "fY": 7.83456087112427, + "fZ": 128.34700012207, + "fTx": 0.274531573057175, + "fTy": 0.0677979364991188, + "fQp": 1.72251999378204, + "fCovMatrix": [ + 0.00165854278020561, + 0.00421632174402475, + -8.55470789247192e-5, + -5.39180073246825e-5, + 2.21038935706019e-4, + 0.0387094058096409, + -3.19518032483757e-4, + -5.00099617056549e-4, + 8.185034384951e-4, + 1.17226491056499e-5, + 2.25074427362415e-6, + -2.76636437774869e-5, + 2.41988582274644e-5, + -4.49401568403118e-7, + 4.98394307214767e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 74.2952423095703, + "fY": 17.0499019622803, + "fZ": 253.266006469727, + "fTx": 1.15265381336212, + "fTy": 0.0914041697978973, + "fQp": 1.72471988201141, + "fCovMatrix": [ + 0.00201824493706226, + 0.00598255405202508, + 1.08104322862346e-4, + 8.26826799311675e-5, + 2.03509247512557e-4, + 0.0480972304940224, + 4.38924587797374e-4, + 6.5469037508592e-4, + 7.57522066123784e-4, + 2.06035074370448e-5, + 4.59917828266043e-6, + 1.97731387743261e-5, + 3.33881689584814e-5, + 9.54037204792257e-8, + 4.49782353825867e-4 + ] + }, + "fFlag": 0, + "fChi2": 28.5026397705078, + "fNDF": 3, + "fB": 0, + "fnEv": 0, + "fHitsArr": { + "_typename": "TClonesArray", + "name": "CbmStsHits", + "arr": [] + } + } + ], + [ + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.113743782043457, + "fY": 0.588733792304993, + "fZ": 0.446708500385284, + "fTx": -0.100411854684353, + "fTy": 0.0182576980441809, + "fQp": 0.171851590275764, + "fCovMatrix": [ + 0.00121915130876005, + -0.00157526461407542, + -3.12615520670079e-5, + 1.03501242847415e-5, + 5.74186706217006e-5, + 0.0378880277276039, + 2.97486585623119e-5, + -2.39057058934122e-4, + -9.22055405681022e-5, + 9.93395019577292e-7, + -2.10161957170385e-7, + -1.58497925895063e-6, + 2.19491153075069e-6, + 7.0918503070061e-7, + 7.72945895732846e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -6.13197088241577, + "fY": 10.9124612808228, + "fZ": 635.900024414062, + "fTx": 0.0194431487470865, + "fTy": 0.0154860503971577, + "fQp": 0.172769650816917, + "fCovMatrix": [ + 0.135963916778564, + 0.0383486896753311, + 3.6564379115589e-4, + 7.20570096746087e-5, + 7.27493315935135e-4, + 0.275383651256561, + 9.25719941733405e-5, + 5.98086451645941e-4, + 2.11843798751943e-4, + 3.41494865097047e-6, + 1.7498560112017e-7, + 1.8765556433209e-6, + 3.78396589439944e-6, + 4.02894784201635e-7, + 7.05648108123569e-6 + ] + }, + "fFlag": -1, + "fChi2": 16.41866, + "fNDF": 13, + "fB": 0, + "fLength": 636.0023, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 0, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 12, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": 117, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": 1.2522908449173, + "fBeta400": -1000, + "fBeta700": 0.999027828449863, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.182159796357155, + "fPidTof400": [], + "fPidTof700": [ + 0.0278569855210373, + 0.479282876594885, + 0.125851408977037, + 0.337534256597142, + 0.00694136249661365, + 0.00333161721207416, + 0.012175674573752, + 0.00702581802745868 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0836195200681686, + "fY": 0.718462407588959, + "fZ": 0.446708500385284, + "fTx": 0.200664833188057, + "fTy": 0.0644500628113747, + "fQp": 0.205368593335152, + "fCovMatrix": [ + 0.00121043354738504, + 7.51231040339917e-4, + -3.17153790092561e-5, + -3.09064625980682e-6, + 5.77419123146683e-5, + 0.0402111560106277, + 8.61757598613622e-8, + -2.53807316767052e-4, + -2.52896461461205e-5, + 1.11059159735305e-6, + -3.05645642129093e-8, + -1.67501616488153e-6, + 2.38139682551264e-6, + 3.06331457977649e-7, + 8.24737344373716e-6 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 126.024215698242, + "fY": 28.6712455749512, + "fZ": 422.371002197266, + "fTx": 0.353906005620956, + "fTy": 0.068443663418293, + "fQp": 0.209955647587776, + "fCovMatrix": [ + 0.0325352735817432, + 0.00746848527342081, + 1.85367811354809e-4, + 2.30380119319307e-5, + 3.13971162540838e-4, + 0.063996858894825, + 3.6662670026999e-5, + 2.48965283390135e-4, + 5.83649198233616e-5, + 2.24442760554666e-6, + 1.39650239816547e-7, + 1.83472332082601e-6, + 2.17277943193039e-6, + 1.80570296492988e-7, + 7.70802853367059e-6 + ] + }, + "fFlag": -1, + "fChi2": 63.5185, + "fNDF": 13, + "fB": 0, + "fLength": 441.7529, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 1, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": 3, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": 1.02663626607586, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.297340214252472, + "fPidTof400": [ + 0.130598533122617, + 0.21583797800367, + 0.183943564412314, + 0.21916459893691, + 0.0624329814818454, + 0.0363794016608691, + 0.0886948999462895, + 0.0629480424354852 + ], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.30139833688736, + "fY": 0.1864023655653, + "fZ": 0.446708500385284, + "fTx": 0.134838849306107, + "fTy": -0.11217276006937, + "fQp": 0.562926828861237, + "fCovMatrix": [ + 0.00584008684381843, + -0.00123285257723182, + -1.75772758666426e-4, + 9.88045667327242e-6, + 1.67197795235552e-4, + 0.0616421885788441, + 3.57064072886715e-6, + -5.71430660784245e-4, + -1.45398344102432e-5, + 6.46936314296909e-6, + -8.85034836528575e-8, + -5.29768340129522e-6, + 9.37898039410356e-6, + 2.59945551306373e-7, + 3.53833565895911e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 78.3410491943359, + "fY": -30.1586742401123, + "fZ": 248.565994262695, + "fTx": 0.519947171211243, + "fTy": -0.138447120785713, + "fQp": 0.568591356277466, + "fCovMatrix": [ + 0.00111755426041782, + -0.00150139129254967, + 3.1857311114436e-5, + -1.81215455086203e-5, + 5.22565605933778e-5, + 0.0204639304429293, + -6.45808249828406e-5, + 2.0539241086226e-4, + -8.36852050269954e-5, + 2.64465393229329e-6, + -8.06947014098114e-7, + 2.75229331236915e-6, + 4.93603874929249e-6, + -1.25252370253293e-6, + 3.4731492633e-5 + ] + }, + "fFlag": -1, + "fChi2": 48.13725, + "fNDF": 11, + "fB": 0, + "fLength": 264.1259, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 2, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.359468817710876, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0466443933546543, + "fY": -0.145162776112556, + "fZ": 0.446708500385284, + "fTx": -0.241355091333389, + "fTy": 0.0830243080854416, + "fQp": 1.87991809844971, + "fCovMatrix": [ + 0.0138168260455132, + -0.00339613761752844, + -0.00118863512761891, + 6.9206187617965e-5, + 3.14348202664405e-4, + 0.142328485846519, + 8.17291656858288e-5, + -0.00290396297350526, + 8.38347696117125e-5, + 1.19657546747476e-4, + -3.72808381143841e-6, + -2.29592878895346e-5, + 1.44215999171138e-4, + 1.12929251372407e-6, + 3.83465056074783e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 67.4413909912109, + "fY": 18.4549140930176, + "fZ": 217.451995849609, + "fTx": 1.14467430114746, + "fTy": 0.122764363884926, + "fQp": 1.95217978954315, + "fCovMatrix": [ + 0.00171380024403334, + -0.00418118108063936, + 1.0429337999085e-4, + -7.7113312727306e-5, + 1.41469237860292e-4, + 0.0365858227014542, + -3.63614817615598e-4, + 6.59077544696629e-4, + -4.98083070851862e-4, + 2.47048610617639e-5, + -2.76183914138528e-6, + 2.36326213780558e-5, + 3.55777374352328e-5, + -4.08496134696179e-6, + 3.6235831794329e-4 + ] + }, + "fFlag": -1, + "fChi2": 26.7675, + "fNDF": 15, + "fB": 0, + "fLength": 243.3695, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 3, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.57079815864563, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0722319558262825, + "fY": 0.354784071445465, + "fZ": 0.446708500385284, + "fTx": -0.155001595616341, + "fTy": 0.0933444499969482, + "fQp": 0.863337874412537, + "fCovMatrix": [ + 0.00248112971894443, + -0.0022091583814472, + -1.71584979398176e-4, + 2.0161514839856e-5, + 9.59185126703233e-5, + 0.0701298043131828, + 4.46569429186638e-5, + -7.85009935498238e-4, + -9.24255000427365e-5, + 1.4471720533038e-5, + -5.93432559981011e-7, + -5.66963035453227e-6, + 2.19426583498716e-5, + 8.22816389245418e-7, + 7.96381355030462e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.3584899902344, + "fY": 23.1596603393555, + "fZ": 253.266006469727, + "fTx": 0.386137813329697, + "fTy": 0.0894111171364784, + "fQp": 0.872905194759369, + "fCovMatrix": [ + 0.00141222530510277, + 0.00261890306137502, + 4.1884839447448e-5, + 3.52654060407076e-5, + 6.37184057268314e-5, + 0.026132557541132, + 1.03059472166933e-4, + 3.20465071126819e-4, + 1.36897549964488e-4, + 3.59388832293916e-6, + 1.2825257726945e-6, + 4.27736631536391e-6, + 8.88297381607117e-6, + 1.62169681061641e-6, + 7.93475410318933e-5 + ] + }, + "fFlag": -1, + "fChi2": 36.37777, + "fNDF": 15, + "fB": 0, + "fLength": 258.6746, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 4, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.0808681026101112, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0223507452756166, + "fY": 0.117746315896511, + "fZ": 0.446708500385284, + "fTx": -0.158949002623558, + "fTy": -0.108076266944408, + "fQp": 0.321490377187729, + "fCovMatrix": [ + 0.00110964721534401, + 0.0016296305693686, + -4.07910520152654e-5, + -1.11586468847236e-5, + 3.87022519134916e-5, + 0.0413209311664104, + -3.79046941816341e-5, + -3.13119031488895e-4, + 7.54496431909502e-5, + 1.99892588170769e-6, + 2.76388362863145e-7, + -1.59209389494208e-6, + 4.23597293774947e-6, + -5.77993034767132e-7, + 1.44496598295518e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 9.21086978912354, + "fY": -66.7490005493164, + "fZ": 627.099975585938, + "fTx": 0.0693006217479706, + "fTy": -0.106068350374699, + "fQp": 0.325574189424515, + "fCovMatrix": [ + 0.214608564972878, + -0.0352199971675873, + 5.92130701988935e-4, + -6.48957429802977e-5, + 9.30178386624902e-4, + 0.33765435218811, + -8.78709979588166e-5, + 7.95151281636208e-4, + -1.35593116283417e-4, + 4.50117113359738e-6, + -1.83297686362494e-7, + 2.47051798396569e-6, + 4.84003430756275e-6, + -2.35852496643929e-7, + 1.33578841996496e-5 + ] + }, + "fFlag": -1, + "fChi2": 23.4274, + "fNDF": 13, + "fB": 0, + "fLength": 631.7896, + "fNhits": 10, + "fUsing": false, + "fGemTrack": 5, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 26, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.955971454867903, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.307907283306122, + "fPidTof400": [], + "fPidTof700": [ + 0.849397820405311, + 0.0280379574723017, + 0.0380931545550009, + 0.0273978671350635, + 0.0121024510356469, + 0.00564051559051651, + 0.0270490304126194, + 0.01228120339354 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.106933452188969, + "fY": -0.370311707258224, + "fZ": 0.446708500385284, + "fTx": -0.235435292124748, + "fTy": 0.0907222703099251, + "fQp": 2.46053838729858, + "fCovMatrix": [ + 0.014126705005765, + -0.00404291227459908, + -7.56452966015786e-4, + 7.92645660112612e-5, + 7.98755150754005e-4, + 0.182829931378365, + 7.63797652325593e-5, + -0.00320534314960241, + 6.16679200902581e-4, + 4.36723821621854e-5, + -2.70802843260753e-6, + -6.14533710177056e-5, + 8.48018826218322e-5, + -3.15751526613894e-6, + 0.00108029355760664 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 35.9676246643066, + "fY": 14.2686767578125, + "fZ": 154.856994628906, + "fTx": 0.896000862121582, + "fTy": 0.118299603462219, + "fQp": 2.51388120651245, + "fCovMatrix": [ + 0.001817143172957, + -0.00485007045790553, + 1.14804308395833e-4, + -9.64944920269772e-5, + 2.9752537375316e-4, + 0.0413326025009155, + -4.27107122959569e-4, + 7.91111495345831e-4, + -0.00113374111242592, + 2.6783502107719e-5, + -3.85322800866561e-6, + 5.09271048940718e-5, + 4.6236724301707e-5, + -1.47345344885252e-5, + 0.00102324690669775 + ] + }, + "fFlag": -1, + "fChi2": 40.41425, + "fNDF": 11, + "fB": 0, + "fLength": 167.6239, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 6, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.807983875274658, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.316711187362671, + "fY": 0.238925993442535, + "fZ": 0.446708500385284, + "fTx": -0.343945235013962, + "fTy": -0.0580112785100937, + "fQp": 0.409561008214951, + "fCovMatrix": [ + 0.00555423181504011, + 0.00246460200287402, + -1.38709059683606e-4, + -2.05631240532966e-5, + 1.15155235107522e-4, + 0.0547902584075928, + -5.04528798046522e-5, + -4.56332985777408e-4, + 4.36690097558312e-5, + 4.2953188312822e-6, + 4.69048217155432e-7, + -3.72575595974922e-6, + 6.47122760710772e-6, + -7.24516155514721e-7, + 2.43893591687083e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -53.5613479614258, + "fY": -13.3742799758911, + "fZ": 248.565994262695, + "fTx": -0.0919805094599724, + "fTy": -0.051100492477417, + "fQp": 0.409756720066071, + "fCovMatrix": [ + 0.00102374202106148, + -0.00121821509674191, + 2.25714866246562e-5, + -9.65455365076195e-6, + 5.50462027604226e-5, + 0.0189228896051645, + -3.68259061360732e-5, + 1.56089285155758e-4, + -8.76016565598547e-5, + 1.22756193832174e-6, + -2.51058338562871e-7, + 2.36619644056191e-6, + 2.87100806417584e-6, + -4.09444822935257e-7, + 2.46403506025672e-5 + ] + }, + "fFlag": -1, + "fChi2": 22.50924, + "fNDF": 9, + "fB": 0, + "fLength": 254.4599, + "fNhits": 7, + "fUsing": false, + "fGemTrack": 7, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.339586406946182, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.195573806762695, + "fY": -1.81441295146942, + "fZ": 0.446708500385284, + "fTx": -0.0233523342758417, + "fTy": -0.0799169391393661, + "fQp": 0.211819499731064, + "fCovMatrix": [ + 0.00239080400206149, + 1.70066123246215e-4, + -5.87307076784782e-5, + -9.92962213786086e-7, + 7.24626806913875e-5, + 0.0632314011454582, + -4.44729812443256e-5, + -3.873614477925e-4, + 1.19298085337505e-4, + 2.17506953958946e-6, + 2.37903734046085e-7, + -2.04682828552905e-6, + 3.95881806980469e-6, + -6.84297958741809e-7, + 1.02914364106255e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 57.9138565063477, + "fY": -54.6964263916016, + "fZ": 635.900024414062, + "fTx": 0.127945572137833, + "fTy": -0.0842056721448898, + "fQp": 0.215001165866852, + "fCovMatrix": [ + 0.178465560078621, + -0.0452135726809502, + 4.70553990453482e-4, + -9.18271689442918e-5, + 9.15236596483737e-4, + 0.334037303924561, + -1.1111512867501e-4, + 7.4203364783898e-4, + -1.988829462789e-4, + 2.43283329837141e-6, + -2.38534653362876e-7, + 2.3646659883525e-6, + 2.8837989702879e-6, + -4.04263175823871e-7, + 9.14934480533702e-6 + ] + }, + "fFlag": -1, + "fChi2": 39.02974, + "fNDF": 9, + "fB": 0, + "fLength": 640.8456, + "fNhits": 8, + "fUsing": false, + "fGemTrack": 8, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 25, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.980564064138401, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.24577975273132, + "fPidTof400": [], + "fPidTof700": [ + 0.936496883123008, + 0.0124580799429877, + 0.0168911515414285, + 0.0121781551086254, + 0.00461783656238372, + 0.00195265796344994, + 0.0107138115963022, + 0.00469142416181431 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -2.5022611618042, + "fY": -0.48456397652626, + "fZ": 0.446708500385284, + "fTx": 0.09127426892519, + "fTy": -0.0951503813266754, + "fQp": -0.993796586990356, + "fCovMatrix": [ + 0.0420446656644344, + -0.0174753814935684, + -0.00113928818609565, + 1.40313539304771e-4, + 0.0010245005832985, + 0.118863306939602, + 2.32575504924171e-4, + -0.00162115576677024, + -3.16957710310817e-4, + 6.6767395765055e-5, + -2.39103087551484e-6, + -2.33741357078543e-5, + 6.86382845742628e-5, + 2.84903512692836e-6, + 1.34686910314485e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -58.270393371582, + "fY": -24.5115928649902, + "fZ": 248.565994262695, + "fTx": -0.582086145877838, + "fTy": -0.102219641208649, + "fQp": -1.00568675994873, + "fCovMatrix": [ + 0.00128551793750376, + -0.00207453384064138, + 4.9034886615118e-5, + -2.93046323349699e-5, + 8.9734407083597e-5, + 0.0242247544229031, + -1.19483127491549e-4, + 3.08274960843846e-4, + -2.00828450033441e-4, + 5.85356519877678e-6, + -1.18506238777627e-6, + 6.76520085107768e-6, + 1.06499564935802e-5, + -3.04863306155312e-6, + 1.18108830065466e-4 + ] + }, + "fFlag": -1, + "fChi2": 32.46508, + "fNDF": 9, + "fB": 0, + "fLength": 260.707, + "fNhits": 7, + "fUsing": false, + "fGemTrack": 9, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.63166427612305, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0710224881768227, + "fY": 0.05183345079422, + "fZ": 0.446708500385284, + "fTx": 0.360555469989777, + "fTy": -0.100696377456188, + "fQp": 0.868661105632782, + "fCovMatrix": [ + 0.00175835390109569, + -0.00117000739555806, + -1.18933327030391e-4, + 1.62687065312639e-5, + 2.11807171581313e-4, + 0.138006910681725, + -6.73187387292273e-5, + -0.00164641381707042, + 6.95851165801287e-4, + 1.04335795185762e-5, + 4.73094388553363e-7, + -1.58148668560898e-5, + 2.91128362732707e-5, + -9.29293946683174e-6, + 2.2163889661897e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 64.4297180175781, + "fY": -13.9177446365356, + "fZ": 123.677001953125, + "fTx": 0.72672039270401, + "fTy": -0.134330794215202, + "fQp": 0.878399670124054, + "fCovMatrix": [ + 0.00160757114645094, + -0.00398816168308258, + 7.29574530851096e-5, + -8.36182516650297e-5, + 2.40785084315576e-4, + 0.0378738828003407, + -2.46375158894807e-4, + 6.83184887748212e-4, + -7.99094792455435e-4, + 7.44503131500096e-6, + -5.03312639921205e-6, + 2.31208141485695e-5, + 2.11625283554895e-5, + -1.67757134477142e-5, + 2.12662940612063e-4 + ] + }, + "fFlag": -1, + "fChi2": 4.796133, + "fNDF": 7, + "fB": 0, + "fLength": 141.1552, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 10, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.375572264194489, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -1.34116351604462, + "fY": -1.36811017990112, + "fZ": 0.446708500385284, + "fTx": 0.0989279821515083, + "fTy": 0.0329475291073322, + "fQp": 0.173811748623848, + "fCovMatrix": [ + 0.046872902661562, + -0.0271047055721283, + -6.04064960498363e-4, + 1.53399203554727e-4, + 9.83070000074804e-4, + 0.107374183833599, + 3.17508354783058e-4, + -7.07785424310714e-4, + -7.41539755836129e-4, + 8.14452778286068e-6, + -1.82926487468649e-6, + -1.25158912851475e-5, + 6.05001014264417e-6, + 4.36901927969302e-6, + 3.17835838359315e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 36.9998054504395, + "fY": 6.80868768692017, + "fZ": 253.266006469727, + "fTx": 0.204165861010551, + "fTy": 0.0321086347103119, + "fQp": 0.174466639757156, + "fCovMatrix": [ + 0.00132604071404785, + 0.00240976945497096, + 3.02924581774278e-5, + 2.5230410756194e-5, + 1.25503007438965e-4, + 0.025324797257781, + 6.86817729729228e-5, + 2.36949999816716e-4, + 3.32722527673468e-4, + 1.11861686491466e-6, + 7.92246112268913e-7, + 5.05562411490246e-6, + 3.14955241265125e-6, + 4.21537333750166e-6, + 3.16932710120454e-5 + ] + }, + "fFlag": -1, + "fChi2": 8.981709, + "fNDF": 7, + "fB": 0, + "fLength": 256.0445, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 11, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.21998953819275, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.472078382968903, + "fY": -0.11114527285099, + "fZ": 0.446708500385284, + "fTx": -0.047980472445488, + "fTy": -0.0546752586960793, + "fQp": 0.264409244060516, + "fCovMatrix": [ + 0.0632011517882347, + 0.0241218619048595, + -8.60568252392113e-4, + -1.34613204863854e-4, + 0.00126098853070289, + 0.11348532885313, + -2.8231434407644e-4, + -8.57013161294162e-4, + 6.5651984186843e-4, + 1.27156299640774e-5, + 1.60285753736389e-6, + -1.63434997375589e-5, + 9.33580122364219e-6, + -3.73514421880827e-6, + 4.36296577390749e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.82009363174438, + "fY": -13.8860502243042, + "fZ": 248.565994262695, + "fTx": 0.107870183885098, + "fTy": -0.0562192648649216, + "fQp": 0.266337841749191, + "fCovMatrix": [ + 0.00115839694626629, + -0.00171898689586669, + 2.91786582238274e-5, + -1.94178428500891e-5, + 1.24229423818178e-4, + 0.0224172528833151, + -5.91218558838591e-5, + 2.1739570365753e-4, + -2.88082315819338e-4, + 1.38089103529637e-6, + -7.26864755051793e-7, + 5.93746290178387e-6, + 3.33536263497081e-6, + -3.93559366784757e-6, + 4.36123991676141e-5 + ] + }, + "fFlag": -1, + "fChi2": 13.15495, + "fNDF": 7, + "fB": 0, + "fLength": 248.9029, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 12, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.73689329624176, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0597548820078373, + "fY": 0.644053101539612, + "fZ": 0.446708500385284, + "fTx": -0.107609897851944, + "fTy": -0.200291991233826, + "fQp": -0.562099874019623, + "fCovMatrix": [ + 0.00382377323694527, + 0.00269884592853487, + -1.30351749248803e-4, + -1.71071842487436e-5, + 3.48907429724932e-4, + 0.0906038582324982, + -4.06905928684864e-5, + -8.86596040800214e-4, + -3.42734019795898e-5, + 5.48633215657901e-6, + 1.50057630321498e-7, + -1.26574777823407e-5, + 1.21654602480703e-5, + 1.77455467564869e-6, + 9.3246424512472e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -34.5075836181641, + "fY": -31.8353710174561, + "fZ": 159.557006835938, + "fTx": -0.346722215414047, + "fTy": -0.21097306907177, + "fQp": -0.572068274021149, + "fCovMatrix": [ + 0.00153660564683378, + 0.00338289677165449, + 4.58140784758143e-5, + 4.59371112810913e-5, + 1.61742660566233e-4, + 0.0334698744118214, + 1.14889880933333e-4, + 4.34220593888313e-4, + 3.44392232364044e-4, + 2.73831551567127e-6, + 1.49882725963835e-6, + 1.05627932498464e-5, + 8.82463154994184e-6, + 3.68091014024685e-6, + 9.21655009733513e-5 + ] + }, + "fFlag": -1, + "fChi2": 50.0075, + "fNDF": 7, + "fB": 0, + "fLength": 166.6362, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 13, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.237428858876228, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0644420459866524, + "fY": 0.28891995549202, + "fZ": 0.446708500385284, + "fTx": -0.109520241618156, + "fTy": -0.264354079961777, + "fQp": 2.00249004364014, + "fCovMatrix": [ + 0.0148330349475145, + -0.00361188943497837, + -0.00138078932650387, + -7.04352669345099e-6, + 5.40123030077666e-4, + 0.204159691929817, + -8.48091167426901e-6, + -0.00359647208824754, + -6.31751259788871e-4, + 1.36617629323155e-4, + 5.07185995957116e-6, + -4.58278191217687e-5, + 1.77940702997148e-4, + 3.13839137788818e-7, + 9.79271368123591e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.8955745697021, + "fY": -33.7819709777832, + "fZ": 123.677001953125, + "fTx": 0.604310631752014, + "fTy": -0.315734297037125, + "fQp": 2.09776401519775, + "fCovMatrix": [ + 0.00176150107290596, + -0.00480693858116865, + 1.03912498161662e-4, + -1.12679801532067e-4, + 2.87616538116708e-4, + 0.042500589042902, + -4.01500758016482e-4, + 8.34156293421984e-4, + -9.35784832108766e-4, + 1.83507636393188e-5, + -7.35896674086689e-6, + 5.00350506627001e-5, + 4.53848879260477e-5, + -1.4240275049815e-5, + 9.32074501179159e-4 + ] + }, + "fFlag": -1, + "fChi2": 66.72202, + "fNDF": 7, + "fB": 0, + "fLength": 133.3012, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 14, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.167724788188934, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.54710507392883, + "fY": -0.58077609539032, + "fZ": 0.446708500385284, + "fTx": 0.0338729247450829, + "fTy": -0.0313976965844631, + "fQp": 0.202479869127274, + "fCovMatrix": [ + 0.160711407661438, + -0.0383793190121651, + -0.00174940226133913, + 1.56199675984681e-4, + 0.0031978590413928, + 0.206317380070686, + 3.42362414812669e-4, + -0.00121129816398025, + -6.0384685639292e-4, + 2.00798640435096e-5, + -1.31709532524837e-6, + -3.56181517418008e-5, + 9.03579257283127e-6, + 2.11933797800157e-6, + 8.1467951531522e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 24.739673614502, + "fY": -8.64188003540039, + "fZ": 248.565994262695, + "fTx": 0.153393998742104, + "fTy": -0.0334637500345707, + "fQp": 0.203488066792488, + "fCovMatrix": [ + 0.00120611628517509, + -0.00176589959301054, + 3.30342554661911e-5, + -1.81667473952984e-5, + 1.64499200764112e-4, + 0.0246628411114216, + -4.92055478389375e-5, + 2.77021696092561e-4, + -1.80929011548869e-4, + 1.72334603121271e-6, + -2.53595430876885e-7, + 1.0244283657812e-5, + 4.93520428790362e-6, + 1.19064839054772e-6, + 8.14808299764991e-5 + ] + }, + "fFlag": -1, + "fChi2": 2.793974, + "fNDF": 5, + "fB": 0, + "fLength": 249.5455, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 15, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.87326192855835, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0134795252233744, + "fY": 0.487246483564377, + "fZ": 0.446708500385284, + "fTx": -0.0687238201498985, + "fTy": -0.264258414506912, + "fQp": 0.469837635755539, + "fCovMatrix": [ + 0.00256364024244249, + 0.00289767188951373, + -1.15898430522066e-4, + -4.13587767980061e-5, + 5.24579489137977e-4, + 0.172234535217285, + -2.6559637626633e-4, + -0.0018809080356732, + 0.00192667171359062, + 6.12427538726479e-6, + 3.29693284584209e-6, + -2.57115116255591e-5, + 2.43352551478893e-5, + -2.42432324739639e-5, + 2.14631159906276e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.12681382894516, + "fY": -32.1258316040039, + "fZ": 123.677001953125, + "fTx": 0.0742319375276566, + "fTy": -0.26606622338295, + "fQp": 0.47090420126915, + "fCovMatrix": [ + 0.00158424722030759, + -0.00395862851291895, + 6.28770649200305e-5, + -8.84528126334772e-5, + 3.37789009790868e-4, + 0.0385282747447491, + -2.04121737624519e-4, + 7.34325964003801e-4, + -0.00110242667142302, + 4.39162113252678e-6, + -4.81559709442081e-6, + 2.59254975389922e-5, + 2.14575829886599e-5, + -2.56246821663808e-5, + 2.14337997022085e-4 + ] + }, + "fFlag": -1, + "fChi2": 3.557666, + "fNDF": 5, + "fB": 0, + "fLength": 127.5816, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 16, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.077278658747673, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -12.1896190643311, + "fY": 2.49409508705139, + "fZ": 0.446708500385284, + "fTx": -0.00102446682285517, + "fTy": 0.0395563989877701, + "fQp": 0.380936354398727, + "fCovMatrix": [ + 0.0611070431768894, + -0.0354166217148304, + -0.00119458755943924, + 2.26294883759692e-4, + 0.00155877380166203, + 0.120648585259914, + 4.24436875618994e-4, + -0.00121659121941775, + -0.0010009107645601, + 1.22825935250148e-4, + -2.79522691926104e-6, + -2.12772811210016e-5, + 1.19090829684865e-4, + 6.7240457610751e-6, + 6.08225964242592e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 16.5165977478027, + "fY": 12.2913675308228, + "fZ": 253.266006469727, + "fTx": 0.229917138814926, + "fTy": 0.0385008491575718, + "fQp": 0.383702665567398, + "fCovMatrix": [ + 0.00140638451557606, + 0.0031376676633954, + 3.78932563762646e-5, + 3.06943329633214e-5, + 1.49175975820981e-4, + 0.0336156375706196, + 1.34585134219378e-4, + 2.975782554131e-4, + 6.11140800174326e-4, + 2.04978573492554e-6, + 1.21983202916454e-6, + 7.85819793236442e-6, + 4.30095087722293e-6, + 5.96624204263208e-6, + 6.05825152888428e-5 + ] + }, + "fFlag": -1, + "fChi2": 4.295112, + "fNDF": 5, + "fB": 0, + "fLength": 255.3587, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 17, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 12.3314142227173, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0444554686546326, + "fY": 0.348040878772736, + "fZ": 0.446708500385284, + "fTx": -0.0752754285931587, + "fTy": -0.266079545021057, + "fQp": 0.319220513105392, + "fCovMatrix": [ + 0.00225992104969919, + 0.00305393501184881, + -9.69212924246676e-5, + -4.40127951151226e-5, + 5.14772429596633e-4, + 0.170411959290504, + -2.71132768830284e-4, + -0.00182572042103857, + 0.0019931229762733, + 4.74177841169876e-6, + 3.36953053192701e-6, + -2.44284583459375e-5, + 2.2066391466069e-5, + -2.48597789322957e-5, + 1.80513045052066e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -3.65879273414612, + "fY": -32.4332733154297, + "fZ": 123.677001953125, + "fTx": 0.021767932921648, + "fTy": -0.266411513090134, + "fQp": 0.319602519273758, + "fCovMatrix": [ + 0.00156673660967499, + -0.00387575500644743, + 6.05840032221749e-5, + -8.63880923134275e-5, + 3.30092705553398e-4, + 0.0381363146007061, + -1.93470521480776e-4, + 7.24260287825018e-4, + -0.0010770196095109, + 3.9610790736333e-6, + -4.63677679363173e-6, + 2.43303911702242e-5, + 2.08122073672712e-5, + -2.54360911640106e-5, + 1.80816088686697e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.044239, + "fNDF": 5, + "fB": 0, + "fLength": 127.6035, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 18, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.0782802104949951, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.10143184661865, + "fY": 0.943868219852448, + "fZ": 0.446708500385284, + "fTx": -0.0236356854438782, + "fTy": 0.0478610992431641, + "fQp": 0.106951728463173, + "fCovMatrix": [ + 0.14646415412426, + 0.0157565474510193, + -0.0015795404324308, + -1.41862719829078e-5, + 0.00332151097245514, + 0.175634920597076, + -1.01814752270002e-4, + -9.37131466343999e-4, + 8.13772203400731e-5, + 1.74941469595069e-5, + -2.12643570307591e-7, + -3.62929167749826e-5, + 5.82600614507101e-6, + 1.26183351767395e-6, + 8.15489547676407e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 17.9083042144775, + "fY": 28.0036888122559, + "fZ": 597.099975585938, + "fTx": 0.0445287711918354, + "fTy": 0.0445158071815968, + "fQp": 0.0825817957520485, + "fCovMatrix": [ + 0.364190697669983, + 0.0381823219358921, + 0.0010879811597988, + 5.49031028640456e-5, + 0.00419190991669893, + 0.441666811704636, + 9.56025323830545e-5, + 0.00107291282620281, + 3.79249722755048e-5, + 3.26988333654299e-6, + 1.19356840855289e-7, + 1.27025923575275e-5, + 2.66925280811847e-6, + -3.73543485920891e-7, + 5.37693849764764e-5 + ] + }, + "fFlag": -1, + "fChi2": 28.96204, + "fNDF": 5, + "fB": 0, + "fLength": 597.7899, + "fNhits": 6, + "fUsing": false, + "fGemTrack": 19, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 9, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.804089836905722, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.2472208738327, + "fPidTof400": [], + "fPidTof700": [ + 0.119469895061994, + 0.11648865799471, + 0.11725495135731, + 0.11642242444021, + 0.129323001966123, + 0.148480637199097, + 0.123413530982756, + 0.1291469009978 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.928329765796661, + "fY": -0.00530472630634904, + "fZ": 0.446708500385284, + "fTx": -0.0476474948227406, + "fTy": -0.108358539640903, + "fQp": 0.300448805093765, + "fCovMatrix": [ + 0.0205874796956778, + -0.0218283198773861, + -3.42761719366536e-4, + 1.31376218632795e-4, + 8.29507829621434e-4, + 0.0849663093686104, + 3.40031983796507e-4, + -5.73873636312783e-4, + -9.89176100119948e-4, + 6.53728420729749e-6, + -2.04609477805207e-6, + -1.43179122460424e-5, + 5.54201233171625e-6, + 6.14383043284761e-6, + 4.8235207941616e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 7.91399574279785, + "fY": -24.2552947998047, + "fZ": 222.151992797852, + "fTx": 0.11579817533493, + "fTy": -0.110671669244766, + "fQp": 0.300759524106979, + "fCovMatrix": [ + 0.00144522078335285, + 0.00259754969738424, + 3.88384942198172e-5, + 3.15018660330679e-5, + 1.55900037498213e-4, + 0.0258977226912975, + 8.17190230009146e-5, + 2.48358410317451e-4, + 3.75826784875244e-4, + 1.75587786088727e-6, + 1.22047936201852e-6, + 7.71112809161423e-6, + 3.81520703740534e-6, + 6.17916612100089e-6, + 4.81271272292361e-5 + ] + }, + "fFlag": -1, + "fChi2": 9.90101, + "fNDF": 5, + "fB": 0, + "fLength": 223.4231, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 20, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.05338907241821, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.13331127166748, + "fY": -1.12110900878906, + "fZ": 0.446708500385284, + "fTx": -0.0173953901976347, + "fTy": 0.0628743693232536, + "fQp": 0.320655584335327, + "fCovMatrix": [ + 0.0583643950521946, + -0.0429685451090336, + -0.00102648814208806, + 2.20086571061984e-4, + 0.00155384629033506, + 0.128345862030983, + 5.27929747477174e-4, + -0.00103958090767264, + -0.00124197418335825, + 8.71188894961961e-5, + -2.80641279459815e-6, + -2.08510009542806e-5, + 8.30017452244647e-5, + 6.46857915853616e-6, + 5.66176458960399e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 10.7545213699341, + "fY": 14.619312286377, + "fZ": 253.266006469727, + "fTx": 0.175300538539886, + "fTy": 0.0621379911899567, + "fQp": 0.323985666036606, + "fCovMatrix": [ + 0.00143892969936132, + 0.0025955606251955, + 3.82889738830272e-5, + 3.2501597161172e-5, + 1.61684947670437e-4, + 0.0259502083063126, + 8.20754066808149e-5, + 2.53723876085132e-4, + 3.79059580154717e-4, + 1.79275116352073e-6, + 1.24236237297737e-6, + 7.63735897635343e-6, + 4.16995817431598e-6, + 6.60814203001792e-6, + 5.67811584915034e-5 + ] + }, + "fFlag": -1, + "fChi2": 13.0799, + "fNDF": 5, + "fB": 0, + "fLength": 254.58, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 21, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 9.23084259033203, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.843642950057983, + "fY": -0.48146265745163, + "fZ": 0.446708500385284, + "fTx": 0.0686445757746696, + "fTy": -0.106640420854092, + "fQp": 0.209226995706558, + "fCovMatrix": [ + 0.13631746172905, + -0.0395477153360844, + -0.0014649648219347, + 1.68585451319814e-4, + 0.00297867809422314, + 0.187767058610916, + 3.53419251041487e-4, + -9.96352639049292e-4, + -6.25751563347876e-4, + 1.65008386829868e-5, + -1.45064245771209e-6, + -3.29569265886676e-5, + 6.30119484412717e-6, + 2.42129408434266e-6, + 7.3498253186699e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.516040802002, + "fY": -27.4323062896729, + "fZ": 248.565994262695, + "fTx": 0.196304440498352, + "fTy": -0.110583245754242, + "fQp": 0.210500478744507, + "fCovMatrix": [ + 0.00120895623695105, + -0.00177905173040926, + 3.32296367560048e-5, + -1.8623793948791e-5, + 1.56467198394239e-4, + 0.0247090216726065, + -5.03061746712774e-5, + 2.78040184639394e-4, + -1.6888887330424e-4, + 1.74129593233374e-6, + -2.8823438924519e-7, + 9.76290812104708e-6, + 4.95667654831777e-6, + 1.07869789189863e-6, + 7.42414413252845e-5 + ] + }, + "fFlag": -1, + "fChi2": 14.86593, + "fNDF": 5, + "fB": 0, + "fLength": 251.9622, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 22, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.26132702827454, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -19.2282829284668, + "fY": 4.06761169433594, + "fZ": 0.446708500385284, + "fTx": 0.0927537381649017, + "fTy": 0.0284985508769751, + "fQp": 0.193146929144859, + "fCovMatrix": [ + 0.0606342479586601, + -0.0221270453184843, + -8.87219503056258e-4, + 9.80075928964652e-5, + 0.00195298518519849, + 0.12959098815918, + 2.26609423407353e-4, + -8.89979652129114e-4, + -4.36870177509263e-4, + 3.75641611753963e-5, + -8.27293149541219e-7, + -2.66763308900408e-5, + 3.2165706215892e-5, + 1.34837273435551e-6, + 7.3485862230882e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 11.7369527816772, + "fY": 10.1584901809692, + "fZ": 217.451995849609, + "fTx": 0.195405215024948, + "fTy": 0.0278738830238581, + "fQp": 0.193810537457466, + "fCovMatrix": [ + 0.00122305878903717, + -0.00181355641689152, + 3.46680826623924e-5, + -1.83849115273915e-5, + 1.60300332936458e-4, + 0.0247811619192362, + -5.19911627634428e-5, + 2.76879087323323e-4, + -1.93408704944886e-4, + 1.84531995728321e-6, + -2.47711994916244e-7, + 1.04186356111313e-5, + 4.85624241264304e-6, + 9.14421434572432e-7, + 7.33600318199024e-5 + ] + }, + "fFlag": -1, + "fChi2": 15.94391, + "fNDF": 5, + "fB": 0, + "fLength": 219.4563, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 23, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 19.5378093719482, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.535743653774261, + "fY": 1.13074922561646, + "fZ": 0.446708500385284, + "fTx": 0.0088078249245882, + "fTy": 0.124283142387867, + "fQp": -1.08276271820068, + "fCovMatrix": [ + 0.0205681435763836, + -0.00946416705846786, + -6.27778354100883e-4, + 4.78475521958899e-5, + 9.43946302868426e-4, + 0.16974076628685, + 2.93887889711186e-4, + -0.00174504995811731, + -0.00100176921114326, + 2.82505607174244e-5, + -1.57591944116575e-6, + -3.04493350995472e-5, + 3.598545663408e-5, + 7.35173580324044e-6, + 2.16082407860085e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -45.8982467651367, + "fY": 26.5154438018799, + "fZ": 190.85400390625, + "fTx": -0.550392150878906, + "fTy": 0.153908878564835, + "fQp": -1.0933438539505, + "fCovMatrix": [ + 0.0016527270199731, + 0.00375722139142454, + 5.61533379368484e-5, + 5.73905490455218e-5, + 1.73844207893126e-4, + 0.0337851718068123, + 1.5984958736226e-4, + 4.66885743662715e-4, + 5.14892512001097e-4, + 5.31236173628713e-6, + 1.87523312433768e-6, + 1.50291079989984e-5, + 1.36366652441211e-5, + 7.82930146669969e-6, + 2.06039971089922e-4 + ] + }, + "fFlag": -1, + "fChi2": 17.98244, + "fNDF": 5, + "fB": 0, + "fLength": 200.5973, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 24, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.905997157096863, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.828063666820526, + "fY": 1.32057547569275, + "fZ": 0.446708500385284, + "fTx": 0.0525042191147804, + "fTy": 0.076543316245079, + "fQp": 0.260553300380707, + "fCovMatrix": [ + 0.157716661691666, + 0.0197686683386564, + -0.00170101039111614, + -3.8990743632894e-5, + 0.00344474543817341, + 0.18804831802845, + -1.40642136102542e-4, + -0.00103673757985234, + 1.59807517775334e-4, + 1.9831073586829e-5, + 3.73987134594245e-8, + -3.82388498110231e-5, + 7.60457533033332e-6, + 7.31151999389112e-7, + 8.72718810569495e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 33.9409980773926, + "fY": 20.5864219665527, + "fZ": 253.266006469727, + "fTx": 0.210582479834557, + "fTy": 0.0765761435031891, + "fQp": 0.26235419511795, + "fCovMatrix": [ + 0.00145445531234145, + 0.00275185145437717, + 3.95754941564519e-5, + 2.84991037915461e-5, + 1.90182065125555e-4, + 0.0289667211472988, + 7.69189500715584e-5, + 3.15010925987735e-4, + 3.13600699882954e-4, + 1.93685445992742e-6, + 5.99234567744134e-7, + 1.08821486719535e-5, + 5.13304030391737e-6, + 9.56498297455255e-7, + 8.76150515978225e-5 + ] + }, + "fFlag": -1, + "fChi2": 19.22278, + "fNDF": 5, + "fB": 0, + "fLength": 256.0777, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 25, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.24199759960175, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0512982718646526, + "fY": 1.06561839580536, + "fZ": 0.446708500385284, + "fTx": 0.0198498331010342, + "fTy": 0.110577538609505, + "fQp": -1.19012749195099, + "fCovMatrix": [ + 0.00603315327316523, + 0.00704765599220991, + -3.97437339415774e-4, + -1.23337362310849e-4, + 0.0015260394429788, + 0.280310779809952, + -1.66871061082929e-4, + -0.00403328100219369, + 0.00104829901829362, + 2.91554206341971e-5, + 3.98109477828257e-6, + -9.39659003051929e-5, + 7.87801909609698e-5, + -3.100903268205e-5, + 0.00134257483296096 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -9.37472343444824, + "fY": 11.430046081543, + "fZ": 92.4069976806641, + "fTx": -0.238975748419762, + "fTy": 0.116884142160416, + "fQp": -1.2022613286972, + "fCovMatrix": [ + 0.00181734294164926, + -0.00530816009268165, + 7.91477577877231e-5, + -1.48450635606423e-4, + 5.27066120412201e-4, + 0.047173984348774, + -2.73892597761005e-4, + 0.00118228862993419, + -0.00185405183583498, + 8.10304391052341e-6, + -5.2895188673574e-6, + 6.60147197777405e-5, + 5.66577327845152e-5, + -3.31722803821322e-5, + 0.00132040248718113 + ] + }, + "fFlag": -1, + "fChi2": 22.29893, + "fNDF": 5, + "fB": 0, + "fLength": 93.42108, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 26, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.640410184860229, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.700390338897705, + "fY": 0.90983772277832, + "fZ": 0.446708500385284, + "fTx": -0.548557937145233, + "fTy": -0.305793702602386, + "fQp": 2.18843913078308, + "fCovMatrix": [ + 0.0741067007184029, + 0.0273595526814461, + -0.00337378145195544, + -7.50150938984007e-4, + 0.0033147088252008, + 0.30476975440979, + -0.00107568292878568, + -0.00604549515992403, + 0.00265475339256227, + 2.26271324208938e-4, + 4.30196050729137e-5, + -1.69975362950936e-4, + 2.360731450608e-4, + -6.06054345553275e-5, + 0.00152116548269987 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -20.3196315765381, + "fY": -32.7212295532227, + "fZ": 123.677001953125, + "fTx": 0.20149177312851, + "fTy": -0.26336732506752, + "fQp": 2.23557496070862, + "fCovMatrix": [ + 0.00191347696818411, + -0.00565362721681595, + 1.08587002614513e-4, + -1.2761885591317e-4, + 5.17589738592505e-4, + 0.0476216077804565, + -4.27084742113948e-4, + 9.8123773932457e-4, + -0.00190889881923795, + 1.62221658683848e-5, + -8.1552079791436e-6, + 6.61053418298252e-5, + 4.30222571594641e-5, + -3.38782410835847e-5, + 0.00154678162652999 + ] + }, + "fFlag": -1, + "fChi2": 23.61363, + "fNDF": 5, + "fB": 0, + "fLength": 131.0269, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 27, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.878863215446472, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.430907219648361, + "fY": 0.819810748100281, + "fZ": 0.446708500385284, + "fTx": 0.354820370674133, + "fTy": -0.161246061325073, + "fQp": 0.664999186992645, + "fCovMatrix": [ + 0.00955541804432869, + -0.00530777126550674, + -2.87420203676447e-4, + 6.70724984956905e-5, + 5.19839581102133e-4, + 0.125300273299217, + 1.08587206341326e-4, + -0.0012696391204372, + -6.76059920806438e-4, + 1.10646278699278e-5, + -1.73058799646242e-6, + -1.68200404004892e-5, + 1.83946885954356e-5, + 8.74752367963083e-6, + 9.66972947935574e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 81.8046035766602, + "fY": -27.8622398376465, + "fZ": 159.557006835938, + "fTx": 0.712900757789612, + "fTy": -0.214687287807465, + "fQp": 0.6629798412323, + "fCovMatrix": [ + 0.00161223881877959, + 0.00377275561913848, + 5.2143404900562e-5, + 4.81264833069872e-5, + 1.53602843056433e-4, + 0.0361070893704891, + 1.45044105011038e-4, + 4.82708710478619e-4, + 4.52368607511744e-4, + 3.82798089049174e-6, + 1.44914736210922e-6, + 1.09584916572203e-5, + 1.07873020169791e-5, + 3.82571352020022e-6, + 9.4176190032158e-5 + ] + }, + "fFlag": -1, + "fChi2": 29.0788, + "fNDF": 5, + "fB": 0, + "fLength": 182.7927, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 28, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.560243666172028, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.08742094039917, + "fY": -0.293393194675446, + "fZ": 0.446708500385284, + "fTx": -0.0401604361832142, + "fTy": -0.0164600592106581, + "fQp": 0.10171927511692, + "fCovMatrix": [ + 1.59696066379547, + 0.660858631134033, + -0.0156218260526657, + -0.00313152791932225, + 0.0318597480654716, + 0.65833842754364, + -0.00644648913294077, + -0.00318792019970715, + 0.0132419569417834, + 1.5323277330026e-4, + 3.06120855384506e-5, + -3.1325820600614e-4, + 1.59172777784988e-5, + -6.30246649961919e-5, + 6.45809981506318e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.08927249908447, + "fY": -11.032865524292, + "fZ": 635.900024414062, + "fTx": 0.0233717299997807, + "fTy": -0.0169893242418766, + "fQp": 0.0680521056056023, + "fCovMatrix": [ + 0.720901787281036, + -0.158103734254837, + 0.00197278172709048, + -3.69012559531257e-4, + 0.00920373201370239, + 0.658935248851776, + -4.29656472988427e-4, + 0.00152434047777206, + -0.00211671344004571, + 5.74976684220019e-6, + -1.00950876458228e-6, + 2.54789156315383e-5, + 3.92320316677797e-6, + -5.14099565407378e-6, + 1.29324762383476e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.530421, + "fNDF": 3, + "fB": 0, + "fLength": 635.7604, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 29, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": 11, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": 0.982413048336234, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.23891544342041, + "fPidTof400": [], + "fPidTof700": [ + 0.00377830140596851, + 0.00282265424851867, + 0.00302278320239034, + 0.00280648252323255, + 0.352906208430629, + 0.00236113640578434, + 0.00655261886666298, + 0.625749814916814 + ], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.94281661510468, + "fY": 1.05254948139191, + "fZ": 0.446708500385284, + "fTx": -0.0460996776819229, + "fTy": 0.0232866797596216, + "fQp": 0.157823503017426, + "fCovMatrix": [ + 0.86102294921875, + -0.457817822694778, + -0.00844337046146393, + 0.0022731083445251, + 0.0167319793254137, + 0.634925365447998, + 0.00446182582527399, + -0.0032517989166081, + -0.00919024553149939, + 8.3519124018494e-5, + -2.22535654756939e-5, + -1.65581965120509e-4, + 1.80169045052025e-5, + 4.60318733530585e-5, + 3.44207452144474e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 2.1041431427002, + "fY": 6.79212951660156, + "fZ": 253.266006469727, + "fTx": 0.0468702279031277, + "fTy": 0.0221596695482731, + "fQp": 0.158737048506737, + "fCovMatrix": [ + 0.00187287107110023, + 0.00517367757856846, + 6.87778447172605e-5, + 8.69970317580737e-5, + 5.25635492522269e-4, + 0.0436974242329597, + 2.40288529312238e-4, + 6.76476571243256e-4, + 0.00211965525522828, + 3.98110887545045e-6, + 4.53476877737558e-6, + 3.50696209352463e-5, + 1.39108415169176e-5, + 4.35302827099804e-5, + 3.44250904163346e-4 + ] + }, + "fFlag": -1, + "fChi2": 0.6264067, + "fNDF": 3, + "fB": 0, + "fLength": 252.9831, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 30, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.07289290428162, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -5.56726026535034, + "fY": 1.88980782032013, + "fZ": 0.446708500385284, + "fTx": -0.00756088923662901, + "fTy": -0.0327454805374146, + "fQp": 0.218929752707481, + "fCovMatrix": [ + 0.0281521212309599, + -0.0200254637748003, + -5.85395784582943e-4, + 1.46306061651558e-4, + 0.00123560742940754, + 0.115272685885429, + 2.61412293184549e-4, + -0.00110655347816646, + -5.40421751793474e-4, + 4.21449658460915e-5, + -1.78392735961097e-6, + -2.21715617954032e-5, + 4.38980569015257e-5, + 2.76233777185553e-6, + 7.98879918875173e-5 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.81798672676086, + "fY": -4.31223726272583, + "fZ": 186.154006958008, + "fTx": 0.0906062945723534, + "fTy": -0.0340937301516533, + "fQp": 0.220142289996147, + "fCovMatrix": [ + 0.00228732591494918, + -0.00766046345233917, + 4.16833136114292e-5, + -7.82218339736573e-5, + 1.34086134494282e-4, + 0.0586880035698414, + -9.49596069403924e-5, + 6.17937359493226e-4, + -8.07608885224909e-5, + 1.95375764633354e-6, + -6.85975749092904e-7, + 1.08221520349616e-5, + 8.30812223284738e-6, + 2.07624725589994e-6, + 7.99878544057719e-5 + ] + }, + "fFlag": -1, + "fChi2": 9.890654, + "fNDF": 3, + "fB": 0, + "fLength": 186.0561, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 31, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 5.72475862503052, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 1.40435910224915, + "fY": -1.74788320064545, + "fZ": 0.446708500385284, + "fTx": 0.0159829445183277, + "fTy": 0.0666084289550781, + "fQp": -0.0630679279565811, + "fCovMatrix": [ + 0.359982132911682, + 0.0454927869141102, + -0.00394425308331847, + 7.40441828384064e-5, + 0.00865282118320465, + 0.177479684352875, + -4.34850342571735e-4, + -8.83849628735334e-4, + 8.17067746538669e-4, + 4.34577923442703e-5, + -1.18699938411737e-6, + -9.56689837039448e-5, + 5.04924128108541e-6, + 3.46451156474359e-6, + 2.13246297789738e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.728297472000122, + "fY": 15.1543607711792, + "fZ": 253.266006469727, + "fTx": -0.0212028790265322, + "fTy": 0.0670934021472931, + "fQp": -0.0630813986063004, + "fCovMatrix": [ + 0.00170980067923665, + 0.00438810000196099, + 6.43509774818085e-5, + 2.79260748357046e-5, + 3.84177605155855e-4, + 0.0395979657769203, + 2.32808495638892e-4, + 3.1552481232211e-4, + 0.00148620537947863, + 4.30931640948984e-6, + 6.17797468294157e-7, + 2.9539532988565e-5, + 4.65721086584381e-6, + 1.86477541319618e-6, + 2.11488266359083e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.07215, + "fNDF": 3, + "fB": 0, + "fLength": 253.4007, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 32, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 2.6056342124939, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0225908625870943, + "fY": 2.4101722240448, + "fZ": 0.446708500385284, + "fTx": -0.0205847378820181, + "fTy": 0.0317823737859726, + "fQp": 0.262870192527771, + "fCovMatrix": [ + 0.410086780786514, + 0.0469960048794746, + -0.00456686085090041, + 6.65025654598139e-5, + 0.00882185809314251, + 0.229289501905441, + -4.43539873231202e-4, + -0.00149148085620254, + 8.27870098873973e-4, + 5.22158370586112e-5, + -1.14772262804763e-6, + -9.82185010798275e-5, + 1.33087651192909e-5, + 3.38607537742064e-6, + 2.22015733015724e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 14.576849937439, + "fY": 10.2098379135132, + "fZ": 253.266006469727, + "fTx": 0.135617300868034, + "fTy": 0.0301221162080765, + "fQp": 0.264727205038071, + "fCovMatrix": [ + 0.00171579921152443, + 0.00442134169861674, + 6.48677450953983e-5, + 2.92732129310025e-5, + 3.80714831408113e-4, + 0.0397795774042606, + 2.3569269978907e-4, + 3.22912295814604e-4, + 0.00147179246414453, + 4.43919816461857e-6, + 7.01510657563631e-7, + 2.92453114525415e-5, + 5.09910523760482e-6, + 1.95571692529484e-6, + 2.21771551878192e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.6951, + "fNDF": 3, + "fB": 0, + "fLength": 253.6778, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 33, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.9854781627655, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.629141807556152, + "fY": 1.38312804698944, + "fZ": 0.446708500385284, + "fTx": 0.146586313843727, + "fTy": 0.00271266396157444, + "fQp": 0.192928344011307, + "fCovMatrix": [ + 0.149345919489861, + -0.0577854551374912, + -0.00205688877031207, + 1.69445615028962e-4, + 0.00482555339112878, + 0.153863877058029, + 7.25681020412594e-4, + -9.60102246608585e-4, + -0.00172866601496935, + 2.90175394184189e-5, + -1.89735999356344e-6, + -6.68615102767944e-5, + 8.06202206149464e-6, + 3.97035546484403e-6, + 1.75839726580307e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 42.284595489502, + "fY": 1.7777191400528, + "fZ": 217.451995849609, + "fTx": 0.251348227262497, + "fTy": 0.00114794040564448, + "fQp": 0.193487912416458, + "fCovMatrix": [ + 0.00140010926406831, + -0.0029458578210324, + 5.59846776013728e-5, + -1.63711501954822e-5, + 2.90705327643082e-4, + 0.0321751311421394, + -1.85875440365635e-4, + 2.63134745182469e-4, + -0.00103027222212404, + 4.47622051069629e-6, + -9.90499948727575e-9, + 2.62509583990322e-5, + 5.04389936395455e-6, + 2.64827554019575e-6, + 1.75261535332538e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.77436, + "fNDF": 3, + "fB": 0, + "fLength": 221.4154, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 34, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 1.12807381153107, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.741546928882599, + "fY": 4.85820436477661, + "fZ": 0.446708500385284, + "fTx": 0.19030949473381, + "fTy": 0.0252211969345808, + "fQp": -0.462024539709091, + "fCovMatrix": [ + 0.420751214027405, + 0.0515755452215672, + -0.00470444280654192, + 4.05961691285484e-5, + 0.00976410880684853, + 0.224917396903038, + -4.92765102535486e-4, + -0.00132196012418717, + 8.68746836204082e-4, + 6.0438564105425e-5, + -8.71645795541554e-7, + -1.11932982690632e-4, + 1.63539098139154e-5, + 3.21649645229627e-6, + 2.60348548181355e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 13.6117811203003, + "fY": 11.6619310379028, + "fZ": 253.266006469727, + "fTx": -0.0849352851510048, + "fTy": 0.0285291355103254, + "fQp": -0.465198427438736, + "fCovMatrix": [ + 0.00172228959854692, + 0.00445574428886175, + 6.58447606838308e-5, + 3.0620507459389e-5, + 3.84085607947782e-4, + 0.0399787276983261, + 2.39864952163771e-4, + 3.32715193508193e-4, + 0.00148236250970513, + 4.74132048111642e-6, + 7.53851111312542e-7, + 2.96433372568572e-5, + 6.02678755967645e-6, + 1.60450338171358e-6, + 2.58154206676409e-4 + ] + }, + "fFlag": -1, + "fChi2": 12.82246, + "fNDF": 3, + "fB": 0, + "fLength": 254.0149, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 35, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 4.49988603591919, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -0.0719772577285767, + "fY": 0.726722061634064, + "fZ": 0.446708500385284, + "fTx": -0.213506519794464, + "fTy": -0.143965721130371, + "fQp": -2.62076330184937, + "fCovMatrix": [ + 0.00797438062727451, + 0.00720387883484364, + -6.53111434075981e-4, + -9.67506784945726e-5, + 0.0017830478027463, + 0.321473628282547, + -1.51318730786443e-4, + -0.00658326270058751, + 0.00148632749915123, + 6.07886504440103e-5, + 9.80958958507472e-8, + -1.58694179845043e-4, + 1.94639462279156e-4, + 4.33506102126557e-5, + 0.00314619881100953 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -65.9978485107422, + "fY": -15.9892063140869, + "fZ": 97.1070022583008, + "fTx": -1.69931781291962, + "fTy": -0.28000882267952, + "fQp": -2.60817050933838, + "fCovMatrix": [ + 0.0023685097694397, + 0.0083130206912756, + 2.14044077438302e-4, + 2.21727692405693e-4, + 4.34383895481005e-4, + 0.0642749667167664, + 9.29289672058076e-4, + 0.00157989992294461, + 0.00178945402149111, + 2.0627336925827e-4, + 3.11331641569268e-5, + 5.96506637521088e-4, + 9.46382278925739e-5, + 6.35135511402041e-5, + 0.00276731047779322 + ] + }, + "fFlag": -1, + "fChi2": 26.27061, + "fNDF": 5, + "fB": 0, + "fLength": 130.3361, + "fNhits": 5, + "fUsing": false, + "fGemTrack": 36, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.303768336772919, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0557866953313351, + "fY": 0.547424077987671, + "fZ": 0.446708500385284, + "fTx": 0.429236263036728, + "fTy": -0.275659441947937, + "fQp": 2.17269659042358, + "fCovMatrix": [ + 0.0197780951857567, + -0.00987072102725506, + -0.00182154367212206, + 2.94619821943343e-4, + 0.00291714025661349, + 0.418625175952911, + 2.52996629569679e-4, + -0.00894289463758469, + -0.00197083782404661, + 2.09425037610345e-4, + -1.89258062164299e-5, + -2.41016896325164e-4, + 3.31170595018193e-4, + 3.93724658351857e-5, + 0.00362231628969312 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 39.5060920715332, + "fY": -18.5408248901367, + "fZ": 60.9249992370605, + "fTx": 0.971311092376709, + "fTy": -0.388391822576523, + "fQp": 2.23315715789795, + "fCovMatrix": [ + 0.00245717912912369, + -0.00909164734184742, + 1.58361988724209e-4, + -2.69030395429581e-4, + 6.81250647176057e-4, + 0.070623591542244, + -5.55392180103809e-4, + 0.00196365104056895, + -0.00189403316471726, + 2.47496318479534e-5, + -2.33925493375864e-5, + 8.39190033730119e-5, + 1.84656732017174e-4, + -5.43450478289742e-5, + 0.00324276322498918 + ] + }, + "fFlag": -1, + "fChi2": 0.01600785, + "fNDF": 3, + "fB": 0, + "fLength": 76.87881, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 37, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.150820776820183, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.0865775346755981, + "fY": 1.03615427017212, + "fZ": 0.446708500385284, + "fTx": 0.490233063697815, + "fTy": -0.271417737007141, + "fQp": 1.6378653049469, + "fCovMatrix": [ + 0.00971092842519283, + -0.00865449476987123, + -8.71058786287904e-4, + 2.03632385819219e-4, + 0.00204137898981571, + 0.406613826751709, + 1.50130203110166e-4, + -0.00797386933118105, + -8.66855261847377e-4, + 1.02072430308908e-4, + -9.47271746554179e-6, + -1.61702104378492e-4, + 2.30386460316367e-4, + 3.07723848891328e-6, + 0.00214667920954525 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 40.114372253418, + "fY": -17.2033081054688, + "fZ": 60.9249992370605, + "fTx": 0.89084392786026, + "fTy": -0.348761737346649, + "fQp": 1.6664445400238, + "fCovMatrix": [ + 0.00244997604750097, + -0.0090667437762022, + 1.51414395077154e-4, + -2.62064364505932e-4, + 7.42975214961916e-4, + 0.0705385282635689, + -5.31124067492783e-4, + 0.00194119138177484, + -0.002225091913715, + 1.75859604496509e-5, + -1.97827012016205e-5, + 6.81519377394579e-5, + 1.69458886375651e-4, + -5.7736957387533e-5, + 0.00198274431750178 + ] + }, + "fFlag": -1, + "fChi2": 0.1320775, + "fNDF": 3, + "fB": 0, + "fLength": 76.24169, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 38, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.622270882129669, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -30.9979572296143, + "fY": 4.43448543548584, + "fZ": 0.446708500385284, + "fTx": 0.0402201563119888, + "fTy": 0.0601904541254044, + "fQp": 1.87127530574799, + "fCovMatrix": [ + 1.32694137096405, + -0.106557555496693, + -0.0177334845066071, + 8.25475435703993e-4, + 0.00908469036221504, + 1.40546059608459, + 0.0013534432509914, + -0.0161437466740608, + -0.00204152660444379, + 2.49203236307949e-4, + -1.15576422103914e-5, + -1.53714412590489e-4, + 2.04331721761264e-4, + 1.62767955771415e-5, + 5.45246468391269e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 86.7152557373047, + "fY": 17.499963760376, + "fZ": 190.85400390625, + "fTx": 1.84347748756409, + "fTy": 0.138669148087502, + "fQp": 1.97133362293243, + "fCovMatrix": [ + 0.00211035180836916, + 0.00650257663801312, + 1.25869875773787e-4, + 1.28308791317977e-4, + 1.88947567949072e-4, + 0.05129624158144, + 5.15072897542268e-4, + 9.42497921641916e-4, + 7.66049546655267e-4, + 4.11660621466581e-5, + 9.57041356741684e-6, + 5.5888343922561e-5, + 3.89481283491477e-5, + 1.91698745766189e-5, + 3.72251815861091e-4 + ] + }, + "fFlag": -1, + "fChi2": 5.015832, + "fNDF": 3, + "fB": 0, + "fLength": 241.3628, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 39, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 31.2234497070312, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 0.142423272132874, + "fY": 0.623891711235046, + "fZ": 0.446708500385284, + "fTx": -0.0736589878797531, + "fTy": 0.298795640468597, + "fQp": 2.80417394638062, + "fCovMatrix": [ + 0.0445475578308105, + 0.0275441370904446, + -0.00331222778186202, + -6.77968375384808e-4, + 0.00995489209890366, + 1.3541864156723, + -6.81058096233755e-4, + -0.0393065959215164, + 0.0296369660645723, + 3.44947155099362e-4, + 1.09068150777603e-5, + -6.63490616716444e-4, + 0.00142230000346899, + -8.73721961397678e-4, + 0.0108823031187057 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 3.45915913581848, + "fY": 14.4354619979858, + "fZ": 46.7879981994629, + "fTx": 0.234864756464958, + "fTy": 0.301912605762482, + "fQp": 2.95631885528564, + "fCovMatrix": [ + 3.31636285409331e-4, + 0.00638530729338527, + 3.2258660212392e-5, + 3.13805445330217e-4, + 3.01188760204241e-4, + 0.292764902114868, + 3.11581214191392e-4, + 0.0143494522199035, + -0.0112698068842292, + 1.21231414595968e-5, + 2.43910999415675e-5, + 2.18840417801403e-4, + 0.0011020228266716, + -8.5128570208326e-4, + 0.0106315473094583 + ] + }, + "fFlag": -1, + "fChi2": 7.60299, + "fNDF": 3, + "fB": 0, + "fLength": 48.78945, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 40, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 0.264814794063568, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 8.30461597442627, + "fY": -5.9334716796875, + "fZ": 0.446708500385284, + "fTx": -0.265362769365311, + "fTy": 0.0571171008050442, + "fQp": 1.03822529315948, + "fCovMatrix": [ + 5.15337038040161, + -0.00919716153293848, + -0.0533259771764278, + 7.47839163523167e-4, + 0.029088081791997, + 4.7500114440918, + 8.3266239380464e-4, + -0.0450916662812233, + 3.28805443132296e-4, + 5.94176410231739e-4, + -1.50604137161281e-5, + -3.8828028482385e-4, + 4.67599922558293e-4, + 8.13724273029948e-6, + 0.00107832241337746 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 26.9697799682617, + "fY": 8.39235782623291, + "fZ": 253.266006469727, + "fTx": 0.444779872894287, + "fTy": 0.0642979964613914, + "fQp": 1.18556535243988, + "fCovMatrix": [ + 0.00186509417835623, + 0.00526912836357951, + 8.09190751169808e-5, + 6.40154685243033e-5, + 3.54248360963538e-4, + 0.0448441095650196, + 3.1117265461944e-4, + 5.57739695068449e-4, + 0.0013737817062065, + 9.65948038356146e-6, + 1.98274415197375e-6, + 5.237402729108e-5, + 2.17948781937594e-5, + 2.6742793579615e-6, + 0.00105986534617841 + ] + }, + "fFlag": -1, + "fChi2": 9.604467, + "fNDF": 3, + "fB": 0, + "fLength": 259.5284, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 41, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 10.4857606887817, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + }, + { + "_typename": "BmnGlobalTrack", + "fUniqueID": 0, + "fBits": 0, + "fHits": [], + "fParamFirst": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": -8.67306518554688, + "fY": -0.893381178379059, + "fZ": 0.446708500385284, + "fTx": -0.244425937533379, + "fTy": 0.0710715800523758, + "fQp": 1.46282720565796, + "fCovMatrix": [ + 1.94970905780792, + 0.0666303187608719, + -0.0393972508609295, + 4.9722200492397e-4, + 0.0140476133674383, + 1.89005267620087, + 1.53647080878727e-4, + -0.0352988466620445, + 7.02263845596462e-4, + 0.00511521846055984, + -9.02606479940005e-5, + -1.82768955710344e-4, + 0.00483105797320604, + 3.06898095914221e-6, + 5.15780760906637e-4 + ] + }, + "fParamLast": { + "_typename": "FairTrackParam", + "fUniqueID": 0, + "fBits": 0, + "fX": 74.2952423095703, + "fY": 17.0499019622803, + "fZ": 253.266006469727, + "fTx": 1.15265381336212, + "fTy": 0.0914041697978973, + "fQp": 1.72471988201141, + "fCovMatrix": [ + 0.00201824493706226, + 0.00598255405202508, + 1.08104322862346e-4, + 8.26826799311675e-5, + 2.03509247512557e-4, + 0.0480972304940224, + 4.38924587797374e-4, + 6.5469037508592e-4, + 7.57522066123784e-4, + 2.06035074370448e-5, + 4.59917828266043e-6, + 1.97731387743261e-5, + 3.33881689584814e-5, + 9.54037204792257e-8, + 4.49782353825867e-4 + ] + }, + "fFlag": -1, + "fChi2": 28.50264, + "fNDF": 3, + "fB": 0, + "fLength": 284.762, + "fNhits": 4, + "fUsing": false, + "fGemTrack": 42, + "fSsdTrack": -1, + "fSilTrack": -1, + "fTof1Hit": -1, + "fTof2Hit": -1, + "fDch1Track": -1, + "fDch2Track": -1, + "fDchTrack": -1, + "fMwpc1Track": -1, + "fMwpc2Track": -1, + "fUpstreamTrack": -1, + "fScWallCellId": -1, + "fCscHit": [ + -1, + -1, + -1, + -1 + ], + "fScWallSignal": -1000, + "fBeta400": -1000, + "fBeta700": -1000, + "fdQdNUpper": 0, + "fdQdNLower": 0, + "fA": -1, + "fZ": 0, + "fPDG": 0, + "fChi2InVertex": 2.34478793822074e-310, + "fDCAInVertex": 8.74019145965576, + "fPidTof400": [], + "fPidTof700": [], + "fIsPrimary": true, + "fRefIndex": 0 + } + ] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_1.json b/demo/playground/src/jvmMain/resources/root/event_1.json new file mode 100644 index 00000000..ca057754 --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_1.json @@ -0,0 +1,215 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2112745000, + "fStsHits" : [216, 221, 5, 50, 63, 82, 133], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.79052305221558, + "fY" : 8.83165168762207, + "fZ" : 36.5065002441406, + "fTx" : -0.11185921728611, + "fTy" : 0.228091076016426, + "fQp" : 0.893607378005981, + "fCovMatrix" : [1.68777798535302e-4, -9.69577522482723e-4, -1.07744517663377e-5, 1.2614247680176e-5, 2.87587154161884e-5, 0.0403835587203503, 5.90448107686825e-5, -5.16064348630607e-4, -2.05383723368868e-4, 2.20405854634009e-6, -8.30146461794357e-7, -5.49759215573431e-6, 1.16227884063846e-5, 3.6013934732182e-6, 1.46196922287345e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.67626953125, + "fY" : 43.7959594726562, + "fZ" : 190.759826660156, + "fTx" : 0.240885242819786, + "fTy" : 0.230351597070694, + "fQp" : 0.896391570568085, + "fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4] + }, + "fFlag" : 0, + "fChi2" : 3.59655165672302, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [79, 108, 136, 160], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 7.56474113464355, + "fY" : -6.31765508651733, + "fZ" : 123.474571228027, + "fTx" : 0.198165953159332, + "fTy" : -0.0599287338554859, + "fQp" : 0.826108694076538, + "fCovMatrix" : [0.00192060391418636, -0.00543995574116707, -7.47249359847046e-5, 9.40304598771036e-5, 4.32362634455785e-4, 0.0452092550694942, 2.69763870164752e-4, -7.19496863894165e-4, -0.00178805936593562, 5.47440777154407e-6, -4.97666542287334e-6, -3.32396593876183e-5, 1.67156704264926e-5, 3.69572808267549e-5, 3.62657097866759e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 38.4175720214844, + "fY" : -12.5351896286011, + "fZ" : 222.266052246094, + "fTx" : 0.428264498710632, + "fTy" : -0.0652719661593437, + "fQp" : 0.827384233474731, + "fCovMatrix" : [0.00191446917597204, 0.00539331184700131, 7.50113686081022e-5, 9.10265880520456e-5, 4.29905543569475e-4, 0.0449054278433323, 2.68147414317355e-4, 7.0479983696714e-4, 0.00177141127642244, 5.60895068701939e-6, 4.76898094348144e-6, 3.39166836056393e-5, 1.61108710017288e-5, 3.51894050254487e-5, 3.57192009687424e-4] + }, + "fFlag" : 0, + "fChi2" : 0.0889237225055695, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.514997541904449, + "fY" : 0.614071667194366, + "fZ" : 0.716018855571747, + "fTx" : -0.182437181472778, + "fTy" : 0.231170654296875, + "fQp" : 0.890645802021027, + "fCovMatrix" : [0.00640107085928321, -0.00549036636948586, -2.40077963098884e-4, 5.9050194977317e-5, 4.4034980237484e-4, 0.0939982086420059, 1.37060953420587e-4, -0.0010447750100866, -3.45796346664429e-4, 1.4494138667942e-5, -1.88720639471285e-6, -1.71545361808967e-5, 2.24065261136275e-5, 4.27886925535859e-6, 1.46344274980947e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.67626953125, + "fY" : 43.7959594726562, + "fZ" : 190.759826660156, + "fTx" : 0.240885242819786, + "fTy" : 0.230351597070694, + "fQp" : 0.896391570568085, + "fCovMatrix" : [0.00152156152762473, 0.00325645040720701, 4.73157851956785e-5, 4.51812447863631e-5, 1.32256536744535e-4, 0.0311740729957819, 1.29416745039634e-4, 3.94528120523319e-4, 3.28425812767819e-4, 3.75195077140233e-6, 1.75166894678114e-6, 9.62230569712119e-6, 9.89728778222343e-6, 4.38717188444571e-6, 1.46559861605056e-4] + }, + "fFlag" : -1, + "fChi2" : 3.596552, + "fNDF" : 9, + "fB" : 0, + "fLength" : 196.4224, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.169359803199768, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.30332088470459, + "fY" : 0.709633886814117, + "fZ" : 0.716018855571747, + "fTx" : -0.0394387505948544, + "fTy" : -0.0554707236588001, + "fQp" : 0.794627845287323, + "fCovMatrix" : [1.0362377166748, -0.242409482598305, -0.0120293609797955, 0.00132000644225627, 0.0113498065620661, 1.10034370422363, 0.0026963478885591, -0.0100266374647617, -0.00638964772224426, 1.71858730027452e-4, -1.46718830364989e-5, -1.39145020511933e-4, 1.31993641844019e-4, 3.72123940906022e-5, 3.64089268259704e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 153.443832397461, + "fY" : -27.7408638000488, + "fZ" : 422.371002197266, + "fTx" : 0.623147189617157, + "fTy" : -0.0757252722978592, + "fQp" : 0.879441320896149, + "fCovMatrix" : [0.210621446371078, 0.00677151698619127, 0.00126052019186318, -1.89192069228739e-5, 0.00233594398014247, 0.117487587034702, 1.90632126759738e-5, 5.61361608561128e-4, 3.66047053830698e-4, 5.4321233619703e-5, -1.38209452416049e-6, 1.40239317261148e-5, 3.86252722819336e-5, -2.07852266953523e-7, 1.6525064711459e-4] + }, + "fFlag" : -1, + "fChi2" : 28.54445, + "fNDF" : 3, + "fB" : 0, + "fLength" : 456.7299, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 0, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.813491527513362, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.82100653648376, + "fPidTof400" : [0.698706510566553, 0.0456706934329348, 0.070160747316434, 0.044178479600919, 0.0321317585690916, 0.0203602877603981, 0.0563498151154308, 0.0324417076382387], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_2.json b/demo/playground/src/jvmMain/resources/root/event_2.json new file mode 100644 index 00000000..22e6c5f8 --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_2.json @@ -0,0 +1,5150 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1682, 1766, 1829, 464, 768, 972, 1137, 1393], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.63523077964783, + "fY" : -1.11952388286591, + "fZ" : 24.867000579834, + "fTx" : -0.166404068470001, + "fTy" : -0.0722663849592209, + "fQp" : -0.659868478775024, + "fCovMatrix" : [1.58311304403469e-4, 0.00105864810757339, -8.34709226182895e-6, -1.12343277578475e-5, 2.62966495938599e-5, 0.041155993938446, -4.28007515438367e-5, -4.41101816250011e-4, 2.18053421122022e-4, 1.02060232620715e-6, 4.78974982343061e-7, -3.52032748196507e-6, 7.39310189601383e-6, -2.87856505565287e-6, 7.60013062972575e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -53.3829460144043, + "fY" : -13.1547222137451, + "fZ" : 185.683853149414, + "fTx" : -0.468784332275391, + "fTy" : -0.0797551199793816, + "fQp" : -0.660838067531586, + "fCovMatrix" : [0.00121652521193027, -0.00194779026787728, 3.82801008527167e-5, -2.38575230468996e-5, 1.03297272289637e-4, 0.0245428644120693, -8.60174477566034e-5, 2.80060805380344e-4, -2.55426042713225e-4, 3.07012169287191e-6, -9.24756022868678e-7, 7.38780818210216e-6, 6.4618020587659e-6, -2.95916311188194e-6, 7.52489650039934e-5] + }, + "fFlag" : 0, + "fChi2" : 0.682691812515259, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1763, 1827, 467, 767, 973, 1153, 1413, 1483], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -5.50913715362549, + "fY" : -1.61793780326843, + "fZ" : 33.2939987182617, + "fTx" : -0.153988212347031, + "fTy" : -0.0633151158690453, + "fQp" : 0.356036454439163, + "fCovMatrix" : [1.35921887704171e-4, 5.25149109307677e-4, -5.04478293805732e-6, -4.25407552029355e-6, 1.32292962007341e-5, 0.028402591124177, -1.43782526720315e-5, -2.4180811305996e-4, -1.33881485453458e-5, 6.79417325955001e-7, 8.60398827740028e-8, -1.90996661331155e-6, 3.24026382259035e-6, 5.01784484185919e-7, 2.29810775635997e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -18.7020149230957, + "fY" : -13.5386352539062, + "fZ" : 221.990875244141, + "fTx" : 0.0132204964756966, + "fTy" : -0.0631681606173515, + "fQp" : 0.356655418872833, + "fCovMatrix" : [0.0011939414544031, 0.0018086233176291, 2.46283125306945e-5, 1.62282540259184e-5, 6.86891944496892e-5, 0.0225373078137636, 4.09956592193339e-5, 1.98697045561858e-4, 1.08902706415392e-4, 9.78696903075615e-7, 3.44910347394034e-7, 2.85334499494638e-6, 2.87495959128137e-6, 8.18456555862213e-7, 2.30724126595305e-5] + }, + "fFlag" : 0, + "fChi2" : 1.9497594833374, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1737188256, + "fStsHits" : [183, 630, 804, 993, 1315, 1437, 1504], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.96963500976562, + "fY" : 3.22212386131287, + "fZ" : 65.8386535644531, + "fTx" : 0.120770797133446, + "fTy" : 0.0367443077266216, + "fQp" : 0.182414337992668, + "fCovMatrix" : [0.00101125857327133, 0.00100853201001883, -2.16253556573065e-5, -7.20290472600027e-6, 6.52337694191374e-5, 0.0182508211582899, -2.26020365516888e-5, -1.44205492688343e-4, 4.419145261636e-5, 9.44088810683752e-7, 1.08565920697856e-7, -2.68945814241306e-6, 1.99062742467504e-6, 1.17405193122977e-7, 1.55548805196304e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 37.679759979248, + "fY" : 10.0525703430176, + "fZ" : 253.266006469727, + "fTx" : 0.203942775726318, + "fTy" : 0.0364765599370003, + "fQp" : 0.182578787207603, + "fCovMatrix" : [0.0011457153595984, 0.00149737962055951, 2.23015576921171e-5, 1.09393286038539e-5, 7.10815002094023e-5, 0.0201594308018684, 2.97546375804814e-5, 1.54651876073331e-4, 7.5706047937274e-5, 7.75048363266251e-7, 1.82903008294488e-7, 2.54641827268642e-6, 1.86880970431957e-6, 2.43735712501802e-7, 1.55496582010528e-5] + }, + "fFlag" : 0, + "fChi2" : 2.22132515907288, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1601148318, + "fStsHits" : [1718, 1796, 211, 693, 818, 1020, 1326], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -5.71760082244873, + "fY" : 0.689112067222595, + "fZ" : 36.5065002441406, + "fTx" : -0.151977360248566, + "fTy" : 0.00709940027445555, + "fQp" : 0.156383261084557, + "fCovMatrix" : [1.44718200317584e-4, -7.90981808677316e-4, -5.82021084483131e-6, 8.37171864986885e-6, 2.73877376457676e-5, 0.0344392620027065, 4.076426193933e-5, -3.35155404172838e-4, -2.47787014814094e-4, 6.88013926719577e-7, -5.29977342011989e-7, -3.60629746865015e-6, 4.35047195423977e-6, 3.54779081135348e-6, 3.01437412417727e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -24.49658203125, + "fY" : 1.74604022502899, + "fZ" : 190.759826660156, + "fTx" : -0.0914124399423599, + "fTy" : 0.00656518992036581, + "fQp" : 0.156333759427071, + "fCovMatrix" : [0.00133210537023842, 0.00254281889647245, 3.07717891701031e-5, 2.77981016552076e-5, 1.17731280624866e-4, 0.027555949985981, 6.91556560923345e-5, 2.83489149296656e-4, 2.94191704597324e-4, 1.14010765628336e-6, 7.86034036082128e-7, 5.11840653416584e-6, 4.08969299314776e-6, 3.48841217601148e-6, 3.02118824038189e-5] + }, + "fFlag" : 0, + "fChi2" : 2.61141204833984, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1090165622, + "fStsHits" : [209, 694, 811, 1010, 1317, 1455, 1505], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -17.8449935913086, + "fY" : 9.73141670227051, + "fZ" : 65.8457717895508, + "fTx" : -0.215278327465057, + "fTy" : 0.148166984319687, + "fQp" : 0.661383807659149, + "fCovMatrix" : [0.00113124051131308, 0.00145179522223771, -3.19208447763231e-5, -1.5488221833948e-5, 8.24654853204265e-5, 0.0208098106086254, -5.58063184143975e-5, -2.12456070585176e-4, 1.1660285963444e-4, 2.40666872741713e-6, 4.76995353437815e-7, -5.59231239094515e-6, 5.07825825479813e-6, -6.84226563407719e-7, 6.93799593136646e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -28.8700866699219, + "fY" : 36.6349716186523, + "fZ" : 253.266006469727, + "fTx" : 0.0915517956018448, + "fTy" : 0.13888768851757, + "fQp" : 0.663964629173279, + "fCovMatrix" : [0.0013174363411963, 0.00216729799285531, 3.46993256243877e-5, 2.37835829466349e-5, 7.89249243098311e-5, 0.0238640792667866, 7.23723351256922e-5, 2.47721880441532e-4, 9.2910930106882e-5, 2.31840249398374e-6, 7.41987889796292e-7, 4.51600999440416e-6, 5.64657284485293e-6, 3.95186390278468e-7, 6.98939329595305e-5] + }, + "fFlag" : 0, + "fChi2" : 5.7842812538147, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1550214659, + "fStsHits" : [1678, 1770, 1832, 468, 724, 968, 1126], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.61242008209229, + "fY" : -5.50625228881836, + "fZ" : 24.867000579834, + "fTx" : -0.153559222817421, + "fTy" : -0.204351961612701, + "fQp" : 0.915053844451904, + "fCovMatrix" : [1.71674299053848e-4, 0.00124005193356425, -9.80737422651146e-6, -1.48666276800213e-5, 2.9903852919233e-5, 0.0517979934811592, -3.81923309760168e-5, -6.50938018225133e-4, -1.95993605302647e-4, 1.43080853831634e-6, 4.31599147532324e-7, -6.17102477917797e-6, 1.24674479593523e-5, 4.02873274651938e-6, 1.74217610037886e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.8365318775177, + "fY" : -32.9046325683594, + "fZ" : 159.629043579102, + "fTx" : 0.167047187685966, + "fTy" : -0.20632404088974, + "fQp" : 0.914145052433014, + "fCovMatrix" : [0.00155416806228459, 0.00351027329452336, 4.78662987006828e-5, 4.80297567264643e-5, 1.67868478456512e-4, 0.034046433866024, 1.29982028738596e-4, 4.5236645382829e-4, 4.79995826026425e-4, 3.62696550837427e-6, 1.50596133607905e-6, 1.30671187434928e-5, 1.08145477497601e-5, 5.51082939637126e-6, 1.74894215888344e-4] + }, + "fFlag" : 0, + "fChi2" : 62.482234954834, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509938528, + "fStsHits" : [1636, 1707, 1794, 685, 814, 1008, 1321, 1454, 1506], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.70249974727631, + "fY" : 4.77476358413696, + "fZ" : 28.9860000610352, + "fTx" : -0.0554607696831226, + "fTy" : 0.148796871304512, + "fQp" : 0.119566723704338, + "fCovMatrix" : [9.98170871753246e-5, 3.74785478925332e-4, -3.02104444926954e-6, -2.04468597075902e-6, 9.24034793570172e-6, 0.0330311395227909, -1.56929090735503e-5, -2.07925797440112e-4, 3.61919737770222e-5, 2.56948766264031e-7, 5.6199063180884e-8, -8.75137914135848e-7, 1.69477459621703e-6, 1.6178902662034e-9, 5.08493167217239e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.76850318908691, + "fY" : 38.0125923156738, + "fZ" : 253.266006469727, + "fTx" : 0.00997702591121197, + "fTy" : 0.147619038820267, + "fQp" : 0.119642995297909, + "fCovMatrix" : [0.00100874423515052, 0.00117198028601706, 1.63884978974238e-5, 7.29519751985208e-6, 4.17295595980249e-5, 0.0191394723951817, 1.79422495421022e-5, 1.43677883897908e-4, 3.47817585861776e-5, 4.42629755070811e-7, 7.17247630177553e-8, 1.18746982025186e-6, 1.66530287515343e-6, -7.33179161827024e-9, 5.09104575030506e-6] + }, + "fFlag" : 0, + "fChi2" : 3.65150594711304, + "fNDF" : 13, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1593, 1644, 1720, 1797, 212, 690, 812, 1009], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.09095358848572, + "fY" : 2.90811204910278, + "fZ" : 19.0084991455078, + "fTx" : -0.153810381889343, + "fTy" : 0.128865405917168, + "fQp" : 0.528272271156311, + "fCovMatrix" : [1.57698406837881e-4, -0.00116014084778726, -7.51515744923381e-6, 1.18563257274218e-5, 3.05232642858755e-5, 0.051769096404314, 1.7445650883019e-5, -5.60092157684267e-4, 1.36088274302892e-4, 8.43438726860768e-7, -1.54633866600307e-7, -3.94911512557883e-6, 8.30690532893641e-6, -2.50242283073021e-6, 8.02850117906928e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.1900281906128, + "fY" : 20.1586036682129, + "fZ" : 154.893341064453, + "fTx" : 0.0223866682499647, + "fTy" : 0.125468313694, + "fQp" : 0.52903938293457, + "fCovMatrix" : [0.00118864618707448, -0.00201725121587515, 3.29115355270915e-5, -2.80263557215221e-5, 1.24523183330894e-4, 0.0269913990050554, -7.08940933691338e-5, 3.47086053807288e-4, -2.71533383056521e-4, 2.06066397367977e-6, -9.20225318168377e-7, 7.71232225815766e-6, 7.54866641727858e-6, -3.4717002108664e-6, 8.07631731731817e-5] + }, + "fFlag" : 0, + "fChi2" : 0.560838520526886, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1672, 1775, 1838, 461, 770, 1155, 1411, 1485], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.87697601318359, + "fY" : 0.080434538424015, + "fZ" : 24.867000579834, + "fTx" : -0.262285262346268, + "fTy" : -0.0302867814898491, + "fQp" : 0.574987947940826, + "fCovMatrix" : [1.61355375894345e-4, 0.00101068778894842, -9.4217311925604e-6, -1.12355837700306e-5, 3.08064340970304e-6, 0.0403573177754879, -3.77155956812203e-5, -4.77352383313701e-4, -1.23886769870296e-4, 1.20324261843052e-6, 4.16166756167513e-7, -1.4757878261662e-6, 1.14798785944004e-5, 6.69174198719702e-7, 7.2559661930427e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -30.0807361602783, + "fY" : -5.78548860549927, + "fZ" : 221.928085327148, + "fTx" : 0.0210418067872524, + "fTy" : -0.0293070133775473, + "fQp" : 0.576870679855347, + "fCovMatrix" : [0.00132818543352187, 0.00221483828499913, 3.30795446643606e-5, 2.5192939574481e-5, 1.05427883681841e-4, 0.0246683564037085, 6.37786215520464e-5, 2.38898894167505e-4, 2.15005653444678e-4, 1.80109100256232e-6, 7.71973873270326e-7, 6.46460057396325e-6, 4.64114327769494e-6, 2.72861416306114e-6, 7.34642962925136e-5] + }, + "fFlag" : 0, + "fChi2" : 1.21061491966248, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1589, 1637, 1706, 1795, 246, 817, 1005, 1323], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.25973784923553, + "fY" : 4.75281524658203, + "fZ" : 20.1884994506836, + "fTx" : -0.0586002320051193, + "fTy" : 0.207550808787346, + "fQp" : 0.285871863365173, + "fCovMatrix" : [1.29143983940594e-4, 6.2837143195793e-4, -5.66779226573999e-6, -4.78541460324777e-6, 2.199209848186e-5, 0.0403592400252819, -4.04380534746451e-6, -3.29683098243549e-4, -4.71849853056483e-5, 4.89187698349269e-7, 8.88997586656615e-9, -2.14619285543449e-6, 3.7864051591896e-6, 8.07122034984786e-7, 2.28951030294411e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.11983871459961, + "fY" : 39.9874572753906, + "fZ" : 190.759826660156, + "fTx" : 0.0620537921786308, + "fTy" : 0.206056728959084, + "fQp" : 0.286139667034149, + "fCovMatrix" : [0.00119367893785238, 0.00193155149463564, 2.52228346653283e-5, 1.92373408935964e-5, 7.64093638281338e-5, 0.0246099624782801, 4.20779288106132e-5, 2.31990285101347e-4, 1.01877601991873e-4, 1.02140506896831e-6, 4.58338035969064e-7, 3.38780637321179e-6, 3.69359349861043e-6, 9.96966150523804e-7, 2.29560191655764e-5] + }, + "fFlag" : 0, + "fChi2" : 1.32319784164429, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1768, 1831, 471, 766, 974, 1414, 1480, 1578], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.36828136444092, + "fY" : -0.453498303890228, + "fZ" : 33.2939987182617, + "fTx" : -0.0959276705980301, + "fTy" : -0.0285605732351542, + "fQp" : 0.165866121649742, + "fCovMatrix" : [1.36803573695943e-4, 5.3773820400238e-4, -5.17474018124631e-6, -3.6998362702434e-6, 9.60905708780047e-6, 0.0247320514172316, -2.49111944867764e-5, -1.74587636138313e-4, 7.60740076657385e-5, 6.40066389223648e-7, 1.60146484518009e-7, -8.24300684598711e-7, 2.28267299462459e-6, -5.28317059433903e-7, 8.68895767780486e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -14.5694913864136, + "fY" : -6.65738916397095, + "fZ" : 248.485992431641, + "fTx" : -0.0104469852522016, + "fTy" : -0.029131792485714, + "fQp" : 0.166121900081635, + "fCovMatrix" : [9.30208479985595e-4, -0.00101866282057017, 1.61596672114683e-5, -8.17098771221936e-6, 4.52994027000386e-5, 0.0186960771679878, -1.66406480275327e-5, 1.3092921290081e-4, -4.22760458604898e-5, 5.84355689170479e-7, -1.87937203577349e-7, 1.65296296472661e-6, 1.55595296291722e-6, -5.9433574506329e-7, 8.71440352057107e-6] + }, + "fFlag" : 0, + "fChi2" : 1.48762679100037, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1601, 1655, 1736, 1809, 699, 836, 1038, 1345], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.85181069374084, + "fY" : -2.45643901824951, + "fZ" : 15.9584999084473, + "fTx" : 0.241178929805756, + "fTy" : -0.163667619228363, + "fQp" : 0.25532478094101, + "fCovMatrix" : [1.48446240928024e-4, -0.00158200669102371, -5.49221476831008e-6, 1.17448435048573e-5, 1.96525179489981e-5, 0.0678103491663933, 2.29246252274606e-5, -5.2765931468457e-4, -2.77748713415349e-5, 4.39525621231951e-7, -1.38289337314745e-7, -1.79930907506787e-6, 4.96373559144558e-6, -6.69981119472141e-8, 1.58070597535698e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 55.0374336242676, + "fY" : -31.1423664093018, + "fZ" : 186.27587890625, + "fTx" : 0.366489827632904, + "fTy" : -0.175483256578445, + "fQp" : 0.255306541919708, + "fCovMatrix" : [0.00105818000156432, -0.00150494289118797, 2.36668620345881e-5, -1.8978571461048e-5, 6.11486830166541e-5, 0.023076020181179, -3.95588904211763e-5, 2.58579704677686e-4, -8.41691216919571e-5, 1.04949799606402e-6, -4.62299027503832e-7, 2.83598228634219e-6, 4.9294499149255e-6, -7.70337180711067e-7, 1.57309768837877e-5] + }, + "fFlag" : 0, + "fChi2" : 5.11094665527344, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509940368, + "fStsHits" : [1616, 1695, 1773, 460, 771, 969, 1154, 1412], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.44671630859375, + "fY" : -1.43176901340485, + "fZ" : 16.1784992218018, + "fTx" : -0.372697472572327, + "fTy" : -0.0688439831137657, + "fQp" : 1.17891657352448, + "fCovMatrix" : [1.88983511179686e-4, 0.0015832909848541, -1.23509471450234e-5, -2.19342946365941e-5, 1.75969016709132e-5, 0.0622915513813496, -5.95990131841972e-5, -9.39551973715425e-4, 2.01952090719715e-4, 2.23867687054735e-6, 8.13113956610323e-7, -5.18520164405345e-6, 2.46821564360289e-5, -3.19497144118941e-6, 2.40546825807542e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.1258335113525, + "fY" : -11.6612462997437, + "fZ" : 185.833938598633, + "fTx" : 0.142297178506851, + "fTy" : -0.054171446710825, + "fQp" : 1.1889933347702, + "fCovMatrix" : [0.00134163885377347, -0.00245691742748022, 5.10454046889208e-5, -3.7505309592234e-5, 1.53668865095824e-4, 0.0273020192980766, -1.37132912641391e-4, 3.72970214812085e-4, -3.93421592889354e-4, 5.40775272384053e-6, -1.81297491508303e-6, 1.40981837830623e-5, 1.20690865514916e-5, -4.63336573375273e-6, 2.43694987148046e-4] + }, + "fFlag" : 0, + "fChi2" : 24.6987056732178, + "fNDF" : 11, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1656, 1737, 1815, 308, 704, 833, 1343], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.57648801803589, + "fY" : -3.68273878097534, + "fZ" : 24.511999130249, + "fTx" : 0.195369839668274, + "fTy" : -0.178091257810593, + "fQp" : 0.371276766061783, + "fCovMatrix" : [1.40133095555939e-4, -9.54277405980974e-4, -5.58432475372683e-6, 9.50169487623498e-6, 1.68482984008733e-5, 0.0459047444164753, -6.16809393250151e-6, -4.74974774988368e-4, 1.03478741948493e-4, 6.33763249879848e-7, 7.57914335736132e-8, -2.27954933507135e-6, 6.80246739648283e-6, -1.7073256231015e-6, 2.84394482150674e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.4424476623535, + "fY" : -33.5017509460449, + "fZ" : 186.244964599609, + "fTx" : 0.368892908096313, + "fTy" : -0.193302035331726, + "fQp" : 0.372141301631927, + "fCovMatrix" : [0.00215255655348301, -0.00685461703687906, 3.92403235309757e-5, -6.76833660691045e-5, 9.6430660050828e-5, 0.0515968352556229, -1.1207955685677e-4, 5.03702322021127e-4, -2.41851797909476e-4, 1.51022993577499e-6, -1.23772463211935e-6, 4.18293348047882e-6, 6.72852365823928e-6, -2.80614221992437e-6, 2.82885594060645e-5] + }, + "fFlag" : 0, + "fChi2" : 0.71911495923996, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1582, 1627, 1700, 1786, 190, 566, 797], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.91899347305298, + "fY" : 2.11925148963928, + "fZ" : 18.9384994506836, + "fTx" : 0.282313615083694, + "fTy" : 0.0963860377669334, + "fQp" : 1.24172008037567, + "fCovMatrix" : [1.8620268383529e-4, 0.00177033746149391, -1.06157103800797e-5, -2.47538027906558e-5, 4.88820041937288e-5, 0.0877573862671852, -1.10954943011166e-5, -0.00125766696874052, -1.21624769235495e-4, 2.3399172732752e-6, 1.71174647789485e-7, -1.06720299299923e-5, 2.53151047218125e-5, 6.96951656209421e-6, 3.55073425453156e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 58.0685119628906, + "fY" : 13.1218519210815, + "fZ" : 128.266860961914, + "fTx" : 0.735637307167053, + "fTy" : 0.110303997993469, + "fQp" : 1.2478494644165, + "fCovMatrix" : [0.00186582887545228, 0.00535924965515733, 7.37560476409271e-5, 9.87442472251132e-5, 2.09176956559531e-4, 0.0458656288683414, 2.62276356806979e-4, 7.90530757512897e-4, 7.02802964951843e-4, 8.63070454215631e-6, 4.20958849645103e-6, 2.75256006716518e-5, 2.33199843933107e-5, 9.57082284003263e-6, 3.41619132086635e-4] + }, + "fFlag" : 0, + "fChi2" : 2.624995470047, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1581, 1624, 1699, 1779, 192, 801, 979], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 7.30123615264893, + "fY" : 3.61234211921692, + "fZ" : 18.9384994506836, + "fTx" : 0.400299787521362, + "fTy" : 0.171811938285828, + "fQp" : 0.586377561092377, + "fCovMatrix" : [1.71267107361928e-4, 0.00129874085541815, -8.0822110248846e-6, -1.52227730723098e-5, 3.39580110448878e-5, 0.0674368962645531, 3.79077096113178e-6, -6.51829701382667e-4, 5.75321028009057e-5, 9.65329036262119e-7, 3.30068502307768e-7, -4.19109483118518e-6, 9.42516362556489e-6, -3.72629028788651e-6, 6.94321570335887e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 79.3677291870117, + "fY" : 28.174129486084, + "fZ" : 154.960510253906, + "fTx" : 0.673740983009338, + "fTy" : 0.198277235031128, + "fQp" : 0.583659291267395, + "fCovMatrix" : [0.00126076629385352, -0.00243792682886124, 4.26691185566597e-5, -2.5351766453241e-5, 1.08721644210164e-4, 0.0306138880550861, -1.34073343360797e-4, 3.3120164880529e-4, -3.81166988518089e-4, 3.79051311938383e-6, -5.50403228771756e-7, 8.82440872373991e-6, 8.84583005245076e-6, -1.61029106493515e-6, 6.83862963342108e-5] + }, + "fFlag" : 0, + "fChi2" : 2.89603352546692, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [1693, 1777, 1839, 731, 956, 1142, 1389], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -14.4623870849609, + "fY" : -0.987330555915833, + "fZ" : 23.6770000457764, + "fTx" : -0.579053103923798, + "fTy" : -0.0570501871407032, + "fQp" : 0.863117575645447, + "fCovMatrix" : [1.97907516849227e-4, 0.00209042918868363, -1.04955170172616e-5, -2.81542670563795e-5, 2.24658724619076e-5, 0.101877294480801, -2.67292525677476e-5, -0.00128722749650478, 6.64381601382047e-4, 1.71738327026105e-6, 7.05982927229343e-7, -6.41472115603392e-6, 2.64421905740164e-5, -5.25053610545001e-6, 2.37592685152777e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -74.1618881225586, + "fY" : -8.63301086425781, + "fZ" : 185.569320678711, + "fTx" : -0.184854105114937, + "fTy" : -0.0359268859028816, + "fQp" : 0.860927820205688, + "fCovMatrix" : [0.00133630225900561, -0.00249010743573308, 4.98670633533038e-5, -3.79545454052277e-5, 1.97672576177865e-4, 0.0283685196191072, -1.33573688799515e-4, 3.96652292693034e-4, -5.11784397531301e-4, 4.70526947538019e-6, -1.85892827175849e-6, 1.6102258086903e-5, 1.1450300917204e-5, -7.41731901143794e-6, 2.47276970185339e-4] + }, + "fFlag" : 0, + "fChi2" : 8.69698905944824, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1605, 1662, 1753, 1819, 263, 705], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.962284207344055, + "fY" : -4.97440195083618, + "fZ" : 14.7185001373291, + "fTx" : 0.0764660537242889, + "fTy" : -0.379733800888062, + "fQp" : 0.857872784137726, + "fCovMatrix" : [2.0666402997449e-4, -0.00249408837407827, -1.17340641736519e-5, 4.41386764578056e-5, 1.09821899968665e-4, 0.116383440792561, 5.1216109568486e-5, -0.00188099266961217, -0.00108879338949919, 1.76009689312195e-6, -1.69761813140212e-6, -1.46356633194955e-5, 3.91918038076255e-5, 3.63967665180098e-5, 4.03767073294148e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 14.6517648696899, + "fY" : -36.9337005615234, + "fZ" : 97.2979049682617, + "fTx" : 0.267938584089279, + "fTy" : -0.39751985669136, + "fQp" : 0.858786880970001, + "fCovMatrix" : [0.0020041186362505, 0.0062880627810955, 7.17065486242063e-5, 1.29548876429908e-4, 4.24215395469218e-4, 0.0527210347354412, 2.48639262281358e-4, 0.00104399619158357, 0.00170484441332519, 5.03440105603659e-6, 3.60055105375068e-6, 3.17915582854766e-5, 3.6310881114332e-5, 2.93589273496764e-5, 4.00858378270641e-4] + }, + "fFlag" : 0, + "fChi2" : 0.89791738986969, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [721, 953, 1110, 1355, 1471, 1516], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.25988674163818, + "fY" : -6.55236673355103, + "fZ" : 97.2322540283203, + "fTx" : 0.112791605293751, + "fTy" : -0.0707813948392868, + "fQp" : 0.232450231909752, + "fCovMatrix" : [0.00117024907376617, 0.00171570701058954, -3.07101399812382e-5, -1.84520740731386e-5, 1.22394587378949e-4, 0.0223012287169695, -6.06233661528677e-5, -2.12679311516695e-4, 2.77405692031607e-4, 1.42863052587927e-6, 7.09916434971092e-7, -6.28078259978793e-6, 3.08710696117487e-6, -3.51495418726699e-6, 3.8643669540761e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.1994171142578, + "fY" : -17.4566535949707, + "fZ" : 248.743057250977, + "fTx" : 0.199927106499672, + "fTy" : -0.0728905349969864, + "fQp" : 0.232502847909927, + "fCovMatrix" : [0.00115935911890119, -0.0017235407140106, 2.88825049210573e-5, -1.94963467947673e-5, 1.19995631393977e-4, 0.0224260333925486, -5.84204062761273e-5, 2.16226137126796e-4, -2.78120045550168e-4, 1.31434103423089e-6, -7.26508289972116e-7, 5.67927645533928e-6, 3.21425773108786e-6, -3.81498466595076e-6, 3.85692983400077e-5] + }, + "fFlag" : 0, + "fChi2" : 0.997307777404785, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1666, 1746, 1823, 253, 710, 831], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.429752796888351, + "fY" : -5.56902074813843, + "fZ" : 23.511999130249, + "fTx" : 0.0281199067831039, + "fTy" : -0.262201458215714, + "fQp" : 0.450742155313492, + "fCovMatrix" : [1.71506268088706e-4, -0.00138802453875542, -9.07607409317279e-6, 1.67480648087803e-5, 5.69293915759772e-5, 0.0817670300602913, -4.9255042540608e-5, -0.00110312970355153, 7.15361966285855e-4, 1.35715686155891e-6, 8.7630496636848e-7, -1.01259338407544e-5, 1.81684117706027e-5, -1.32359300550888e-5, 1.45553101901896e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.8525915145874, + "fY" : -31.998348236084, + "fZ" : 123.511558532715, + "fTx" : 0.144777610898018, + "fTy" : -0.267102360725403, + "fQp" : 0.451087117195129, + "fCovMatrix" : [0.0014291099505499, -0.0032419697381556, 4.93956431455445e-5, -6.88998552504927e-5, 2.42930182139389e-4, 0.0350515246391296, -1.43318975460716e-4, 6.34233001619577e-4, -6.86827290337533e-4, 3.12987617689942e-6, -3.23209337693697e-6, 1.69907871168107e-5, 1.81877385330154e-5, -1.51279182318831e-5, 1.4542366261594e-4] + }, + "fFlag" : 0, + "fChi2" : 1.26801037788391, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1609, 1664, 1757, 1824, 447, 725], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.958474099636078, + "fY" : -4.00479793548584, + "fZ" : 14.7185001373291, + "fTx" : 0.0282110013067722, + "fTy" : -0.316333919763565, + "fQp" : -1.62459671497345, + "fCovMatrix" : [2.16376312891953e-4, -0.00255327112972736, -1.41942136906437e-5, 4.57001624454278e-5, 9.58225573413074e-5, 0.11887838691473, 5.26813673786819e-5, -0.00199402496218681, 1.80576505954377e-4, 3.50398408954788e-6, -1.71135047821735e-6, -2.37921722145984e-5, 4.77122339361813e-5, 1.63027780217817e-5, 0.00108523073140532] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.2619371414185, + "fY" : -30.3149681091309, + "fZ" : 97.207145690918, + "fTx" : -0.3241907954216, + "fTy" : -0.32882833480835, + "fQp" : -1.62593746185303, + "fCovMatrix" : [0.00208903150632977, 0.00674401968717575, 8.48563431645744e-5, 1.50043764733709e-4, 4.01053373934701e-4, 0.0551445372402668, 3.204517706763e-4, 0.00114413211122155, 0.00138048059307039, 1.01180758065311e-5, 5.6384528761555e-6, 6.00225175730884e-5, 4.38956740254071e-5, 1.84727196028689e-5, 0.00107722356915474] + }, + "fFlag" : 0, + "fChi2" : 2.50778245925903, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1657, 1743, 1816, 307, 701, 834], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.46813249588013, + "fY" : -4.90692043304443, + "fZ" : 24.511999130249, + "fTx" : 0.192595615983009, + "fTy" : -0.224652722477913, + "fQp" : 0.495586484670639, + "fCovMatrix" : [1.72917585587129e-4, -0.00137926626484841, -9.14703650778392e-6, 1.71005558513571e-5, 5.57157072762493e-5, 0.0805980414152145, -4.74049120384734e-5, -0.00109869404695928, 6.4483133610338e-4, 1.33415574055107e-6, 8.18372313915461e-7, -1.00341840152396e-5, 1.8302867829334e-5, -1.19414598884759e-5, 1.43495824886486e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 30.012149810791, + "fY" : -27.715295791626, + "fZ" : 123.628150939941, + "fTx" : 0.329684227705002, + "fTy" : -0.236884519457817, + "fQp" : 0.496926605701447, + "fCovMatrix" : [0.00145258323755115, -0.0033528795465827, 5.184545807424e-5, -7.23689227015711e-5, 2.35452040215023e-4, 0.0356061942875385, -1.54099107021466e-4, 6.50815549306571e-4, -6.81751174852252e-4, 3.47621858054481e-6, -3.51407697962713e-6, 1.70653893292183e-5, 1.8816896044882e-5, -1.5315948985517e-5, 1.42825228977017e-4] + }, + "fFlag" : 0, + "fChi2" : 5.73322486877441, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509944048, + "fStsHits" : [1604, 1662, 1754, 1820, 259, 707], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.00981318950653, + "fY" : -5.04285573959351, + "fZ" : 14.7185001373291, + "fTx" : 0.0774484053254128, + "fTy" : -0.38495859503746, + "fQp" : 0.491351902484894, + "fCovMatrix" : [2.02897266717628e-4, -0.00245960406027734, -1.08946769614704e-5, 4.33608802268282e-5, 1.04796490631998e-4, 0.115326032042503, 4.9168236728292e-5, -0.00183966604527086, -9.66426974628121e-4, 1.25384838156606e-6, -1.6737062651373e-6, -1.2068853720848e-5, 3.64447005267721e-5, 3.21440202242229e-5, 2.2832109243609e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 11.5724449157715, + "fY" : -37.1252288818359, + "fZ" : 97.2810516357422, + "fTx" : 0.184642106294632, + "fTy" : -0.393206566572189, + "fQp" : 0.491282910108566, + "fCovMatrix" : [0.0019843983463943, 0.00619267066940665, 6.76561103318818e-5, 1.29911699332297e-4, 4.06330276746303e-4, 0.0522433407604694, 2.30213481700048e-4, 0.00104126078076661, 0.00156744290143251, 3.52676556758524e-6, 3.81714471586747e-6, 2.33595692407107e-5, 3.48855210177135e-5, 2.8559716156451e-5, 2.27711803745478e-4] + }, + "fFlag" : 0, + "fChi2" : 7.03528499603271, + "fNDF" : 7, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1039371012, + "fStsHits" : [765, 975, 1149, 1417, 1577], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.75026273727417, + "fY" : -5.4413857460022, + "fZ" : 97.2235488891602, + "fTx" : 0.00724998163059354, + "fTy" : -0.0642959550023079, + "fQp" : 0.211119934916496, + "fCovMatrix" : [0.00117649475578219, 0.00176432740408927, -3.10638570226729e-5, -2.034405588347e-5, 1.29306718008593e-4, 0.0234715472906828, -6.32680676062591e-5, -2.56088271271437e-4, 3.33813339238986e-4, 1.4295483197202e-6, 8.16821227545006e-7, -6.65486368234269e-6, 4.64160257251933e-6, -5.36914512849762e-6, 4.19976058765315e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.39248609542847, + "fY" : -15.2550344467163, + "fZ" : 248.595626831055, + "fTx" : 0.0840076804161072, + "fTy" : -0.0652276128530502, + "fQp" : 0.211302027106285, + "fCovMatrix" : [0.00215878384187818, -0.00652850000187755, 4.08105552196503e-5, -5.81041713303421e-5, 1.60905838129111e-4, 0.0475969351828098, -1.20058350148611e-4, 4.1928852442652e-4, -4.92834951728582e-4, 1.36078983814514e-6, -1.21245784612256e-6, 6.16464149061358e-6, 4.7944809011824e-6, -5.55816268388298e-6, 4.20562355429865e-5] + }, + "fFlag" : 0, + "fChi2" : 0.207960084080696, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -2033030591, + "fStsHits" : [1590, 1646, 1726, 1803, 208], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.34458017349243, + "fY" : 2.0635199546814, + "fZ" : 19.0084991455078, + "fTx" : -0.369900912046432, + "fTy" : 0.0637445524334908, + "fQp" : -1.67988467216492, + "fCovMatrix" : [2.78333347523585e-4, -0.00444477424025536, -1.9564025933505e-5, 1.10813583887648e-4, 2.54579092143103e-4, 0.199755907058716, 1.42027798574418e-4, -0.00469854427501559, -0.00203349813818932, 4.77896810480161e-6, -6.82736936141737e-6, -6.56101910863072e-5, 1.42291624797508e-4, 1.47602855577134e-4, 0.00213012704625726] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -29.1511573791504, + "fY" : 5.16933584213257, + "fZ" : 65.8757781982422, + "fTx" : -0.621299684047699, + "fTy" : 0.0697667375206947, + "fQp" : -1.68280816078186, + "fCovMatrix" : [0.00207065301947296, 0.00739669566974044, 1.5232952137012e-4, 2.03452989808284e-4, 0.00115508679300547, 0.0626869574189186, 5.78183040488511e-4, 0.00173771800473332, 0.00466901436448097, 1.66032168635866e-5, 1.37709239425021e-5, 1.00848628790118e-4, 1.44337231176905e-4, 1.39568408485502e-4, 0.00202691182494164] + }, + "fFlag" : 0, + "fChi2" : 0.227177545428276, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 804756743, + "fStsHits" : [830, 1016, 1341, 1460, 1513], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.858320772647858, + "fY" : 6.28393602371216, + "fZ" : 128.181015014648, + "fTx" : 0.0218003634363413, + "fTy" : 0.0314105115830898, + "fQp" : 0.173579782247543, + "fCovMatrix" : [0.00124174356460571, 0.00186171405948699, -3.65540909115225e-5, -1.86703055078397e-5, 1.78873349796049e-4, 0.0248651541769505, -5.55277656530961e-5, -2.76516511803493e-4, 2.27594617172144e-4, 2.0022507669637e-6, 2.58518213058778e-7, -1.19733213068685e-5, 4.80156813864596e-6, 8.01276428319397e-7, 8.51308141136542e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.86859655380249, + "fY" : 10.1788835525513, + "fZ" : 253.266006469727, + "fTx" : 0.0719021633267403, + "fTy" : 0.030917601659894, + "fQp" : 0.17361880838871, + "fCovMatrix" : [0.00144070305395871, 0.00268978602252901, 3.8227914046729e-5, 2.6859030185733e-5, 1.96151857380755e-4, 0.0287036336958408, 7.1467540692538e-5, 3.07969428831711e-4, 3.20376071613282e-4, 1.76498826931493e-6, 4.9620382469584e-7, 1.0976058547385e-5, 4.83661369798938e-6, 7.20734192327654e-7, 8.51301738293841e-5] + }, + "fFlag" : 0, + "fChi2" : 0.441367298364639, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1784436488, + "fStsHits" : [1633, 1705, 1792, 251, 684], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.196990102529526, + "fY" : 4.10607433319092, + "fZ" : 28.9860000610352, + "fTx" : 2.31513069593348e-4, + "fTy" : 0.118222609162331, + "fQp" : 0.258941113948822, + "fCovMatrix" : [2.31129874009639e-4, 0.00292214122600853, -1.58259845193243e-5, -6.40172074781731e-5, 2.03543633688241e-4, 0.140206709504128, -5.95078163314611e-5, -0.00282353395596147, 0.0014167760964483, 2.27871191782469e-6, 2.79866867458622e-6, -3.25443397741765e-5, 6.69783912599087e-5, -6.38097335468046e-5, 5.69196708966047e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.04422128200531, + "fY" : 11.5715970993042, + "fZ" : 92.2562408447266, + "fTx" : 0.0397122837603092, + "fTy" : 0.117785260081291, + "fQp" : 0.259079456329346, + "fCovMatrix" : [0.0019244517898187, -0.00591123849153519, 8.24297530925833e-5, -1.79509283043444e-4, 7.10876774974167e-4, 0.0508608967065811, -2.78832420008257e-4, 0.00141337746754289, -0.00265289493836462, 5.02301281812834e-6, -6.6773113758245e-6, 5.02329530718271e-5, 6.71694069751538e-5, -6.46529588266276e-5, 5.70721633266658e-4] + }, + "fFlag" : 0, + "fChi2" : 0.969777345657349, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2111848766, + "fStsHits" : [1741, 1812, 303, 719, 954], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.863436460495, + "fY" : -2.1556568145752, + "fZ" : 33.2039985656738, + "fTx" : 0.129835516214371, + "fTy" : -0.0879562199115753, + "fQp" : 0.433623850345612, + "fCovMatrix" : [1.83617870789021e-4, -0.00140847999136895, -1.03897600638447e-5, 1.92811603483278e-5, 5.59829240955878e-5, 0.0814942494034767, -1.10115513962228e-4, -0.00126815272960812, 0.00147929741069674, 2.54401743404742e-6, 2.19742628360109e-6, -1.96452256204793e-5, 2.49728036578745e-5, -3.28479363815859e-5, 3.4016027348116e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 20.04958152771, + "fY" : -10.2683620452881, + "fZ" : 123.573219299316, + "fTx" : 0.231167927384377, + "fTy" : -0.0918390303850174, + "fQp" : 0.433601051568985, + "fCovMatrix" : [0.00166628626175225, -0.00440471712499857, 7.23644261597656e-5, -9.8583557701204e-5, 4.49243234470487e-4, 0.0411870628595352, -2.49812321271747e-4, 8.06081690825522e-4, -0.00164000503718853, 5.4716306294722e-6, -5.69700978303445e-6, 3.84218983526807e-5, 2.34642557188636e-5, -3.62011523975525e-5, 3.3855639048852e-4] + }, + "fFlag" : 0, + "fChi2" : 1.28278923034668, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -583166863, + "fStsHits" : [820, 1018, 1340, 1459, 1514], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.18088924884796, + "fY" : 7.13062906265259, + "fZ" : 128.181015014648, + "fTx" : 0.0525054931640625, + "fTy" : 0.0577929578721523, + "fQp" : 0.223693534731865, + "fCovMatrix" : [0.00124389829579741, 0.00187493627890944, -3.67922184523195e-5, -1.9085904568783e-5, 1.77849171450362e-4, 0.0249385163187981, -5.70193769817706e-5, -2.78742809314281e-4, 2.31804602663033e-4, 2.05450055545953e-6, 2.91427767251662e-7, -1.19767664727988e-5, 4.92232766191592e-6, 6.38823962617607e-7, 8.7709297076799e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.65340137481689, + "fY" : 14.3349628448486, + "fZ" : 253.266006469727, + "fTx" : 0.11790207028389, + "fTy" : 0.0574194453656673, + "fQp" : 0.22418674826622, + "fCovMatrix" : [0.00144579424522817, 0.00271411100402474, 3.87558866350446e-5, 2.74546582659241e-5, 1.94436361198314e-4, 0.0288186054676771, 7.36644433345646e-5, 3.11019335640594e-4, 3.17794881993905e-4, 1.83949623533408e-6, 5.32548142473388e-7, 1.09920383692952e-5, 4.97932387588662e-6, 7.55248663608654e-7, 8.79240033100359e-5] + }, + "fFlag" : 0, + "fChi2" : 7.09661912918091, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 2107400207, + "fStsHits" : [1592, 1640, 1710, 207, 681], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.00900554656982, + "fY" : 5.7161545753479, + "fZ" : 19.0084991455078, + "fTx" : -0.156598970293999, + "fTy" : 0.305210292339325, + "fQp" : 2.57373809814453, + "fCovMatrix" : [2.5570543948561e-4, -0.00347107835114002, -1.94583844859153e-5, 6.41185470158234e-5, 1.35626905830577e-4, 0.153904005885124, 7.85877928137779e-5, -0.0029579671099782, 0.00157759909052402, 7.68603149481351e-6, -2.09810787055176e-6, -7.30215760995634e-5, 8.75331534189172e-5, -5.53514037164859e-5, 0.00436392892152071] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.69932627677917, + "fY" : 27.9923896789551, + "fZ" : 92.2562408447266, + "fTx" : 0.326712906360626, + "fTy" : 0.314964473247528, + "fQp" : 2.5777063369751, + "fCovMatrix" : [0.0019453507848084, -0.00591527670621872, 1.0935653699562e-4, -1.62201758939773e-4, 7.15228088665754e-4, 0.0500840172171593, -4.09632222726941e-4, 0.00128573877736926, -0.00303747202269733, 2.28120879910421e-5, -3.43982901540585e-6, 1.61356016178615e-4, 7.76000015321188e-5, -4.8420228267787e-5, 0.00437125051394105] + }, + "fFlag" : 0, + "fChi2" : 12.9892539978027, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 1146774797, + "fStsHits" : [1639, 1722, 241, 686, 1006], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.33991861343384, + "fY" : 3.3494861125946, + "fZ" : 28.9860000610352, + "fTx" : -0.0734212100505829, + "fTy" : 0.18664975464344, + "fQp" : 0.457632958889008, + "fCovMatrix" : [1.37585622724146e-4, 3.231153532397e-4, -7.759179425193e-6, -4.15190743296989e-6, 3.29127615259495e-5, 0.0465634614229202, -3.26022345689125e-5, -6.06094661634415e-4, 3.92252404708415e-4, 1.48185415582702e-6, 4.88209195736999e-7, -5.9483263612492e-6, 1.23654426715802e-5, -7.32584976503858e-6, 1.02529127616435e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.85358667373657, + "fY" : 26.7497463226318, + "fZ" : 154.893341064453, + "fTx" : 0.0682987794280052, + "fTy" : 0.18551504611969, + "fQp" : 0.458666443824768, + "fCovMatrix" : [0.00234777061268687, -0.00808644108474255, 4.71720522909891e-5, -8.98432699614204e-5, 1.90876264241524e-4, 0.0612202808260918, -1.42043427331373e-4, 6.91099616233259e-4, -5.6737702107057e-4, 2.28793101086922e-6, -1.78430468622537e-6, 1.14754893729696e-5, 1.07599435068551e-5, -7.92009814176708e-6, 1.02951998997014e-4] + }, + "fFlag" : 0, + "fChi2" : 18.1715698242188, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1002, 1300, 1449, 1497], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.73212194442749, + "fY" : 7.62100839614868, + "fZ" : 154.930511474609, + "fTx" : 0.0688236728310585, + "fTy" : 0.0455737896263599, + "fQp" : 0.193551555275917, + "fCovMatrix" : [0.00191372714471072, -0.00537101458758116, -7.67493256716989e-5, 8.98420912562869e-5, 5.31863130163401e-4, 0.0446399599313736, 2.74645746685565e-4, -6.9100089604035e-4, -0.00216327188536525, 4.91318405693164e-6, -5.14892190039973e-6, -3.9024405850796e-5, 1.41200571306399e-5, 4.36181217082776e-5, 3.39367223205045e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.7385778427124, + "fY" : 12.0891809463501, + "fZ" : 253.266006469727, + "fTx" : 0.112201519310474, + "fTy" : 0.0453274585306644, + "fQp" : 0.193596020340919, + "fCovMatrix" : [0.00188012362923473, 0.00521380174905062, 6.9455367338378e-5, 8.78330101841129e-5, 5.20087778568268e-4, 0.0439235866069794, 2.43776274146512e-4, 6.81218691170216e-4, 0.00210053799673915, 4.06200524594169e-6, 4.60243154520867e-6, 3.49099573213607e-5, 1.40494394145207e-5, 4.31489788752515e-5, 3.39114689268172e-4] + }, + "fFlag" : 0, + "fChi2" : 0.411130547523499, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1019, 1337, 1466, 1510], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.7900447845459, + "fY" : 1.92675232887268, + "fZ" : 154.863342285156, + "fTx" : 0.0236554350703955, + "fTy" : 0.0151996146887541, + "fQp" : 0.308184832334518, + "fCovMatrix" : [0.00191863265354186, -0.00539835495874286, -7.74139843997546e-5, 9.04433109099045e-5, 5.40200329851359e-4, 0.0447931326925755, 2.78089544735849e-4, -6.94478861987591e-4, -0.00220557954162359, 5.05971138409222e-6, -5.19395143783186e-6, -4.01898687414359e-5, 1.43396091516479e-5, 4.43324133811984e-5, 3.64607170922682e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0862729549408, + "fY" : 3.39191007614136, + "fZ" : 253.266006469727, + "fTx" : 0.0919949263334274, + "fTy" : 0.0146251767873764, + "fQp" : 0.308357298374176, + "fCovMatrix" : [0.00187728903256357, 0.00520153529942036, 6.91362147335894e-5, 8.78545251907781e-5, 5.24696835782379e-4, 0.0438745133578777, 2.42525129579008e-4, 6.81901117786765e-4, 0.00212102546356618, 4.1156172301271e-6, 4.55953340861015e-6, 3.50678055838216e-5, 1.42927547130967e-5, 4.36515038018115e-5, 3.64597100997344e-4] + }, + "fFlag" : 0, + "fChi2" : 0.453778833150864, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [999, 1303, 1448, 1498], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.75856113433838, + "fY" : 5.29568672180176, + "fZ" : 154.930511474609, + "fTx" : 0.0780638679862022, + "fTy" : 0.0281242504715919, + "fQp" : 0.0756367072463036, + "fCovMatrix" : [0.00191509409341961, -0.00537667190656066, -7.70171245676465e-5, 8.98398866411299e-5, 5.36072591785342e-4, 0.0446596220135689, 2.75755912298337e-4, -6.90656190272421e-4, -0.00218208692967892, 4.90661386720603e-6, -5.17673879585345e-6, -3.91841604141518e-5, 1.40340262078098e-5, 4.40198164142203e-5, 3.35204240400344e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 17.3073558807373, + "fY" : 8.05453491210938, + "fZ" : 253.266006469727, + "fTx" : 0.0948937758803368, + "fTy" : 0.0280081648379564, + "fQp" : 0.0756424963474274, + "fCovMatrix" : [0.00187675538472831, 0.00519617134705186, 6.89028020133264e-5, 8.74576508067548e-5, 5.23877679370344e-4, 0.0438308529555798, 2.41132453083992e-4, 6.78879441693425e-4, 0.00211673392914236, 3.9582828321727e-6, 4.5645338104805e-6, 3.49516412825324e-5, 1.38887553475797e-5, 4.35075889981817e-5, 3.35134332999587e-4] + }, + "fFlag" : 0, + "fChi2" : 0.495197772979736, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [1109, 1357, 1472, 1571], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 22.9461498260498, + "fY" : -2.31094193458557, + "fZ" : 159.739318847656, + "fTx" : 0.188223868608475, + "fTy" : -0.0197214782238007, + "fQp" : 0.227153733372688, + "fCovMatrix" : [0.00179139547981322, 0.00477984780445695, -9.2383568699006e-5, -9.00091908988543e-5, 7.05861079040915e-4, 0.0414791218936443, -3.37911857059225e-4, -6.96462811902165e-4, 0.00288166361860931, 7.74141426518327e-6, 6.99613701726776e-6, -6.60418736515567e-5, 1.56029600475449e-5, -6.25387256150134e-5, 6.03570078965276e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 41.9540824890137, + "fY" : -4.10293197631836, + "fZ" : 248.796600341797, + "fTx" : 0.235984206199646, + "fTy" : -0.0203404352068901, + "fQp" : 0.227200746536255, + "fCovMatrix" : [0.00174356333445758, -0.00458400696516037, 8.15501189208589e-5, -8.98631260497496e-5, 6.81965495459735e-4, 0.0407083556056023, -2.93669785605744e-4, 6.95800816174597e-4, -0.00278137647546828, 6.21894605501438e-6, -6.38650772089022e-6, 5.82726097491104e-5, 1.60044910444412e-5, -6.40857906546444e-5, 6.02325773797929e-4] + }, + "fFlag" : 0, + "fChi2" : 0.698075890541077, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [810, 992, 1291, 1423], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 22.281042098999, + "fY" : 11.1978244781494, + "fZ" : 128.236862182617, + "fTx" : 0.213279917836189, + "fTy" : 0.0798255801200867, + "fQp" : 0.304712682962418, + "fCovMatrix" : [0.0017848601564765, 0.00476990174502134, -8.87135829543695e-5, -9.23507905099541e-5, 6.37873541563749e-4, 0.0415498688817024, -3.24260152410716e-4, -7.0833828067407e-4, 0.00262450193986297, 7.20816069588182e-6, 6.92722278472502e-6, -5.76723614358343e-5, 1.62298274517525e-5, -5.90791678405367e-5, 5.1123951561749e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.484375, + "fY" : 18.3676624298096, + "fZ" : 217.384552001953, + "fTx" : 0.284152507781982, + "fTy" : 0.0814678445458412, + "fQp" : 0.305033385753632, + "fCovMatrix" : [0.00175817660056055, -0.00463350908830762, 8.5848179878667e-5, -8.76575941219926e-5, 6.27167988568544e-4, 0.0408595725893974, -3.1003967160359e-4, 6.86733517795801e-4, -0.00256027095019817, 6.89906937623164e-6, -6.45210820948705e-6, 5.61424931220245e-5, 1.5617781173205e-5, -5.63507528568152e-5, 5.09658188093454e-4] + }, + "fFlag" : 0, + "fChi2" : 1.08289587497711, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [819, 1004, 1324, 1489], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.48127460479736, + "fY" : 14.1055374145508, + "fZ" : 128.181015014648, + "fTx" : 0.0669111758470535, + "fTy" : 0.106525674462318, + "fQp" : 0.562852263450623, + "fCovMatrix" : [0.00135837646666914, 0.00231276173144579, -4.58314134448301e-5, -3.72795839211904e-5, 2.04240073799156e-4, 0.0267512481659651, -9.33977207751013e-5, -3.52231087163091e-4, 3.5840822965838e-4, 3.15209990731091e-6, 1.46359877817304e-6, -1.48442813951988e-5, 9.25817039387766e-6, -3.60681519850914e-6, 1.43416997161694e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.8721809387207, + "fY" : 27.4688682556152, + "fZ" : 253.266006469727, + "fTx" : 0.239092364907265, + "fTy" : 0.106934949755669, + "fQp" : 0.564698278903961, + "fCovMatrix" : [0.00229982333257794, 0.00780216185376048, 4.0141665522242e-5, 7.67691526561975e-5, 1.28212152048945e-4, 0.0601321943104267, 8.49204225232825e-5, 6.12380274105817e-4, 5.99656232225243e-6, 2.48483934228716e-6, 8.56475082855468e-7, 1.06208335637348e-5, 9.37485037866281e-6, -1.77873027951136e-6, 1.43166267662309e-4] + }, + "fFlag" : 0, + "fChi2" : 1.11068141460419, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [639, 803, 1001, 1339], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.4885950088501, + "fY" : 3.8629424571991, + "fZ" : 92.2331237792969, + "fTx" : -0.0242228172719479, + "fTy" : 0.0985142067074776, + "fQp" : -0.330903857946396, + "fCovMatrix" : [0.00190640171058476, -0.00534825166687369, -7.4283110734541e-5, 9.04774060472846e-5, 4.89153375383466e-4, 0.0446081645786762, 2.65156908426434e-4, -6.94628863129765e-4, -0.00199959939345717, 4.69204860564787e-6, -5.0137605285272e-6, -3.50844784406945e-5, 1.44616788020357e-5, 4.09551321354229e-5, 3.06548143271357e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.08387875556946, + "fY" : 13.6549243927002, + "fZ" : 190.759826660156, + "fTx" : -0.10558620095253, + "fTy" : 0.100344710052013, + "fQp" : -0.331057548522949, + "fCovMatrix" : [0.00188889005221426, 0.0052486308850348, 7.33881024643779e-5, 8.69609430083074e-5, 4.84872958622873e-4, 0.0440538413822651, 2.59661668678746e-4, 6.78094103932381e-4, 0.00196568109095097, 4.63806691186619e-6, 4.78684660265571e-6, 3.48159555869643e-5, 1.40232677949825e-5, 3.92855836253148e-5, 3.06403584545478e-4] + }, + "fFlag" : 0, + "fChi2" : 1.66834080219269, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [996, 1312, 1441, 1503], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 10.3489437103271, + "fY" : 4.70093584060669, + "fZ" : 154.930511474609, + "fTx" : 0.114422798156738, + "fTy" : 0.0214356426149607, + "fQp" : 0.205062597990036, + "fCovMatrix" : [0.00191554531920701, -0.00537964282557368, -7.71532868384384e-5, 8.9897439465858e-5, 5.28358912561089e-4, 0.0446815341711044, 2.76426231721416e-4, -6.91475346684456e-4, -0.00215133302845061, 4.97471410199068e-6, -5.17047965331585e-6, -3.88837579521351e-5, 1.41577957037953e-5, 4.33041859650984e-5, 3.3617319422774e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 24.005033493042, + "fY" : 6.79686689376831, + "fZ" : 253.266006469727, + "fTx" : 0.160805702209473, + "fTy" : 0.0212317742407322, + "fQp" : 0.205193266272545, + "fCovMatrix" : [0.00187896145507693, 0.00520860031247139, 6.91965979058295e-5, 8.78914870554581e-5, 5.16361207701266e-4, 0.0439009629189968, 2.42643247474916e-4, 6.81457633618265e-4, 0.00208820379339159, 4.03758804168319e-6, 4.58853901363909e-6, 3.45933949574828e-5, 1.40722304422525e-5, 4.29789324698504e-5, 3.36067983880639e-4] + }, + "fFlag" : 0, + "fChi2" : 4.17218637466431, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 784894032, + "fStsHits" : [823, 1014, 1301, 1440], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.209159761667252, + "fY" : 5.51541423797607, + "fZ" : 128.181015014648, + "fTx" : 0.0891838893294334, + "fTy" : 0.0620394684374332, + "fQp" : 1.02081644535065, + "fCovMatrix" : [0.00179648376069963, 0.00484131509438157, -9.11472598090768e-5, -9.4970477221068e-5, 6.41372753307223e-4, 0.0420113168656826, -3.36277502356097e-4, -7.32080370653421e-4, 0.00263895676471293, 8.72109558258671e-6, 6.75840738040279e-6, -5.9632020565914e-5, 2.0143908841419e-5, -5.86929418204818e-5, 7.53887987229973e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 18.6140308380127, + "fY" : 11.1579370498657, + "fZ" : 217.384552001953, + "fTx" : 0.324826687574387, + "fTy" : 0.0648133456707001, + "fQp" : 1.02351033687592, + "fCovMatrix" : [0.00179702998138964, -0.00483735324814916, 9.20187958399765e-5, -9.39793317229487e-5, 6.35934644378722e-4, 0.0419517792761326, -3.39350604917854e-4, 7.26883299648762e-4, -0.00259862025268376, 8.94437198439846e-6, -6.71676525598741e-6, 5.96006648265757e-5, 1.98985035240185e-5, -5.73953657294624e-5, 7.41470488719642e-4] + }, + "fFlag" : 0, + "fChi2" : 10.8240270614624, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [1586, 1629, 1703, 1784], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 2.08460211753845, + "fY" : 3.47573447227478, + "fZ" : 20.1884994506836, + "fTx" : 0.16789023578167, + "fTy" : 0.16056589782238, + "fQp" : 6.63444900512695, + "fCovMatrix" : [3.26649431372061e-4, 0.00607380550354719, -3.47558998328168e-5, -3.04218527162448e-4, 8.30986129585654e-4, 0.278783947229385, -2.87038332317024e-4, -0.0139748118817806, 0.0139984898269176, 4.31774933531415e-5, 2.40868921537185e-5, -6.08670234214514e-4, 0.00117100204806775, -0.00112597877159715, 0.0572077855467796] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.4197807312012, + "fY" : 7.84360790252686, + "fZ" : 46.3479995727539, + "fTx" : 0.674497842788696, + "fTy" : 0.180485606193542, + "fQp" : 6.65022325515747, + "fCovMatrix" : [3.4709763713181e-4, 0.00678978255018592, 3.63292347174138e-5, 3.32853232976049e-4, 9.68408057815395e-5, 0.311384648084641, 2.99614679533988e-4, 0.0151938563212752, -0.015667324885726, 8.55263933772221e-5, 2.96559246635297e-5, 8.48880503326654e-4, 0.00118385872337967, -0.00109430367592722, 0.0491611175239086] + }, + "fFlag" : 0, + "fChi2" : 0.00596811110153794, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223088, + "fStsHits" : [1665, 1748, 1836, 462], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.712063908576965, + "fY" : -3.38685655593872, + "fZ" : 23.511999130249, + "fTx" : -0.0905543118715286, + "fTy" : -0.213576912879944, + "fQp" : -4.52138519287109, + "fCovMatrix" : [3.10847914079204e-4, -0.00515546835958958, -3.06443726003636e-5, 1.49077081005089e-4, 3.62573016900569e-4, 0.222128584980965, 2.35367304412648e-4, -0.00670933164656162, 0.00310587813146412, 2.11121332540642e-5, -5.10366817252361e-6, -2.44588678469881e-4, 2.87801318336278e-4, -3.01768741337582e-4, 0.0212442204356194] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.7083158493042, + "fY" : -11.8248224258423, + "fZ" : 61.02734375, + "fTx" : -0.561766088008881, + "fTy" : -0.246598660945892, + "fQp" : -4.54282855987549, + "fCovMatrix" : [0.00231565581634641, -0.00833991821855307, 2.11953214602545e-4, -2.98762606689706e-4, 0.00200965511612594, 0.0665908977389336, -7.94334802776575e-4, 0.00232968013733625, -0.00770675344392657, 5.23287199030165e-5, -9.87282601272454e-6, 2.70730466581881e-4, 3.05086723528802e-4, -2.41832807660103e-4, 0.019675899296999] + }, + "fFlag" : 0, + "fChi2" : 0.126345127820969, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1681, 1772, 1835, 469], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.88433885574341, + "fY" : -5.33419370651245, + "fZ" : 24.867000579834, + "fTx" : -0.148824334144592, + "fTy" : -0.153178632259369, + "fQp" : 0.323248863220215, + "fCovMatrix" : [2.95291596557945e-4, 0.00507724098861217, -2.48809756158153e-5, -1.57063564984128e-4, 4.58680733572692e-4, 0.230090022087097, -1.96246211999096e-4, -0.00679233251139522, 0.0024279688950628, 5.24611232322059e-6, 1.26538825497846e-5, -1.44563178764656e-4, 2.51001823926345e-4, -3.72937996871769e-4, 0.00492896279320121] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.76997375488281, + "fY" : -10.8661489486694, + "fZ" : 61.0379409790039, + "fTx" : -0.120636485517025, + "fTy" : -0.152578368782997, + "fQp" : 0.323388069868088, + "fCovMatrix" : [0.00224469392560422, -0.00816680397838354, 1.83035343070515e-4, -2.75593047263101e-4, 0.00273431115783751, 0.0664315596222878, -7.01152719557285e-4, 0.00225460040383041, -0.0107996184378862, 1.73376683960669e-5, -1.98681918845978e-5, 2.78609455563128e-4, 2.4982143077068e-4, -3.56033619027585e-4, 0.00484105106443167] + }, + "fFlag" : 0, + "fChi2" : 1.90603971481323, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223136, + "fStsHits" : [1739, 1811, 714, 840], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.09232807159424, + "fY" : -3.98210906982422, + "fZ" : 33.2039985656738, + "fTx" : 0.200135305523872, + "fTy" : -0.137657016515732, + "fQp" : 2.13950061798096, + "fCovMatrix" : [2.81723798252642e-4, -0.00458552315831184, -2.06011136469897e-5, 5.82041539018974e-5, 1.0711484355852e-4, 0.199366182088852, 1.29341031424701e-4, -0.00275158672593534, -0.00123315514065325, 6.10193319516839e-6, -7.06659307070368e-7, -2.98638224194292e-5, 5.66852613701485e-5, 1.94280801224522e-6, 0.00113400362897664] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.6317138671875, + "fY" : -18.7386264801025, + "fZ" : 123.735862731934, + "fTx" : 0.922451794147491, + "fTy" : -0.211355149745941, + "fQp" : 2.14829063415527, + "fCovMatrix" : [0.00199073599651456, -0.00600775657221675, 1.30909102153964e-4, -1.49604718899354e-4, 4.00048622395843e-4, 0.0492274090647697, -5.2100548055023e-4, 0.00109832175076008, -0.00148220511619002, 2.66304086835589e-5, -8.38927280710777e-6, 6.87345527694561e-5, 6.45601903670467e-5, -1.4814616406511e-5, 0.00107164145447314] + }, + "fFlag" : 0, + "fChi2" : 2.83805012702942, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1714, 1793, 557, 786], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.01563191413879, + "fY" : 8.8020715713501, + "fZ" : 36.5065002441406, + "fTx" : 0.0238136984407902, + "fTy" : 0.229776665568352, + "fQp" : 3.00857210159302, + "fCovMatrix" : [2.64756876276806e-4, -0.00391674833372235, -2.09588379220804e-5, 6.66756313876249e-5, 1.23633171824622e-5, 0.183763533830643, 4.85840973851737e-5, -0.00292594847269356, 0.0015829544281587, 9.95756727206754e-6, -3.02706757793203e-6, -3.11150288325734e-5, 8.82402819115669e-5, 1.12403367893421e-5, 0.0023886754643172] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.9655494689941, + "fY" : 31.9299697875977, + "fZ" : 128.266860961914, + "fTx" : 1.03927612304688, + "fTy" : 0.324166595935822, + "fQp" : 3.00718474388123, + "fCovMatrix" : [0.00225362344644964, 0.0075716795399785, 1.34594927658327e-4, 1.78253525518812e-4, 3.82453668862581e-4, 0.0592034570872784, 5.54147001821548e-4, 0.00129310914780945, 0.00136285566259176, 4.59551192761865e-5, 1.16209812404122e-5, 1.57154776388779e-4, 7.96331441961229e-5, 1.55477555381367e-5, 0.00224633538164198] + }, + "fFlag" : 0, + "fChi2" : 2.90521001815796, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223248, + "fStsHits" : [1683, 1765, 1833, 769], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.49905848503113, + "fY" : -4.73205327987671, + "fZ" : 24.867000579834, + "fTx" : -0.182313904166222, + "fTy" : -0.12723571062088, + "fQp" : -0.796673059463501, + "fCovMatrix" : [2.58392479736358e-4, 0.00391368288546801, -1.59541250468465e-5, -5.6714841775829e-5, 1.36179805849679e-4, 0.179493710398674, -5.48938623978756e-5, -0.00261219637468457, -2.17309025174472e-5, 2.42193846133887e-6, 7.85031886607612e-7, -2.42338719544932e-5, 5.2817995310761e-5, 1.84369109774707e-5, 4.60917421150953e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -22.0228366851807, + "fY" : -14.0940723419189, + "fZ" : 97.1422271728516, + "fTx" : -0.338983148336411, + "fTy" : -0.132703423500061, + "fQp" : -0.786303102970123, + "fCovMatrix" : [0.00249015097506344, 0.00926257483661175, 8.01757778390311e-5, 1.46307735121809e-4, 4.15503891417757e-4, 0.071669764816761, 2.8469690005295e-4, 0.00112168665509671, 0.0013581917155534, 4.9180093810719e-6, 5.47497120351181e-6, 3.15871002385393e-5, 5.38857966603246e-5, 2.07644352485659e-5, 4.52636770205572e-4] + }, + "fFlag" : 0, + "fChi2" : 4.02894258499146, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [1600, 1654, 1805, 323], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.07217502593994, + "fY" : -2.39451503753662, + "fZ" : 15.9584999084473, + "fTx" : 0.420909732580185, + "fTy" : -0.201101765036583, + "fQp" : 2.85020518302917, + "fCovMatrix" : [2.82053020782769e-4, -0.004905772395432, -2.29373454203596e-5, 1.13983885967173e-4, 2.73937796009704e-4, 0.226012468338013, 1.02235942904372e-4, -0.00534120853990316, -0.00137035315856338, 1.03694828794687e-5, -2.33197056331846e-6, -1.0354309779359e-4, 1.69253908097744e-4, 1.42875364872452e-8, 0.00385891180485487] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 35.2132225036621, + "fY" : -12.9507713317871, + "fZ" : 61.2922630310059, + "fTx" : 0.945975542068481, + "fTy" : -0.284506976604462, + "fQp" : 2.88229727745056, + "fCovMatrix" : [0.00233683804981411, -0.00856001209467649, 1.85092372703366e-4, -2.543551963754e-4, 8.70178337208927e-4, 0.0678045079112053, -6.34722004178911e-4, 0.00189690559636801, -0.00251634069718421, 3.38984646077733e-5, -2.53437228820985e-5, 8.01854839664884e-5, 1.95868473383598e-4, -6.10732240602374e-5, 0.0034143861848861] + }, + "fFlag" : 0, + "fChi2" : 6.32332944869995, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886492624, + "fStsHits" : [688, 821, 997, 1163], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.210880279541, + "fY" : 9.14961528778076, + "fZ" : 92.2262420654297, + "fTx" : 0.268496483564377, + "fTy" : 0.0843126401305199, + "fQp" : 0.404653936624527, + "fCovMatrix" : [0.00189176446292549, -0.00527186086401343, -7.27753067621961e-5, 8.81685991771519e-5, 4.18113690102473e-4, 0.0442262329161167, 2.58130748989061e-4, -6.84046244714409e-4, -0.00168485485482961, 4.6416130317084e-6, -4.77597404824337e-6, -3.00879692076705e-5, 1.43454008139088e-5, 3.39827383868396e-5, 2.44524126173928e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 21.804407119751, + "fY" : 17.5602760314941, + "fZ" : 190.816345214844, + "fTx" : 0.382342100143433, + "fTy" : 0.0868466049432755, + "fQp" : 0.404914736747742, + "fCovMatrix" : [0.00190632219891995, 0.00534393405541778, 7.47169833630323e-5, 9.11921524675563e-5, 4.20524040237069e-4, 0.0445523224771023, 2.66797083895653e-4, 6.97484647389501e-4, 0.00170170434284955, 4.85355940327281e-6, 5.06681362821837e-6, 3.06623078358825e-5, 1.476433044445e-5, 3.50714653905015e-5, 2.42588197579607e-4] + }, + "fFlag" : 0, + "fChi2" : 8.00023555755615, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 886223136, + "fStsHits" : [1703, 1782, 194, 473], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.95647144317627, + "fY" : 7.19097709655762, + "fZ" : 36.4264984130859, + "fTx" : 0.488533347845078, + "fTy" : 0.16237935423851, + "fQp" : 3.89113664627075, + "fCovMatrix" : [2.71968718152493e-4, 0.00365265016444027, -2.19121720874682e-5, -1.0013045539381e-4, 9.04925327631645e-5, 0.17259469628334, -6.57515920465812e-5, -0.00457445345818996, 0.00113340897951275, 1.7093965652748e-5, 4.73313457405311e-6, -9.16516219149344e-5, 1.89009631867521e-4, -8.29447890282609e-5, 0.00527296680957079] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 75.0670471191406, + "fY" : 19.5143299102783, + "fZ" : 92.2631225585938, + "fTx" : 3.7820155620575, + "fTy" : 0.601390242576599, + "fQp" : 3.85533571243286, + "fCovMatrix" : [0.00235269544646144, -0.00818183925002813, 5.11665304657072e-4, -1.08604559500236e-4, 4.72164072562009e-4, 0.0635098516941071, -0.00206283130683005, 0.00135259691160172, -0.00227036792784929, 0.00325425225310028, 6.31853705272079e-4, 0.00235342606902122, 3.95051145460457e-4, 4.07467334298417e-4, 0.00299980654381216] + }, + "fFlag" : 0, + "fChi2" : 9.25080680847168, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0740007385611534, + "fY" : 0.677288472652435, + "fZ" : -0.029397277161479, + "fTx" : -0.132579430937767, + "fTy" : -0.0721291899681091, + "fQp" : -0.658152520656586, + "fCovMatrix" : [0.00221950025297701, 0.0028900564648211, -1.04220271168742e-4, -2.53592424996896e-5, 1.63976801559329e-4, 0.0685155019164085, -6.93701877025887e-5, -6.83764228597283e-4, 2.89757415885106e-4, 1.90980463230517e-5, 7.73996305269975e-7, -7.43909049560898e-6, 2.4674836822669e-5, -2.87492434836167e-6, 7.77224195189774e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -53.3829460144043, + "fY" : -13.1547222137451, + "fZ" : 185.683853149414, + "fTx" : -0.468784332275391, + "fTy" : -0.0797551199793816, + "fQp" : -0.660838067531586, + "fCovMatrix" : [0.00121652521193027, -0.00194779026787728, 3.82801008527167e-5, -2.38575230468996e-5, 1.03297272289637e-4, 0.0245428644120693, -8.60174477566034e-5, 2.80060805380344e-4, -2.55426042713225e-4, 3.07012169287191e-6, -9.24756022868678e-7, 7.38780818210216e-6, 6.4618020587659e-6, -2.95916311188194e-6, 7.52489650039934e-5] + }, + "fFlag" : -1, + "fChi2" : 0.6826918, + "fNDF" : 11, + "fB" : 0, + "fLength" : 195.034, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.210160583257675, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0565017387270927, + "fY" : 0.494460880756378, + "fZ" : -0.029397277161479, + "fTx" : -0.179241627454758, + "fTy" : -0.0634460225701332, + "fQp" : 0.355513691902161, + "fCovMatrix" : [0.00171372515615076, 0.00121204636525363, -5.64642687095329e-5, -6.87115743858158e-6, 1.0493984882487e-4, 0.0483764111995697, -1.55542984430213e-5, -3.68349603377283e-4, -2.98307495540939e-5, 6.93179117661202e-6, 1.21132771369048e-7, -3.54249959855224e-6, 8.94996264833026e-6, 4.8634649374435e-7, 2.29968627536437e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.34597206115723, + "fY" : -36.7444114685059, + "fZ" : 597.099975585938, + "fTx" : 0.0729218125343323, + "fTy" : -0.0618063695728779, + "fQp" : 0.358231991529465, + "fCovMatrix" : [0.331405907869339, 0.0342925935983658, 9.26587206777185e-4, 6.27643530606292e-5, 0.00156141619663686, 0.422792285680771, 7.94868537923321e-5, 0.00100473617203534, 1.76515794009902e-4, 5.05353909829864e-6, 1.32167642163949e-7, 4.4491644075606e-6, 4.93799279865925e-6, 3.2901203894653e-7, 1.93345149455126e-5] + }, + "fFlag" : -1, + "fChi2" : 2.345246, + "fNDF" : 11, + "fB" : 0, + "fLength" : 600.161, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 31, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.953495024098538, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0322453156113625, + "fPidTof400" : [], + "fPidTof700" : [0.644609602414643, 0.0694591290661035, 0.0999944691296863, 0.0676239011016339, 0.0258690273393539, 0.0127859635663681, 0.0534378617075987, 0.0262200456746122], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0555508695542812, + "fY" : 0.789763331413269, + "fZ" : -0.029397277161479, + "fTx" : 0.093839704990387, + "fTy" : 0.0370822511613369, + "fQp" : 0.182179391384125, + "fCovMatrix" : [0.0116515140980482, 0.00359308440238237, -1.67895312188193e-4, -1.30996895677526e-5, 3.21652245474979e-4, 0.0466934405267239, -3.43895189871546e-5, -2.97956197755411e-4, 3.54110343323555e-5, 3.85609973818646e-6, 8.41147453911617e-8, -4.98619874633732e-6, 3.75554623133212e-6, 1.46831339975506e-7, 1.55608831846621e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 115.492073059082, + "fY" : 23.1709060668945, + "fZ" : 605.900024414062, + "fTx" : 0.223378911614418, + "fTy" : 0.037110548466444, + "fQp" : 0.181536912918091, + "fCovMatrix" : [0.17296989262104, 0.0270088110119104, 4.87490324303508e-4, 4.76852655992843e-5, 0.00122358207590878, 0.272770643234253, 6.78752548992634e-5, 6.24767446424812e-4, 7.79907350079156e-5, 2.03847548618796e-6, 1.22276247793707e-7, 3.50633217749419e-6, 2.10773487197002e-6, 7.30451219510542e-8, 1.37240003823536e-5] + }, + "fFlag" : -1, + "fChi2" : 3.761668, + "fNDF" : 9, + "fB" : 0, + "fLength" : 617.8355, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 2, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 0, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.971411726424795, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.331369638442993, + "fPidTof400" : [], + "fPidTof700" : [0.106999403059693, 0.0541017738352127, 0.062242782061034, 0.0534903252441693, 0.0607867282988083, 0.0188247780843922, 0.581212027214649, 0.0623421822020417], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0666805133223534, + "fY" : 0.428164750337601, + "fZ" : -0.029397277161479, + "fTx" : -0.164223328232765, + "fTy" : 0.0071898540481925, + "fQp" : 0.156282559037209, + "fCovMatrix" : [0.00208490528166294, -0.00386034185066819, -5.61424240004271e-5, 3.31496303260792e-5, 2.03864430659451e-4, 0.0647998973727226, 9.00229279068299e-5, -4.98076085932553e-4, -3.77679069060832e-4, 2.48717469730764e-6, -8.14599786735926e-7, -5.97023336013081e-6, 5.37509959031013e-6, 3.56370742338186e-6, 3.01462678180542e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -52.7552871704102, + "fY" : 4.46160650253296, + "fZ" : 635.900024414062, + "fTx" : -0.0584225989878178, + "fTy" : 0.00611235853284597, + "fQp" : 0.14877887070179, + "fCovMatrix" : [0.489943891763687, 0.0843223929405212, 0.00122661679051816, 1.37403840199113e-4, 0.00245483871549368, 0.52642035484314, 1.8254027236253e-4, 0.00109178281854838, 4.23482531914487e-4, 5.18732576892944e-6, 2.97387003911354e-7, 5.68062205275055e-6, 4.51046071248129e-6, 6.98760686645983e-7, 1.69157738127979e-5] + }, + "fFlag" : -1, + "fChi2" : 9.146291, + "fNDF" : 9, + "fB" : 0, + "fLength" : 638.3365, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 3, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 43, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.941049282810426, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0534606203436852, + "fPidTof400" : [], + "fPidTof700" : [0.0839293680874064, 0.0691443786358444, 0.0725100750284162, 0.0688654569786821, 0.218816546462281, 0.159709845292051, 0.113744289889448, 0.21328003962587], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.00191991194151342, + "fY" : -0.182826071977615, + "fZ" : -0.029397277161479, + "fTx" : -0.323013454675674, + "fTy" : 0.15284352004528, + "fQp" : 0.659121811389923, + "fCovMatrix" : [0.0335149951279163, 0.00798405054956675, -5.71855984162539e-4, -2.68500389211113e-5, 8.36657825857401e-4, 0.080984078347683, -8.70597796165384e-5, -7.50974228139967e-4, 1.40999851282686e-4, 3.57154640369117e-5, -1.06207596672903e-6, -1.695135688351e-5, 3.26826593664009e-5, -3.52053177721245e-8, 6.94709597155452e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -28.8700866699219, + "fY" : 36.6349716186523, + "fZ" : 253.266006469727, + "fTx" : 0.0915517956018448, + "fTy" : 0.13888768851757, + "fQp" : 0.663964629173279, + "fCovMatrix" : [0.0013174363411963, 0.00216729799285531, 3.46993256243877e-5, 2.37835829466349e-5, 7.89249243098311e-5, 0.0238640792667866, 7.23723351256922e-5, 2.47721880441532e-4, 9.2910930106882e-5, 2.31840249398374e-6, 7.41987889796292e-7, 4.51600999440416e-6, 5.64657284485293e-6, 3.95186390278468e-7, 6.98939329595305e-5] + }, + "fFlag" : -1, + "fChi2" : 5.784281, + "fNDF" : 9, + "fB" : 0, + "fLength" : 259.1661, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 4, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.654710590839386, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.179565787315369, + "fY" : -0.399083405733109, + "fZ" : -0.029397277161479, + "fTx" : -0.201461151242256, + "fTy" : -0.205910712480545, + "fQp" : 0.910654604434967, + "fCovMatrix" : [0.00247417250648141, 0.00274470099247992, -1.29717140225694e-4, -2.78156312560895e-5, 2.99764738883823e-4, 0.0925460234284401, -4.29163264925592e-5, -0.00102607894223183, -2.91065400233492e-4, 5.89180563110858e-5, 2.62338539869234e-6, -1.5305888155126e-5, 6.89567896188237e-5, 3.5991758977616e-6, 1.74445245647803e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.8365318775177, + "fY" : -32.9046325683594, + "fZ" : 159.629043579102, + "fTx" : 0.167047187685966, + "fTy" : -0.20632404088974, + "fQp" : 0.914145052433014, + "fCovMatrix" : [0.00155416806228459, 0.00351027329452336, 4.78662987006828e-5, 4.80297567264643e-5, 1.67868478456512e-4, 0.034046433866024, 1.29982028738596e-4, 4.5236645382829e-4, 4.79995826026425e-4, 3.62696550837427e-6, 1.50596133607905e-6, 1.30671187434928e-5, 1.08145477497601e-5, 5.51082939637126e-6, 1.74894215888344e-4] + }, + "fFlag" : -1, + "fChi2" : 62.48223, + "fNDF" : 9, + "fB" : 0, + "fLength" : 163.8421, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 5, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.895907878875732, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0139392474666238, + "fY" : 0.455241650342941, + "fZ" : -0.029397277161479, + "fTx" : -0.062625527381897, + "fTy" : 0.148939579725266, + "fQp" : 0.119508534669876, + "fCovMatrix" : [5.78801264055073e-4, 9.634830057621e-4, -1.53702530951705e-5, -3.56837290382828e-6, 3.91939029213972e-5, 0.0465439446270466, -1.91397884918842e-5, -2.5883741909638e-4, 3.60415215254761e-5, 9.66233187682519e-7, 4.68406611275896e-8, -1.17995512027846e-6, 2.2916310626897e-6, 8.62989057992536e-9, 5.08634002471808e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -6.76850318908691, + "fY" : 38.0125923156738, + "fZ" : 253.266006469727, + "fTx" : 0.00997702591121197, + "fTy" : 0.147619038820267, + "fQp" : 0.119642995297909, + "fCovMatrix" : [0.00100874423515052, 0.00117198028601706, 1.63884978974238e-5, 7.29519751985208e-6, 4.17295595980249e-5, 0.0191394723951817, 1.79422495421022e-5, 1.43677883897908e-4, 3.47817585861776e-5, 4.42629755070811e-7, 7.17247630177553e-8, 1.18746982025186e-6, 1.66530287515343e-6, -7.33179161827024e-9, 5.09104575030506e-6] + }, + "fFlag" : -1, + "fChi2" : 3.651506, + "fNDF" : 13, + "fB" : 0, + "fLength" : 256.2021, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 6, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0258415304124355, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0389177985489368, + "fY" : 0.448986709117889, + "fZ" : -0.029397277161479, + "fTx" : -0.174546033143997, + "fTy" : 0.129471302032471, + "fQp" : 0.527156710624695, + "fCovMatrix" : [0.0010258931433782, -0.0017312727868557, -5.28234850207809e-5, 1.48109857036616e-5, 1.36350776301697e-4, 0.0762835368514061, 1.59505343617639e-5, -7.40130781196058e-4, 1.82737523573451e-4, 1.48886438182672e-5, -3.93580336321975e-7, -7.10239601175999e-6, 2.17374108615331e-5, -2.39764813159127e-6, 8.03250004537404e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.1900281906128, + "fY" : 20.1586036682129, + "fZ" : 154.893341064453, + "fTx" : 0.0223866682499647, + "fTy" : 0.125468313694, + "fQp" : 0.52903938293457, + "fCovMatrix" : [0.00118864618707448, -0.00201725121587515, 3.29115355270915e-5, -2.80263557215221e-5, 1.24523183330894e-4, 0.0269913990050554, -7.08940933691338e-5, 3.47086053807288e-4, -2.71533383056521e-4, 2.06066397367977e-6, -9.20225318168377e-7, 7.71232225815766e-6, 7.54866641727858e-6, -3.4717002108664e-6, 8.07631731731817e-5] + }, + "fFlag" : -1, + "fChi2" : 0.5608385, + "fNDF" : 11, + "fB" : 0, + "fLength" : 156.83, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 7, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0223205760121346, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0595742650330067, + "fY" : 0.836916446685791, + "fZ" : -0.029397277161479, + "fTx" : -0.294198930263519, + "fTy" : -0.0304462239146233, + "fQp" : 0.573667526245117, + "fCovMatrix" : [0.00174248847179115, 0.00238847779110074, -7.30393221601844e-5, -2.14202755159931e-5, 9.12808754947037e-5, 0.0714968591928482, -4.04166348744184e-5, -7.88744306191802e-4, -1.40165313496254e-4, 1.99451569642406e-5, 5.33542049652169e-7, -5.51650691704708e-6, 2.84034485957818e-5, 6.42699262698443e-7, 7.26091820979491e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.1114253997803, + "fY" : -17.3297557830811, + "fZ" : 627.099975585938, + "fTx" : 0.117817349731922, + "fTy" : -0.028366457670927, + "fQp" : 0.584481775760651, + "fCovMatrix" : [0.591495037078857, 0.0372841954231262, 0.00177296262700111, 4.17713163187727e-5, 0.00279141054488719, 0.607945024967194, 5.95685487496667e-5, 0.00164023577235639, 2.83282657619566e-4, 3.05342837236822e-5, -1.90274089817422e-8, 6.21156414126744e-6, 2.97543447231874e-5, 3.70998293419689e-7, 5.38747299287934e-5] + }, + "fFlag" : -1, + "fChi2" : 1.322424, + "fNDF" : 11, + "fB" : 0, + "fLength" : 632.3667, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 8, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 32, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.66598499103137, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.366903215646744, + "fPidTof400" : [], + "fPidTof700" : [0.0296857656813575, 0.0192531548640818, 0.021505703857677, 0.0190692797998261, 0.433669813466485, 0.0459036074703152, 0.0565353274279246, 0.374377347432333], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0465898849070072, + "fY" : 0.553586721420288, + "fZ" : -0.029397277161479, + "fTx" : -0.0703434571623802, + "fTy" : 0.207842886447906, + "fQp" : 0.285599648952484, + "fCovMatrix" : [6.56671356409788e-4, 7.71137769334018e-4, -2.46595536737004e-5, -4.32917977377656e-6, 7.51452389522456e-5, 0.0552795119583607, -4.64672382349818e-7, -4.11612389143556e-4, -6.38001729384996e-5, 4.0657282625034e-6, -8.79117152408071e-8, -3.08945914184733e-6, 7.27768338038004e-6, 8.36427375361382e-7, 2.29028191824909e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.11983871459961, + "fY" : 39.9874572753906, + "fZ" : 190.759826660156, + "fTx" : 0.0620537921786308, + "fTy" : 0.206056728959084, + "fQp" : 0.286139667034149, + "fCovMatrix" : [0.00119367893785238, 0.00193155149463564, 2.52228346653283e-5, 1.92373408935964e-5, 7.64093638281338e-5, 0.0246099624782801, 4.20779288106132e-5, 2.31990285101347e-4, 1.01877601991873e-4, 1.02140506896831e-6, 4.58338035969064e-7, 3.38780637321179e-6, 3.69359349861043e-6, 9.96966150523804e-7, 2.29560191655764e-5] + }, + "fFlag" : -1, + "fChi2" : 1.323198, + "fNDF" : 11, + "fB" : 0, + "fLength" : 194.9633, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 9, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0835930556058884, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0259277746081352, + "fY" : 0.497226029634476, + "fZ" : -0.029397277161479, + "fTx" : -0.107399627566338, + "fTy" : -0.0284976586699486, + "fQp" : 0.165723696351051, + "fCovMatrix" : [0.00143562606535852, 0.00178038876038045, -3.84828381356783e-5, -9.68738731899066e-6, 4.74320513603743e-5, 0.0390435010194778, -3.6724977690028e-5, -2.58285814197734e-4, 9.36405267566442e-5, 2.05063588509802e-6, 2.00309884235139e-7, -1.42571036576555e-6, 3.52463871422515e-6, -5.25847838162008e-7, 8.69256200530799e-6] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -12.2916278839111, + "fY" : -17.5992946624756, + "fZ" : 627.099975585938, + "fTx" : 0.00854089763015509, + "fTy" : -0.0289660077542067, + "fQp" : 0.166625663638115, + "fCovMatrix" : [0.148046761751175, -0.0303253699094057, 4.45078534539789e-4, -6.29990681773052e-5, 8.43557121697813e-4, 0.261670053005219, -7.34995119273663e-5, 6.11280789598823e-4, -1.67856240295805e-4, 4.74621310786461e-6, -1.55629805931312e-7, 2.18870354729006e-6, 4.95414224133128e-6, -3.70353092193909e-7, 7.84113217378035e-6] + }, + "fFlag" : -1, + "fChi2" : 1.703628, + "fNDF" : 11, + "fB" : 0, + "fLength" : 627.9094, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 10, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 36, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.981190015078161, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0277214013040066, + "fPidTof400" : [], + "fPidTof700" : [0.264831582444079, 0.099058080392236, 0.118656458213957, 0.0976499434722578, 0.0698905569127598, 0.0246110081281543, 0.253963106951953, 0.0713392634846027], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0660625994205475, + "fY" : 0.156047880649567, + "fZ" : -0.029397277161479, + "fTx" : 0.232560113072395, + "fTy" : -0.163165777921677, + "fQp" : 0.255133837461472, + "fCovMatrix" : [5.06653159391135e-4, -0.00217646267265081, -1.92137031262973e-5, 1.41351611091522e-5, 5.27632182638627e-5, 0.0859930515289307, 2.56181083386764e-5, -6.11333991400898e-4, -2.69352440227522e-5, 3.37526330440596e-6, -2.34994359971097e-7, -2.33265086535539e-6, 7.68585505284136e-6, -3.95814048204102e-8, 1.58123348228401e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 55.0374336242676, + "fY" : -31.1423664093018, + "fZ" : 186.27587890625, + "fTx" : 0.366489827632904, + "fTy" : -0.175483256578445, + "fQp" : 0.255306541919708, + "fCovMatrix" : [0.00105818000156432, -0.00150494289118797, 2.36668620345881e-5, -1.8978571461048e-5, 6.11486830166541e-5, 0.023076020181179, -3.95588904211763e-5, 2.58579704677686e-4, -8.41691216919571e-5, 1.04949799606402e-6, -4.62299027503832e-7, 2.83598228634219e-6, 4.9294499149255e-6, -7.70337180711067e-7, 1.57309768837877e-5] + }, + "fFlag" : -1, + "fChi2" : 5.110947, + "fNDF" : 11, + "fB" : 0, + "fLength" : 197.0814, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 11, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.316398054361343, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.029531504958868, + "fY" : -0.30577677488327, + "fZ" : -0.029397277161479, + "fTx" : -0.418623745441437, + "fTy" : -0.0700498446822166, + "fQp" : 1.17042815685272, + "fCovMatrix" : [0.0015906278276816, 0.00322215468622744, -1.27519058878534e-4, -3.8563332054764e-5, 1.79388167452998e-4, 0.099520243704319, -8.62178494571708e-5, -0.00140073359943926, 2.56149884080514e-4, 1.46425547427498e-4, 4.58337945019593e-6, -1.46780648719869e-5, 1.47418890264817e-4, -3.48796061189205e-6, 2.41092668147758e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.1258335113525, + "fY" : -11.6612462997437, + "fZ" : 185.833938598633, + "fTx" : 0.142297178506851, + "fTy" : -0.054171446710825, + "fQp" : 1.1889933347702, + "fCovMatrix" : [0.00134163885377347, -0.00245691742748022, 5.10454046889208e-5, -3.7505309592234e-5, 1.53668865095824e-4, 0.0273020192980766, -1.37132912641391e-4, 3.72970214812085e-4, -3.93421592889354e-4, 5.40775272384053e-6, -1.81297491508303e-6, 1.40981837830623e-5, 1.20690865514916e-5, -4.63336573375273e-6, 2.43694987148046e-4] + }, + "fFlag" : -1, + "fChi2" : 24.69871, + "fNDF" : 11, + "fB" : 0, + "fLength" : 189.8812, + "fNhits" : 8, + "fUsing" : false, + "fGemTrack" : 12, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.779283165931702, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0240551009774208, + "fY" : 0.674277245998383, + "fZ" : -0.029397277161479, + "fTx" : 0.176159054040909, + "fTy" : -0.177063018083572, + "fQp" : 0.37081640958786, + "fCovMatrix" : [0.0010780377779156, -8.84766515810043e-4, -4.12856061302591e-5, 6.88902537149261e-6, 9.13657931960188e-5, 0.0734804943203926, -1.65775963978376e-5, -6.55427982565016e-4, 1.44494799314998e-4, 7.058639312163e-6, -9.47400913275942e-9, -3.75339618585713e-6, 1.29052205011249e-5, -1.64153811965662e-6, 2.84535872197011e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.4424476623535, + "fY" : -33.5017509460449, + "fZ" : 186.244964599609, + "fTx" : 0.368892908096313, + "fTy" : -0.193302035331726, + "fQp" : 0.372141301631927, + "fCovMatrix" : [0.00215255655348301, -0.00685461703687906, 3.92403235309757e-5, -6.76833660691045e-5, 9.6430660050828e-5, 0.0515968352556229, -1.1207955685677e-4, 5.03702322021127e-4, -2.41851797909476e-4, 1.51022993577499e-6, -1.23772463211935e-6, 4.18293348047882e-6, 6.72852365823928e-6, -2.80614221992437e-6, 2.82885594060645e-5] + }, + "fFlag" : -1, + "fChi2" : 0.719115, + "fNDF" : 9, + "fB" : 0, + "fLength" : 196.2505, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 13, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.20367656648159, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0617795810103416, + "fY" : 0.293817669153214, + "fZ" : -0.029397277161479, + "fTx" : 0.231379643082619, + "fTy" : 0.096101388335228, + "fQp" : 1.22818338871002, + "fCovMatrix" : [0.00403393572196364, 0.00236393650993705, -3.13459051540121e-4, -2.8485423172242e-5, 3.93314432585612e-4, 0.146797671914101, 9.8125246950076e-7, -0.00196340912953019, -2.53541278652847e-4, 1.44722478580661e-4, 2.66153642769495e-6, -2.52219087997219e-5, 1.60045368829742e-4, 6.95107792125782e-6, 3.55977565050125e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 58.0685119628906, + "fY" : 13.1218519210815, + "fZ" : 128.266860961914, + "fTx" : 0.735637307167053, + "fTy" : 0.110303997993469, + "fQp" : 1.2478494644165, + "fCovMatrix" : [0.00186582887545228, 0.00535924965515733, 7.37560476409271e-5, 9.87442472251132e-5, 2.09176956559531e-4, 0.0458656288683414, 2.62276356806979e-4, 7.90530757512897e-4, 7.02802964951843e-4, 8.63070454215631e-6, 4.20958849645103e-6, 2.75256006716518e-5, 2.33199843933107e-5, 9.57082284003263e-6, 3.41619132086635e-4] + }, + "fFlag" : -1, + "fChi2" : 2.624995, + "fNDF" : 9, + "fB" : 0, + "fLength" : 143.5484, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 14, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.179138273000717, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0260817781090736, + "fY" : 0.36417630314827, + "fZ" : -0.029397277161479, + "fTx" : 0.373044222593307, + "fTy" : 0.170719236135483, + "fQp" : 0.585384905338287, + "fCovMatrix" : [0.00100781524088234, 0.00166274583898485, -4.68139005533885e-5, -2.35737807088299e-5, 1.44563353387639e-4, 0.095621332526207, -5.58875171918771e-6, -8.41636268887669e-4, 1.29279447719455e-4, 2.1956511773169e-5, 1.61192679115629e-6, -7.38532344257692e-6, 2.79109026450897e-5, -3.83259930458735e-6, 6.94699774612673e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 79.3677291870117, + "fY" : 28.174129486084, + "fZ" : 154.960510253906, + "fTx" : 0.673740983009338, + "fTy" : 0.198277235031128, + "fQp" : 0.583659291267395, + "fCovMatrix" : [0.00126076629385352, -0.00243792682886124, 4.26691185566597e-5, -2.5351766453241e-5, 1.08721644210164e-4, 0.0306138880550861, -1.34073343360797e-4, 3.3120164880529e-4, -3.81166988518089e-4, 3.79051311938383e-6, -5.50403228771756e-7, 8.82440872373991e-6, 8.84583005245076e-6, -1.61029106493515e-6, 6.83862963342108e-5] + }, + "fFlag" : -1, + "fChi2" : 2.896034, + "fNDF" : 9, + "fB" : 0, + "fLength" : 177.5232, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 15, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.12270288169384, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0483073107898235, + "fY" : 0.393165171146393, + "fZ" : -0.029397277161479, + "fTx" : -0.644379854202271, + "fTy" : -0.0592610761523247, + "fQp" : 0.85918128490448, + "fCovMatrix" : [0.00376315508037806, 0.00458553526550531, -3.42107960022986e-4, -5.83488363190554e-5, 3.93477501347661e-4, 0.178966328501701, -1.13283669634257e-4, -0.00210009817965329, 7.97470158431679e-4, 1.28874045913108e-4, 4.61120998807019e-6, -2.46611161855981e-5, 1.15384376840666e-4, -5.94538005316281e-6, 2.37791973631829e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -94.1140823364258, + "fY" : -19.8559474945068, + "fZ" : 605.900024414062, + "fTx" : -0.0226183347404003, + "fTy" : -0.0160221420228481, + "fQp" : 0.912991106510162, + "fCovMatrix" : [0.733367383480072, 1.0477769683348e-4, 0.00341560994274914, 2.05661308427807e-6, 3.92372399801388e-4, 0.702567219734192, -5.40282280780957e-6, 0.00354262278415263, 1.75905952346511e-4, 4.54554756288417e-5, -1.43423610765581e-8, 6.49140361019818e-7, 4.53696411568671e-5, 1.24108589716343e-6, 2.2716514649801e-4] + }, + "fFlag" : -1, + "fChi2" : 19.51908, + "fNDF" : 9, + "fB" : 0, + "fLength" : 621.7869, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 16, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 5, + "fTof2Hit" : 51, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.824839869161684, + "fBeta700" : 0.78413891117737, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0789182558655739, + "fPidTof400" : [0.371941016941938, 0.102499799654331, 0.179855863574656, 0.0983373147844284, 0.0578651987152106, 0.0389610684070502, 0.0921986281773345, 0.0583411097450511], + "fPidTof700" : [0.840198601123537, 0.0225780273705623, 0.0345356921530953, 0.0218340212657471, 0.01834113077067, 0.011741656473423, 0.0322547736695629, 0.018516097173403], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0270361006259918, + "fY" : 0.617177248001099, + "fZ" : -0.029397277161479, + "fTx" : 0.0507588386535645, + "fTy" : -0.378645896911621, + "fQp" : 0.854494571685791, + "fCovMatrix" : [0.00147134403232485, -0.00451167533174157, -1.01672383607365e-4, 7.60751572670415e-5, 4.14297945098951e-4, 0.180836632847786, 1.07913074316457e-4, -0.00251592299900949, -0.00162807607557625, 5.15010979142971e-5, -3.40793894793023e-6, -2.64719310507644e-5, 9.45847568800673e-5, 3.66812273568939e-5, 4.03933663619682e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 14.6517648696899, + "fY" : -36.9337005615234, + "fZ" : 97.2979049682617, + "fTx" : 0.267938584089279, + "fTy" : -0.39751985669136, + "fQp" : 0.858786880970001, + "fCovMatrix" : [0.0020041186362505, 0.0062880627810955, 7.17065486242063e-5, 1.29548876429908e-4, 4.24215395469218e-4, 0.0527210347354412, 2.48639262281358e-4, 0.00104399619158357, 0.00170484441332519, 5.03440105603659e-6, 3.60055105375068e-6, 3.17915582854766e-5, 3.6310881114332e-5, 2.93589273496764e-5, 4.00858378270641e-4] + }, + "fFlag" : -1, + "fChi2" : 0.8979174, + "fNDF" : 7, + "fB" : 0, + "fLength" : 105.7154, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 17, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.146498799324036, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0211788676679134, + "fY" : 0.264890640974045, + "fZ" : -0.029397277161479, + "fTx" : 0.0602984353899956, + "fTy" : -0.0695310831069946, + "fQp" : 0.231331944465637, + "fCovMatrix" : [0.0574447922408581, 0.0230465475469828, -7.54404463805258e-4, -1.2372930359561e-4, 0.00118127150926739, 0.107154481112957, -2.66663468210027e-4, -7.53610976971686e-4, 6.10624963883311e-4, 1.22538394862204e-5, 1.43956913234433e-6, -1.50341811604449e-5, 9.04982425709022e-6, -3.36638117914845e-6, 3.8673428207403e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.1994171142578, + "fY" : -17.4566535949707, + "fZ" : 248.743057250977, + "fTx" : 0.199927106499672, + "fTy" : -0.0728905349969864, + "fQp" : 0.232502847909927, + "fCovMatrix" : [0.00115935911890119, -0.0017235407140106, 2.88825049210573e-5, -1.94963467947673e-5, 1.19995631393977e-4, 0.0224260333925486, -5.84204062761273e-5, 2.16226137126796e-4, -2.78120045550168e-4, 1.31434103423089e-6, -7.26508289972116e-7, 5.67927645533928e-6, 3.21425773108786e-6, -3.81498466595076e-6, 3.85692983400077e-5] + }, + "fFlag" : -1, + "fChi2" : 0.9973078, + "fNDF" : 7, + "fB" : 0, + "fLength" : 251.7808, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 18, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.213376849889755, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0265165511518717, + "fY" : 0.598047256469727, + "fZ" : -0.029397277161479, + "fTx" : 0.00665936945006251, + "fTy" : -0.261780083179474, + "fQp" : 0.45001232624054, + "fCovMatrix" : [0.00199006428010762, 5.24522620253265e-4, -8.60151048982516e-5, -1.23626432468882e-5, 3.79494274966419e-4, 0.144032061100006, -1.25099832075648e-4, -0.00155290775001049, 0.00102622515987605, 1.2004950804112e-5, 1.56970281750546e-6, -1.71131014212733e-5, 2.81398060906213e-5, -1.31918177430634e-5, 1.45577345392667e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.8525915145874, + "fY" : -31.998348236084, + "fZ" : 123.511558532715, + "fTx" : 0.144777610898018, + "fTy" : -0.267102360725403, + "fQp" : 0.451087117195129, + "fCovMatrix" : [0.0014291099505499, -0.0032419697381556, 4.93956431455445e-5, -6.88998552504927e-5, 2.42930182139389e-4, 0.0350515246391296, -1.43318975460716e-4, 6.34233001619577e-4, -6.86827290337533e-4, 3.12987617689942e-6, -3.23209337693697e-6, 1.69907871168107e-5, 1.81877385330154e-5, -1.51279182318831e-5, 1.4542366261594e-4] + }, + "fFlag" : -1, + "fChi2" : 1.26801, + "fNDF" : 7, + "fB" : 0, + "fLength" : 128.2301, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 19, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.127429127693176, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.184611901640892, + "fY" : 0.671454608440399, + "fZ" : -0.029397277161479, + "fTx" : 0.0760625302791595, + "fTy" : -0.317902356386185, + "fQp" : -1.61735594272614, + "fCovMatrix" : [0.00308883422985673, -0.00466789305210114, -2.43805014179088e-4, 8.51078075356781e-5, 6.88052852638066e-4, 0.189663529396057, 1.16647715913132e-4, -0.00286581763066351, -7.18182127457112e-5, 1.14074267912656e-4, -5.64381707590655e-6, -5.61336091777775e-5, 1.66277313837782e-4, 1.80466577148763e-5, 0.00109390704892576] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.2619371414185, + "fY" : -30.3149681091309, + "fZ" : 97.207145690918, + "fTx" : -0.3241907954216, + "fTy" : -0.32882833480835, + "fQp" : -1.62593746185303, + "fCovMatrix" : [0.00208903150632977, 0.00674401968717575, 8.48563431645744e-5, 1.50043764733709e-4, 4.01053373934701e-4, 0.0551445372402668, 3.204517706763e-4, 0.00114413211122155, 0.00138048059307039, 1.01180758065311e-5, 5.6384528761555e-6, 6.00225175730884e-5, 4.38956740254071e-5, 1.84727196028689e-5, 0.00107722356915474] + }, + "fFlag" : -1, + "fChi2" : 2.507782, + "fNDF" : 7, + "fB" : 0, + "fLength" : 103.4519, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 20, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.25052347779274, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0657527521252632, + "fY" : 0.585246980190277, + "fZ" : -0.029397277161479, + "fTx" : 0.166888251900673, + "fTy" : -0.223062187433243, + "fQp" : 0.494734257459641, + "fCovMatrix" : [0.00211634044535458, 5.25640149135143e-4, -9.03631007531658e-5, -1.00845736596966e-5, 3.96233925130218e-4, 0.145723015069962, -1.21151497296523e-4, -0.0015668214764446, 9.32940165512264e-4, 1.45359554153401e-5, 1.05100161817973e-6, -1.75148707057815e-5, 3.0253077056841e-5, -1.15782904686057e-5, 1.43525379826315e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 30.012149810791, + "fY" : -27.715295791626, + "fZ" : 123.628150939941, + "fTx" : 0.329684227705002, + "fTy" : -0.236884519457817, + "fQp" : 0.496926605701447, + "fCovMatrix" : [0.00145258323755115, -0.0033528795465827, 5.184545807424e-5, -7.23689227015711e-5, 2.35452040215023e-4, 0.0356061942875385, -1.54099107021466e-4, 6.50815549306571e-4, -6.81751174852252e-4, 3.47621858054481e-6, -3.51407697962713e-6, 1.70653893292183e-5, 1.8816896044882e-5, -1.5315948985517e-5, 1.42825228977017e-4] + }, + "fFlag" : -1, + "fChi2" : 5.733225, + "fNDF" : 7, + "fB" : 0, + "fLength" : 130.673, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 21, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.11856509745121, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0218580476939678, + "fY" : 0.629203677177429, + "fZ" : -0.029397277161479, + "fTx" : 0.0626749098300934, + "fTy" : -0.38428658246994, + "fQp" : 0.490630775690079, + "fCovMatrix" : [0.00101967749651521, -0.00444304011762142, -5.33855709363706e-5, 7.46301666367799e-5, 3.33140487782657e-4, 0.177638679742813, 1.07444931927603e-4, -0.00239206408150494, -0.00144222122617066, 1.40433867272804e-5, -2.7796868380392e-6, -1.87960813491372e-5, 5.00846144859679e-5, 3.23565327562392e-5, 2.28346092626452e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 11.5724449157715, + "fY" : -37.1252288818359, + "fZ" : 97.2810516357422, + "fTx" : 0.184642106294632, + "fTy" : -0.393206566572189, + "fQp" : 0.491282910108566, + "fCovMatrix" : [0.0019843983463943, 0.00619267066940665, 6.76561103318818e-5, 1.29911699332297e-4, 4.06330276746303e-4, 0.0522433407604694, 2.30213481700048e-4, 0.00104126078076661, 0.00156744290143251, 3.52676556758524e-6, 3.81714471586747e-6, 2.33595692407107e-5, 3.48855210177135e-5, 2.8559716156451e-5, 2.27711803745478e-4] + }, + "fFlag" : -1, + "fChi2" : 7.035285, + "fNDF" : 7, + "fB" : 0, + "fLength" : 105.1616, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 22, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.168071672320366, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0474835783243179, + "fY" : 0.78285539150238, + "fZ" : -0.029397277161479, + "fTx" : -0.039885189384222, + "fTy" : -0.0637722164392471, + "fQp" : 0.210131198167801, + "fCovMatrix" : [0.0561482682824135, 0.0274022594094276, -7.35882786102593e-4, -1.61013696924783e-4, 0.00125679664779454, 0.129250317811966, -3.34718672093004e-4, -9.15000098757446e-4, 8.5243140347302e-4, 1.16585915748146e-5, 2.02640694624279e-6, -1.6065296222223e-5, 9.78590742306551e-6, -5.31669820702518e-6, 4.20234391640406e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 42.9485397338867, + "fY" : -39.0178604125977, + "fZ" : 597.099975585938, + "fTx" : 0.111159361898899, + "fTy" : -0.0674694031476974, + "fQp" : 0.220070779323578, + "fCovMatrix" : [0.27581062912941, -0.113243870437145, 7.99520348664373e-4, -2.47204530751333e-4, 0.00246219406835735, 0.466205537319183, -3.06058267597109e-4, 0.00106651033274829, -8.55989404954016e-4, 3.14367594000942e-6, -6.80913501582836e-7, 7.30455985831213e-6, 3.31925457430771e-6, -1.96429277821153e-6, 3.07057962345425e-5] + }, + "fFlag" : -1, + "fChi2" : 6.698724, + "fNDF" : 5, + "fB" : 0, + "fLength" : 600.5325, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 23, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 25, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.978990160074654, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.322582691907883, + "fPidTof400" : [], + "fPidTof700" : [0.644231726842223, 0.0664468963396918, 0.0872551431364887, 0.0650876397940315, 0.0280942881718885, 0.011603313325726, 0.0687209491232589, 0.028560043266692], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.0269705541431904, + "fY" : 0.86626672744751, + "fZ" : -0.029397277161479, + "fTx" : -0.296288967132568, + "fTy" : 0.0620612986385822, + "fQp" : -1.67327976226807, + "fCovMatrix" : [0.00480414787307382, -0.013381153345108, -3.17799451295286e-4, 2.98244412988424e-4, 0.0024010946508497, 0.430685579776764, 4.40666102804244e-4, -0.00748321134597063, -0.0048612505197525, 1.33756286231801e-4, -1.45052717925864e-5, -1.56944210175425e-4, 2.52640224061906e-4, 1.49373343447223e-4, 0.00213810801506042] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -29.1511573791504, + "fY" : 5.16933584213257, + "fZ" : 65.8757781982422, + "fTx" : -0.621299684047699, + "fTy" : 0.0697667375206947, + "fQp" : -1.68280816078186, + "fCovMatrix" : [0.00207065301947296, 0.00739669566974044, 1.5232952137012e-4, 2.03452989808284e-4, 0.00115508679300547, 0.0626869574189186, 5.78183040488511e-4, 0.00173771800473332, 0.00466901436448097, 1.66032168635866e-5, 1.37709239425021e-5, 1.00848628790118e-4, 1.44337231176905e-4, 1.39568408485502e-4, 0.00202691182494164] + }, + "fFlag" : -1, + "fChi2" : 0.2271775, + "fNDF" : 5, + "fB" : 0, + "fLength" : 73.08131, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 24, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.400149792432785, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.53253877162933, + "fY" : 2.21172761917114, + "fZ" : -0.029397277161479, + "fTx" : -0.0300991535186768, + "fTy" : 0.0320842824876308, + "fQp" : 0.172622725367546, + "fCovMatrix" : [0.16963754594326, 0.017030593007803, -0.00184271612670273, -2.05997530429158e-5, 0.00341897248290479, 0.197976991534233, -1.13096597488038e-4, -0.00117654190398753, 1.00956378446426e-4, 2.07278790185228e-5, -1.55807782675765e-7, -3.75098570657428e-5, 8.69890664034756e-6, 1.15531929623103e-6, 8.51549120852724e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 37.985050201416, + "fY" : 20.02707862854, + "fZ" : 597.099975585938, + "fTx" : 0.0948549509048462, + "fTy" : 0.0276641175150871, + "fQp" : 0.183003291487694, + "fCovMatrix" : [0.444777190685272, 0.0305360313504934, 0.0021095525007695, -2.7875737487193e-6, 0.00371088227257133, 0.507221102714539, 3.36427910951898e-5, 0.00198251358233392, 5.01687463838607e-5, 1.77293622982688e-5, 1.26534516198262e-8, 6.10570623393869e-6, 1.72857144207228e-5, -4.63965051267223e-7, 6.02575310040265e-5] + }, + "fFlag" : -1, + "fChi2" : 3.748917, + "fNDF" : 5, + "fB" : 0, + "fLength" : 598.9304, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 25, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 28, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.94725859496145, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.29666018486023, + "fPidTof400" : [], + "fPidTof700" : [0.0415304638190809, 0.031574482504858, 0.0337090888263306, 0.0314008064952473, 0.404591798136961, 0.0348745042397562, 0.0673819225101498, 0.354936933467617], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0261322315782309, + "fY" : 0.672808051109314, + "fZ" : -0.029397277161479, + "fTx" : -0.015124392695725, + "fTy" : 0.11842468380928, + "fQp" : 0.258600860834122, + "fCovMatrix" : [0.00573420384898782, 0.0115867666900158, -2.22130765905604e-4, -1.98144538444467e-4, 0.00165110838133842, 0.360558211803436, -3.23505606502295e-4, -0.00477726384997368, 0.00326071726158261, 1.12036650534719e-5, 6.37417360849213e-6, -6.61796366330236e-5, 6.99954543961212e-5, -6.32923911325634e-5, 5.69206080399454e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.04422128200531, + "fY" : 11.5715970993042, + "fZ" : 92.2562408447266, + "fTx" : 0.0397122837603092, + "fTy" : 0.117785260081291, + "fQp" : 0.259079456329346, + "fCovMatrix" : [0.0019244517898187, -0.00591123849153519, 8.24297530925833e-5, -1.79509283043444e-4, 7.10876774974167e-4, 0.0508608967065811, -2.78832420008257e-4, 0.00141337746754289, -0.00265289493836462, 5.02301281812834e-6, -6.6773113758245e-6, 5.02329530718271e-5, 6.71694069751538e-5, -6.46529588266276e-5, 5.70721633266658e-4] + }, + "fFlag" : -1, + "fChi2" : 0.9697773, + "fNDF" : 5, + "fB" : 0, + "fLength" : 92.94762, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 26, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.202112466096878, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0650663748383522, + "fY" : 0.752111494541168, + "fZ" : -0.029397277161479, + "fTx" : 0.0998178720474243, + "fTy" : -0.0871179550886154, + "fQp" : 0.432712346315384, + "fCovMatrix" : [0.0072921933606267, 0.00709884241223335, -2.55254155490547e-4, -9.13754774956033e-5, 0.00111449335236102, 0.194643661379814, -3.62266961019486e-4, -0.00215245992876589, 0.0025608807336539, 1.59097653522622e-5, 4.36912660006783e-6, -4.32320339314174e-5, 3.38455211021937e-5, -3.23116764775477e-5, 3.40189901180565e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 130.623626708984, + "fY" : -40.7317199707031, + "fZ" : 418.510986328125, + "fTx" : 0.435034066438675, + "fTy" : -0.10467367619276, + "fQp" : 0.449056595563889, + "fCovMatrix" : [0.237828284502029, -0.00405357731506228, 0.0010494802845642, 9.03557884157635e-6, 0.00171555520500988, 0.122831404209137, -1.28254732771893e-5, 3.97770665585995e-4, 9.06293371372158e-6, 1.19462147267768e-5, -2.69630845650681e-7, 8.22162201075116e-6, 8.13378301245393e-6, 1.14923835781156e-7, 3.84919003408868e-5] + }, + "fFlag" : -1, + "fChi2" : 2.270605, + "fNDF" : 5, + "fB" : 0, + "fLength" : 441.7074, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 27, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : 3, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : 0.944945620734558, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.282895892858505, + "fPidTof400" : [0.367648475365766, 0.127063850850765, 0.205042066366208, 0.122866346238009, 0.0401267387508722, 0.0218435322333356, 0.0748099160462014, 0.0405990741488423], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.42327404022217, + "fY" : -0.326961070299149, + "fZ" : -0.029397277161479, + "fTx" : -0.0146566452458501, + "fTy" : 0.0585484281182289, + "fQp" : 0.223260626196861, + "fCovMatrix" : [0.158489212393761, 0.0182309299707413, -0.00171128590591252, -2.75821930699749e-5, 0.00347473053261638, 0.187137201428413, -1.24398502521217e-4, -0.00103616446722299, 1.26505750813521e-4, 1.89588517969241e-5, -8.85600570654788e-8, -3.83404294552747e-5, 6.71664110996062e-6, 1.00011595804972e-6, 8.77205238793977e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 57.5408630371094, + "fY" : 34.4138870239258, + "fZ" : 605.900024414062, + "fTx" : 0.139108642935753, + "fTy" : 0.0569998435676098, + "fQp" : 0.210490927100182, + "fCovMatrix" : [0.393921136856079, 0.0393110178411007, 0.00115129828918725, 5.51040066056885e-5, 0.00425325985997915, 0.467863172292709, 9.65387298492715e-5, 0.00112714653369039, -8.35825812828261e-6, 4.31362559538684e-6, 1.26172437830974e-7, 1.26203412946779e-5, 3.70305133401416e-6, -4.76045869390873e-7, 5.79466977796983e-5] + }, + "fFlag" : -1, + "fChi2" : 13.67719, + "fNDF" : 5, + "fB" : 0, + "fLength" : 610.8903, + "fNhits" : 6, + "fUsing" : false, + "fGemTrack" : 28, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 18, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.961042344437543, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 3.5486433506012, + "fPidTof400" : [], + "fPidTof700" : [0.163541824372634, 0.0752980829855243, 0.0879493177328712, 0.0743604180735853, 0.0748810563531657, 0.0254346008230213, 0.421924078710961, 0.076610620948237], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.00911172479391098, + "fY" : -0.164421364665031, + "fZ" : -0.029397277161479, + "fTx" : -0.263669341802597, + "fTy" : 0.312872141599655, + "fQp" : 2.44544816017151, + "fCovMatrix" : [0.0111502641811967, -0.00783455837517977, -0.00132511043921113, 2.06394455744885e-4, 0.00329444627277553, 0.303729832172394, 2.42670794250444e-4, -0.00564314238727093, 0.0024704618845135, 0.00162572483532131, -1.28985644550994e-4, -2.56872037425637e-4, 0.00173591135535389, -3.69936387869529e-5, 0.00438861642032862] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.69932627677917, + "fY" : 27.9923896789551, + "fZ" : 92.2562408447266, + "fTx" : 0.326712906360626, + "fTy" : 0.314964473247528, + "fQp" : 2.5777063369751, + "fCovMatrix" : [0.0019453507848084, -0.00591527670621872, 1.0935653699562e-4, -1.62201758939773e-4, 7.15228088665754e-4, 0.0500840172171593, -4.09632222726941e-4, 0.00128573877736926, -0.00303747202269733, 2.28120879910421e-5, -3.43982901540585e-6, 1.61356016178615e-4, 7.76000015321188e-5, -4.8420228267787e-5, 0.00437125051394105] + }, + "fFlag" : -1, + "fChi2" : 12.98925, + "fNDF" : 5, + "fB" : 0, + "fLength" : 97.86718, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 29, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.635798931121826, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.205629661679268, + "fY" : -2.07671427726746, + "fZ" : -0.029397277161479, + "fTx" : -0.101186849176884, + "fTy" : 0.187364757061005, + "fQp" : 0.457021623849869, + "fCovMatrix" : [0.00312046287581325, 0.00223815767094493, -1.17492134450004e-4, -2.22616636165185e-5, 2.98019789624959e-4, 0.0929653644561768, -7.64726355555467e-5, -0.00100807147100568, 6.01950858253986e-4, 4.9029290494218e-6, 7.80315247084218e-7, -1.21380680866423e-5, 1.47311247928883e-5, -7.12718838258297e-6, 1.02549296570942e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.85358667373657, + "fY" : 26.7497463226318, + "fZ" : 154.893341064453, + "fTx" : 0.0682987794280052, + "fTy" : 0.18551504611969, + "fQp" : 0.458666443824768, + "fCovMatrix" : [0.00234777061268687, -0.00808644108474255, 4.71720522909891e-5, -8.98432699614204e-5, 1.90876264241524e-4, 0.0612202808260918, -1.42043427331373e-4, 6.91099616233259e-4, -5.6737702107057e-4, 2.28793101086922e-6, -1.78430468622537e-6, 1.14754893729696e-5, 1.07599435068551e-5, -7.92009814176708e-6, 1.02951998997014e-4] + }, + "fFlag" : -1, + "fChi2" : 18.17157, + "fNDF" : 5, + "fB" : 0, + "fLength" : 157.7993, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 30, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.55332398414612, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.220339760184288, + "fY" : 0.496376216411591, + "fZ" : -0.029397277161479, + "fTx" : -0.00211817072704434, + "fTy" : 0.0463929995894432, + "fQp" : 0.192528858780861, + "fCovMatrix" : [0.856019198894501, -0.456166356801987, -0.00840072520077229, 0.00226182793267071, 0.0166160743683577, 0.631114602088928, 0.00442369421944022, -0.00323805911466479, -0.00905261561274529, 8.46254843054339e-5, -2.20356432691915e-5, -1.63838849402964e-4, 1.9668965251185e-5, 4.52888671134133e-5, 3.39393533067778e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 59.8817138671875, + "fY" : 27.3704490661621, + "fZ" : 605.900024414062, + "fTx" : 0.133832946419716, + "fTy" : 0.0435036905109882, + "fQp" : 0.194726914167404, + "fCovMatrix" : [0.571133196353912, 0.166687563061714, 0.00170184893067926, 4.04814578359947e-4, 0.00755761843174696, 0.629211246967316, 4.91408747620881e-4, 0.00156522076576948, 0.00230193347670138, 5.77202399654198e-6, 1.20644983780949e-6, 2.28702065214748e-5, 4.64329423266463e-6, 5.85072166359168e-6, 1.16228613478597e-4] + }, + "fFlag" : -1, + "fChi2" : 1.136688, + "fNDF" : 3, + "fB" : 0, + "fLength" : 610.1001, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 31, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 17, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.959020259347422, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.256132513284683, + "fPidTof400" : [], + "fPidTof700" : [0.100323871326863, 0.0618762176814875, 0.0688716803211751, 0.0613313895791886, 0.135889689500624, 0.0316363397150543, 0.398927631656923, 0.141143180218685], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.594629168510437, + "fY" : -0.528902053833008, + "fZ" : -0.029397277161479, + "fTx" : -0.088595800101757, + "fTy" : 0.0164505969733, + "fQp" : 0.301856219768524, + "fCovMatrix" : [1.06943094730377, -0.462121158838272, -0.0106638744473457, 0.00227981200441718, 0.0175477415323257, 0.81369423866272, 0.00450004823505878, -0.00511496514081955, -0.00920255575329065, 1.12717963929754e-4, -2.23288261622656e-5, -1.74585802596994e-4, 4.31654116255231e-5, 4.5806937123416e-5, 3.64787119906396e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0862729549408, + "fY" : 3.39191007614136, + "fZ" : 253.266006469727, + "fTx" : 0.0919949263334274, + "fTy" : 0.0146251767873764, + "fQp" : 0.308357298374176, + "fCovMatrix" : [0.00187728903256357, 0.00520153529942036, 6.91362147335894e-5, 8.78545251907781e-5, 5.24696835782379e-4, 0.0438745133578777, 2.42525129579008e-4, 6.81901117786765e-4, 0.00212102546356618, 4.1156172301271e-6, 4.55953340861015e-6, 3.50678055838216e-5, 1.42927547130967e-5, 4.36515038018115e-5, 3.64597100997344e-4] + }, + "fFlag" : -1, + "fChi2" : 0.4537788, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.7004, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 32, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.14597833156586, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.09693610668182, + "fY" : 0.910544335842133, + "fZ" : -0.029397277161479, + "fTx" : 0.0502183735370636, + "fTy" : 0.0284693744033575, + "fQp" : 0.075424924492836, + "fCovMatrix" : [0.838427007198334, -0.459652572870255, -0.00817697867751122, 0.00227581011131406, 0.0165521930903196, 0.610160529613495, 0.00446027610450983, -0.00299714901484549, -0.00912789348512888, 8.03524162620306e-5, -2.21804511966184e-5, -1.62804528372362e-4, 1.54056233441224e-5, 4.55905319540761e-5, 3.35209013428539e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 54.5434494018555, + "fY" : 18.9760284423828, + "fZ" : 605.900024414062, + "fTx" : 0.107005573809147, + "fTy" : 0.0305983368307352, + "fQp" : 0.0930930972099304, + "fCovMatrix" : [0.56563675403595, 0.16722559928894, 0.00174596754368395, 3.85296909371391e-4, 0.00747825298458338, 0.630052626132965, 4.69339312985539e-4, 0.00162073923274875, 0.00243019312620163, 6.25193024461623e-6, 1.09307734419417e-6, 2.14953815884655e-5, 5.22690470461384e-6, 5.85555244470015e-6, 1.14141497761011e-4] + }, + "fFlag" : -1, + "fChi2" : 1.849876, + "fNDF" : 3, + "fB" : 0, + "fLength" : 608.6982, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 33, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 16, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.964560714384518, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.21388041973114, + "fPidTof400" : [], + "fPidTof700" : [0.10117938835824, 0.0942040931723345, 0.0959314236723074, 0.0940568189165485, 0.130333869166391, 0.243004121015255, 0.111581046200226, 0.129709239498698], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.246271401643753, + "fY" : 0.686478555202484, + "fZ" : -0.029397277161479, + "fTx" : 0.100004196166992, + "fTy" : -0.0179095789790154, + "fQp" : 0.224228218197823, + "fCovMatrix" : [1.69934582710266, 0.65160471200943, -0.0165731161832809, -0.00302895391359925, 0.0309155844151974, 0.740846633911133, -0.00629291869699955, -0.00405672565102577, 0.0124902306124568, 1.65061966981739e-4, 2.93027151201386e-5, -3.01817432045937e-4, 2.81286993413232e-5, -5.82969296374358e-5, 6.03647727984935e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 142.015197753906, + "fY" : -11.789249420166, + "fZ" : 635.900024414062, + "fTx" : 0.261783063411713, + "fTy" : -0.019876891747117, + "fQp" : 0.226378262042999, + "fCovMatrix" : [0.730842769145966, -0.143765032291412, 0.00208974187262356, -2.76358332484961e-4, 0.00865746289491653, 0.679372608661652, -3.38425335939974e-4, 0.00169669126626104, -0.00208298489451408, 1.00880961326766e-5, -6.78339972637332e-7, 2.09066220122622e-5, 8.40418761072215e-6, -4.18415947933681e-6, 1.39396972372197e-4] + }, + "fFlag" : -1, + "fChi2" : 0.7122054, + "fNDF" : 3, + "fB" : 0, + "fLength" : 652.5759, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 34, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 11, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.961074312249346, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.302201956510544, + "fPidTof400" : [], + "fPidTof700" : [0.16953417865818, 0.0772015667756544, 0.0903175448300243, 0.0762310570567533, 0.0754740336517106, 0.0258108121152269, 0.408230231610065, 0.0772005753023855], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.31043136119843, + "fY" : 0.955302178859711, + "fZ" : -0.029397277161479, + "fTx" : 0.118221916258335, + "fTy" : 0.080058217048645, + "fQp" : 0.304001986980438, + "fCovMatrix" : [0.71472954750061, 0.382430553436279, -0.0081872995942831, -0.00216610520146787, 0.0187111124396324, 0.500702857971191, -0.00434806989505887, -0.00290845660492778, 0.0101454136893153, 9.55057694227435e-5, 2.47198422584916e-5, -2.16604617889971e-4, 1.89319252967834e-5, -5.7865894632414e-5, 5.11259189806879e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 182.258880615234, + "fY" : 54.7707633972168, + "fZ" : 635.900024414062, + "fTx" : 0.336056143045425, + "fTy" : 0.0871101394295692, + "fQp" : 0.289522975683212, + "fCovMatrix" : [0.853387951850891, -0.0890597105026245, 0.00231860484927893, -9.03638356248848e-5, 0.0064244456589222, 0.737602531909943, -1.39394192956388e-4, 0.00185612577479333, -0.00130663730669767, 1.10044711618684e-5, -1.21694503363301e-8, 1.13985988718923e-5, 9.43024042499019e-6, -1.70210228134238e-6, 9.79300020844676e-5] + }, + "fFlag" : -1, + "fChi2" : 1.942739, + "fNDF" : 3, + "fB" : 0, + "fLength" : 665.3834, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 35, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 44, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.943914470571102, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.36478054523468, + "fPidTof400" : [], + "fPidTof700" : [0.299908382087893, 0.0963566464599368, 0.118141380702889, 0.0948122947218994, 0.0706504221956119, 0.028977843999243, 0.21920849937744, 0.0719445304550872], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.252122759819031, + "fY" : 0.321497887372971, + "fZ" : -0.029397277161479, + "fTx" : -0.102842479944229, + "fTy" : 0.108841717243195, + "fQp" : 0.559573948383331, + "fCovMatrix" : [0.256441533565521, 0.0546441897749901, -0.00284473551437259, -2.32375226914883e-4, 0.00498967245221138, 0.317853808403015, -4.59515140391886e-4, -0.00212748255580664, 7.54551903810352e-4, 4.81743991258554e-5, 1.53570385919011e-6, -5.81435924686957e-5, 3.23050117003731e-5, -2.43649560616177e-6, 1.43535420647822e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 126.55753326416, + "fY" : 66.642333984375, + "fZ" : 627.099975585938, + "fTx" : 0.301141917705536, + "fTy" : 0.104078777134418, + "fQp" : 0.552973508834839, + "fCovMatrix" : [0.532510101795197, 0.0278261322528124, 0.00150426605250686, 2.44738821493229e-5, 0.00452664634212852, 0.669826984405518, 4.28096900577657e-5, 0.00156850682105869, -6.47904933430254e-4, 1.31127917484264e-5, 2.68308809836526e-7, 1.29740210468299e-5, 1.20586528282729e-5, -1.80539052507811e-6, 9.89683685475029e-5] + }, + "fFlag" : -1, + "fChi2" : 5.43474, + "fNDF" : 3, + "fB" : 0, + "fLength" : 648.571, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 36, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 46, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.87911074165808, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.263937652111053, + "fPidTof400" : [], + "fPidTof700" : [0.750915369238995, 0.0399837095214084, 0.0555775724630657, 0.0389796081023081, 0.0248800841573318, 0.0137625154800943, 0.0507148910696421, 0.0251862499671541], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 8.35125255584717, + "fY" : -5.16963291168213, + "fZ" : -0.029397277161479, + "fTx" : 0.0455385223031044, + "fTy" : 0.0973970219492912, + "fQp" : -0.328985333442688, + "fCovMatrix" : [0.191143482923508, -0.139769360423088, -0.00275204074569046, 9.80156473815441e-4, 0.00684849871322513, 0.325831949710846, 0.00194071175064892, -0.00250163651071489, -0.0058176857419312, 4.03635312977713e-5, -1.37330607685726e-5, -9.97970928438008e-5, 2.20568235818064e-5, 4.17378359998111e-5, 3.08208429487422e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 3.08387875556946, + "fY" : 13.6549243927002, + "fZ" : 190.759826660156, + "fTx" : -0.10558620095253, + "fTy" : 0.100344710052013, + "fQp" : -0.331057548522949, + "fCovMatrix" : [0.00188889005221426, 0.0052486308850348, 7.33881024643779e-5, 8.69609430083074e-5, 4.84872958622873e-4, 0.0440538413822651, 2.59661668678746e-4, 6.78094103932381e-4, 0.00196568109095097, 4.63806691186619e-6, 4.78684660265571e-6, 3.48159555869643e-5, 1.40232677949825e-5, 3.92855836253148e-5, 3.06403584545478e-4] + }, + "fFlag" : -1, + "fChi2" : 1.668341, + "fNDF" : 3, + "fB" : 0, + "fLength" : 192.0008, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 37, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 10.0490455627441, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.28303253650665, + "fY" : 1.30700790882111, + "fZ" : -0.029397277161479, + "fTx" : 0.0388444475829601, + "fTy" : 0.022368460893631, + "fQp" : 0.203636944293976, + "fCovMatrix" : [0.885250806808472, -0.456907033920288, -0.00862818583846092, 0.00226107379421592, 0.0165749415755272, 0.655868411064148, 0.00442192470654845, -0.00343009643256664, -0.00898995902389288, 8.562996663386e-5, -2.19829889829271e-5, -1.63257514941506e-4, 2.04157349799061e-5, 4.4899989006808e-5, 3.36210272507742e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 92.9929122924805, + "fY" : 15.0256376266479, + "fZ" : 627.099975585938, + "fTx" : 0.187706679105759, + "fTy" : 0.0218684803694487, + "fQp" : 0.224675580859184, + "fCovMatrix" : [0.594597280025482, 0.162580519914627, 0.00167092029005289, 3.75143717974424e-4, 0.00739389378577471, 0.651716470718384, 4.48378792498261e-4, 0.00154582876712084, 0.00215009367093444, 5.87892918701982e-6, 1.04710966297716e-6, 2.09640384127852e-5, 4.87662600789918e-6, 5.20957382832421e-6, 1.08788466604892e-4] + }, + "fFlag" : -1, + "fChi2" : 7.156267, + "fNDF" : 3, + "fB" : 0, + "fLength" : 634.7792, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 38, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : 13, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : 0.952927221992502, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.56047129631042, + "fPidTof400" : [], + "fPidTof700" : [0.100793094280577, 0.0632901473876582, 0.0702298936320627, 0.0627474411774333, 0.157275123535341, 0.0347752208236058, 0.347029417332214, 0.163859661831108], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.04722690582275, + "fY" : -2.69119024276733, + "fZ" : -0.029397277161479, + "fTx" : -0.214173540472984, + "fTy" : 0.066271185874939, + "fQp" : 0.973324179649353, + "fCovMatrix" : [1.90959751605988, 0.345857620239258, -0.0221297480165958, -0.00174162059556693, 0.0235025100409985, 1.65526366233826, -0.00379488314501941, -0.0158087480813265, 0.00983281247317791, 2.70639488007873e-4, 1.81523137143813e-5, -2.8962770011276e-4, 1.7496311920695e-4, -5.34687205799855e-5, 7.56440567784011e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 18.6140308380127, + "fY" : 11.1579370498657, + "fZ" : 217.384552001953, + "fTx" : 0.324826687574387, + "fTy" : 0.0648133456707001, + "fQp" : 1.02351033687592, + "fCovMatrix" : [0.00179702998138964, -0.00483735324814916, 9.20187958399765e-5, -9.39793317229487e-5, 6.35934644378722e-4, 0.0419517792761326, -3.39350604917854e-4, 7.26883299648762e-4, -0.00259862025268376, 8.94437198439846e-6, -6.71676525598741e-6, 5.96006648265757e-5, 1.98985035240185e-5, -5.73953657294624e-5, 7.41470488719642e-4] + }, + "fFlag" : -1, + "fChi2" : 10.82403, + "fNDF" : 3, + "fB" : 0, + "fLength" : 220.8732, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 39, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 9.55130958557129, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.91946142911911, + "fY" : 0.232333868741989, + "fZ" : -0.029397277161479, + "fTx" : -0.0127219893038273, + "fTy" : 0.160901710391045, + "fQp" : 2.90746116638184, + "fCovMatrix" : [0.177920520305634, 0.0281006842851639, -0.013226586394012, -6.87061459757388e-4, 0.0368262194097042, 1.46299779415131, -9.60385252255946e-4, -0.0484406352043152, 0.0363761745393276, 0.00313101150095463, 1.39051771839149e-5, -0.00289830728434026, 0.00418889243155718, -0.00107791973277926, 0.0573726929724216] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.4197807312012, + "fY" : 7.84360790252686, + "fZ" : 46.3479995727539, + "fTx" : 0.674497842788696, + "fTy" : 0.180485606193542, + "fQp" : 6.65022325515747, + "fCovMatrix" : [3.4709763713181e-4, 0.00678978255018592, 3.63292347174138e-5, 3.32853232976049e-4, 9.68408057815395e-5, 0.311384648084641, 2.99614679533988e-4, 0.0151938563212752, -0.015667324885726, 8.55263933772221e-5, 2.96559246635297e-5, 8.48880503326654e-4, 0.00118385872337967, -0.00109430367592722, 0.0491611175239086] + }, + "fFlag" : -1, + "fChi2" : 0.005968111, + "fNDF" : 3, + "fB" : 0, + "fLength" : 50.51086, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 40, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.916526854038239, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.275234311819077, + "fY" : 1.66185438632965, + "fZ" : -0.029397277161479, + "fTx" : 0.122508220374584, + "fTy" : -0.217079237103462, + "fQp" : -4.45832967758179, + "fCovMatrix" : [0.114827856421471, -0.0195787586271763, -0.00612082332372665, 4.99484944157302e-4, 0.0182293485850096, 0.788843810558319, 5.74966601561755e-4, -0.0182638317346573, 0.00971878785640001, 3.3414555946365e-4, -2.01960465346929e-5, -0.00125481258146465, 5.39348344318569e-4, -2.4483390734531e-4, 0.0213687140494585] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -10.7083158493042, + "fY" : -11.8248224258423, + "fZ" : 61.02734375, + "fTx" : -0.561766088008881, + "fTy" : -0.246598660945892, + "fQp" : -4.54282855987549, + "fCovMatrix" : [0.00231565581634641, -0.00833991821855307, 2.11953214602545e-4, -2.98762606689706e-4, 0.00200965511612594, 0.0665908977389336, -7.94334802776575e-4, 0.00232968013733625, -0.00770675344392657, 5.23287199030165e-5, -9.87282601272454e-6, 2.70730466581881e-4, 3.05086723528802e-4, -2.41832807660103e-4, 0.019675899296999] + }, + "fFlag" : -1, + "fChi2" : 0.1263451, + "fNDF" : 3, + "fB" : 0, + "fLength" : 65.30978, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 41, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.21506714820862, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.0335058271884918, + "fY" : -1.51622080802917, + "fZ" : -0.029397277161479, + "fTx" : -0.165475994348526, + "fTy" : -0.153514385223389, + "fQp" : 0.322940051555634, + "fCovMatrix" : [0.0123558649793267, 0.0297732409089804, -6.35048025287688e-4, -7.31324544176459e-4, 0.00731065683066845, 0.72432404756546, -0.00114081020001322, -0.0130683984607458, 0.0117901284247637, 3.77267788280733e-5, 3.2857740734471e-5, -3.99347540223971e-4, 2.5628472212702e-4, -3.79003584384918e-4, 0.00492897210642695] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.76997375488281, + "fY" : -10.8661489486694, + "fZ" : 61.0379409790039, + "fTx" : -0.120636485517025, + "fTy" : -0.152578368782997, + "fQp" : 0.323388069868088, + "fCovMatrix" : [0.00224469392560422, -0.00816680397838354, 1.83035343070515e-4, -2.75593047263101e-4, 0.00273431115783751, 0.0664315596222878, -7.01152719557285e-4, 0.00225460040383041, -0.0107996184378862, 1.73376683960669e-5, -1.98681918845978e-5, 2.78609455563128e-4, 2.4982143077068e-4, -3.56033619027585e-4, 0.00484105106443167] + }, + "fFlag" : -1, + "fChi2" : 1.90604, + "fNDF" : 3, + "fB" : 0, + "fLength" : 62.37534, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 42, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 1.98709070682526, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -0.00213396013714373, + "fY" : 0.48422384262085, + "fZ" : -0.029397277161479, + "fTx" : 0.0537827350199223, + "fTy" : -0.132247969508171, + "fQp" : 2.03384852409363, + "fCovMatrix" : [0.101356752216816, -0.0128131154924631, -0.00456118118017912, 6.7466105974745e-5, 0.00246793427504599, 0.533158957958221, 1.97527144337073e-4, -0.00875409226864576, -0.0013283061562106, 7.86647957284003e-4, -3.3255462312809e-6, -1.09059757960495e-4, 8.35597806144506e-4, 3.04340073853382e-6, 0.00114914972800761] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 49.6317138671875, + "fY" : -18.7386264801025, + "fZ" : 123.735862731934, + "fTx" : 0.922451794147491, + "fTy" : -0.211355149745941, + "fQp" : 2.14829063415527, + "fCovMatrix" : [0.00199073599651456, -0.00600775657221675, 1.30909102153964e-4, -1.49604718899354e-4, 4.00048622395843e-4, 0.0492274090647697, -5.2100548055023e-4, 0.00109832175076008, -0.00148220511619002, 2.66304086835589e-5, -8.38927280710777e-6, 6.87345527694561e-5, 6.45601903670467e-5, -1.4814616406511e-5, 0.00107164145447314] + }, + "fFlag" : -1, + "fChi2" : 2.83805, + "fNDF" : 3, + "fB" : 0, + "fLength" : 139.7365, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 43, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.0390104465186596, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.563175976276398, + "fY" : 0.295070111751556, + "fZ" : -0.029397277161479, + "fTx" : -0.210707888007164, + "fTy" : 0.237468779087067, + "fQp" : 2.66978096961975, + "fCovMatrix" : [0.119420446455479, -0.0222559794783592, -0.00668415892869234, 6.79671531543136e-4, 0.00474497023969889, 0.61498498916626, 7.88265897426754e-4, -0.0122374352067709, 9.89413587376475e-4, 0.00234816665761173, -1.29664302221499e-4, -2.24227813305333e-4, 0.00244257412850857, 2.40578519878909e-5, 0.00245440984144807] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.9655494689941, + "fY" : 31.9299697875977, + "fZ" : 128.266860961914, + "fTx" : 1.03927612304688, + "fTy" : 0.324166595935822, + "fQp" : 3.00718474388123, + "fCovMatrix" : [0.00225362344644964, 0.0075716795399785, 1.34594927658327e-4, 1.78253525518812e-4, 3.82453668862581e-4, 0.0592034570872784, 5.54147001821548e-4, 0.00129310914780945, 0.00136285566259176, 4.59551192761865e-5, 1.16209812404122e-5, 1.57154776388779e-4, 7.96331441961229e-5, 1.55477555381367e-5, 0.00224633538164198] + }, + "fFlag" : -1, + "fChi2" : 2.90521, + "fNDF" : 3, + "fB" : 0, + "fLength" : 145.9663, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 44, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.557120323181152, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.513113439083099, + "fY" : -1.57424020767212, + "fZ" : -0.029397277161479, + "fTx" : -0.141265794634819, + "fTy" : -0.126548111438751, + "fQp" : -0.795029163360596, + "fCovMatrix" : [0.00408678036183119, 0.00675002112984657, -1.90156177268364e-4, -6.32357405265793e-5, 0.00104396394453943, 0.342634350061417, -4.0326027374249e-5, -0.00397018203511834, -4.78200527140871e-4, 1.22749943329836e-5, -1.96956435161155e-7, -4.79923328384757e-5, 5.88821931160055e-5, 1.83065239980351e-5, 4.62605647044256e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -22.0228366851807, + "fY" : -14.0940723419189, + "fZ" : 97.1422271728516, + "fTx" : -0.338983148336411, + "fTy" : -0.132703423500061, + "fQp" : -0.786303102970123, + "fCovMatrix" : [0.00249015097506344, 0.00926257483661175, 8.01757778390311e-5, 1.46307735121809e-4, 4.15503891417757e-4, 0.071669764816761, 2.8469690005295e-4, 0.00112168665509671, 0.0013581917155534, 4.9180093810719e-6, 5.47497120351181e-6, 3.15871002385393e-5, 5.38857966603246e-5, 2.07644352485659e-5, 4.52636770205572e-4] + }, + "fFlag" : -1, + "fChi2" : 4.028943, + "fNDF" : 3, + "fB" : 0, + "fLength" : 100.9747, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 45, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 2.1003634929657, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.225736543536186, + "fY" : 0.73824143409729, + "fZ" : -0.029397277161479, + "fTx" : 0.315195262432098, + "fTy" : -0.191795274615288, + "fQp" : 2.64431071281433, + "fCovMatrix" : [0.0222062785178423, -0.0094115762040019, -0.002589798765257, 2.46618670644239e-4, 0.0031125124078244, 0.455695301294327, 1.93938249140047e-4, -0.0101200696080923, -0.00145055854227394, 0.00224911631084979, -1.20157463243231e-4, -2.46833777055144e-4, 0.00226118532009423, 8.53220899443841e-6, 0.00390081130899489] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 35.2132225036621, + "fY" : -12.9507713317871, + "fZ" : 61.2922630310059, + "fTx" : 0.945975542068481, + "fTy" : -0.284506976604462, + "fQp" : 2.88229727745056, + "fCovMatrix" : [0.00233683804981411, -0.00856001209467649, 1.85092372703366e-4, -2.543551963754e-4, 8.70178337208927e-4, 0.0678045079112053, -6.34722004178911e-4, 0.00189690559636801, -0.00251634069718421, 3.38984646077733e-5, -2.53437228820985e-5, 8.01854839664884e-5, 1.95868473383598e-4, -6.10732240602374e-5, 0.0034143861848861] + }, + "fFlag" : -1, + "fChi2" : 6.323329, + "fNDF" : 3, + "fB" : 0, + "fLength" : 74.54071, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 46, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.32871201634407, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -30.5383033752441, + "fY" : 1.39664745330811, + "fZ" : -0.029397277161479, + "fTx" : 0.177466601133347, + "fTy" : 0.0839891508221626, + "fQp" : 0.404217898845673, + "fCovMatrix" : [0.165444180369377, -0.131337389349937, -0.00230440474115312, 9.09044698346406e-4, 0.00588673027232289, 0.302562415599823, 0.00179641973227262, -0.00214587501250207, -0.00481910118833184, 3.27145353367086e-5, -1.25628876048722e-5, -8.52862722240388e-5, 1.63093718583696e-5, 3.41204977303278e-5, 2.44537193793803e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 21.804407119751, + "fY" : 17.5602760314941, + "fZ" : 190.816345214844, + "fTx" : 0.382342100143433, + "fTy" : 0.0868466049432755, + "fQp" : 0.404914736747742, + "fCovMatrix" : [0.00190632219891995, 0.00534393405541778, 7.47169833630323e-5, 9.11921524675563e-5, 4.20524040237069e-4, 0.0445523224771023, 2.66797083895653e-4, 6.97484647389501e-4, 0.00170170434284955, 4.85355940327281e-6, 5.06681362821837e-6, 3.06623078358825e-5, 1.476433044445e-5, 3.50714653905015e-5, 2.42588197579607e-4] + }, + "fFlag" : -1, + "fChi2" : 8.000236, + "fNDF" : 3, + "fB" : 0, + "fLength" : 199.1183, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 47, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 30.5868377685547, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -4.15788125991821, + "fY" : 1.49865877628326, + "fZ" : -0.029397277161479, + "fTx" : 0.165132060647011, + "fTy" : 0.152950182557106, + "fQp" : 2.11752772331238, + "fCovMatrix" : [0.803330659866333, 0.0291136298328638, -0.104805134236813, -0.00241396785713732, 0.0123779531568289, 1.47373652458191, -0.00225822115316987, -0.112295806407928, 0.00424707541242242, 0.0190371759235859, 3.99815151467919e-4, -5.48746669664979e-4, 0.0189147349447012, -8.27027688501403e-5, 0.00546088628470898] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 75.0670471191406, + "fY" : 19.5143299102783, + "fZ" : 92.2631225585938, + "fTx" : 3.7820155620575, + "fTy" : 0.601390242576599, + "fQp" : 3.85533571243286, + "fCovMatrix" : [0.00235269544646144, -0.00818183925002813, 5.11665304657072e-4, -1.08604559500236e-4, 4.72164072562009e-4, 0.0635098516941071, -0.00206283130683005, 0.00135259691160172, -0.00227036792784929, 0.00325425225310028, 6.31853705272079e-4, 0.00235342606902122, 3.95051145460457e-4, 4.07467334298417e-4, 0.00299980654381216] + }, + "fFlag" : -1, + "fChi2" : 9.250807, + "fNDF" : 3, + "fB" : 0, + "fLength" : 158.3051, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 48, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.31654691696167, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/demo/playground/src/jvmMain/resources/root/event_3.json b/demo/playground/src/jvmMain/resources/root/event_3.json new file mode 100644 index 00000000..f464037f --- /dev/null +++ b/demo/playground/src/jvmMain/resources/root/event_3.json @@ -0,0 +1,1370 @@ +[ +[{ + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 296852409, + "fStsHits" : [34, 58, 92, 111, 171, 294, 404], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 6.57000637054443, + "fY" : -9.91232872009277, + "fZ" : 61.1045799255371, + "fTx" : 0.114455692470074, + "fTy" : -0.1505176872015, + "fQp" : 0.338748455047607, + "fCovMatrix" : [0.00120294780936092, -0.00171040813438594, -2.56735456787283e-5, 1.45627755046007e-5, 6.92404646542855e-5, 0.0211342666298151, 4.00367316615302e-5, -1.75163280800916e-4, -9.87588136922568e-5, 1.06791651433014e-6, -3.21843600659122e-7, -2.9935415568616e-6, 2.51033725362504e-6, 6.99544045801304e-7, 2.2037434973754e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.1752090454102, + "fY" : -38.9115219116211, + "fZ" : 248.808853149414, + "fTx" : 0.279569119215012, + "fTy" : -0.157896891236305, + "fQp" : 0.340472787618637, + "fCovMatrix" : [0.00104028766509145, -0.00114251440390944, 2.29178640438477e-5, -1.0253203981847e-5, 6.06082467129454e-5, 0.0189696997404099, -3.21910156344529e-5, 1.621104311198e-4, -3.92368820030242e-5, 1.24302925996744e-6, -2.82433489928735e-7, 2.32914885600621e-6, 2.77825802186271e-6, -2.97843882890447e-8, 2.20006022573216e-5] + }, + "fFlag" : 0, + "fChi2" : 4.72594213485718, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509938528, + "fStsHits" : [495, 502, 509, 6, 36, 88, 149, 274, 362], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.46920967102051, + "fY" : 4.42782402038574, + "fZ" : 27.8159999847412, + "fTx" : 0.100209705531597, + "fTy" : 0.168729975819588, + "fQp" : -0.836885154247284, + "fCovMatrix" : [1.54722292791121e-4, 8.1766297807917e-4, -8.44947771838633e-6, -9.4166016424424e-6, 1.2599280125869e-5, 0.0388076938688755, -1.58085754264903e-6, -4.45390585809946e-4, -5.80995438212994e-5, 1.41129896746861e-6, 1.41468447623083e-7, -2.47726916313695e-6, 9.47681564866798e-6, 4.38638409150371e-7, 7.41747935535386e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.2282524108887, + "fY" : 43.8057022094727, + "fZ" : 253.266006469727, + "fTx" : -0.393378973007202, + "fTy" : 0.183965146541595, + "fQp" : -0.841169774532318, + "fCovMatrix" : [0.00138695456553251, 0.00245250947773457, 4.07528132200241e-5, 3.07277732645161e-5, 6.74965558573604e-5, 0.0257465783506632, 9.16569624678232e-5, 2.88728624582291e-4, 1.5688432904426e-4, 3.51272797161073e-6, 7.95116307017452e-7, 4.9578438847675e-6, 8.48969284561463e-6, 1.90970308722171e-6, 7.40295581636019e-5] + }, + "fFlag" : 0, + "fChi2" : 4.60224008560181, + "fNDF" : 13, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509942208, + "fStsHits" : [500, 505, 511, 40, 91, 110, 148], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.1521635055542, + "fY" : 4.84085178375244, + "fZ" : 28.9860000610352, + "fTx" : -0.146197408437729, + "fTy" : 0.17111112177372, + "fQp" : -1.1365875005722, + "fCovMatrix" : [1.54369670781307e-4, 8.92427342478186e-4, -1.27299881569343e-5, -9.00611303222831e-6, 1.47260780067882e-5, 0.0776186287403107, -1.79295893758535e-4, -8.92429146915674e-4, -1.04104001366068e-4, 2.71486078418093e-6, 1.70441876434779e-6, -4.23068786403746e-6, 1.92049847100861e-5, 1.56831117692491e-6, 1.90227205166593e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -69.8452606201172, + "fY" : 35.5888671875, + "fZ" : 190.759826660156, + "fTx" : -0.755924940109253, + "fTy" : 0.234108626842499, + "fQp" : -1.1410653591156, + "fCovMatrix" : [0.0016210189787671, 0.00367055041715503, 5.95567980781198e-5, 4.92073886562139e-5, 1.30036598420702e-4, 0.0339352935552597, 1.72936561284587e-4, 4.68151818495244e-4, 3.72272508684546e-4, 7.08813240635209e-6, 1.15282068691158e-6, 1.59920909936773e-5, 1.43599054354127e-5, 8.06203615866252e-7, 1.84375589014962e-4] + }, + "fFlag" : 0, + "fChi2" : 8.86424922943115, + "fNDF" : 9, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : -1067520869, + "fStsHits" : [93, 113, 213, 302, 437], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 12.5838489532471, + "fY" : -2.74226856231689, + "fZ" : 123.501998901367, + "fTx" : 0.125694692134857, + "fTy" : -0.0128870774060488, + "fQp" : 0.235099822282791, + "fCovMatrix" : [0.00148753076791763, -0.00286372099071741, -4.24543140979949e-5, 2.97241167572793e-5, 1.96587119717151e-4, 0.0292670801281929, 8.35246173664927e-5, -3.15573968691751e-4, -3.55950993252918e-4, 2.13228327083925e-6, -6.59350348541921e-7, -1.18663283501519e-5, 4.95868243888253e-6, 1.70585974501591e-6, 8.24067028588615e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.9461936950684, + "fY" : -4.42597818374634, + "fZ" : 248.747436523438, + "fTx" : 0.196269676089287, + "fTy" : -0.0137906949967146, + "fQp" : 0.234843328595161, + "fCovMatrix" : [0.00120935030281544, -0.00178178038913757, 3.31491100951098e-5, -1.84210657607764e-5, 1.62665004609153e-4, 0.0247486550360918, -5.01800968777388e-5, 2.78292311122641e-4, -1.82114410563372e-4, 1.74688352672092e-6, -2.68147317683542e-7, 1.01446121334448e-5, 4.99256657349179e-6, 1.13328542283853e-6, 8.19254855741747e-5] + }, + "fFlag" : 0, + "fChi2" : 20.5910758972168, + "fNDF" : 5, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [89, 106, 141, 239], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 10.9574069976807, + "fY" : 10.8984527587891, + "fZ" : 128.236862182617, + "fTx" : 0.13301394879818, + "fTy" : 0.0904059484601021, + "fQp" : 0.308079034090042, + "fCovMatrix" : [0.0017817176412791, 0.00475242547690868, -8.85804984136485e-5, -9.14301272132434e-5, 6.59521669149399e-4, 0.0414591357111931, -3.23259591823444e-4, -7.04148609656841e-4, 0.00271017011255026, 7.20695197742316e-6, 6.85740587869077e-6, -5.9744681493612e-5, 1.60877989401342e-5, -6.05789900873788e-5, 5.47787582036108e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 25.9320220947266, + "fY" : 18.9775524139404, + "fZ" : 217.384552001953, + "fTx" : 0.202286452054977, + "fTy" : 0.091080442070961, + "fQp" : 0.30821368098259, + "fCovMatrix" : [0.00176186766475439, -0.00465359771624207, 8.62092056195252e-5, -8.90066658030264e-5, 6.51401758659631e-4, 0.0409622117877007, -3.11948562739417e-4, 6.92703877575696e-4, -0.00266375578939915, 6.9299348979257e-6, -6.57674172543921e-6, 5.83395376452245e-5, 1.5830855772947e-5, -5.93766999372747e-5, 5.46319701243192e-4] + }, + "fFlag" : 0, + "fChi2" : 0.100665181875229, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [109, 150, 268, 370], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.04536199569702, + "fY" : 22.8184032440186, + "fZ" : 154.863342285156, + "fTx" : -0.00300517166033387, + "fTy" : 0.152006968855858, + "fQp" : 0.124095372855663, + "fCovMatrix" : [0.00190175464376807, -0.00531620439141989, -7.45397337595932e-5, 8.9641755039338e-5, 5.00830821692944e-4, 0.0443901121616364, 2.65212351223454e-4, -6.89060485456139e-4, -0.00202822429127991, 4.62873231299454e-6, -5.03400860907277e-6, -3.58479737769812e-5, 1.40884512802586e-5, 4.14812056988012e-5, 2.99814593745396e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.87017381191254, + "fY" : 37.7572059631348, + "fZ" : 253.266006469727, + "fTx" : 0.0264327693730593, + "fTy" : 0.151600807905197, + "fQp" : 0.124097675085068, + "fCovMatrix" : [0.00188965618144721, 0.0052546733058989, 7.22920085536316e-5, 8.74364632181823e-5, 4.96948370710015e-4, 0.044090673327446, 2.55633989581838e-4, 6.79159304127097e-4, 0.00200395938009024, 4.36992058894248e-6, 4.77146477351198e-6, 3.46658707712777e-5, 1.38237774081063e-5, 4.04370002797805e-5, 2.99695821013302e-4] + }, + "fFlag" : 0, + "fChi2" : 0.226910412311554, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [97, 136, 222, 314], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -3.58799624443054, + "fY" : -8.976881980896, + "fZ" : 123.397521972656, + "fTx" : -0.0131417205557227, + "fTy" : -0.0661567151546478, + "fQp" : 0.162161365151405, + "fCovMatrix" : [0.00190816225949675, -0.00534867076203227, -7.42775955586694e-5, 8.95381745067425e-5, 4.84511750983074e-4, 0.0445656515657902, 2.64561153016984e-4, -6.88906409777701e-4, -0.00197574705816805, 4.58586055174237e-6, -4.97963310408522e-6, -3.43889660143759e-5, 1.40434758577612e-5, 4.01280922233127e-5, 2.8115973691456e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.89048075675964, + "fY" : -15.52707862854, + "fZ" : 222.077667236328, + "fTx" : 0.0265315920114517, + "fTy" : -0.0665754824876785, + "fQp" : 0.162168383598328, + "fCovMatrix" : [0.00189096131362021, 0.00525919208303094, 7.12687469786033e-5, 8.75819096108899e-5, 4.80103975860402e-4, 0.0441058911383152, 2.50725541263819e-4, 6.79370888974518e-4, 0.00194779096636921, 4.24357494921423e-6, 4.68637608719291e-6, 3.30064540321473e-5, 1.38364857775741e-5, 3.94360940845218e-5, 2.81097542028874e-4] + }, + "fFlag" : 0, + "fChi2" : 0.451097756624222, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [123, 186, 329, 449], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.5336303710938, + "fY" : -3.46899247169495, + "fZ" : 159.687271118164, + "fTx" : -0.124593898653984, + "fTy" : -0.0750735253095627, + "fQp" : 0.354338347911835, + "fCovMatrix" : [0.00179788842797279, 0.00481476075947285, -9.4004011771176e-5, -9.17777142603882e-5, 7.1522785583511e-4, 0.0416768379509449, -3.45318461768329e-4, -7.08897190634161e-4, 0.00290325935930014, 8.33640388009371e-6, 7.05097045283765e-6, -6.65459374431521e-5, 1.7228041542694e-5, -6.33006930002011e-5, 6.9790770066902e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.85834217071533, + "fY" : -10.2067451477051, + "fZ" : 248.59846496582, + "fTx" : -0.0520231463015079, + "fTy" : -0.0764518603682518, + "fQp" : 0.354904860258102, + "fCovMatrix" : [0.00174834718927741, -0.004612120334059, 8.24026938062161e-5, -9.13782932912e-5, 7.04309437423944e-4, 0.0408704169094563, -2.97947903163731e-4, 7.05018232110888e-4, -0.00286549958400428, 6.46585021968349e-6, -6.47028218736523e-6, 6.13997981417924e-5, 1.67413891176693e-5, -6.62249440210871e-5, 7.03481142409146e-4] + }, + "fFlag" : 0, + "fChi2" : 3.45493102073669, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [126, 180, 312, 408], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.11370420455933, + "fY" : -6.19081974029541, + "fZ" : 159.640716552734, + "fTx" : 0.0766926929354668, + "fTy" : -0.0279160887002945, + "fQp" : 0.13067901134491, + "fCovMatrix" : [0.00179118709638715, 0.00477873161435127, -9.22102408367209e-5, -9.02009705896489e-5, 7.27188482414931e-4, 0.0414711087942123, -3.37155506713316e-4, -6.97095936629921e-4, 0.00297126267105341, 7.66818720876472e-6, 7.01760245647165e-6, -6.78419237374328e-5, 1.55325342348078e-5, -6.47546985419467e-5, 6.31099799647927e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.1892690658569, + "fY" : -8.69165992736816, + "fZ" : 248.638809204102, + "fTx" : 0.10332266241312, + "fTy" : -0.0282121077179909, + "fQp" : 0.130729869008064, + "fCovMatrix" : [0.0017405046382919, -0.00456876307725906, 8.11685167718679e-5, -8.95584089448676e-5, 7.05139013007283e-4, 0.0406320914626122, -2.91850272333249e-4, 6.9410540163517e-4, -0.0028778335545212, 6.1214336710691e-6, -6.37108087175875e-6, 6.03011758357752e-5, 1.58327566168737e-5, -6.63357495795935e-5, 6.34717929642648e-4] + }, + "fFlag" : 0, + "fChi2" : 8.80130481719971, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [118, 182, 331, 447], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.6413908004761, + "fY" : -6.14414262771606, + "fZ" : 159.68798828125, + "fTx" : -0.137811452150345, + "fTy" : -0.0411436446011066, + "fQp" : -0.970387399196625, + "fCovMatrix" : [0.00180307461414486, 0.00485242856666446, -9.49772147578187e-5, -9.2729547759518e-5, 6.89088425133377e-4, 0.0419448800384998, -3.51462047547102e-4, -7.19539937563241e-4, 0.0028468556702137, 9.27071050682571e-6, 6.83604685036698e-6, -6.56809643260203e-5, 1.94475542230066e-5, -5.98876467847731e-5, 7.98660155851394e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.4837646484375, + "fY" : -9.48062133789062, + "fZ" : 248.519302368164, + "fTx" : -0.352763444185257, + "fTy" : -0.0339179635047913, + "fQp" : -0.972050666809082, + "fCovMatrix" : [0.00178857066202909, -0.00480817910283804, 9.02258398127742e-5, -9.74497888819315e-5, 6.59170967992395e-4, 0.0418470054864883, -3.33041214616969e-4, 7.43029173463583e-4, -0.00274206721223891, 8.91559921001317e-6, -6.74819648338598e-6, 5.53193567611743e-5, 2.14663104998181e-5, -6.56304910080507e-5, 7.88591278251261e-4] + }, + "fFlag" : 0, + "fChi2" : 11.6502780914307, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 0, + "fStsHits" : [125, 201, 301, 438], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 9.01333904266357, + "fY" : -4.94230794906616, + "fZ" : 159.662322998047, + "fTx" : 0.266647726297379, + "fTy" : -0.0456439964473248, + "fQp" : 0.358276426792145, + "fCovMatrix" : [0.00179056881461293, 0.00477772951126099, -9.21343598747626e-5, -9.01032763067633e-5, 6.40454236418009e-4, 0.0414822958409786, -3.37014178512618e-4, -6.97992625646293e-4, 0.00260217650793493, 7.85415795689914e-6, 6.90964134264505e-6, -5.95282181166112e-5, 1.60820218297886e-5, -5.63795147172641e-5, 5.22615504451096e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.6136207580566, + "fY" : -9.08453845977783, + "fZ" : 248.767608642578, + "fTx" : 0.348794728517532, + "fTy" : -0.0466611199080944, + "fQp" : 0.357887446880341, + "fCovMatrix" : [0.00174852868076414, -0.00460646999999881, 8.27661424409598e-5, -8.9719491370488e-5, 6.22440304141492e-4, 0.0408178381621838, -2.99103499855846e-4, 6.9653894752264e-4, -0.00252968561835587, 6.56514612273895e-6, -6.37573566564242e-6, 5.31558325747028e-5, 1.64152570505394e-5, -5.77251703361981e-5, 5.26623975019902e-4] + }, + "fFlag" : 0, + "fChi2" : 13.0512256622314, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509947728, + "fStsHits" : [134, 236, 326, 418], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.37234425544739, + "fY" : -3.36550641059875, + "fZ" : 159.607604980469, + "fTx" : 0.0546356178820133, + "fTy" : -0.0443619750440121, + "fQp" : 1.37652194499969, + "fCovMatrix" : [0.00182872219011188, 0.00499599240720272, -9.81753037194721e-5, -9.82725541689433e-5, 6.9363642251119e-4, 0.0427631102502346, -3.67360975360498e-4, -7.55574263166636e-4, 0.002793526975438, 1.06962861536886e-5, 6.94656819177908e-6, -7.06074861227535e-5, 2.33454065892147e-5, -5.84443005209323e-5, 0.00108496204484254] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.0822811126709, + "fY" : -7.50871706008911, + "fZ" : 248.654602050781, + "fTx" : 0.35296493768692, + "fTy" : -0.0471868738532066, + "fQp" : 1.38267636299133, + "fCovMatrix" : [0.00181278993841261, -0.00494082737714052, 9.53344424488023e-5, -1.00094614026602e-4, 6.32787239737809e-4, 0.0426238588988781, -3.58232791768387e-4, 7.70228973124176e-4, -0.00252008717507124, 1.11789231596049e-5, -6.73666454531485e-6, 5.27514894201886e-5, 2.64508908003336e-5, -5.84950903430581e-5, 0.00108214910142124] + }, + "fFlag" : 0, + "fChi2" : 7.96521520614624, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}, { + "_typename" : "CbmStsTrack", + "fUniqueID" : 0, + "fBits" : 0, + "ststrk" : 509947728, + "fStsHits" : [115, 197, 303, 409], + "fMvdHits" : [], + "fPidHypo" : 211, + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 15.0809373855591, + "fY" : -6.98929262161255, + "fZ" : 159.695938110352, + "fTx" : 0.0689177364110947, + "fTy" : -0.00790996197611094, + "fQp" : -0.841446995735168, + "fCovMatrix" : [0.00180781364906579, 0.00486746476963162, -9.56724179559387e-5, -9.2438880528789e-5, 7.55298184230924e-4, 0.0419658273458481, -3.5373936407268e-4, -7.14505207724869e-4, 0.00312060676515102, 8.95912853593472e-6, 7.02754232406733e-6, -7.28257728042081e-5, 1.81177365448093e-5, -6.62021557218395e-5, 8.50404088851064e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.2809133529663, + "fY" : -7.53941249847412, + "fZ" : 248.638809204102, + "fTx" : -0.100862711668015, + "fTy" : -0.00437753833830357, + "fQp" : -0.844026267528534, + "fCovMatrix" : [0.00176415592432022, -0.00469323294237256, 8.53097735671327e-5, -9.46945510804653e-5, 7.16785027179867e-4, 0.0412978753447533, -3.11316456645727e-4, 7.260687998496e-4, -0.00294898869469762, 7.65372715250123e-6, -6.52985136184725e-6, 5.96674617554527e-5, 1.96662622329313e-5, -7.00035234331153e-5, 8.53373727295548e-4] + }, + "fFlag" : 0, + "fChi2" : 16.2323703765869, + "fNDF" : 3, + "fB" : 0, + "fnEv" : 0, + "fHitsArr" : { + "_typename" : "TClonesArray", + "name" : "CbmStsHits", + "arr" : [] + } +}] +, +[{ + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.0553092956543, + "fY" : -0.759159684181213, + "fZ" : -0.0741752609610558, + "fTx" : 0.0682807937264442, + "fTy" : -0.148917526006699, + "fQp" : 0.33812740445137, + "fCovMatrix" : [0.0126965418457985, -0.00686986232176423, -1.94974621990696e-4, 3.77058713638689e-5, 3.4901627805084e-4, 0.0537109524011612, 7.84804724389687e-5, -3.72759677702561e-4, -1.43871977343224e-4, 8.03290822659619e-6, -4.70490732595863e-7, -5.99395752942655e-6, 8.34861111798091e-6, 7.59855993237579e-7, 2.20557340071537e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.1752090454102, + "fY" : -38.9115219116211, + "fZ" : 248.808853149414, + "fTx" : 0.279569119215012, + "fTy" : -0.157896891236305, + "fQp" : 0.340472787618637, + "fCovMatrix" : [0.00104028766509145, -0.00114251440390944, 2.29178640438477e-5, -1.0253203981847e-5, 6.06082467129454e-5, 0.0189696997404099, -3.21910156344529e-5, 1.621104311198e-4, -3.92368820030242e-5, 1.24302925996744e-6, -2.82433489928735e-7, 2.32914885600621e-6, 2.77825802186271e-6, -2.97843882890447e-8, 2.20006022573216e-5] + }, + "fFlag" : -1, + "fChi2" : 4.725942, + "fNDF" : 9, + "fB" : 0, + "fLength" : 256.1725, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 0, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.236941069364548, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.972045302391052, + "fY" : -0.280813157558441, + "fZ" : -0.0741752609610558, + "fTx" : 0.149191468954086, + "fTy" : 0.168982222676277, + "fQp" : -0.834105968475342, + "fCovMatrix" : [0.0029536911752075, 0.00129893212579191, -1.44318444654346e-4, -1.68929509527516e-5, 1.44262303365394e-4, 0.072073370218277, -1.02829853858566e-5, -7.96541280578822e-4, -6.96946008247323e-5, 3.18914135277737e-5, 9.77228637566441e-7, -6.86927978676977e-6, 3.9630860555917e-5, 3.83387657620915e-7, 7.7078329923097e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -26.2282524108887, + "fY" : 43.8057022094727, + "fZ" : 253.266006469727, + "fTx" : -0.393378973007202, + "fTy" : 0.183965146541595, + "fQp" : -0.841169774532318, + "fCovMatrix" : [0.00138695456553251, 0.00245250947773457, 4.07528132200241e-5, 3.07277732645161e-5, 6.74965558573604e-5, 0.0257465783506632, 9.16569624678232e-5, 2.88728624582291e-4, 1.5688432904426e-4, 3.51272797161073e-6, 7.95116307017452e-7, 4.9578438847675e-6, 8.48969284561463e-6, 1.90970308722171e-6, 7.40295581636019e-5] + }, + "fFlag" : -1, + "fChi2" : 4.60224, + "fNDF" : 13, + "fB" : 0, + "fLength" : 261.9332, + "fNhits" : 9, + "fUsing" : false, + "fGemTrack" : 1, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.250558197498322, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.05267107486725, + "fY" : -0.100232698023319, + "fZ" : -0.0741752609610558, + "fTx" : -0.0768801420927048, + "fTy" : 0.169134110212326, + "fQp" : -1.13182425498962, + "fCovMatrix" : [0.0067399088293314, 0.00791787542402744, -3.10500880004838e-4, -5.94121775066014e-5, 3.12555144773796e-4, 0.148948058485985, -2.36758729442954e-4, -0.00165140617173165, -1.53704575495794e-4, 5.67395400139503e-5, 1.25742951695429e-6, -1.59005121531663e-5, 7.31128166080453e-5, 1.79939468125667e-6, 1.9548847922124e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -69.8452606201172, + "fY" : 35.5888671875, + "fZ" : 190.759826660156, + "fTx" : -0.755924940109253, + "fTy" : 0.234108626842499, + "fQp" : -1.1410653591156, + "fCovMatrix" : [0.0016210189787671, 0.00367055041715503, 5.95567980781198e-5, 4.92073886562139e-5, 1.30036598420702e-4, 0.0339352935552597, 1.72936561284587e-4, 4.68151818495244e-4, 3.72272508684546e-4, 7.08813240635209e-6, 1.15282068691158e-6, 1.59920909936773e-5, 1.43599054354127e-5, 8.06203615866252e-7, 1.84375589014962e-4] + }, + "fFlag" : -1, + "fChi2" : 8.864249, + "fNDF" : 9, + "fB" : 0, + "fLength" : 210.9485, + "fNhits" : 7, + "fUsing" : false, + "fGemTrack" : 2, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.434302598237991, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.49803411960602, + "fY" : -1.23369157314301, + "fZ" : -0.0741752609610558, + "fTx" : 0.0571040958166122, + "fTy" : -0.0116128865629435, + "fQp" : 0.233414620161057, + "fCovMatrix" : [0.16058374941349, -0.0386939495801926, -0.00183908792678267, 1.57955844770186e-4, 0.00322318007238209, 0.20668363571167, 3.43304360285401e-4, -0.00129437737632543, -5.93546603340656e-4, 2.30489913519705e-5, -1.32737147851003e-6, -3.59687473974191e-5, 1.18543348435196e-5, 2.08487495001464e-6, 8.24516027932987e-5] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 32.9461936950684, + "fY" : -4.42597818374634, + "fZ" : 248.747436523438, + "fTx" : 0.196269676089287, + "fTy" : -0.0137906949967146, + "fQp" : 0.234843328595161, + "fCovMatrix" : [0.00120935030281544, -0.00178178038913757, 3.31491100951098e-5, -1.84210657607764e-5, 1.62665004609153e-4, 0.0247486550360918, -5.01800968777388e-5, 2.78292311122641e-4, -1.82114410563372e-4, 1.74688352672092e-6, -2.68147317683542e-7, 1.01446121334448e-5, 4.99256657349179e-6, 1.13328542283853e-6, 8.19254855741747e-5] + }, + "fFlag" : -1, + "fChi2" : 20.59108, + "fNDF" : 5, + "fB" : 0, + "fLength" : 251.1237, + "fNhits" : 5, + "fUsing" : false, + "fGemTrack" : 3, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.865585923194885, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 0.168660625815392, + "fY" : -0.732907712459564, + "fZ" : -0.0741752609610558, + "fTx" : 0.0394175723195076, + "fTy" : 0.0910284221172333, + "fQp" : 0.306645959615707, + "fCovMatrix" : [0.730717658996582, 0.378915369510651, -0.00844841357320547, -0.00212396425195038, 0.0194573123008013, 0.505575299263, -0.00431815348565578, -0.00303975376300514, 0.0103680109605193, 1.0205547005171e-4, 2.42906644416507e-5, -2.25800249609165e-4, 2.3960954422364e-5, -5.85240559303202e-5, 5.47828210983425e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 25.9320220947266, + "fY" : 18.9775524139404, + "fZ" : 217.384552001953, + "fTx" : 0.202286452054977, + "fTy" : 0.091080442070961, + "fQp" : 0.30821368098259, + "fCovMatrix" : [0.00176186766475439, -0.00465359771624207, 8.62092056195252e-5, -8.90066658030264e-5, 6.51401758659631e-4, 0.0409622117877007, -3.11948562739417e-4, 6.92703877575696e-4, -0.00266375578939915, 6.9299348979257e-6, -6.57674172543921e-6, 5.83395376452245e-5, 1.5830855772947e-5, -5.93766999372747e-5, 5.46319701243192e-4] + }, + "fFlag" : -1, + "fChi2" : 0.1006652, + "fNDF" : 3, + "fB" : 0, + "fLength" : 220.2086, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 4, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.849169433116913, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.09552073478699, + "fY" : -0.791672945022583, + "fZ" : -0.0741752609610558, + "fTx" : -0.0488560423254967, + "fTy" : 0.152769893407822, + "fQp" : 0.123951099812984, + "fCovMatrix" : [0.764037489891052, -0.442365646362305, -0.00743837049230933, 0.00222868844866753, 0.0149596650153399, 0.610441923141479, 0.00428155763074756, -0.00300545059144497, -0.00863859802484512, 7.33681226847693e-5, -2.16770458791871e-5, -1.46979771670885e-4, 1.57766862685094e-5, 4.39250106865074e-5, 2.99817853374407e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -1.87017381191254, + "fY" : 37.7572059631348, + "fZ" : 253.266006469727, + "fTx" : 0.0264327693730593, + "fTy" : 0.151600807905197, + "fQp" : 0.124097675085068, + "fCovMatrix" : [0.00188965618144721, 0.0052546733058989, 7.22920085536316e-5, 8.74364632181823e-5, 4.96948370710015e-4, 0.044090673327446, 2.55633989581838e-4, 6.79159304127097e-4, 0.00200395938009024, 4.36992058894248e-6, 4.77146477351198e-6, 3.46658707712777e-5, 1.38237774081063e-5, 4.04370002797805e-5, 2.99695821013302e-4] + }, + "fFlag" : -1, + "fChi2" : 0.2269104, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.3305, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 5, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.280481159687042, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 1.08058607578278, + "fY" : -0.838285148143768, + "fZ" : -0.0741752609610558, + "fTx" : -0.0602659471333027, + "fTy" : -0.0657347366213799, + "fQp" : 0.161692976951599, + "fCovMatrix" : [0.373369604349136, -0.256095170974731, -0.00429155910387635, 0.00146932841744274, 0.0100092217326164, 0.437035441398621, 0.00290561700239778, -0.00253340043127537, -0.00696604512631893, 5.08210650878027e-5, -1.67745038197609e-5, -1.16124640044291e-4, 1.66389145306312e-5, 4.05125792894978e-5, 2.81171407550573e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.89048075675964, + "fY" : -15.52707862854, + "fZ" : 222.077667236328, + "fTx" : 0.0265315920114517, + "fTy" : -0.0665754824876785, + "fQp" : 0.162168383598328, + "fCovMatrix" : [0.00189096131362021, 0.00525919208303094, 7.12687469786033e-5, 8.75819096108899e-5, 4.80103975860402e-4, 0.0441058911383152, 2.50725541263819e-4, 6.79370888974518e-4, 0.00194779096636921, 4.24357494921423e-6, 4.68637608719291e-6, 3.30064540321473e-5, 1.38364857775741e-5, 3.94360940845218e-5, 2.81097542028874e-4] + }, + "fFlag" : -1, + "fChi2" : 0.4510978, + "fNDF" : 3, + "fB" : 0, + "fLength" : 222.739, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 6, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 0.319944620132446, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 44.9544410705566, + "fY" : 8.4261474609375, + "fZ" : -0.0741752609610558, + "fTx" : -0.263924449682236, + "fTy" : -0.0746458247303963, + "fQp" : 0.349957019090652, + "fCovMatrix" : [1.98384606838226, 0.685470521450043, -0.0193782690912485, -0.00341549632139504, 0.0342621468007565, 0.942128956317902, -0.00669290637597442, -0.00555382901802659, 0.0129474010318518, 1.91260362043977e-4, 3.34627511620056e-5, -3.44516127370298e-4, 3.62282080459408e-5, -6.4479245338589e-5, 6.98037445545197e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 5.85834217071533, + "fY" : -10.2067451477051, + "fZ" : 248.59846496582, + "fTx" : -0.0520231463015079, + "fTy" : -0.0764518603682518, + "fQp" : 0.354904860258102, + "fCovMatrix" : [0.00174834718927741, -0.004612120334059, 8.24026938062161e-5, -9.13782932912e-5, 7.04309437423944e-4, 0.0408704169094563, -2.97947903163731e-4, 7.05018232110888e-4, -0.00286549958400428, 6.46585021968349e-6, -6.47028218736523e-6, 6.13997981417924e-5, 1.67413891176693e-5, -6.62249440210871e-5, 7.03481142409146e-4] + }, + "fFlag" : -1, + "fChi2" : 3.454931, + "fNDF" : 3, + "fB" : 0, + "fLength" : 252.7396, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 7, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 44.8642272949219, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -2.98815751075745, + "fY" : -1.79677057266235, + "fZ" : -0.0741752609610558, + "fTx" : 0.0268787071108818, + "fTy" : -0.0271434132009745, + "fQp" : 0.129942655563354, + "fCovMatrix" : [1.62950122356415, 0.661146819591522, -0.0158530920743942, -0.00310880900360644, 0.0316362045705318, 0.676753103733063, -0.00640787184238434, -0.00336016505025327, 0.0130223669111729, 1.54828841914423e-4, 3.01927830150817e-5, -3.09189374092966e-4, 1.78518203028943e-5, -6.14967430010438e-5, 6.31117378361523e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.1892690658569, + "fY" : -8.69165992736816, + "fZ" : 248.638809204102, + "fTx" : 0.10332266241312, + "fTy" : -0.0282121077179909, + "fQp" : 0.130729869008064, + "fCovMatrix" : [0.0017405046382919, -0.00456876307725906, 8.11685167718679e-5, -8.95584089448676e-5, 7.05139013007283e-4, 0.0406320914626122, -2.91850272333249e-4, 6.9410540163517e-4, -0.0028778335545212, 6.1214336710691e-6, -6.37108087175875e-6, 6.03011758357752e-5, 1.58327566168737e-5, -6.63357495795935e-5, 6.34717929642648e-4] + }, + "fFlag" : -1, + "fChi2" : 8.801305, + "fNDF" : 3, + "fB" : 0, + "fLength" : 249.424, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 8, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.17802572250366, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 4.81049203872681, + "fY" : 1.1469452381134, + "fZ" : -0.0741752609610558, + "fTx" : 0.236087128520012, + "fTy" : -0.050562396645546, + "fQp" : -0.957896947860718, + "fCovMatrix" : [2.08753252029419, 0.596874952316284, -0.0210686512291431, -0.0023795876186341, 0.0366438962519169, 1.04195284843445, -0.00575345195829868, -0.00679782964289188, 0.0115563711151481, 2.30263074627146e-4, 2.25388430408202e-5, -3.76431678887457e-4, 6.72532478347421e-5, -4.65640514448751e-5, 8.11638543382287e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -8.4837646484375, + "fY" : -9.48062133789062, + "fZ" : 248.519302368164, + "fTx" : -0.352763444185257, + "fTy" : -0.0339179635047913, + "fQp" : -0.972050666809082, + "fCovMatrix" : [0.00178857066202909, -0.00480817910283804, 9.02258398127742e-5, -9.74497888819315e-5, 6.59170967992395e-4, 0.0418470054864883, -3.33041214616969e-4, 7.43029173463583e-4, -0.00274206721223891, 8.91559921001317e-6, -6.74819648338598e-6, 5.53193567611743e-5, 2.14663104998181e-5, -6.56304910080507e-5, 7.88591278251261e-4] + }, + "fFlag" : -1, + "fChi2" : 11.65028, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.0336, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 9, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 4.16944980621338, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -21.5212783813477, + "fY" : 2.11670660972595, + "fZ" : -0.0741752609610558, + "fTx" : 0.123838409781456, + "fTy" : -0.0428293310105801, + "fQp" : 0.350397825241089, + "fCovMatrix" : [1.76534926891327, 0.628246784210205, -0.0174159202724695, -0.00295637990348041, 0.0278382040560246, 0.900808334350586, -0.00597109459340572, -0.00593680469319224, 0.0113444663584232, 2.63705820543692e-4, 2.76864393526921e-5, -2.69689393462613e-4, 1.36653063236736e-4, -5.36378138349392e-5, 5.22854039445519e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 36.6136207580566, + "fY" : -9.08453845977783, + "fZ" : 248.767608642578, + "fTx" : 0.348794728517532, + "fTy" : -0.0466611199080944, + "fQp" : 0.357887446880341, + "fCovMatrix" : [0.00174852868076414, -0.00460646999999881, 8.27661424409598e-5, -8.9719491370488e-5, 6.22440304141492e-4, 0.0408178381621838, -2.99103499855846e-4, 6.9653894752264e-4, -0.00252968561835587, 6.56514612273895e-6, -6.37573566564242e-6, 5.31558325747028e-5, 1.64152570505394e-5, -5.77251703361981e-5, 5.26623975019902e-4] + }, + "fFlag" : -1, + "fChi2" : 13.05123, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.5815, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 10, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 22.6697101593018, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 31.6281032562256, + "fY" : 3.4384138584137, + "fZ" : -0.0741752609610558, + "fTx" : -0.467039108276367, + "fTy" : -0.0435147099196911, + "fQp" : 1.1711448431015, + "fCovMatrix" : [7.91541337966919, 0.779726445674896, -0.0805382579565048, -0.0050742132589221, 0.0481211170554161, 6.39190053939819, -0.00789854489266872, -0.0591910779476166, 0.012303021736443, 8.90450435690582e-4, 5.3377567382995e-5, -5.28921955265105e-4, 6.28222827799618e-4, -6.57707278151065e-5, 0.0010983272222802] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 16.0822811126709, + "fY" : -7.50871706008911, + "fZ" : 248.654602050781, + "fTx" : 0.35296493768692, + "fTy" : -0.0471868738532066, + "fQp" : 1.38267636299133, + "fCovMatrix" : [0.00181278993841261, -0.00494082737714052, 9.53344424488023e-5, -1.00094614026602e-4, 6.32787239737809e-4, 0.0426238588988781, -3.58232791768387e-4, 7.70228973124176e-4, -0.00252008717507124, 1.11789231596049e-5, -6.73666454531485e-6, 5.27514894201886e-5, 2.64508908003336e-5, -5.84950903430581e-5, 0.00108214910142124] + }, + "fFlag" : -1, + "fChi2" : 7.965215, + "fNDF" : 3, + "fB" : 0, + "fLength" : 256.0514, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 11, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 30.8907814025879, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}, { + "_typename" : "BmnGlobalTrack", + "fUniqueID" : 0, + "fBits" : 0, + "fHits" : [], + "fParamFirst" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : -24.1479740142822, + "fY" : -5.13045358657837, + "fZ" : -0.0741752609610558, + "fTx" : 0.4214788377285, + "fTy" : -0.0166378784924746, + "fQp" : -0.825638711452484, + "fCovMatrix" : [2.25483560562134, 0.679172396659851, -0.0261307191103697, -0.00274870544672012, 0.0411236099898815, 0.892340660095215, -0.00686908280476928, -0.0075940815731883, 0.0129511076956987, 9.46337939240038e-4, 2.36712530750083e-5, -4.33476088801399e-4, 6.35952048469335e-4, -5.28009732079227e-5, 8.67289258167148e-4] + }, + "fParamLast" : { + "_typename" : "FairTrackParam", + "fUniqueID" : 0, + "fBits" : 0, + "fX" : 13.2809133529663, + "fY" : -7.53941249847412, + "fZ" : 248.638809204102, + "fTx" : -0.100862711668015, + "fTy" : -0.00437753833830357, + "fQp" : -0.844026267528534, + "fCovMatrix" : [0.00176415592432022, -0.00469323294237256, 8.53097735671327e-5, -9.46945510804653e-5, 7.16785027179867e-4, 0.0412978753447533, -3.11316456645727e-4, 7.260687998496e-4, -0.00294898869469762, 7.65372715250123e-6, -6.52985136184725e-6, 5.96674617554527e-5, 1.96662622329313e-5, -7.00035234331153e-5, 8.53373727295548e-4] + }, + "fFlag" : -1, + "fChi2" : 16.23237, + "fNDF" : 3, + "fB" : 0, + "fLength" : 253.9741, + "fNhits" : 4, + "fUsing" : false, + "fGemTrack" : 12, + "fSsdTrack" : -1, + "fSilTrack" : -1, + "fTof1Hit" : -1, + "fTof2Hit" : -1, + "fDch1Track" : -1, + "fDch2Track" : -1, + "fDchTrack" : -1, + "fMwpc1Track" : -1, + "fMwpc2Track" : -1, + "fUpstreamTrack" : -1, + "fScWallCellId" : -1, + "fCscHit" : [-1, -1, -1, -1], + "fScWallSignal" : -1000, + "fBeta400" : -1000, + "fBeta700" : -1000, + "fdQdNUpper" : 0, + "fdQdNLower" : 0, + "fA" : -1, + "fZ" : 0, + "fPDG" : 0, + "fChi2InVertex" : 2.34478793822074e-310, + "fDCAInVertex" : 25.5586757659912, + "fPidTof400" : [], + "fPidTof700" : [], + "fIsPrimary" : true, + "fRefIndex" : 0 +}] +] diff --git a/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.root b/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.root new file mode 100644 index 00000000..e69de29b diff --git a/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip b/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip new file mode 100644 index 00000000..1680404c Binary files /dev/null and b/demo/playground/src/jvmMain/resources/root/geometry_run_7-2076.zip differ diff --git a/demo/playground/src/jvmMain/resources/root/geometry_run_8_8000.zip b/demo/playground/src/jvmMain/resources/root/geometry_run_8_8000.zip new file mode 100644 index 00000000..016288f9 Binary files /dev/null and b/demo/playground/src/jvmMain/resources/root/geometry_run_8_8000.zip differ diff --git a/demo/sat-demo/build.gradle.kts b/demo/sat-demo/build.gradle.kts index 267e4a82..5e881b63 100644 --- a/demo/sat-demo/build.gradle.kts +++ b/demo/sat-demo/build.gradle.kts @@ -1,5 +1,5 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") application } @@ -8,15 +8,15 @@ kscience { // useSerialization { // json() // } - application() + useKtor() + dependencies{ + implementation("io.ktor:ktor-server-cio") + implementation(projects.visionforgeThreejs.visionforgeThreejsServer) + implementation(spclibs.logback.classic) + } } -group = "ru.mipt.npm" - -dependencies{ - implementation(project(":visionforge-threejs:visionforge-threejs-server")) - implementation("ch.qos.logback:logback-classic:1.2.3") -} +group = "center.sciprog" application { mainClass.set("ru.mipt.npm.sat.SatServerKt") diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt index 93650fb2..d2c30422 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/geometry.kt @@ -6,7 +6,7 @@ import space.kscience.visionforge.style import space.kscience.visionforge.useStyle import kotlin.math.PI -internal fun visionOfSatellite( +internal fun Solids.visionOfSatellite( layers: Int = 10, layerHeight: Number = 10, xSegments: Int = 3, @@ -14,7 +14,7 @@ internal fun visionOfSatellite( xSegmentSize: Number = 30, ySegmentSize: Number = xSegmentSize, fiberDiameter: Number = 1.0, -): SolidGroup = SolidGroup { +): SolidGroup = solidGroup { color("darkgreen") val transparent by style { this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3 @@ -31,7 +31,7 @@ internal fun visionOfSatellite( val totalXSize = xSegments * xSegmentSize.toDouble() val totalYSize = ySegments * ySegmentSize.toDouble() for (layer in 1..layers) { - group("layer[$layer]") { + solidGroup("layer[$layer]") { for (i in 1..xSegments) { for (j in 1..ySegments) { box(xSegmentSize, ySegmentSize, layerHeight, name = "segment[$i,$j]") { @@ -42,7 +42,7 @@ internal fun visionOfSatellite( } } } - group("fibers") { + solidGroup("fibers") { for (i in 1..xSegments) { cylinder(fiberDiameter, totalYSize) { useStyle(red) diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt index fbacc5b1..9f2f7e59 100644 --- a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/satServer.kt @@ -1,38 +1,57 @@ package ru.mipt.npm.sat +import io.ktor.server.cio.CIO +import io.ktor.server.engine.embeddedServer +import io.ktor.server.http.content.staticResources +import io.ktor.server.routing.routing import kotlinx.coroutines.* import kotlinx.html.div import kotlinx.html.h1 import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.request +import space.kscience.dataforge.meta.Null import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.Page -import space.kscience.visionforge.html.plus +import space.kscience.visionforge.Colors +import space.kscience.visionforge.html.VisionPage import space.kscience.visionforge.server.close import space.kscience.visionforge.server.openInBrowser -import space.kscience.visionforge.server.serve +import space.kscience.visionforge.server.visionPage import space.kscience.visionforge.solid.* import space.kscience.visionforge.three.threeJsHeader -import space.kscience.visionforge.visionManager import kotlin.random.Random +@Suppress("ExtractKtorModule") fun main() { val satContext = Context("sat") { plugin(Solids) } - //Create a geometry - val sat = visionOfSatellite(ySegments = 3) + val solids = satContext.request(Solids) - val server = satContext.visionManager.serve { - page(header = Page.threeJsHeader + Page.styleSheetHeader("css/styles.css")) { + //Create a geometry + val sat = solids.visionOfSatellite(ySegments = 3).apply { + ambientLight { + color(Colors.white) + } + } + val server = embeddedServer(CIO, port = 7777) { + routing { + staticResources("", null, null) + } + + visionPage( + solids.visionManager, VisionPage.threeJsHeader, + VisionPage.styleSheetHeader("css/styles.css") + ) { div("flex-column") { h1 { +"Satellite detector demo" } vision { sat } } } - } + + }.start(false) server.openInBrowser() @@ -46,7 +65,8 @@ fun main() { val targetVision = sat[target] as Solid targetVision.color("red") delay(1000) - targetVision.color.clear() + //use to ensure that color is cleared + targetVision.color.value = Null delay(500) } } diff --git a/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt new file mode 100644 index 00000000..89dc3a09 --- /dev/null +++ b/demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt @@ -0,0 +1,21 @@ +package ru.mipt.npm.sat + +import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.solid.box +import space.kscience.visionforge.solid.invoke +import space.kscience.visionforge.solid.material +import space.kscience.visionforge.solid.solid +import space.kscience.visionforge.three.makeThreeJsFile + +@OptIn(DFExperimental::class) +fun main() = makeThreeJsFile(resourceLocation = ResourceLocation.SYSTEM) { + vision ("canvas") { + solid { + box(100, 100, 100) + material { + emissiveColor("red") + } + } + } +} \ No newline at end of file diff --git a/demo/solid-showcase/build.gradle.kts b/demo/solid-showcase/build.gradle.kts index bc391b9d..05a02260 100644 --- a/demo/solid-showcase/build.gradle.kts +++ b/demo/solid-showcase/build.gradle.kts @@ -1,44 +1,26 @@ -import ru.mipt.npm.gradle.DependencyConfiguration -import ru.mipt.npm.gradle.FXModule - plugins { - id("ru.mipt.npm.gradle.mpp") - application + id("space.kscience.gradle.mpp") +// application } kscience { useCoroutines() - val fxVersion: String by rootProject.extra - useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION) - application() -} - -kotlin { - - jvm { - withJava() + jvm() + js{ + binaries.executable() + } + dependencies { + implementation(projects.visionforgeSolid) + implementation(projects.visionforgeGdml) } - sourceSets { - commonMain { - dependencies { - implementation(project(":visionforge-solid")) -// implementation(project(":visionforge-gdml")) - } - } - jvmMain { - dependencies { - implementation(project(":visionforge-fx")) - } - } - jsMain { - dependencies { - implementation(project(":visionforge-threejs")) - } - } + jsMain { + implementation(projects.visionforgeThreejs) } } -application { - mainClassName = "space.kscience.visionforge.solid.demo.FXDemoAppKt" -} \ No newline at end of file +kotlin.explicitApi = null + +//application { +// mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") +//} \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt index 016f2ecf..4b5bdf53 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/VisionLayout.kt @@ -3,7 +3,10 @@ package space.kscience.visionforge.solid.demo import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision +import space.kscience.visionforge.solid.Solids -public interface VisionLayout { - public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) +interface VisionLayout { + val solids: Solids + + fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) } \ No newline at end of file diff --git a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt index a0ab9273..9e2ecedb 100644 --- a/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt +++ b/demo/solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo/demo.kt @@ -4,6 +4,8 @@ import kotlinx.coroutines.* import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.invoke import space.kscience.dataforge.names.Name +import space.kscience.kmath.geometry.Euclidean3DSpace +import space.kscience.kmath.geometry.radians import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions @@ -18,7 +20,12 @@ fun VisionLayout.demo(name: String, title: String = name, block: SolidGro val meta = Meta { "title" put title } - val vision = SolidGroup(block) + val vision = solids.solidGroup { + block() + ambientLight { + color(Colors.white) + } + } render(Name.parse(name), vision, meta) } @@ -39,6 +46,7 @@ val canvasOptions = Canvas3DOptions { @OptIn(DelicateCoroutinesApi::class) fun VisionLayout.showcase() { demo("shapes", "Basic shapes") { + ambientLight() box(100.0, 100.0, 100.0) { z = -110.0 color("teal") @@ -62,7 +70,7 @@ fun VisionLayout.showcase() { } demo("dynamic", "Dynamic properties") { - val group = group { + val group = solidGroup { box(100, 100, 100) { z = 110.0 opacity = 0.5 @@ -94,11 +102,18 @@ fun VisionLayout.showcase() { demo("rotation", "Rotations") { box(100, 100, 100) - group { + solidGroup { x = 200 rotationY = PI / 4 + axes(200) box(100, 100, 100) { - rotationZ = PI / 4 + rotate((PI / 4).radians, Euclidean3DSpace.zAxis) + GlobalScope.launch(Dispatchers.Main) { + while (isActive) { + delay(100) + rotate((PI/20).radians,Euclidean3DSpace.yAxis) + } + } color(Colors.red) } } @@ -124,7 +139,10 @@ fun VisionLayout.showcase() { color(Colors.blue) } repeat(20) { - polyline(Point3D(100, 100, 100), Point3D(-100, -100, -100)) { + polyline( + Float32Vector3D(100, 100, 100), + Float32Vector3D(-100, -100, -100) + ) { thickness = 3.0 rotationX = it * PI2 / 20 color(Colors.green) @@ -141,6 +159,10 @@ fun VisionLayout.showcase() { z = 26 } } + + demo("STL", "STL loaded from URL") { + stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl") + } } fun VisionLayout.showcaseCSG() { diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt index eb27f4d6..5bdbcefe 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoApp.kt @@ -1,9 +1,9 @@ package space.kscience.visionforge.solid.demo -import kotlinx.browser.document import kotlinx.coroutines.delay import kotlinx.coroutines.isActive import kotlinx.coroutines.launch +import org.w3c.dom.Document import space.kscience.visionforge.Application import space.kscience.visionforge.solid.x import space.kscience.visionforge.solid.y @@ -12,7 +12,7 @@ import kotlin.random.Random private class ThreeDemoApp : Application { - override fun start(state: Map) { + override fun start(document: Document, state: Map) { val element = document.getElementById("demo") ?: error("Element with id 'demo' not found on page") diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt index 6dcfa36f..50e7f174 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/ThreeDemoGrid.kt @@ -10,12 +10,13 @@ import org.w3c.dom.Element import org.w3c.dom.HTMLDivElement import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.three.ThreeCanvas import space.kscience.visionforge.solid.three.ThreePlugin @@ -25,7 +26,9 @@ class ThreeDemoGrid(element: Element) : VisionLayout { private val outputs: MutableMap = HashMap() - private val three = Global.fetch(ThreePlugin) + private val three = Global.request(ThreePlugin) + + override val solids: Solids get() = three.solids init { element.clear() diff --git a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt index af828f46..701df81b 100644 --- a/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt +++ b/demo/solid-showcase/src/jsMain/kotlin/space/kscience/visionforge/solid/demo/VariableBox.kt @@ -1,20 +1,19 @@ package space.kscience.visionforge.solid.demo -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.BoxGeometry -import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.int import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.asValue import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.set -import space.kscience.visionforge.setProperty +import space.kscience.visionforge.setChild import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY import space.kscience.visionforge.solid.layer import space.kscience.visionforge.solid.three.* +import three.core.Object3D +import three.geometries.BoxGeometry +import three.objects.Mesh import kotlin.math.max internal fun SolidGroup.varBox( @@ -22,11 +21,11 @@ internal fun SolidGroup.varBox( ySize: Number, name: String = "", action: VariableBox.() -> Unit = {}, -): VariableBox = VariableBox(xSize, ySize).apply(action).also { set(name, it) } +): VariableBox = VariableBox(xSize, ySize).apply(action).also { setChild(name, it) } internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision() { - override fun render(three: ThreePlugin): Object3D { + override suspend fun render(three: ThreePlugin): Object3D { val geometry = BoxGeometry(xSize, ySize, 1) val material = ThreeMaterials.DEFAULT.clone() @@ -44,13 +43,13 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision it.layers.enable(this@VariableBox.layer) } } - mesh.scale.z = meta[VALUE].number?.toDouble() ?: 1.0 + mesh.scale.z = properties.getValue(VALUE)?.number?.toDouble() ?: 1.0 //add listener to object properties onPropertyChange { name -> when { name == VALUE -> { - val value = meta.get(VALUE).int ?: 0 + val value = properties.getValue(VALUE)?.int ?: 0 val size = value.toFloat() / 255f * 20f mesh.scale.z = size.toDouble() mesh.position.z = size.toDouble() / 2 @@ -61,7 +60,8 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256) mesh.updateMatrix() } - name.startsWith(MeshThreeFactory.EDGES_KEY) -> mesh.applyEdges(this@VariableBox) + + name.startsWith(EDGES_KEY) -> mesh.applyEdges(this@VariableBox) else -> mesh.updateProperty(this@VariableBox, name) } } @@ -70,9 +70,9 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision } var value: Int - get() = meta[VALUE].int ?: 0 + get() = properties.getValue(VALUE)?.int ?: 0 set(value) { - setProperty(VALUE, value.asValue()) + properties.setValue(VALUE, value.asValue()) } companion object { diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt similarity index 100% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoApp.kt diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt similarity index 91% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt index ef03092a..81501016 100644 --- a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt +++ b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/FXDemoGrid.kt @@ -10,9 +10,11 @@ import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.FX3DPlugin import space.kscience.visionforge.solid.FXCanvas3D import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.Solids import tornadofx.* class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout { + private val outputs = FXCollections.observableHashMap() override val root: Parent = borderpane { @@ -24,6 +26,9 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout { } private val fx3d = Global.fetch(FX3DPlugin) + override val solids: Solids get() = fx3d.solids + + override fun render(name: Name, vision: Solid, meta: Meta) { outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision) diff --git a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt similarity index 96% rename from demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt rename to demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt index 3cdf058e..a4217555 100644 --- a/demo/solid-showcase/src/jvmMain/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt +++ b/demo/solid-showcase/src/jvmMain-fx/kotlin/space/kscience/visionforge/solid/demo/MetaEditorDemo.kt @@ -2,10 +2,10 @@ package space.kscience.visionforge.demo import javafx.geometry.Orientation import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.editor.FXMetaModel import space.kscience.visionforge.editor.MetaViewer import space.kscience.visionforge.editor.MutableMetaEditor diff --git a/docs/hierarchy.md b/docs/hierarchy.md index 720af5d2..15f3306e 100644 --- a/docs/hierarchy.md +++ b/docs/hierarchy.md @@ -3,7 +3,7 @@ ![](../docs/images/hierarchy.png) ### Vision -* function `getPropertyValue(name: Name, inherit: Boolean = false, includeStyles: Boolean = true, includeDefaults: Boolean = true)` - get property value with given layer flags. +* function `getProperty(name: Name, inherit: Boolean = false, includeStyles: Boolean = true, includeDefaults: Boolean = true)` - get property value with given layer flags. * function `setProperty(name: Name, item: Any?)` - a convenient method to set property node or value. If `item` is null, then node is removed, not a value Sets the `item` property to the element with the `name` identification. diff --git a/docs/inheritance.md b/docs/inheritance.md index d99451f3..1fad27d2 100644 --- a/docs/inheritance.md +++ b/docs/inheritance.md @@ -7,7 +7,7 @@ Properties, which can be inherited by objects, are `styles`, `prototypes` (if th All values of `styles` property are contained in class `StyleSheet`, where they all are defined at `Group`s level. The `prototypes` property tree is defined in `SolidGroup` class via `PrototypeHolder` interface, and `SolidReference` class helps to reuse a template object. -The order of inheritance of properties is set in function `getPropertyValue` in `VisionBase` class. +The order of inheritance of properties is set in function `getProperty` in `VisionBase` class. The order is this: * own styles * prototypes diff --git a/docs/tutorial.md b/docs/tutorials/tutorial-solids.md similarity index 91% rename from docs/tutorial.md rename to docs/tutorials/tutorial-solids.md index 8989bd49..2b1e7b57 100644 --- a/docs/tutorial.md +++ b/docs/tutorials/tutorial-solids.md @@ -59,7 +59,7 @@ box(10, 10, 10, name = "small box"){ rotation = Point3D(0, 0, 0) } ``` -![](../docs/images/small-box.png) +![](../images/small-box.png) The `big box` will have properties with custom values. ```kotlin @@ -72,7 +72,7 @@ box(40, 40, 40, name = "big box"){ rotation = Point3D(60, 80, 0) } ``` -![](../docs/images/big-rotated-box.png) +![](../images/big-rotated-box.png) If we compare these boxes, we will see all differences. Here is the function `main` with both boxes. @@ -111,8 +111,8 @@ fun main(){ } } ``` -![](../docs/images/two-boxes-1.png) -![](../docs/images/two-boxes-2.png) +![](../images/two-boxes-1.png) +![](../images/two-boxes-2.png) ***There is plenty of other properties, especially those, which you can create by yourself. Here we mention just a small part.*** @@ -142,8 +142,8 @@ polyline(Point3D(30, 20, 10), Point3D(30, -100, 30), Point3D(30, -100, 30), Poin } ``` -![](../docs/images/polyline-points.png) -![](../docs/images/polyline-points-2.png) +![](../images/polyline-points.png) +![](../images/polyline-points-2.png) ### 2) Box @@ -165,7 +165,7 @@ Let's create just usual `box` with equal ribs. color("pink") } ``` - ![](../docs/images/box.png) + ![](../images/box.png) Now, let's make `box` with bigger `y` value. ```kotlin @@ -175,7 +175,7 @@ Now, let's make `box` with bigger `y` value. ``` As you can see, only the rib of `y-axis` differs from other ribs. - ![](../docs/images/high-box.png) + ![](../images/high-box.png) For a final trial, let's create a `box` with a bigger `x` value. @@ -189,7 +189,7 @@ For a final trial, let's create a `box` with a bigger `x` value. ``` Predictably, only the `x-axis` rib is bigger than other ribs. - ![](../docs/images/wide-box.png) + ![](../images/wide-box.png) ### 3) Sphere @@ -206,7 +206,7 @@ As for `radius`, it has `Float` type, and, as you can guess, it sets the radius color("blue") } ``` - ![](../docs/images/sphere.png) + ![](../images/sphere.png) ### 4) Hexagon @@ -220,7 +220,7 @@ It is solid which has six edges. It is set by eight values: `node1`,..., `node8` 5) Edge with vertices `node1`, `node5`, `node8`, `node4` 6) Edge with vertices `node8`, `node5`, `node6`, `node7` -![](../docs/images/scheme.png) +![](../images/scheme.png) As the hexagon takes in specific points, we understand that this solid cannot be moved, it is fixed in space, and it can't make pivots. @@ -239,7 +239,7 @@ Let's make classic parallelepiped. color("green") } ``` - ![](../docs/images/classic-hexagon.png) + ![](../images/classic-hexagon.png) Now, let's make a custom hexagon. @@ -258,7 +258,7 @@ hexagon( color("brown") } ``` - ![](../docs/images/custom-hexagon.png) + ![](../images/custom-hexagon.png) ### 3) Cone It takes in six values: `bottomRadius`, `height`, `upperRadius`, `startAngle`, `angle`, and `name`. @@ -274,8 +274,8 @@ Let's build a classic cone: color("beige") } ``` - ![](../docs/images/cone-1.png) - ![](../docs/images/cone-2.png) + ![](../images/cone-1.png) + ![](../images/cone-2.png) First of all, we have to try to build a frustum cone: ```kotlin @@ -283,7 +283,7 @@ cone(60, 80, name = "cone") { color(0u, 40u, 0u) } ``` -![](../docs/images/frustum-cone.png) +![](../images/frustum-cone.png) Now, we need to make a try to build a cone segment: @@ -292,8 +292,8 @@ cone(60, 80, angle = PI, name = "cone") { color(0u, 0u, 200u) } ``` -![](../docs/images/cone-segment-1.png) -![](../docs/images/cone-segment-2.png) +![](../images/cone-segment-1.png) +![](../images/cone-segment-2.png) Finally, the segment of frustum cone is left for a try: ```kotlin @@ -301,7 +301,7 @@ cone(60, 100, 20, PI*3/4, angle = PI/3, name = "cone") { color(190u, 0u, 0u) } ``` -![](../docs/images/frustum-cone-segment.png) +![](../images/frustum-cone-segment.png) ### 4) Cone Surface This solid is set by seven values:`bottomOuterRadius`, `bottomInnerRadius`, `height`, `topOuterRadius`, `topInnerRadius`, `startAngle`, and `angle`. @@ -318,8 +318,8 @@ Let's build usual cone surface with almost all properties set: rotation = Point3D(2, 50, -9) } ``` -![](../docs/images/cone-surface-1.png) -![](../docs/images/cone-surface-2.png) +![](../images/cone-surface-1.png) +![](../images/cone-surface-2.png) Now, let's create a cone surface and set all it's properties: @@ -329,8 +329,8 @@ coneSurface(30, 25, 10, 10, 8,0f, pi*3/4, name = "cone surface") { rotation = Point3D(2, 50, -9) } ``` -![](../docs/images/cone-surface-fragment.png) -![](../docs/images/cone-surface-fragment-2.png) +![](../images/cone-surface-fragment.png) +![](../images/cone-surface-fragment-2.png) ### 5) Cylinder @@ -344,8 +344,8 @@ cylinder(40, 100, "cylinder"){ color("indigo") } ``` -![](../docs/images/cylinder-1.png) -![](../docs/images/cylinder-2.png) +![](../images/cylinder-1.png) +![](../images/cylinder-2.png) ### 6) Tube `tube` takes in `radius`, `height`, `innerRadius`, `startAngle`, `angle`, and `name`. *All values are familiar from `cone`, and `coneSurface` solids.* @@ -356,7 +356,7 @@ tube(50, 40, 20, name = "usual tube"){ opacity = 0.4 } ``` -![](../docs/images/tube.png) +![](../images/tube.png) This is an example of tube fragment: @@ -365,7 +365,7 @@ tube(50, 40, 20, 0f, PI, name = "fragmented tube"){ color("white") } ``` -![](../docs/images/tube-fragment.png) +![](../images/tube-fragment.png) ### 7) Extruded `extruded` is set by two values: `shape`, and `layer`. diff --git a/docs/uml/Vision.puml b/docs/uml/Vision.puml index 04e873b9..f590a13e 100644 --- a/docs/uml/Vision.puml +++ b/docs/uml/Vision.puml @@ -3,7 +3,7 @@ interface Vision{ val parent: VisionGroup? - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } interface Solid{ @@ -81,7 +81,7 @@ Solid <--- Composite interface SolidReference{ val prototype: Solid - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } VisionGroup <---- SolidReference SolidReferenceGroup -- SolidReference @@ -91,7 +91,7 @@ class SolidReferenceGroup{ var properties: MutableMeta? val prototype: Solid val children: Map - fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value? + fun getProperty(name,inherit,includeStyles,includeDefaults): Value? } VisionBase <-- SolidReferenceGroup VisionGroup <-- SolidReferenceGroup diff --git a/gradle.properties b/gradle.properties index e029eef4..4e33feb5 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1,12 +1,13 @@ kotlin.code.style=official kotlin.mpp.stability.nowarn=true +kotlin.js.compiler=ir +#kotlin.incremental.js.ir=true -kotlin.jupyter.add.scanner=false - -org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G org.gradle.parallel=true +org.gradle.jvmargs=-Xmx4G -publishing.github=false -publishing.sonatype=false +org.jetbrains.compose.experimental.jscanvas.enabled=true -toolsVersion=0.11.1-kotlin-1.6.10 \ No newline at end of file +toolsVersion=0.15.2-kotlin-1.9.21 +#kotlin.experimental.tryK2=true +#kscience.wasm.disabled=true diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 2e6e5897..a5952066 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,5 +1,5 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-7.3.3-bin.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-8.5-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/jupyter/build.gradle.kts b/jupyter/build.gradle.kts deleted file mode 100644 index 0b406250..00000000 --- a/jupyter/build.gradle.kts +++ /dev/null @@ -1,25 +0,0 @@ -plugins { - id("ru.mipt.npm.gradle.mpp") - id("org.jetbrains.kotlin.jupyter.api") -} - -description = "Common visionforge jupyter module" - -kotlin { - sourceSets { - commonMain{ - dependencies{ - api(projects.visionforgeCore) - } - } - jvmMain { - dependencies { - api(projects.visionforgeServer) - } - } - } -} - -readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL -} \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt b/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt deleted file mode 100644 index 2fbe51c8..00000000 --- a/jupyter/src/jvmMain/kotlin/JupyterPluginBase.kt +++ /dev/null @@ -1,71 +0,0 @@ -package space.kscience.visionforge.jupyter - -import kotlinx.html.p -import kotlinx.html.stream.createHTML -import kotlinx.html.style -import org.jetbrains.kotlinx.jupyter.api.HTML -import org.jetbrains.kotlinx.jupyter.api.declare -import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.ContextAware -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.Vision -import space.kscience.visionforge.html.* - -@DFExperimental -public abstract class JupyterPluginBase(final override val context: Context) : JupyterIntegration(), ContextAware { - - protected val handler: VisionForgeForNotebook = VisionForgeForNotebook(context) - - protected abstract fun Builder.afterLoaded() - - final override fun Builder.onLoaded() { - - onLoaded { - declare("VisionForge" to handler, "vf" to handler) - } - - onShutdown { - handler.stopServer() - } - - import( - "kotlinx.html.*", - "space.kscience.visionforge.html.*" - ) - - render { fragment -> - handler.produceHtml(fragment = fragment) - } - - render { fragment -> - handler.produceHtml(fragment = fragment) - } - - render { vision -> - handler.produceHtml { - vision { vision } - } - - } - - render { page -> - HTML(page.render(createHTML()), true) - } - - render { fragment -> - handler.produceHtml { - if (!handler.isServerRunning()) { - p { - style = "color: red;" - +"The server is not running. Forms are not interactive. Start server with `VisionForge.startServer()." - } - } - fragment(fragment.formBody) - vision { fragment.vision } - } - } - - afterLoaded() - } -} \ No newline at end of file diff --git a/jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt b/jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt deleted file mode 100644 index a91733ce..00000000 --- a/jupyter/src/jvmMain/kotlin/VisionForgeForNotebook.kt +++ /dev/null @@ -1,89 +0,0 @@ -package space.kscience.visionforge.jupyter - -import io.ktor.server.engine.ApplicationEngine -import kotlinx.html.FORM -import kotlinx.html.TagConsumer -import kotlinx.html.p -import kotlinx.html.stream.createHTML -import kotlinx.html.style -import org.jetbrains.kotlinx.jupyter.api.HTML -import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.ContextAware -import space.kscience.dataforge.context.info -import space.kscience.dataforge.context.logger -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.meta.string -import space.kscience.visionforge.html.HtmlFormFragment -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.VisionServer -import space.kscience.visionforge.server.serve -import space.kscience.visionforge.visionManager - -/** - * A handler class that includes a server and common utilities - */ -public class VisionForgeForNotebook(override val context: Context) : ContextAware { - private var counter = 0 - - private var engine: ApplicationEngine? = null - private var server: VisionServer? = null - - public var isolateFragments: Boolean = false - - public fun legacyMode() { - isolateFragments = true - } - - public fun isServerRunning(): Boolean = server != null - - public fun html(block: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(createHTML().apply(block).finalize()) - - public fun startServer( - host: String = context.properties["visionforge.host"].string ?: "localhost", - port: Int = context.properties["visionforge.port"].int ?: VisionServer.DEFAULT_PORT, - configuration: VisionServer.() -> Unit = {}, - ): MimeTypedResult = html { - if (server != null) { - p { - style = "color: red;" - +"Stopping current VisionForge server" - } - } - - engine?.stop(1000, 2000) - engine = context.visionManager.serve(host, port) { - configuration() - server = this - }.start() - - p { - style = "color: blue;" - +"Starting VisionForge server on http://$host:$port" - } - } - - public fun stopServer() { - engine?.apply { - logger.info { "Stopping VisionForge server" } - }?.stop(1000, 2000) - } - - private fun produceHtmlString( - fragment: HtmlVisionFragment, - ): String = server?.serveVisionsFromFragment("content[${counter++}]", fragment) - ?: createHTML().apply { - visionFragment(context, fragment = fragment) - }.finalize() - - public fun produceHtml(isolated: Boolean? = null, fragment: HtmlVisionFragment): MimeTypedResult = - HTML(produceHtmlString(fragment), isolated ?: isolateFragments) - - public fun fragment(body: HtmlVisionFragment): MimeTypedResult = produceHtml(fragment = body) - public fun page(body: HtmlVisionFragment): MimeTypedResult = produceHtml(true, body) - - public fun form(builder: FORM.() -> Unit): HtmlFormFragment = - HtmlFormFragment("form[${counter++}]", builder = builder) -} \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/README.md b/jupyter/visionforge-jupyter-gdml/README.md deleted file mode 100644 index cae8af86..00000000 --- a/jupyter/visionforge-jupyter-gdml/README.md +++ /dev/null @@ -1,32 +0,0 @@ -# Module visionforge-jupyter-gdml - -Jupyter api artifact for GDML rendering - -## Usage - -## Artifact: - -The Maven coordinates of this project are `space.kscience:visionforge-jupyter-gdml:0.2.0`. - -**Gradle Groovy:** -```groovy -repositories { - maven { url 'https://repo.kotlin.link' } - mavenCentral() -} - -dependencies { - implementation 'space.kscience:visionforge-jupyter-gdml:0.2.0' -} -``` -**Gradle Kotlin DSL:** -```kotlin -repositories { - maven("https://repo.kotlin.link") - mavenCentral() -} - -dependencies { - implementation("space.kscience:visionforge-jupyter-gdml:0.2.0") -} -``` diff --git a/jupyter/visionforge-jupyter-gdml/build.gradle.kts b/jupyter/visionforge-jupyter-gdml/build.gradle.kts deleted file mode 100644 index 4a575602..00000000 --- a/jupyter/visionforge-jupyter-gdml/build.gradle.kts +++ /dev/null @@ -1,60 +0,0 @@ -plugins { - id("ru.mipt.npm.gradle.mpp") -} - -description = "Jupyter api artifact for GDML rendering" - -kotlin { - explicitApi = null - js { - useCommonJs() - browser { - webpackTask { - this.outputFileName = "js/gdml-jupyter.js" - } - commonWebpackConfig { - sourceMaps = false - cssSupport.enabled = false - } - } - binaries.executable() - } - - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - from(jsBrowserDistribution) - } - } - - sourceSets { - commonMain { - dependencies { - implementation(projects.visionforgeSolid) - implementation(projects.jupyter) - } - } - jvmMain { - dependencies { - implementation(projects.visionforgeGdml) - } - } - jsMain { - dependencies { - implementation(projects.visionforgeThreejs) - implementation(projects.ui.ring) - } - } - - } -} - -kscience { - jupyterLibrary("space.kscience.visionforge.gdml.jupyter.GdmlForJupyter") -} - -readme { - maturity = ru.mipt.npm.gradle.Maturity.EXPERIMENTAL -} \ No newline at end of file diff --git a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt deleted file mode 100644 index fef274a2..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jsMain/kotlin/gdmlJupyter.kt +++ /dev/null @@ -1,12 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.ring.ThreeWithControlsPlugin -import space.kscience.visionforge.runVisionClient - -@DFExperimental -@JsExport -fun main(): Unit = runVisionClient { - plugin(ThreeWithControlsPlugin) -} - diff --git a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt b/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt deleted file mode 100644 index 0a112ba2..00000000 --- a/jupyter/visionforge-jupyter-gdml/src/jvmMain/kotlin/GdmlForJupyter.kt +++ /dev/null @@ -1,37 +0,0 @@ -package space.kscience.visionforge.gdml.jupyter - -import org.jetbrains.kotlinx.jupyter.api.libraries.resources -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.gdml.Gdml -import space.kscience.visionforge.gdml.toVision -import space.kscience.visionforge.jupyter.JupyterPluginBase -import space.kscience.visionforge.solid.Solids - -@DFExperimental -internal class GdmlForJupyter : JupyterPluginBase( - Context("GDML") { - plugin(Solids) - } -) { - - override fun Builder.afterLoaded() { - - resources { - js("three") { - classPath("js/gdml-jupyter.js") - } - } - - import( - "space.kscience.gdml.*", - "space.kscience.visionforge.gdml.jupyter.*" - ) - - render { gdmlModel -> - handler.produceHtml { - vision { gdmlModel.toVision() } - } - } - } -} diff --git a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js b/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js deleted file mode 100644 index 41da041c..00000000 --- a/jupyter/visionforge-jupyter-gdml/webpack.config.d/01.ring.js +++ /dev/null @@ -1,3 +0,0 @@ -const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; - -config.module.rules.push(...ringConfig.module.rules) \ No newline at end of file diff --git a/settings.gradle.kts b/settings.gradle.kts index 3ae9f6f9..8611d0aa 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,7 +1,6 @@ rootProject.name = "visionforge" enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS") -enableFeaturePreview("VERSION_CATALOGS") pluginManagement { @@ -12,13 +11,14 @@ pluginManagement { maven("https://repo.kotlin.link") mavenCentral() gradlePluginPortal() + maven("https://maven.pkg.jetbrains.space/public/p/compose/dev") } plugins { - id("ru.mipt.npm.gradle.project") version toolsVersion - id("ru.mipt.npm.gradle.mpp") version toolsVersion - id("ru.mipt.npm.gradle.jvm") version toolsVersion - id("ru.mipt.npm.gradle.js") version toolsVersion + id("space.kscience.gradle.project") version toolsVersion + id("space.kscience.gradle.mpp") version toolsVersion + id("space.kscience.gradle.jvm") version toolsVersion + id("space.kscience.gradle.js") version toolsVersion } } @@ -33,8 +33,8 @@ dependencyResolutionManagement { } versionCatalogs { - create("npmlibs") { - from("ru.mipt.npm:version-catalog:$toolsVersion") + create("spclibs") { + from("space.kscience:version-catalog:$toolsVersion") } } } @@ -45,9 +45,10 @@ include( ":ui:ring", // ":ui:material", ":ui:bootstrap", + ":ui:compose", ":visionforge-core", ":visionforge-solid", - ":visionforge-fx", +// ":visionforge-fx", ":visionforge-threejs", ":visionforge-threejs:visionforge-threejs-server", ":visionforge-gdml", @@ -61,8 +62,8 @@ include( ":demo:muon-monitor", ":demo:sat-demo", ":demo:playground", - ":demo:plotly-fx", +// ":demo:plotly-fx", ":demo:js-playground", - ":jupyter", - ":jupyter:visionforge-jupyter-gdml" + ":visionforge-jupyter", + ":visionforge-jupyter:visionforge-jupyter-common" ) diff --git a/ui/bootstrap/build.gradle.kts b/ui/bootstrap/build.gradle.kts index b1b0588e..f50ae119 100644 --- a/ui/bootstrap/build.gradle.kts +++ b/ui/bootstrap/build.gradle.kts @@ -1,15 +1,19 @@ plugins { - kotlin("js") - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra -dependencies { - api(project(":visionforge-solid")) - api(project(":ui:react")) - implementation(npm("file-saver", "2.0.2")) - implementation(npm("bootstrap","4.6.0")) - implementation(npm("jquery","3.5.1")) - implementation(npm("popper.js","1.16.1")) +kscience{ + js() + jsMain{ + dependencies { + api(project(":visionforge-solid")) + api(project(":ui:react")) + implementation(npm("file-saver", "2.0.2")) + implementation(npm("bootstrap","4.6.0")) + implementation(npm("jquery","3.5.1")) + implementation(npm("popper.js","1.16.1")) + } + } } \ No newline at end of file diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt similarity index 97% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt index 2f924ecc..c0171cb7 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/bootstrap.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.bootstrap public fun useBootstrap(){ - kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css") - kotlinext.js.require("bootstrap") + kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css") + kotlinext.js.require("bootstrap") } //public inline fun TagConsumer.card(title: String, crossinline block: TagConsumer.() -> Unit) { diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt similarity index 80% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt index 0d4e2dc7..f42235a8 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/outputConfig.kt @@ -1,10 +1,8 @@ package space.kscience.visionforge.bootstrap -import kotlinx.css.BorderStyle -import kotlinx.css.Color -import kotlinx.css.padding -import kotlinx.css.properties.border -import kotlinx.css.px +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.css.* import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import org.w3c.files.Blob @@ -15,7 +13,6 @@ import react.RBuilder import react.dom.attrs import react.dom.button import react.fc -import space.kscience.dataforge.meta.withDefault import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString import space.kscience.visionforge.react.flexColumn @@ -28,7 +25,7 @@ private fun saveData(event: Event, fileName: String, mimeType: String = "text/pl event.stopPropagation(); event.preventDefault(); - val fileSaver = kotlinext.js.require("file-saver") + val fileSaver = kotlinext.js.require("file-saver") val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) fileSaver.saveAs(blob, fileName) } @@ -47,12 +44,13 @@ public external interface CanvasControlsProps : Props { public var vision: Vision? } + public val CanvasControls: FC = fc("CanvasControls") { props -> flexColumn { flexRow { css { - border(1.px, BorderStyle.solid, Color.blue) - padding(4.px) + border = Border(1.px, BorderStyle.solid, Color.blue) + padding = Padding(4.px) } props.vision?.let { vision -> button { @@ -68,9 +66,10 @@ public val CanvasControls: FC = fc("CanvasControls") { prop } } } + @OptIn(DelicateCoroutinesApi::class) propertyEditor( - ownProperties = props.canvasOptions.meta, - allProperties = props.canvasOptions.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.canvasOptions.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt similarity index 100% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/reactBootstrap.kt diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt similarity index 96% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt index 07bd9b55..23b5071b 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/tabComponent.kt @@ -30,7 +30,7 @@ public external interface TabPaneProps : PropsWithChildren { public val TabPane: FC = fc("TabPane") { props -> var activeTab: String? by useState(props.activeTab) - val children: Array = Children.map(props.children) { + val children: Array?> = Children.map(props.children) { it.asElementOrNull() } ?: emptyArray() diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt similarity index 87% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt index e7602b0e..0d5578a7 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/threeControls.kt @@ -1,7 +1,6 @@ package space.kscience.visionforge.bootstrap import kotlinx.css.* -import kotlinx.css.properties.border import react.FC import react.PropsWithChildren import react.RBuilder @@ -10,8 +9,8 @@ import react.fc import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.react.visionTree +import space.kscience.visionforge.solid.SolidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv @@ -33,13 +32,13 @@ public val ThreeControls: FC = fc { props -> } tab("Tree") { css { - border(1.px, BorderStyle.solid, Color.lightGray) - padding(10.px) + border = Border(1.px, BorderStyle.solid, Color.lightGray) + padding = Padding(10.px) } h2 { +"Object tree" } styledDiv { css { - flex(1.0, 1.0, FlexBasis.inherit) + flex = Flex(1.0, 1.0, FlexBasis.inherit) } props.vision?.let { visionTree(it, props.selected, props.onSelect) @@ -51,7 +50,7 @@ public val ThreeControls: FC = fc { props -> val selectedObject: Vision? = when { selected == null -> null selected.isEmpty() -> props.vision - else -> (props.vision as? VisionGroup)?.get(selected) + else -> (props.vision as? SolidGroup)?.get(selected) } if (selectedObject != null) { visionPropertyEditor(selectedObject, key = selected) diff --git a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt similarity index 51% rename from ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt rename to ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt index a65c1f42..8264ae43 100644 --- a/ui/bootstrap/src/main/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt +++ b/ui/bootstrap/src/jsMain/kotlin/space/kscience/visionforge/bootstrap/visionPropertyEditor.kt @@ -2,13 +2,15 @@ package space.kscience.visionforge.bootstrap import org.w3c.dom.Element import react.RBuilder -import react.dom.render import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.isEmpty import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle +import space.kscience.visionforge.react.EditorPropertyState +import space.kscience.visionforge.react.PropertyEditor import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.react.render +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -19,12 +21,26 @@ public fun RBuilder.visionPropertyEditor( ) { card("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor) { + attrs { + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = { name -> + val ownMeta = vision.properties.own?.get(name) + if (ownMeta != null && !ownMeta.isEmpty()) { + EditorPropertyState.Defined + } else if (vision.properties.root().getValue(name) != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } val styles = if (vision is SolidReference) { (vision.styles + vision.prototype.styles).distinct() @@ -50,6 +66,6 @@ public fun RBuilder.visionPropertyEditor( public fun Element.visionPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = render(this) { +): Unit = space.kscience.visionforge.react.createRoot(this).render { visionPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/ui/bootstrap/src/main/resources/css/custom-bootstrap.css b/ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css similarity index 100% rename from ui/bootstrap/src/main/resources/css/custom-bootstrap.css rename to ui/bootstrap/src/jsMain/resources/css/custom-bootstrap.css diff --git a/ui/compose/build.gradle.kts b/ui/compose/build.gradle.kts new file mode 100644 index 00000000..f77c8e26 --- /dev/null +++ b/ui/compose/build.gradle.kts @@ -0,0 +1,42 @@ + +plugins { + id("space.kscience.gradle.mpp") + alias(spclibs.plugins.compose) +// id("org.jetbrains.compose") version "1.5.11" +// id("com.android.library") +} + +kscience{ + jvm() + js() +// wasm() +} + +kotlin { +// android() + sourceSets { + val commonMain by getting { + dependencies { + + } + } + + val jvmMain by getting { + dependencies { + api(compose.runtime) + api(compose.foundation) + api(compose.material) + api(compose.preview) + } + } + + val jsMain by getting{ + dependencies { + api(compose.html.core) + api("app.softwork:bootstrap-compose:0.1.15") + api("app.softwork:bootstrap-compose-icons:0.1.15") + api(projects.visionforge.visionforgeThreejs) + } + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt new file mode 100644 index 00000000..5aaf4140 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/MetaViewer.kt @@ -0,0 +1,87 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.css.AlignItems +import org.jetbrains.compose.web.css.alignItems +import org.jetbrains.compose.web.dom.A +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.Span +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.isLeaf +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.plus + + +@Composable +private fun MetaViewerItem(root: Meta, name: Name, rootDescriptor: MetaDescriptor? = null) { + var expanded: Boolean by remember { mutableStateOf(true) } + val item: Meta? = root[name] + val descriptorItem: MetaDescriptor? = rootDescriptor?.get(name) + val actualValue = item?.value ?: descriptorItem?.defaultValue + val actualMeta = item ?: descriptorItem?.defaultNode + + val token = name.lastOrNull()?.toString() ?: "" + + FlexRow(attrs = { + classes("metaItem") + style { + alignItems(AlignItems.Center) + } + }) { + if (actualMeta?.isLeaf == false) { + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) + } + onClick { expanded = !expanded } + }) + } + + Span({ + classes(TreeStyles.treeLabel) + if (item == null) { + classes(TreeStyles.treeLabelInactive) + } + }) { + Text(token) + } + + Div { + A { + Text(actualValue.toString()) + } + } + } + if (expanded) { + FlexColumn({ + classes(TreeStyles.tree) + }) { + val keys = buildSet { + descriptorItem?.children?.keys?.forEach { + add(NameToken(it)) + } + actualMeta!!.items.keys.let { addAll(it) } + } + + keys.filter { !it.body.startsWith("@") }.forEach { token -> + Div({ + classes(TreeStyles.treeItem) + }) { + MetaViewerItem(root, name + token, rootDescriptor) + } + } + } + } +} + +@Composable +public fun MetaViewer(meta: Meta, descriptor: MetaDescriptor? = null) { + MetaViewerItem(meta, Name.EMPTY, descriptor) +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt new file mode 100644 index 00000000..2becdbb6 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/NameCrumbs.kt @@ -0,0 +1,44 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.dom.Li +import org.jetbrains.compose.web.dom.Nav +import org.jetbrains.compose.web.dom.Ol +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.length + +@Composable +public fun NameCrumbs(name: Name?, link: (Name) -> Unit): Unit = Nav({ + attr("aria-label","breadcrumb") +}) { + Ol({classes("breadcrumb")}) { + Li({ + classes("breadcrumb-item") + onClick { + link(Name.EMPTY) + } + }) { + Text("\u2302") + } + + if (name != null) { + val tokens = ArrayList(name.length) + name.tokens.forEach { token -> + tokens.add(token) + val fullName = Name(tokens.toList()) + Text(".") + Li({ + classes("breadcrumb-item") + if(tokens.size == name.length) classes("active") + onClick { + link(fullName) + } + }) { + Text(token.toString()) + } + } + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt new file mode 100644 index 00000000..0892b9af --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/PropertyEditor.kt @@ -0,0 +1,183 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.launch +import org.jetbrains.compose.web.attributes.disabled +import org.jetbrains.compose.web.css.AlignItems +import org.jetbrains.compose.web.css.alignItems +import org.jetbrains.compose.web.css.px +import org.jetbrains.compose.web.css.width +import org.jetbrains.compose.web.dom.Button +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.Span +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ObservableMutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.remove +import space.kscience.dataforge.names.* +import space.kscience.visionforge.hidden + + +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public object Defined : EditorPropertyState() + public class Default(public val source: String = "unknown") : EditorPropertyState() + public object Undefined : EditorPropertyState() + +} + +/** + * @param meta Root config object - always non-null + * @param rootDescriptor Full path to the displayed node in [meta]. Could be empty + */ +@Composable +public fun PropertyEditor( + scope: CoroutineScope, + meta: MutableMeta, + getPropertyState: (Name) -> EditorPropertyState, + updates: Flow, + name: Name = Name.EMPTY, + rootDescriptor: MetaDescriptor? = null, + initialExpanded: Boolean? = null, +) { + var expanded: Boolean by remember { mutableStateOf(initialExpanded ?: true) } + val descriptor: MetaDescriptor? = remember(rootDescriptor, name) { rootDescriptor?.get(name) } + var property: MutableMeta by remember { mutableStateOf(meta.getOrCreate(name)) } + var editorPropertyState: EditorPropertyState by remember { mutableStateOf(getPropertyState(name)) } + + + val keys = remember(descriptor) { + buildSet { + descriptor?.children?.filterNot { + it.key.startsWith("@") || it.value.hidden + }?.forEach { + add(NameToken(it.key)) + } + //ownProperty?.items?.keys?.filterNot { it.body.startsWith("@") }?.let { addAll(it) } + } + } + + val token = name.lastOrNull()?.toString() ?: "Properties" + + fun update() { + property = meta.getOrCreate(name) + editorPropertyState = getPropertyState(name) + } + + LaunchedEffect(meta) { + updates.collect { updatedName -> + if (updatedName == name) { + update() + } + } + } + + FlexRow({ + style { + alignItems(AlignItems.Center) + } + }) { + if (keys.isNotEmpty()) { + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) + } + onClick { expanded = !expanded } + }) + } + Span({ + classes(TreeStyles.treeLabel) + if (editorPropertyState != EditorPropertyState.Defined) { + classes(TreeStyles.treeLabelInactive) + } + }) { + Text(token) + } + + if (!name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { + Div({ + style { + width(160.px) + marginAll(1.px, 5.px) + } + }) { + ValueChooser(descriptor, editorPropertyState, property.value) { + property.value = it + editorPropertyState = getPropertyState(name) + } + } + + Button({ + classes(TreeStyles.propertyEditorButton) + if (editorPropertyState != EditorPropertyState.Defined) { + disabled() + } else { + onClick { + meta.remove(name) + update() + } + } + }) { + Text("\u00D7") + } + } + } + if (expanded) { + FlexColumn({ + classes(TreeStyles.tree) + }) { + keys.forEach { token -> + Div({ + classes(TreeStyles.treeItem) + }) { + PropertyEditor(scope, meta, getPropertyState, updates, name + token, descriptor, expanded) + } + } + } + } +} + +@Composable +public fun PropertyEditor( + scope: CoroutineScope, + properties: ObservableMutableMeta, + descriptor: MetaDescriptor? = null, + expanded: Boolean? = null, +) { + PropertyEditor( + scope = scope, + meta = properties, + getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + }, + updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + invokeOnClose { + properties.removeListener(scope) + } + }, + name = Name.EMPTY, + rootDescriptor = descriptor, + initialExpanded = expanded, + ) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt new file mode 100644 index 00000000..cae4e797 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/Tabs.kt @@ -0,0 +1,102 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.dom.* +import org.w3c.dom.HTMLDivElement +import org.w3c.dom.HTMLLIElement + + +public class ComposeTab( + public val key: String, + public val title: String, + public val content: ContentBuilder, + public val disabled: Boolean, + public val titleExt: ContentBuilder, +) + +@Composable +public fun Tabs(tabs: List, activeKey: String) { + var active by remember(activeKey) { mutableStateOf(activeKey) } + + Div({ classes("card", "text-center") }) { + Div({ classes("card-header") }) { + + Ul({ classes("nav", "nav-tabs", "card-header-tabs") }) { + tabs.forEach { tab -> + Li({ + classes("nav-item") + }) { + A(attrs = { + classes("nav-link") + if (active == tab.key) { + classes("active") + } + if (tab.disabled) { + classes("disabled") + } + onClick { + active = tab.key + } + }) { + Text(tab.title) + } + tab.titleExt.invoke(this) + } + } + } + } + tabs.find { it.key == active }?.let { tab -> + Div({ classes("card-body") }) { + tab.content.invoke(this) + } + } + } + + +} + +public class TabBuilder internal constructor(public val key: String) { + private var title: String = key + public var disabled: Boolean = false + private var content: ContentBuilder = {} + private var titleExt: ContentBuilder = {} + + @Composable + public fun Content(content: ContentBuilder) { + this.content = content + } + + @Composable + public fun Title(title: String, titleExt: ContentBuilder = {}) { + this.title = title + this.titleExt = titleExt + } + + internal fun build(): ComposeTab = ComposeTab( + key, + title, + content, + disabled, + titleExt + ) +} + +public class TabsBuilder { + public var active: String = "" + internal val tabs: MutableList = mutableListOf() + + @Composable + public fun Tab(key: String, builder: @Composable TabBuilder.() -> Unit) { + tabs.add(TabBuilder(key).apply { builder() }.build()) + } + + public fun addTab(tab: ComposeTab) { + tabs.add(tab) + } +} + +@Composable +public fun Tabs(builder: @Composable TabsBuilder.() -> Unit) { + val result = TabsBuilder().apply { builder() } + Tabs(result.tabs, result.active) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt new file mode 100644 index 00000000..9816b5c2 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeCanvas.kt @@ -0,0 +1,52 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import kotlinx.dom.clear +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.Div +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.request +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions +import space.kscience.visionforge.solid.three.ThreeCanvas +import space.kscience.visionforge.solid.three.ThreePlugin + +@Composable +public fun ThreeCanvas( + context: Context, + options: Canvas3DOptions?, + solid: Solid?, + selected: Name?, +) { + + val three: ThreePlugin by derivedStateOf { context.request(ThreePlugin) } + + Div({ + style { + maxWidth(100.vw) + maxHeight(100.vh) + width(100.percent) + height(100.percent) + } + }) { + var canvas: ThreeCanvas? = null + DisposableEffect(options) { + canvas = ThreeCanvas(three, scopeElement, options ?: Canvas3DOptions()) + onDispose { + scopeElement.clear() + canvas = null + } + } + LaunchedEffect(solid) { + if (solid != null) { + canvas?.render(solid) + } else { + canvas?.clear() + } + } + LaunchedEffect(selected) { + canvas?.select(selected) + } + } +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt new file mode 100644 index 00000000..c559b946 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeControls.kt @@ -0,0 +1,80 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.Button +import org.jetbrains.compose.web.dom.Text +import org.w3c.files.Blob +import org.w3c.files.BlobPropertyBag +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import space.kscience.visionforge.encodeToString +import space.kscience.visionforge.solid.specifications.Canvas3DOptions + +@Composable +internal fun CanvasControls( + vision: Vision?, + options: Canvas3DOptions, +) { + FlexColumn { + FlexRow({ + style { + border { + width(1.px) + style(LineStyle.Solid) + color(Color("blue")) + } + padding(4.px) + } + }) { + vision?.let { vision -> + Button({ + onClick { event -> + val json = vision.encodeToString() + event.stopPropagation(); + event.preventDefault(); + + val fileSaver = kotlinext.js.require("file-saver") + val blob = Blob(arrayOf(json), BlobPropertyBag("text/json;charset=utf-8")) + fileSaver.saveAs(blob, "object.json") as Unit + } + }) { + Text("Export") + } + } + } + PropertyEditor( + scope = vision?.manager?.context ?: Global, + properties = options.meta, + descriptor = Canvas3DOptions.descriptor, + expanded = false + ) + + } +} + + +@Composable +public fun ThreeControls( + vision: Vision?, + canvasOptions: Canvas3DOptions, + selected: Name?, + onSelect: (Name?) -> Unit, + tabBuilder: @Composable TabsBuilder.() -> Unit = {}, +) { + Tabs { + active = "Tree" + vision?.let { vision -> + Tab("Tree") { + CardTitle("Vision tree") + VisionTree(vision, Name.EMPTY, selected, onSelect) + } + } + Tab("Settings") { + CardTitle("Canvas configuration") + CanvasControls(vision, canvasOptions) + } + tabBuilder() + } +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt new file mode 100644 index 00000000..7a347110 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/ThreeViewWithControls.kt @@ -0,0 +1,169 @@ +@file:OptIn(ExperimentalComposeWebApi::class) + +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import app.softwork.bootstrapcompose.Card +import kotlinx.coroutines.Deferred +import kotlinx.coroutines.launch +import org.jetbrains.compose.web.ExperimentalComposeWebApi +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.dom.* +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.isEmpty +import space.kscience.visionforge.* +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.specifications.Canvas3DOptions + +@Composable +public fun ThreeCanvasWithControls( + solids: Solids, + builderOfSolid: Deferred, + initialSelected: Name?, + options: Canvas3DOptions?, + tabBuilder: @Composable TabsBuilder.() -> Unit = {}, +) { + var selected: Name? by remember { mutableStateOf(initialSelected) } + var solid: Solid? by remember { mutableStateOf(null) } + + LaunchedEffect(builderOfSolid) { + solids.context.launch { + solid = builderOfSolid.await() + //ensure that the solid is properly rooted + if (solid?.parent == null) { + solid?.setAsRoot(solids.context.visionManager) + } + } + } + + val optionsWithSelector = remember(options) { + (options ?: Canvas3DOptions()).apply { + this.onSelect = { + selected = it + } + } + } + + val selectedVision: Vision? = remember(builderOfSolid, selected) { + selected?.let { + when { + it.isEmpty() -> solid + else -> (solid as? SolidGroup)?.get(it) + } + } + } + + + FlexRow({ + style { + height(100.percent) + width(100.percent) + flexWrap(FlexWrap.Wrap) + alignItems(AlignItems.Stretch) + alignContent(AlignContent.Stretch) + } + }) { + FlexColumn({ + style { + height(100.percent) + minWidth(600.px) + flex(10, 1, 600.px) + position(Position.Relative) + } + }) { + if (solid == null) { + Div({ + style { + position(Position.Fixed) + width(100.percent) + height(100.percent) + zIndex(1000) + top(40.percent) + left(0.px) + opacity(0.5) + filter { + opacity(50.percent) + } + } + }) { + Div({ classes("d-flex", " justify-content-center") }) { + Div({ + classes("spinner-grow", "text-primary") + style { + width(3.cssRem) + height(3.cssRem) + zIndex(20) + } + attr("role", "status") + }) { + Span({ classes("sr-only") }) { Text("Loading 3D vision") } + } + } + } + } else { + ThreeCanvas(solids.context, optionsWithSelector, solid, selected) + } + + selectedVision?.let { vision -> + Div({ + style { + position(Position.Absolute) + top(5.px) + right(5.px) + width(450.px) + } + }) { + Card( + headerAttrs = { + // border = true + }, + header = { + NameCrumbs(selected) { selected = it } + } + ) { + PropertyEditor( + scope = solids.context, + meta = vision.properties.root(), + getPropertyState = { name -> + if (vision.properties.own?.get(name) != null) { + EditorPropertyState.Defined + } else if (vision.properties.root()[name] != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + }, + updates = vision.properties.changes, + rootDescriptor = vision.descriptor + ) + + } + + vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> + P { + B { Text("Styles: ") } + Text(styles.joinToString(separator = ", ")) + } + } + } + } + } + } + FlexColumn({ + style { + paddingAll(4.px) + minWidth(400.px) + height(100.percent) + overflowY("auto") + flex(1, 10, 300.px) + } + }) { + ThreeControls(solid, optionsWithSelector, selected, onSelect = { selected = it }, tabBuilder = tabBuilder) + } +} + + diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt new file mode 100644 index 00000000..de9001ba --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/TreeStyles.kt @@ -0,0 +1,94 @@ +package space.kscience.visionforge.compose + +import org.jetbrains.compose.web.ExperimentalComposeWebApi +import org.jetbrains.compose.web.css.* + + +@OptIn(ExperimentalComposeWebApi::class) +public object TreeStyles : StyleSheet() { + /** + * Remove default bullets + */ + public val tree: String by style { + paddingLeft(5.px) + marginLeft(0.px) + listStyleType("none") + } + + /** + * Style the caret/arrow + */ + public val treeCaret: String by style { + cursor("pointer") + userSelect(UserSelect.none) + /* Create the caret/arrow with a unicode, and style it */ + before { + content("\u25B6") + color(Color.black) + display(DisplayStyle.InlineBlock) + marginRight(6.px) + } + } + + /** + * Rotate the caret/arrow icon when clicked on (using JavaScript) + */ + public val treeCaretDown: String by style { + before { + content("\u25B6") + color(Color.black) + display(DisplayStyle.InlineBlock) + marginRight(6.px) + transform { rotate(90.deg) } + } + } + + public val treeItem: String by style { + alignItems(AlignItems.Center) + paddingLeft(10.px) + border { + left { + width(1.px) + color(Color.lightgray) + style = LineStyle.Dashed + } + } + } + + public val treeLabel: String by style { + border(style = LineStyle.None) + paddingAll(left = 4.pt, right = 4.pt) + textAlign("left") + flex(1) + } + + public val treeLabelInactive: String by style { + color(Color.lightgray) + } + + public val treeLabelSelected: String by style { + backgroundColor(Color.lightblue) + } + + public val propertyEditorButton: String by style { + width(24.px) + alignSelf(AlignSelf.Stretch) + marginAll(1.px, 5.px) + backgroundColor(Color.white) + border{ + style(LineStyle.Solid) + } + borderRadius(2.px) + textAlign("center") + textDecoration("none") + cursor("pointer") + disabled { + cursor("auto") + border{ + style(LineStyle.Dashed) + } + color(Color.lightgray) + } + } + +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt new file mode 100644 index 00000000..2de59f90 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/VisionTree.kt @@ -0,0 +1,96 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.css.Color +import org.jetbrains.compose.web.css.color +import org.jetbrains.compose.web.css.cursor +import org.jetbrains.compose.web.css.textDecorationLine +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.Span +import org.jetbrains.compose.web.dom.Text +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.lastOrNull +import space.kscience.dataforge.names.plus +import space.kscience.dataforge.names.startsWith +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.asSequence +import space.kscience.visionforge.compose.TreeStyles.hover +import space.kscience.visionforge.compose.TreeStyles.invoke +import space.kscience.visionforge.isEmpty + + +@Composable +private fun TreeLabel( + vision: Vision, + name: Name, + selected: Name?, + clickCallback: (Name) -> Unit, +) { + Span({ + classes(TreeStyles.treeLabel) + if (name == selected) { + classes(TreeStyles.treeLabelSelected) + } + style { + color(Color("#069")) + cursor("pointer") + hover.invoke { + textDecorationLine("underline") + } + + } + onClick { clickCallback(name) } + }) { + Text(name.lastOrNull()?.toString() ?: "World") + } +} + +@Composable +public fun VisionTree( + vision: Vision, + name: Name = Name.EMPTY, + selected: Name? = null, + clickCallback: (Name) -> Unit, +): Unit { + var expanded: Boolean by remember { mutableStateOf(selected?.startsWith(name) ?: false) } + + //display as node if any child is visible + if (vision is VisionGroup) { + FlexRow { + if (vision.children.keys.any { !it.body.startsWith("@") }) { + Span({ + classes(TreeStyles.treeCaret) + if (expanded) { + classes(TreeStyles.treeCaretDown) + } + onClick { + expanded = !expanded + } + }) + } + TreeLabel(vision, name, selected, clickCallback) + } + if (expanded) { + FlexColumn({ + classes(TreeStyles.tree) + }) { + vision.children.asSequence() + .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children + .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups + .forEach { (childToken, child) -> + Div({ classes(TreeStyles.treeItem) }) { + VisionTree( + child, + name + childToken, + selected, + clickCallback + ) + } + } + } + } + } else { + TreeLabel(vision, name, selected, clickCallback) + } +} diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt new file mode 100644 index 00000000..8b0ee5b5 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/bootstrap.kt @@ -0,0 +1,8 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.dom.H5 +import org.jetbrains.compose.web.dom.Text + +@Composable +public fun CardTitle(title: String): Unit = H5({ classes("card-title") }) { Text(title) } \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt new file mode 100644 index 00000000..0bf8f7c2 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/css.kt @@ -0,0 +1,44 @@ +package space.kscience.visionforge.compose + +import org.jetbrains.compose.web.css.* +import org.jetbrains.compose.web.css.keywords.CSSAutoKeyword + +public enum class UserSelect { + inherit, initial, revert, revertLayer, unset, + + none, auto, text, contain, all; +} + +public fun StyleScope.userSelect(value: UserSelect) { + property("user-select", value.name) +} + +public fun StyleScope.content(value: String) { + property("content", "'$value'") +} + +public fun StyleScope.paddingAll( + top: CSSNumeric = 0.pt, + right: CSSNumeric = top, + bottom: CSSNumeric = top, + left: CSSNumeric = right, +) { + padding(top, right, bottom, left) +} + +public fun StyleScope.marginAll( + top: CSSNumeric = 0.pt, + right: CSSNumeric = top, + bottom: CSSNumeric = top, + left: CSSNumeric = right, +) { + margin(top, right, bottom, left) +} + +public fun StyleScope.zIndex(value: Int) { + property("z-index", "$value") +} + +public fun StyleScope.zIndex(value: CSSAutoKeyword) { + property("z-index", value) +} \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt new file mode 100644 index 00000000..882f1f1c --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/layouts.kt @@ -0,0 +1,41 @@ +package space.kscience.visionforge.compose + +import androidx.compose.runtime.Composable +import org.jetbrains.compose.web.css.DisplayStyle +import org.jetbrains.compose.web.css.FlexDirection +import org.jetbrains.compose.web.css.display +import org.jetbrains.compose.web.css.flexDirection +import org.jetbrains.compose.web.dom.AttrBuilderContext +import org.jetbrains.compose.web.dom.Div +import org.jetbrains.compose.web.dom.ElementScope +import org.w3c.dom.HTMLDivElement + +@Composable +public fun FlexColumn( + attrs: AttrBuilderContext? = null, + content: @Composable ElementScope.() -> Unit, +): Unit = Div( + attrs = { + style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Column) + } + attrs?.invoke(this) + }, + content +) + +@Composable +public fun FlexRow( + attrs: AttrBuilderContext? = null, + content: @Composable ElementScope.() -> Unit, +): Unit = Div( + attrs = { + style { + display(DisplayStyle.Flex) + flexDirection(FlexDirection.Row) + } + attrs?.invoke(this) + }, + content +) \ No newline at end of file diff --git a/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt new file mode 100644 index 00000000..b6aefee7 --- /dev/null +++ b/ui/compose/src/jsMain/kotlin/space/kscience/visionforge/compose/valueChooser.kt @@ -0,0 +1,268 @@ +@file:Suppress("UNUSED_PARAMETER") + +package space.kscience.visionforge.compose + +import androidx.compose.runtime.* +import org.jetbrains.compose.web.attributes.* +import org.jetbrains.compose.web.css.percent +import org.jetbrains.compose.web.css.px +import org.jetbrains.compose.web.css.width +import org.jetbrains.compose.web.dom.Input +import org.jetbrains.compose.web.dom.Option +import org.jetbrains.compose.web.dom.Select +import org.jetbrains.compose.web.dom.Text +import org.w3c.dom.HTMLInputElement +import org.w3c.dom.HTMLOptionElement +import org.w3c.dom.asList +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.ValueRestriction +import space.kscience.dataforge.meta.descriptors.allowedValues +import space.kscience.visionforge.Colors +import space.kscience.visionforge.widgetType +import three.math.Color + + +@Composable +public fun StringValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var stringValue by remember { mutableStateOf(value?.string ?: "") } + Input(type = InputType.Text) { + style { + width(100.percent) + } + value(stringValue) + onKeyDown { event -> + if (event.type == "keydown" && event.asDynamic().key == "Enter") { + stringValue = (event.target as HTMLInputElement).value + onValueChange(stringValue.asValue()) + } + } + onChange { + stringValue = it.target.value + } + } +} + + +@Composable +public fun BooleanValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Input(type = InputType.Checkbox) { + style { + width(100.percent) + } + //this.attributes["indeterminate"] = (props.item == null).toString() + checked(value?.boolean ?: false) + + onChange { + val newValue = it.target.checked + onValueChange(newValue.asValue()) + } + } +} + +@Composable +public fun NumberValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember { mutableStateOf(value?.string ?: "") } + Input(type = InputType.Number) { + style { + width(100.percent) + } + value(innerValue) + onKeyDown { event -> + if (event.type == "keydown" && event.asDynamic().key == "Enter") { + innerValue = (event.target as HTMLInputElement).value + val number = innerValue.toDoubleOrNull() + if (number == null) { + console.error("The input value $innerValue is not a number") + } else { + onValueChange(number.asValue()) + } + } + } + onChange { + innerValue = it.target.value + } + descriptor?.attributes?.get("step").number?.let { + step(it) + } + descriptor?.attributes?.get("min").string?.let { + min(it) + } + descriptor?.attributes?.get("max").string?.let { + max(it) + } + } +} + + +@Composable +public fun ComboValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var selected by remember { mutableStateOf(value?.string ?: "") } + Select({ + style { + width(100.percent) + } + onChange { + selected = it.target.value + onValueChange(selected.asValue()) + } + }, multiple = false) { + descriptor?.allowedValues?.forEach { + Option(it.string, { if (it == value) selected() }) { + Text(it.string) + } + } + + } +} + +@Composable +public fun ColorValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Input(type = InputType.Color) { + style { + width(100.percent) + marginAll(0.px) + } + value( + value?.let { value -> + if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) + else "#" + Color(value.string).getHexString() + } ?: "#000000" + ) + onChange { + onValueChange(it.target.value.asValue()) + } + } +} + + +@Composable +public fun MultiSelectChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + Select({ + onChange { event -> + val newSelected = event.target.selectedOptions.asList() + .map { (it as HTMLOptionElement).value.asValue() } + onValueChange(newSelected.asValue()) + + } + }, multiple = true) { + descriptor?.allowedValues?.forEach { optionValue -> + Option(optionValue.string, { + value?.list?.let { if (optionValue in it) selected() } + }) { + Text(optionValue.string) + } + } + + } +} + +@Composable +public fun RangeValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + var innerValue by remember { mutableStateOf(value?.double) } + var rangeDisabled: Boolean by remember { mutableStateOf(state != EditorPropertyState.Defined) } + + + FlexRow { + if (descriptor?.valueRestriction != ValueRestriction.REQUIRED) { + Input(type = InputType.Checkbox) { + if (!rangeDisabled) defaultChecked() + + onChange { + val checkBoxValue = it.target.checked + rangeDisabled = !checkBoxValue + onValueChange( + if (!checkBoxValue) { + null + } else { + innerValue?.asValue() + } + ) + } + } + } + } + + Input(type = InputType.Range) { + style { + width(100.percent) + } + if (rangeDisabled) disabled() + value(innerValue?.toString() ?: "") + onChange { + val newValue = it.target.value + onValueChange(newValue.toDoubleOrNull()?.asValue()) + innerValue = newValue.toDoubleOrNull() + } + descriptor?.attributes?.get("min").string?.let { + min(it) + } + descriptor?.attributes?.get("max").string?.let { + max(it) + } + descriptor?.attributes?.get("step").number?.let { + step(it) + } + + } + +} + +@Composable +public fun ValueChooser( + descriptor: MetaDescriptor?, + state: EditorPropertyState, + value: Value?, + onValueChange: (Value?) -> Unit, +) { + val rawInput by remember { mutableStateOf(false) } + + val type = descriptor?.valueTypes?.firstOrNull() + + when { + rawInput -> StringValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "color" -> ColorValueChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "multiSelect" -> MultiSelectChooser(descriptor, state, value, onValueChange) + descriptor?.widgetType == "range" -> RangeValueChooser(descriptor, state, value, onValueChange) + type == ValueType.BOOLEAN -> BooleanValueChooser(descriptor, state, value, onValueChange) + type == ValueType.NUMBER -> NumberValueChooser(descriptor, state, value, onValueChange) + descriptor?.allowedValues?.isNotEmpty() ?: false -> ComboValueChooser(descriptor, state, value, onValueChange) + //TODO handle lists + else -> StringValueChooser(descriptor, state, value, onValueChange) + } +} \ No newline at end of file diff --git a/ui/react/build.gradle.kts b/ui/react/build.gradle.kts index 40853ca9..1770feeb 100644 --- a/ui/react/build.gradle.kts +++ b/ui/react/build.gradle.kts @@ -1,11 +1,16 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.mpp") } -dependencies{ - api(project(":visionforge-solid")) - api("org.jetbrains.kotlin-wrappers:kotlin-styled") - api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") +kscience { + js() + jsMain { + dependencies { + api(projects.visionforgeSolid) + api("org.jetbrains.kotlin-wrappers:kotlin-styled") + api("org.jetbrains.kotlin-wrappers:kotlin-react-dom") // implementation(npm("react-select","4.3.0")) - implementation(project(":visionforge-threejs")) + api(projects.visionforgeThreejs) + } + } } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/MetaViewer.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MetaViewer.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt similarity index 80% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt index f3c81a57..fc635d21 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/MultiSelectChooser.kt @@ -10,22 +10,22 @@ import react.dom.attrs import react.dom.option import react.dom.select import react.fc +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.string @JsExport public val MultiSelectChooser: FC = fc("MultiSelectChooser") { props -> val onChange: (Event) -> Unit = { event: Event -> val newSelected = (event.target as HTMLSelectElement).selectedOptions.asList() .map { (it as HTMLOptionElement).value.asValue() } - props.meta.value = newSelected.asValue() + props.onValueChange(newSelected.asValue()) } select { attrs { multiple = true - values = (props.actual.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } + values = (props.value?.list ?: emptyList()).mapTo(HashSet()) { it.string } onChangeFunction = onChange } props.descriptor?.allowedValues?.forEach { optionValue -> diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt similarity index 62% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt index 6c677e2e..b13e7304 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/PropertyEditor.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/PropertyEditor.kt @@ -1,17 +1,24 @@ package space.kscience.visionforge.react +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.launch import kotlinx.css.* import kotlinx.css.properties.TextDecoration import kotlinx.html.js.onClickFunction -import org.w3c.dom.Element import org.w3c.dom.events.Event import react.* import react.dom.attrs -import react.dom.render -import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.meta.remove import space.kscience.dataforge.names.* import space.kscience.visionforge.hidden import styled.css @@ -19,17 +26,30 @@ import styled.styledButton import styled.styledDiv import styled.styledSpan +/** + * The display state of a property + */ +public sealed class EditorPropertyState { + public object Defined : EditorPropertyState() + public class Default(public val source: String = "unknown") : EditorPropertyState() + + public object Undefined : EditorPropertyState() + +} + + public external interface PropertyEditorProps : Props { /** * Root config object - always non-null */ - public var meta: ObservableMutableMeta + public var meta: MutableMeta - /** - * Provide default item (greyed out if used) - */ - public var withDefault: MetaProvider + public var getPropertyState: (Name) -> EditorPropertyState + + public var scope: CoroutineScope + + public var updates: Flow /** * Full path to the displayed node in [meta]. Could be empty @@ -54,7 +74,9 @@ private val PropertyEditorItem: FC = fc("PropertyEditorItem private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { var expanded: Boolean by useState { props.expanded ?: true } val descriptor: MetaDescriptor? = useMemo(props.descriptor, props.name) { props.descriptor?.get(props.name) } - var ownProperty: ObservableMutableMeta by useState { props.meta.getOrCreate(props.name) } + var property: MutableMeta by useState { props.meta.getOrCreate(props.name) } + var editorPropertyState: EditorPropertyState by useState { props.getPropertyState(props.name) } + val keys = useMemo(descriptor) { buildSet { @@ -70,17 +92,19 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { val token = props.name.lastOrNull()?.toString() ?: "Properties" fun update() { - ownProperty = props.meta.getOrCreate(props.name) + property = props.meta.getOrCreate(props.name) + editorPropertyState = props.getPropertyState(props.name) } useEffect(props.meta) { - props.meta.onChange(props) { updatedName -> + val job = props.updates.onEach { updatedName -> if (updatedName == props.name) { update() } - } + }.launchIn(props.scope) + cleanup { - props.meta.removeListener(props) + job.cancel() } } @@ -115,24 +139,28 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { styledSpan { css { +TreeStyles.treeLabel - if (ownProperty.isEmpty()) { + if (editorPropertyState != EditorPropertyState.Defined) { +TreeStyles.treeLabelInactive } } +token } - if (!props.name.isEmpty() && descriptor?.valueRequirement != ValueRequirement.ABSENT) { + if (!props.name.isEmpty() && descriptor?.valueRestriction != ValueRestriction.ABSENT) { styledDiv { css { //+TreeStyles.resizeableInput width = 160.px - margin(1.px, 5.px) + margin = Margin(1.px, 5.px) } ValueChooser { attrs { this.descriptor = descriptor - this.meta = ownProperty - this.actual = props.withDefault.getMeta(props.name) ?: ownProperty + this.state = editorPropertyState + this.value = property.value + this.onValueChange = { + property.value = it + editorPropertyState = props.getPropertyState(props.name) + } } } } @@ -141,7 +169,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { css { width = 24.px alignSelf = Align.stretch - margin(1.px, 5.px) + margin = Margin(1.px, 5.px) backgroundColor = Color.white borderStyle = BorderStyle.solid borderRadius = 2.px @@ -156,7 +184,7 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { } +"\u00D7" attrs { - if (ownProperty.isEmpty()) { + if (editorPropertyState != EditorPropertyState.Defined) { disabled = true } else { onClickFunction = removeClick @@ -179,9 +207,11 @@ private fun RBuilder.propertyEditorItem(props: PropertyEditorProps) { attrs { this.key = props.name.toString() this.meta = props.meta - this.withDefault = props.withDefault this.name = props.name + token this.descriptor = props.descriptor + this.scope = props.scope + this.getPropertyState = { props.getPropertyState(props.name + token) } + this.updates = props.updates } } //configEditor(props.root, props.name + token, props.descriptor, props.default) @@ -197,44 +227,51 @@ public val PropertyEditor: FC = fc("PropertyEditor") { prop attrs { this.key = "" this.meta = props.meta - this.withDefault = props.withDefault this.name = Name.EMPTY this.descriptor = props.descriptor this.expanded = props.expanded + this.scope = props.scope + this.getPropertyState = props.getPropertyState + this.updates = props.updates } } } +@OptIn(ExperimentalCoroutinesApi::class) public fun RBuilder.propertyEditor( - ownProperties: ObservableMutableMeta, - allProperties: MetaProvider = ownProperties, + scope: CoroutineScope, + properties: ObservableMutableMeta, descriptor: MetaDescriptor? = null, key: Any? = null, expanded: Boolean? = null, ) { child(PropertyEditor) { attrs { - this.meta = ownProperties - this.withDefault = allProperties + this.meta = properties this.descriptor = descriptor this.key = key?.toString() ?: "" this.expanded = expanded + this.scope = scope + this.getPropertyState = { name -> + if (properties[name] != null) { + EditorPropertyState.Defined + } else if (descriptor?.get(name)?.defaultValue != null) { + EditorPropertyState.Default("descriptor") + } else { + EditorPropertyState.Undefined + } + } + this.updates = callbackFlow { + properties.onChange(scope) { name -> + scope.launch { + send(name) + } + } + + invokeOnClose { + properties.removeListener(scope) + } + } } } -} - -public fun RBuilder.configEditor( - config: ObservableMutableMeta, - default: MetaProvider = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = propertyEditor(config, default, descriptor, key = key) - -public fun Element.configEditor( - config: ObservableMutableMeta, - default: Meta = config, - descriptor: MetaDescriptor? = null, - key: Any? = null, -): Unit = render(this) { - configEditor(config, default, descriptor, key = key) } \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt similarity index 72% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt index 8ccedc01..bec34fc1 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/RangeValueChooser.kt @@ -4,43 +4,46 @@ import kotlinx.css.pct import kotlinx.css.width import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction +import kotlinx.html.js.onInputFunction import org.w3c.dom.HTMLInputElement import org.w3c.dom.events.Event import react.FC import react.dom.attrs import react.fc import react.useState -import space.kscience.dataforge.meta.descriptors.ValueRequirement +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.descriptors.ValueRestriction import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.string -import space.kscience.dataforge.values.asValue import styled.css import styled.styledInput @JsExport public val RangeValueChooser: FC = fc("RangeValueChooser") { props -> - var innerValue by useState(props.actual.double) - var rangeDisabled: Boolean by useState(props.meta.value == null) + var innerValue by useState(props.value?.double) + var rangeDisabled: Boolean by useState(props.state != EditorPropertyState.Defined) val handleDisable: (Event) -> Unit = { val checkBoxValue = (it.target as HTMLInputElement).checked rangeDisabled = !checkBoxValue - props.meta.value = if (!checkBoxValue) { - null - } else { - innerValue?.asValue() - } + props.onValueChange( + if (!checkBoxValue) { + null + } else { + innerValue?.asValue() + } + ) } val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).value - props.meta.value = newValue.toDoubleOrNull()?.asValue() + props.onValueChange(newValue.toDoubleOrNull()?.asValue()) innerValue = newValue.toDoubleOrNull() } flexRow { - if (props.descriptor?.valueRequirement != ValueRequirement.REQUIRED) { + if (props.descriptor?.valueRestriction != ValueRestriction.REQUIRED) { styledInput(type = InputType.checkBox) { attrs { defaultChecked = rangeDisabled.not() @@ -56,8 +59,8 @@ public val RangeValueChooser: FC = fc("RangeValueChooser") { attrs { disabled = rangeDisabled value = innerValue?.toString() ?: "" - onChangeFunction = handleChange - consumer.onTagEvent(this, "input", handleChange) +// onChangeFunction = handleChange + onInputFunction = handleChange val minValue = props.descriptor?.attributes?.get("min").string minValue?.let { min = it diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt similarity index 88% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt index 4683f579..8cfa515d 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ThreeCanvasComponent.kt @@ -2,10 +2,9 @@ package space.kscience.visionforge.react import kotlinx.css.* import org.w3c.dom.Element -import org.w3c.dom.HTMLElement import react.* import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.names.Name import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.Canvas3DOptions @@ -25,11 +24,11 @@ public val ThreeCanvasComponent: FC = fc("ThreeCanvasComponent val elementRef = useRef(null) var canvas by useState(null) - val three: ThreePlugin = useMemo(props.context) { props.context.fetch(ThreePlugin) } + val three: ThreePlugin = useMemo(props.context) { props.context.request(ThreePlugin) } useEffect(props.solid, props.options, elementRef) { if (canvas == null) { - val element = elementRef.current as? HTMLElement ?: error("Canvas element not found") + val element = elementRef.current ?: error("Canvas element not found") canvas = ThreeCanvas(three, element, props.options ?: Canvas3DOptions()) } } diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt similarity index 92% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt index 5d693a3c..109d0256 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/TreeStyles.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/TreeStyles.kt @@ -52,10 +52,10 @@ public object TreeStyles : StyleSheet("treeStyles", true) { } public val treeLabel:RuleSet by css { - border = "none" - padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) + border = Border.none + padding = Padding(left = 4.pt, right = 4.pt, top = 0.pt, bottom = 0.pt) textAlign = TextAlign.left - flex(1.0) + flex = Flex(1.0) } public val treeLabelInactive: RuleSet by css { diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt similarity index 86% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt index 54fc8ec4..6212a456 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/VisionTree.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/VisionTree.kt @@ -1,11 +1,8 @@ package space.kscience.visionforge.react -import kotlinx.css.Color -import kotlinx.css.Cursor -import kotlinx.css.color -import kotlinx.css.cursor +import kotlinx.css.* +import kotlinx.css.properties.TextDecoration import kotlinx.css.properties.TextDecorationLine -import kotlinx.css.properties.textDecoration import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import react.* @@ -16,6 +13,7 @@ import space.kscience.dataforge.names.plus import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.asSequence import space.kscience.visionforge.isEmpty import styled.css import styled.styledDiv @@ -36,7 +34,7 @@ private val TreeLabel = fc { props -> color = Color("#069") cursor = Cursor.pointer hover { - textDecoration(TextDecorationLine.underline) + textDecoration = TextDecoration(setOf(TextDecorationLine.underline)) } if (props.name == props.selected) { +TreeStyles.treeLabelSelected @@ -61,7 +59,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { //display as node if any child is visible if (obj is VisionGroup) { flexRow { - if (obj.children.any { !it.key.body.startsWith("@") }) { + if (obj.children.keys.any { !it.body.startsWith("@") }) { styledSpan { css { +TreeStyles.treeCaret @@ -81,9 +79,9 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit { css { +TreeStyles.tree } - obj.children.entries - .filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children - .sortedBy { (it.value as? VisionGroup)?.isEmpty() ?: true } // ignore empty groups + obj.children.asSequence() + .filter { !it.first.toString().startsWith("@") } // ignore statics and other hidden children + .sortedBy { (it.second as? VisionGroup)?.children?.isEmpty() ?: true } // ignore empty groups .forEach { (childToken, child) -> styledDiv { css { diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt new file mode 100644 index 00000000..fec86770 --- /dev/null +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/createRoot.kt @@ -0,0 +1,17 @@ + +@file:JsModule("react-dom/client") +@file:JsNonModule + +package space.kscience.visionforge.react + +import org.w3c.dom.Element +import react.dom.client.Root +import react.dom.client.RootOptions + +/** + * Compatibility method to work with old browser API + */ +public external fun createRoot( + container: Element, + options: RootOptions = definedExternally, +): Root diff --git a/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt new file mode 100644 index 00000000..ae47fa65 --- /dev/null +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/ext.kt @@ -0,0 +1,10 @@ +package space.kscience.visionforge.react + +import react.Props +import react.RBuilder +import react.createElement +import react.dom.client.Root + +public fun Root.render(block: RBuilder.() -> Unit) { + render(createElement(block)) +} \ No newline at end of file diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt similarity index 100% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/layout.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/layout.kt diff --git a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt similarity index 82% rename from ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt rename to ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt index 03996c04..5d0c7c3d 100644 --- a/ui/react/src/main/kotlin/space/kscience/visionforge/react/valueChooser.kt +++ b/ui/react/src/jsMain/kotlin/space/kscience/visionforge/react/valueChooser.kt @@ -1,9 +1,6 @@ package space.kscience.visionforge.react -import kotlinx.css.margin -import kotlinx.css.pct -import kotlinx.css.px -import kotlinx.css.width +import kotlinx.css.* import kotlinx.html.InputType import kotlinx.html.js.onChangeFunction import kotlinx.html.js.onKeyDownFunction @@ -19,29 +16,27 @@ import react.useState import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string import space.kscience.visionforge.Colors import space.kscience.visionforge.widgetType import styled.css import styled.styledInput import styled.styledSelect +import three.math.Color public external interface ValueChooserProps : Props { public var descriptor: MetaDescriptor? - public var meta: ObservableMutableMeta - public var actual: Meta + public var state: EditorPropertyState + public var value: Value? + public var onValueChange: (Value?) -> Unit } @JsExport public val StringValueChooser: FC = fc("StringValueChooser") { props -> - var value by useState(props.actual.string ?: "") + var value by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { value = (event.target as HTMLInputElement).value - props.meta.value = value.asValue() + props.onValueChange(value.asValue()) } } val handleChange: (Event) -> Unit = { @@ -63,7 +58,7 @@ public val StringValueChooser: FC = fc("StringValueChooser") public val BooleanValueChooser: FC = fc("BooleanValueChooser") { props -> val handleChange: (Event) -> Unit = { val newValue = (it.target as HTMLInputElement).checked - props.meta.value = newValue.asValue() + props.onValueChange(newValue.asValue()) } styledInput(type = InputType.checkBox) { css { @@ -71,7 +66,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" } attrs { //this.attributes["indeterminate"] = (props.item == null).toString() - checked = props.actual.boolean ?: false + checked = props.value?.boolean ?: false onChangeFunction = handleChange } } @@ -79,7 +74,7 @@ public val BooleanValueChooser: FC = fc("BooleanValueChooser" @JsExport public val NumberValueChooser: FC = fc("NumberValueChooser") { props -> - var innerValue by useState(props.actual.string ?: "") + var innerValue by useState(props.value?.string ?: "") val keyDown: (Event) -> Unit = { event -> if (event.type == "keydown" && event.asDynamic().key == "Enter") { innerValue = (event.target as HTMLInputElement).value @@ -87,7 +82,7 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") if (number == null) { console.error("The input value $innerValue is not a number") } else { - props.meta.value = number.asValue() + props.onValueChange(number.asValue()) } } } @@ -117,10 +112,10 @@ public val NumberValueChooser: FC = fc("NumberValueChooser") @JsExport public val ComboValueChooser: FC = fc("ComboValueChooser") { props -> - var selected by useState(props.actual.string ?: "") + var selected by useState(props.value?.string ?: "") val handleChange: (Event) -> Unit = { selected = (it.target as HTMLSelectElement).value - props.meta.value = selected.asValue() + props.onValueChange(selected.asValue()) } styledSelect { css { @@ -132,7 +127,7 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { } } attrs { - this.value = props.actual.string ?: "" + this.value = props.value?.string ?: "" multiple = false onChangeFunction = handleChange } @@ -142,17 +137,17 @@ public val ComboValueChooser: FC = fc("ComboValueChooser") { @JsExport public val ColorValueChooser: FC = fc("ColorValueChooser") { props -> val handleChange: (Event) -> Unit = { - props.meta.value = (it.target as HTMLInputElement).value.asValue() + props.onValueChange((it.target as HTMLInputElement).value.asValue()) } styledInput(type = InputType.color) { css { width = 100.pct - margin(0.px) + margin = Margin(0.px) } attrs { - this.value = props.actual.value?.let { value -> + this.value = props.value?.let { value -> if (value.type == ValueType.NUMBER) Colors.rgbToString(value.int) - else value.string + else "#" + Color(value.string).getHexString() } ?: "#000000" onChangeFunction = handleChange } diff --git a/ui/ring/build.gradle.kts b/ui/ring/build.gradle.kts index 53dee008..d1f2ff72 100644 --- a/ui/ring/build.gradle.kts +++ b/ui/ring/build.gradle.kts @@ -1,24 +1,25 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra -kotlin{ +kscience{ js{ useCommonJs() browser { commonWebpackConfig { - cssSupport.enabled = false + cssSupport{ + enabled.set(false) + } } } } -} + jsMain{ + api(projects.ui.react) + api("org.jetbrains.kotlin-wrappers:kotlin-ring-ui") -dependencies{ - api(project(":ui:react")) - api("org.jetbrains.kotlin-wrappers:kotlin-ring-ui") - - implementation(npm("core-js","3.12.1")) - implementation(npm("file-saver", "2.0.2")) + implementation(npm("core-js","3.12.1")) + implementation(npm("file-saver", "2.0.2")) + } } \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/ringui/Loader.kt b/ui/ring/src/jsMain/kotlin/ringui/Loader.kt similarity index 100% rename from ui/ring/src/main/kotlin/ringui/Loader.kt rename to ui/ring/src/jsMain/kotlin/ringui/Loader.kt diff --git a/ui/ring/src/main/kotlin/ringui/LoaderScreen.kt b/ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt similarity index 100% rename from ui/ring/src/main/kotlin/ringui/LoaderScreen.kt rename to ui/ring/src/jsMain/kotlin/ringui/LoaderScreen.kt diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt similarity index 67% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt index 5cdcf5c0..6ae2ec62 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeViewWithControls.kt @@ -5,39 +5,46 @@ import kotlinx.coroutines.async import kotlinx.coroutines.launch import kotlinx.css.* import react.* +import react.dom.b import react.dom.div +import react.dom.p import react.dom.span import ringui.* -import space.kscience.dataforge.context.Context +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.length import space.kscience.visionforge.* -import space.kscience.visionforge.react.ThreeCanvasComponent -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.flexRow -import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.react.* import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.solid.solidGroup import space.kscience.visionforge.solid.specifications.Canvas3DOptions import styled.css import styled.styledDiv public external interface ThreeCanvasWithControlsProps : Props { - public var context: Context + public var solids: Solids public var builderOfSolid: Deferred public var selected: Name? public var options: Canvas3DOptions? public var additionalTabs: Map Unit>? } +private val ThreeCanvasWithControlsProps.context get() = solids.context + public fun ThreeCanvasWithControlsProps.solid(block: SolidGroup.() -> Unit) { builderOfSolid = context.async { - SolidGroup(block) + solids.solidGroup(null, block) } } +public fun ThreeCanvasWithControlsProps.options(block: Canvas3DOptions.() -> Unit) { + options = Canvas3DOptions(block) +} + public fun ThreeCanvasWithControlsProps.tab(title: String, block: RBuilder.() -> Unit) { additionalTabs = (additionalTabs ?: emptyMap()) + (title to block) } @@ -77,14 +84,14 @@ public fun RBuilder.nameCrumbs(name: Name?, link: (Name) -> Unit): Unit = styled @JsExport public val ThreeCanvasWithControls: FC = fc("ThreeViewWithControls") { props -> - var selected by useState { props.selected } + var selected: Name? by useState { props.selected } var solid: Solid? by useState(null) useEffect { props.context.launch { solid = props.builderOfSolid.await() //ensure that the solid is properly rooted - if(solid?.parent == null){ + if (solid?.parent == null) { solid?.setAsRoot(props.context.visionManager) } } @@ -104,7 +111,7 @@ public val ThreeCanvasWithControls: FC = fc("Three selected?.let { when { it.isEmpty() -> solid - else -> (solid as? VisionGroup)?.get(it) + else -> (solid as? SolidGroup)?.get(it) } } } @@ -123,7 +130,7 @@ public val ThreeCanvasWithControls: FC = fc("Three css { height = 100.pct minWidth = 600.px - flex(10.0, 1.0, FlexBasis("600px")) + flex = Flex(10.0, 1.0, FlexBasis("600px")) position = Position.relative } @@ -160,12 +167,31 @@ public val ThreeCanvasWithControls: FC = fc("Three nameCrumbs(selected) { selected = it } } IslandContent { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = vision.descriptor, - key = selected - ) + child(PropertyEditor) { + attrs { + this.key = selected.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = vision.descriptor + this.scope = props.context + this.getPropertyState = { name -> + if (vision.properties.own?.get(name) != null) { + EditorPropertyState.Defined + } else if (vision.properties.root()[name] != null) { + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } + vision.styles.takeIf { it.isNotEmpty() }?.let { styles -> + p { + b { +"Styles: " } + +styles.joinToString(separator = ", ") + } + } } } } @@ -173,11 +199,11 @@ public val ThreeCanvasWithControls: FC = fc("Three } flexColumn { css { - padding(4.px) + padding = Padding(4.px) minWidth = 400.px height = 100.pct overflowY = Overflow.auto - flex(1.0, 10.0, FlexBasis("300px")) + flex = Flex(1.0, 10.0, FlexBasis("300px")) } ringThreeControls(options, solid, selected, onSelect, additionalTabs = props.additionalTabs) } diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt similarity index 62% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt index c01b5ae1..94259b2f 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ThreeWithControlsPlugin.kt @@ -2,19 +2,21 @@ package space.kscience.visionforge.ring import kotlinx.coroutines.async import org.w3c.dom.Element -import react.child import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.ElementVisionRenderer import space.kscience.visionforge.Vision +import space.kscience.visionforge.react.render import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.ThreePlugin -import kotlin.reflect.KClass public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { public val three: ThreePlugin by require(ThreePlugin) @@ -24,12 +26,17 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { override fun rateVision(vision: Vision): Int = if (vision is Solid) ElementVisionRenderer.DEFAULT_RATING * 2 else ElementVisionRenderer.ZERO_RATING - override fun render(element: Element, vision: Vision, meta: Meta) { - react.dom.render(element) { - child(ThreeCanvasWithControls) { - attrs { - this.context = this@ThreeWithControlsPlugin.context - this.builderOfSolid = context.async { vision as Solid} + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { + if(meta["controls.enabled"].boolean == false){ + three.render(element, name, vision, meta) + } else { + space.kscience.visionforge.react.createRoot(element).render { + child(ThreeCanvasWithControls) { + attrs { + this.solids = three.solids + this.options = Canvas3DOptions.read(meta) + this.builderOfSolid = context.async { vision as Solid } + } } } } @@ -44,7 +51,7 @@ public class ThreeWithControlsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs.withControls", PluginTag.DATAFORGE_GROUP) - override val type: KClass = ThreeWithControlsPlugin::class - override fun invoke(meta: Meta, context: Context): ThreeWithControlsPlugin = ThreeWithControlsPlugin() + + override fun build(context: Context, meta: Meta): ThreeWithControlsPlugin = ThreeWithControlsPlugin() } } \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt similarity index 64% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt index 06f2a1c0..83529d28 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringPropertyEditor.kt @@ -3,17 +3,15 @@ package space.kscience.visionforge.ring import org.w3c.dom.Element import react.RBuilder import react.dom.p -import react.dom.render import ringui.Island import ringui.SmartTabs import ringui.Tab import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.get import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle -import space.kscience.visionforge.react.flexColumn -import space.kscience.visionforge.react.metaViewer -import space.kscience.visionforge.react.propertyEditor +import space.kscience.visionforge.react.* +import space.kscience.visionforge.root import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.styles @@ -30,12 +28,25 @@ public fun RBuilder.ringPropertyEditor( flexColumn { Island("Properties") { - propertyEditor( - ownProperties = vision.meta, - allProperties = vision.computeProperties(), - descriptor = descriptor, - key = key - ) + child(PropertyEditor) { + attrs { + this.key = key?.toString() + this.meta = vision.properties.root() + this.updates = vision.properties.changes + this.descriptor = descriptor + this.scope = vision.manager?.context ?: error("Orphan vision could not be observed") + this.getPropertyState = {name-> + if(vision.properties.own?.get(name)!= null){ + EditorPropertyState.Defined + } else if(vision.properties.root()[name] != null){ + // TODO differentiate + EditorPropertyState.Default() + } else { + EditorPropertyState.Undefined + } + } + } + } } if (styles.isNotEmpty()) { @@ -72,6 +83,6 @@ public fun RBuilder.ringPropertyEditor( public fun Element.ringPropertyEditor( item: Vision, descriptor: MetaDescriptor? = item.descriptor, -): Unit = render(this) { +): Unit = createRoot(this).render { ringPropertyEditor(item, descriptor = descriptor) } \ No newline at end of file diff --git a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt similarity index 87% rename from ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt rename to ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt index 68cc13b2..6cdc0707 100644 --- a/ui/ring/src/main/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt +++ b/ui/ring/src/jsMain/kotlin/space.kscience.visionforge.ring/ringThreeControls.kt @@ -1,10 +1,8 @@ package space.kscience.visionforge.ring -import kotlinx.css.BorderStyle -import kotlinx.css.Color -import kotlinx.css.padding -import kotlinx.css.properties.border -import kotlinx.css.px +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.css.* import kotlinx.html.js.onClickFunction import org.w3c.dom.events.Event import org.w3c.files.Blob @@ -18,7 +16,6 @@ import react.fc import ringui.Island import ringui.SmartTabs import ringui.Tab -import space.kscience.dataforge.meta.withDefault import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision import space.kscience.visionforge.encodeToString @@ -33,7 +30,7 @@ internal fun saveData(event: Event, fileName: String, mimeType: String = "text/p event.stopPropagation(); event.preventDefault(); - val fileSaver = kotlinext.js.require("file-saver") + val fileSaver = kotlinext.js.require("file-saver") val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8")) fileSaver.saveAs(blob, fileName) } @@ -52,12 +49,13 @@ internal external interface CanvasControlsProps : Props { public var vision: Vision? } +@OptIn(DelicateCoroutinesApi::class) internal val CanvasControls: FC = fc("CanvasControls") { props -> flexColumn { flexRow { css { - border(1.px, BorderStyle.solid, Color.blue) - padding(4.px) + border = Border(1.px, BorderStyle.solid, Color.blue) + padding = Padding(4.px) } props.vision?.let { vision -> button { @@ -75,8 +73,8 @@ internal val CanvasControls: FC = fc("CanvasControls") { pr } } propertyEditor( - ownProperties = props.options.meta, - allProperties = props.options.meta.withDefault(Canvas3DOptions.descriptor.defaultNode), + scope = props.vision?.manager?.context ?: GlobalScope, + properties = props.options.meta, descriptor = Canvas3DOptions.descriptor, expanded = false ) diff --git a/visionforge-core/api/visionforge-core.api b/visionforge-core/api/visionforge-core.api index 0937e26d..f9099a99 100644 --- a/visionforge-core/api/visionforge-core.api +++ b/visionforge-core/api/visionforge-core.api @@ -183,7 +183,7 @@ public class space/kscience/visionforge/SimpleVisionPropertyContainer : space/ks public fun (Lspace/kscience/dataforge/meta/ObservableMutableMeta;)V public synthetic fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta; public fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; } public final class space/kscience/visionforge/StyleReference { @@ -241,8 +241,8 @@ public abstract interface class space/kscience/visionforge/Vision : space/kscien public fun getManager ()Lspace/kscience/visionforge/VisionManager; public abstract fun getMeta ()Lspace/kscience/dataforge/meta/ObservableMutableMeta; public abstract fun getParent ()Lspace/kscience/visionforge/VisionGroup; - public abstract fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public abstract fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; public abstract fun invalidateProperty (Lspace/kscience/dataforge/names/Name;)V public abstract fun setParent (Lspace/kscience/visionforge/VisionGroup;)V public abstract fun update (Lspace/kscience/visionforge/VisionChange;)V @@ -266,7 +266,7 @@ public class space/kscience/visionforge/VisionBase : space/kscience/visionforge/ protected final fun getOrCreateProperties ()Lspace/kscience/dataforge/meta/MutableMeta; public fun getParent ()Lspace/kscience/visionforge/VisionGroup; protected final fun getProperties ()Lspace/kscience/dataforge/meta/MutableMeta; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public fun invalidateProperty (Lspace/kscience/dataforge/names/Name;)V public fun setParent (Lspace/kscience/visionforge/VisionGroup;)V protected final fun setProperties (Lspace/kscience/dataforge/meta/MutableMeta;)V @@ -446,8 +446,8 @@ public final class space/kscience/visionforge/VisionGroupKt { public final class space/kscience/visionforge/VisionKt { public static final fun getPropertyChanges (Lspace/kscience/visionforge/Vision;)Lkotlinx/coroutines/flow/Flow; - public static final fun getPropertyValue (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public static final fun getProperty (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/Vision;Ljava/lang/String;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; public static final fun getVisible (Lspace/kscience/visionforge/Vision;)Ljava/lang/Boolean; public static final fun onPropertyChange (Lspace/kscience/visionforge/Vision;Lkotlin/jvm/functions/Function2;)V public static final fun setProperty (Lspace/kscience/visionforge/Vision;Lspace/kscience/dataforge/names/Name;Ljava/lang/Object;)V @@ -499,8 +499,8 @@ public abstract class space/kscience/visionforge/VisionPlugin : space/kscience/d public abstract interface class space/kscience/visionforge/VisionPropertyContainer { public abstract fun getMeta ()Lspace/kscience/dataforge/meta/MutableMeta; - public abstract fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; - public static synthetic fun getPropertyValue$default (Lspace/kscience/visionforge/VisionPropertyContainer;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; + public abstract fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public static synthetic fun getProperty$default (Lspace/kscience/visionforge/VisionPropertyContainer;Lspace/kscience/dataforge/names/Name;ZZZILjava/lang/Object;)Lspace/kscience/dataforge/values/Value; } public final class space/kscience/visionforge/html/HeadersKt { diff --git a/visionforge-core/build.gradle.kts b/visionforge-core/build.gradle.kts index 227c80dc..f2cac4c6 100644 --- a/visionforge-core/build.gradle.kts +++ b/visionforge-core/build.gradle.kts @@ -1,32 +1,27 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } val dataforgeVersion: String by rootProject.extra -kotlin { - sourceSets { - commonMain { - dependencies { - api("space.kscience:dataforge-context:$dataforgeVersion") - api(npmlibs.kotlinx.html) - api("org.jetbrains.kotlin-wrappers:kotlin-css") - } - } - jsMain { - dependencies { - api("org.jetbrains.kotlin-wrappers:kotlin-extensions") - } - } +kscience { + jvm() + js() + native() + useCoroutines() + dependencies { + api("space.kscience:dataforge-context:$dataforgeVersion") + api(spclibs.kotlinx.html) +// api("org.jetbrains.kotlin-wrappers:kotlin-css") } -} - -kscience{ - useSerialization{ + jsMain { + api("org.jetbrains.kotlin-wrappers:kotlin-extensions") + } + useSerialization { json() } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT +readme { + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt new file mode 100644 index 00000000..0cba6a37 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/AbstractVision.kt @@ -0,0 +1,30 @@ +package space.kscience.visionforge + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.meta.descriptors.MetaDescriptor + + +@Serializable +public abstract class AbstractVision : Vision { + + @Transient + override var parent: Vision? = null + + @SerialName("properties") + protected var propertiesInternal: MutableMeta? = null + + final override val properties: MutableVisionProperties by lazy { + object : AbstractVisionProperties(this) { + override var properties: MutableMeta? + get() = propertiesInternal + set(value) { + propertiesInternal = value + } + } + } + + override val descriptor: MetaDescriptor? get() = null +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt index 58be399e..ad4a4c0e 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Colors.kt @@ -1,11 +1,6 @@ package space.kscience.visionforge -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.number -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.* import kotlin.math.max /** diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt deleted file mode 100644 index 925eecfe..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ComputedVisionProperties.kt +++ /dev/null @@ -1,84 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.NameToken -import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.MutableValueProvider -import space.kscience.dataforge.values.Value - -private class ComputedVisionProperties( - val vision: Vision, - val pathName: Name, - val visionDescriptor: MetaDescriptor, - val parentInheritFlag: Boolean?, - val parentStylesFlag: Boolean? -) : Meta { - - val descriptor: MetaDescriptor? by lazy { visionDescriptor[pathName] } - - override val items: Map - get() { - val metaKeys = vision.meta.getMeta(pathName)?.items?.keys ?: emptySet() - val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() - val inheritFlag = descriptor?.inherited ?: parentInheritFlag - val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag - return (metaKeys + descriptorKeys).associateWith { - ComputedVisionProperties( - vision, - pathName + it, - visionDescriptor, - inheritFlag, - stylesFlag - ) - } - } - - override val value: Value? - get() { - val inheritFlag = descriptor?.inherited ?: parentInheritFlag ?: false - val stylesFlag = descriptor?.usesStyles ?: parentStylesFlag ?: true - return vision.getPropertyValue(pathName, inheritFlag, stylesFlag, true) - } - - override fun toString(): String = Meta.toString(this) - override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) - override fun hashCode(): Int = Meta.hashCode(this) -} - -/** - * Compute property node based on inheritance and style information from the descriptor - */ -public fun Vision.computeProperties(descriptor: MetaDescriptor? = this.descriptor): Meta = - if (descriptor == null) meta else ComputedVisionProperties(this, Name.EMPTY, descriptor, null, null) - -public fun Vision.computePropertyNode( - name: Name, - descriptor: MetaDescriptor? = this.descriptor -): Meta? = computeProperties(descriptor)[name] - -/** - * Compute the property based on the provided value descriptor. By default, use Vision own descriptor - */ -public fun Vision.computeProperty(name: Name, valueDescriptor: MetaDescriptor? = descriptor?.get(name)): Value? { - val inheritFlag = valueDescriptor?.inherited ?: false - val stylesFlag = valueDescriptor?.usesStyles ?: true - return getPropertyValue(name, inheritFlag, stylesFlag) -} - -/** - * Accessor to all vision properties - */ -public fun Vision.computePropertyValues( - descriptor: MetaDescriptor? = this.descriptor -): MutableValueProvider = object : MutableValueProvider { - override fun getValue(name: Name): Value? = computeProperty(name, descriptor?.get(name)) - - override fun setValue(name: Name, value: Value?) { - setProperty(name, value) - } -} - diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt new file mode 100644 index 00000000..e0d44930 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/ControlVision.kt @@ -0,0 +1,63 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.flow.filterIsInstance +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaRepr +import space.kscience.dataforge.meta.MutableMeta + +@Serializable +@SerialName("control") +public abstract class VisionControlEvent : VisionEvent, MetaRepr { + public abstract val meta: Meta + + override fun toMeta(): Meta = meta +} + +public interface ControlVision : Vision { + public val controlEventFlow: SharedFlow + + public fun dispatchControlEvent(event: VisionControlEvent) + + override fun receiveEvent(event: VisionEvent) { + if (event is VisionControlEvent) { + dispatchControlEvent(event) + } else super.receiveEvent(event) + } +} + +/** + * @param payload The optional payload associated with the click event. + */ +@Serializable +@SerialName("control.click") +public class VisionClickEvent(public val payload: Meta = Meta.EMPTY) : VisionControlEvent() { + override val meta: Meta get() = Meta { ::payload.name put payload } +} + + +public interface ClickControl : ControlVision { + /** + * Create and dispatch a click event + */ + public fun click(builder: MutableMeta.() -> Unit = {}) { + dispatchControlEvent(VisionClickEvent(Meta(builder))) + } +} + +/** + * Register listener + */ +public fun ClickControl.onClick(scope: CoroutineScope, block: suspend VisionClickEvent.() -> Unit): Job = + controlEventFlow.filterIsInstance().onEach(block).launchIn(scope) + + +@Serializable +@SerialName("control.valueChange") +public class VisionValueChangeEvent(override val meta: Meta) : VisionControlEvent() \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt new file mode 100644 index 00000000..a6f8c374 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt @@ -0,0 +1,5 @@ +package space.kscience.visionforge + +@OptIn(ExperimentalMultiplatform::class) +@OptionalExpectation +public expect annotation class JvmSynchronized() diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt index d5dfac6e..62d898b8 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleReference.kt @@ -9,7 +9,7 @@ import kotlin.properties.ReadOnlyProperty /** * A reference to a style defined in a specific container */ -public class StyleReference(public val owner: VisionGroup, public val name: String) +public class StyleReference(public val owner: Vision, public val name: String) private tailrec fun styleIsDefined(vision: Vision, reference: StyleReference): Boolean = when { reference.owner === vision -> true @@ -18,14 +18,14 @@ private tailrec fun styleIsDefined(vision: Vision, reference: StyleReference): B } @VisionBuilder -public fun Vision.useStyle(reference: StyleReference) { +public fun Vision.useStyle(reference: StyleReference, notify: Boolean = true) { //check that style is defined in a parent //check(styleIsDefined(this, reference)) { "Style reference does not belong to a Vision parent" } - useStyle(reference.name) + useStyle(reference.name, notify) } @VisionBuilder -public fun VisionGroup.style( +public fun Vision.style( styleKey: String? = null, builder: MutableMeta.() -> Unit, ): ReadOnlyProperty = ReadOnlyProperty { _, property -> @@ -35,7 +35,7 @@ public fun VisionGroup.style( } @VisionBuilder -public fun VisionGroup.style( +public fun Vision.style( spec: Specification, styleKey: String? = null, builder: T.() -> Unit, diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt index 52deee3c..ed893162 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/StyleSheet.kt @@ -5,20 +5,17 @@ import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.stringList import kotlin.jvm.JvmInline /** * A container for styles */ @JvmInline -public value class StyleSheet(private val owner: VisionGroup) { +public value class StyleSheet(private val owner: Vision) { - private val styleNode: Meta? get() = owner.meta[STYLESHEET_KEY] + private val styleNode: Meta get() = owner.properties[STYLESHEET_KEY] - public val items: Map? get() = styleNode?.items + public val items: Map get() = styleNode.items public operator fun get(key: String): Meta? = owner.getStyle(key) @@ -26,7 +23,7 @@ public value class StyleSheet(private val owner: VisionGroup) { * Define a style without notifying owner */ public fun define(key: String, style: Meta?) { - owner.meta.setMeta(STYLESHEET_KEY + key, style) + owner.properties[STYLESHEET_KEY + key] = style } /** @@ -43,7 +40,7 @@ public value class StyleSheet(private val owner: VisionGroup) { /** * Create and set a style */ - public operator fun set(key: String, builder: MutableMeta.() -> Unit) { + public fun update(key: String, builder: MutableMeta.() -> Unit) { val newStyle = get(key)?.toMutableMeta()?.apply(builder) ?: Meta(builder) set(key, newStyle.seal()) } @@ -59,49 +56,48 @@ internal fun Vision.styleChanged(key: String, oldStyle: Meta?, newStyle: Meta?) val tokens: Collection = ((oldStyle?.items?.keys ?: emptySet()) + (newStyle?.items?.keys ?: emptySet())) .map { it.asName() } - tokens.forEach { parent?.invalidateProperty(it) } + tokens.forEach { parent?.properties?.invalidate(it) } } - if (this is VisionGroup) { - for (obj in this) { - obj.styleChanged(key, oldStyle, newStyle) - } + children?.forEach { _, vision -> + vision.styleChanged(key, oldStyle, newStyle) } } - /** * List of names of styles applied to this object. Order matters. Not inherited. */ public var Vision.styles: List - get() = meta.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList() + get() = properties.own?.getValue(Vision.STYLE_KEY)?.stringList ?: emptyList() set(value) { - meta.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) + properties.setValue(Vision.STYLE_KEY, value.map { it.asValue() }.asValue()) } /** * A stylesheet for this group and its descendants. Stylesheet is not applied directly, * but instead is just a repository for named configurations. */ -public val VisionGroup.styleSheet: StyleSheet get() = StyleSheet(this) +public val Vision.styleSheet: StyleSheet get() = StyleSheet(this) /** - * Add style name to the list of styles to be resolved later. The style with given name does not necessary exist at the moment. + * Add style name to the list of styles to be resolved later. + * The style with given name does not necessary exist at the moment. */ -public fun Vision.useStyle(name: String) { - styles = (meta.getMeta(Vision.STYLE_KEY)?.stringList ?: emptyList()) + name +public fun Vision.useStyle(name: String, notify: Boolean = true) { + val newStyle = properties.own?.get(Vision.STYLE_KEY)?.value?.list?.plus(name.asValue()) ?: listOf(name.asValue()) + properties.setValue(Vision.STYLE_KEY, newStyle.asValue(), notify) } /** - * Find a style with given name for given [Vision]. The style is not necessary applied to this [Vision]. + * Resolve a style with given name for given [Vision]. The style is not necessarily applied to this [Vision]. */ -public tailrec fun Vision.getStyle(name: String): Meta? = - meta.getMeta(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) +public fun Vision.getStyle(name: String): Meta? = + properties.own?.get(StyleSheet.STYLESHEET_KEY + name) ?: parent?.getStyle(name) /** * Resolve a property from all styles */ -public fun Vision.getStyleProperty(name: Name): Value? = styles.firstNotNullOfOrNull { getStyle(it)?.get(name)?.value } +public fun Vision.getStyleProperty(name: Name): Meta? = styles.firstNotNullOfOrNull { getStyle(it)?.get(name) } /** * Resolve an item in all style layers diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt index 1c8e3a28..78f917a9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/Vision.kt @@ -1,147 +1,86 @@ package space.kscience.visionforge -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.launch -import space.kscience.dataforge.meta.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import space.kscience.dataforge.context.logger +import space.kscience.dataforge.context.warn +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.boolean import space.kscience.dataforge.meta.descriptors.Described import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.misc.Type +import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.boolean +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties import space.kscience.visionforge.Vision.Companion.TYPE -import kotlin.reflect.KProperty1 /** * A root type for display hierarchy */ -@Type(TYPE) -public interface Vision : Described, Configurable { +@DfType(TYPE) +public interface Vision : Described { /** * The parent object of this one. If null, this one is a root. */ - public var parent: VisionGroup? + public var parent: Vision? /** * Owner [VisionManager]. Used to define coroutine scope a serialization */ public val manager: VisionManager? get() = parent?.manager - /** - * This Vision own properties (ignoring inheritance, styles and defaults) - */ - override val meta: ObservableMutableMeta - /** - * Get property value with given layer flags. - * @param inherit toggles parent node property lookup. Null means inference from descriptor. Default is false. - * @param includeStyles toggles inclusion of properties from styles. default is true - */ - public fun getPropertyValue( - name: Name, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - ): Value? - - - /** - * Notify all listeners that a property has been changed and should be invalidated - */ - public fun invalidateProperty(propertyName: Name) + public val properties: MutableVisionProperties /** * Update this vision using a dif represented by [VisionChange]. */ - public fun update(change: VisionChange) + public fun update(change: VisionChange) { + if (change.children?.isNotEmpty() == true) { + error("Vision is not a group") + } + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } + + /** + * Receive and process a generic [VisionEvent]. + */ + public fun receiveEvent(event: VisionEvent) { + if(event is VisionChange) update(event) + else manager?.logger?.warn { "Undispatched event: $event" } + } override val descriptor: MetaDescriptor? public companion object { public const val TYPE: String = "vision" public val STYLE_KEY: Name = "@style".asName() + public const val STYLE_TARGET: String = "style" public val VISIBLE_KEY: Name = "visible".asName() } } /** - * Flow of property invalidation events. It does not contain property values after invalidation since it is not clear - * if it should include inherited properties etc. + * Control visibility of the element */ -@OptIn(ExperimentalCoroutinesApi::class) -@DFExperimental -public val Vision.propertyChanges: Flow - get() = callbackFlow { - meta.onChange(this) { name -> - launch { - send(name) - } - } - awaitClose { - meta.removeListener(this) - } +public var Vision.visible: Boolean? + get() = properties.getValue(Vision.VISIBLE_KEY)?.boolean + set(value) { + properties.setValue(Vision.VISIBLE_KEY, value?.asValue()) } /** * Subscribe on property updates. The subscription is bound to the given scope and canceled when the scope is canceled */ -public fun Vision.onPropertyChange(callback: Meta.(Name) -> Unit) { - meta.onChange(null, callback) -} - -/** - * Get [Vision] property using key as a String - */ -public fun Vision.getPropertyValue( - key: String, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, -): Value? = getPropertyValue(Name.parse(key), inherit, includeStyles, includeDefaults) - -/** - * A convenience method to set property node or value. If Item is null, then node is removed, not a value - */ -public fun Vision.setProperty(name: Name, item: Any?) { - when (item) { - null -> meta.remove(name) - is Meta -> meta.setMeta(name, item) - is Value -> meta.setValue(name, item) - else -> meta.setValue(name, Value.of(item)) - } -} - -public fun Vision.setPropertyNode(key: String, item: Any?) { - setProperty(Name.parse(key), item) -} - -/** - * Control visibility of the element - */ -public var Vision.visible: Boolean? - get() = getPropertyValue(Vision.VISIBLE_KEY)?.boolean - set(value) = meta.setValue(Vision.VISIBLE_KEY, value?.asValue()) - - -public fun V.useProperty( - property: KProperty1, - owner: Any? = null, - callBack: V.(T) -> Unit, -) { - //Pass initial value. - callBack(property.get(this)) - meta.onChange(owner) { name -> - if (name.startsWith(property.name.asName())) { - callBack(property.get(this@useProperty)) - } - } -} \ No newline at end of file +public fun Vision.onPropertyChange( + scope: CoroutineScope? = manager?.context, + callback: suspend (Name) -> Unit, +): Job = properties.changes.onEach { + callback(it) +}.launchIn(scope ?: error("Orphan Vision can't observe properties")) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt deleted file mode 100644 index 003fec79..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionBase.kt +++ /dev/null @@ -1,176 +0,0 @@ -package space.kscience.visionforge - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.ValueType -import space.kscience.visionforge.Vision.Companion.STYLE_KEY -import kotlin.jvm.Synchronized - -internal data class MetaListener( - val owner: Any? = null, - val callback: Meta.(name: Name) -> Unit, -) - -/** - * A full base implementation for a [Vision] - * @param parent the parent object for this vision. Could've set later. Not serialized. - */ -@Serializable -@SerialName("vision") -public open class VisionBase( - @Transient override var parent: VisionGroup? = null, - @EncodeDefault protected var properties: MutableMeta? = null, -) : Vision { - - @Synchronized - protected fun getOrCreateProperties(): MutableMeta { - if (properties == null) { - val newProperties = MutableMeta() - properties = newProperties - } - return properties!! - } - - @Transient - private val listeners: MutableList = mutableListOf() - - private inner class VisionProperties(val pathName: Name) : ObservableMutableMeta { - - override val items: Map - get() = properties?.get(pathName)?.items?.mapValues { entry -> - VisionProperties(pathName + entry.key) - } ?: emptyMap() - - override var value: Value? - get() = properties?.get(pathName)?.value - set(value) { - val oldValue = properties?.get(pathName)?.value - getOrCreateProperties().setValue(pathName, value) - if (oldValue != value) { - invalidate(Name.EMPTY) - } - } - - override fun getOrCreate(name: Name): ObservableMutableMeta = VisionProperties(pathName + name) - - override fun setMeta(name: Name, node: Meta?) { - getOrCreateProperties().setMeta(pathName + name, node) - invalidate(name) - } - - @DFExperimental - override fun attach(name: Name, node: ObservableMutableMeta) { - val ownProperties = getOrCreateProperties() - if (ownProperties is ObservableMutableMeta) { - ownProperties.attach(pathName + name, node) - } else { - ownProperties.setMeta(pathName + name, node) - node.onChange(this) { childName -> - ownProperties.setMeta(pathName + name + childName, this[childName]) - } - } - } - - override fun invalidate(name: Name) { - invalidateProperty(pathName + name) - } - - @Synchronized - override fun onChange(owner: Any?, callback: Meta.(name: Name) -> Unit) { - if (pathName.isEmpty()) { - listeners.add((MetaListener(owner, callback))) - } else { - listeners.add(MetaListener(owner) { name -> - if (name.startsWith(pathName)) { - (this@MetaListener[pathName] ?: Meta.EMPTY).callback(name.removeHeadOrNull(pathName)!!) - } - }) - } - } - - @Synchronized - override fun removeListener(owner: Any?) { - listeners.removeAll { it.owner === owner } - } - - override fun toString(): String = Meta.toString(this) - override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) - override fun hashCode(): Int = Meta.hashCode(this) - } - - final override val meta: ObservableMutableMeta get() = VisionProperties(Name.EMPTY) - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean, - ): Value? { - properties?.get(name)?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.let { return it } - } - if (inherit) { - parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - } - if (includeDefaults) { - descriptor?.defaultNode?.get(name)?.value.let { return it } - } - return null - } - - override val descriptor: MetaDescriptor? get() = null - - override fun invalidateProperty(propertyName: Name) { - if (propertyName == STYLE_KEY) { - styles.mapNotNull { getStyle(it) }.asSequence() - .flatMap { it.items.asSequence() } - .distinctBy { it.key } - .forEach { - invalidateProperty(it.key.asName()) - } - } - listeners.forEach { it.callback(properties ?: Meta.EMPTY, propertyName) } - } - - override fun update(change: VisionChange) { - change.properties?.let { - updateProperties(Name.EMPTY, it) - } - } - - public companion object { - public val descriptor: MetaDescriptor = MetaDescriptor { - value(STYLE_KEY, ValueType.STRING) { - multiple = true - } - } - - public fun Vision.updateProperties(at: Name, item: Meta) { - meta.setValue(at, item.value) - item.items.forEach { (token, item) -> - updateProperties(at + token, item) - } - } - - } -} - -//fun VisualObject.findStyle(styleName: Name): Meta? { -// if (this is VisualGroup) { -// val style = resolveStyle(styleName) -// if (style != null) return style -// } -// return parent?.findStyle(styleName) -//} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt index ad0d0d70..87bff794 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionChange.kt @@ -1,149 +1,208 @@ package space.kscience.visionforge -import kotlinx.coroutines.* +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.coroutineScope +import kotlinx.coroutines.delay import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.flow import kotlinx.coroutines.flow.launchIn import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.* -import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.isEmpty import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.Null -import kotlin.jvm.Synchronized import kotlin.time.Duration + + +/** + * A vision used only in change propagation and showing that the target should be removed + */ +@Serializable +@SerialName("null") +public object NullVision : Vision { + override var parent: Vision? + get() = null + set(_) { + error("Can't set parent for null vision") + } + + override val properties: MutableVisionProperties get() = error("Can't get properties of `NullVision`") + + override val descriptor: MetaDescriptor? = null +} + /** * Create a deep copy of given Vision without external connections. */ -private fun Vision.deepCopy(): Vision { +private fun Vision.deepCopy(manager: VisionManager): Vision { + if (this is NullVision) return NullVision + //Assuming that unrooted visions are already isolated - val manager = this.manager ?: return this //TODO replace by efficient deep copy val json = manager.encodeToJsonElement(this) return manager.decodeFromJson(json) } -/** - * An update for a [Vision] or a [VisionGroup] - */ -public class VisionChangeBuilder : VisionContainerBuilder { - private var reset: Boolean = false +/** + * An event that contains changes made to a vision. + * + * @param vision a new value for vision content. If the Vision is to be removed should be [NullVision] + * @param properties updated properties + * @param children a map of children changed in ths [VisionChange]. + */ +@Serializable +@SerialName("change") +public data class VisionChange( + public val vision: Vision? = null, + public val properties: Meta? = null, + public val children: Map? = null, +) : VisionEvent + +/** + * An update for a [Vision] + */ +public class VisionChangeBuilder : MutableVisionContainer { + private var vision: Vision? = null - private val propertyChange = MutableMeta() + private var propertyChange = MutableMeta() private val children: HashMap = HashMap() + public operator fun get(name: Name): VisionChangeBuilder? = children[name] + public fun isEmpty(): Boolean = propertyChange.isEmpty() && propertyChange.isEmpty() && children.isEmpty() - @Synchronized + @JvmSynchronized private fun getOrPutChild(visionName: Name): VisionChangeBuilder = children.getOrPut(visionName) { VisionChangeBuilder() } + @JvmSynchronized + internal fun reset() { + vision = null + propertyChange = MutableMeta() + children.clear() + } + public fun propertyChanged(visionName: Name, propertyName: Name, item: Meta?) { if (visionName == Name.EMPTY) { //Write property removal as [Null] - propertyChange[propertyName] = (item ?: Meta(Null)) + if (propertyName.isEmpty()) { + propertyChange = item?.toMutableMeta() ?: MutableMeta() + } else { + propertyChange[propertyName] = (item ?: Meta(Null)) + } } else { getOrPutChild(visionName).propertyChanged(Name.EMPTY, propertyName, item) } } - override fun set(name: Name?, child: Vision?) { + override fun setChild(name: Name?, child: Vision?) { if (name == null) error("Static children are not allowed in VisionChange") getOrPutChild(name).apply { - vision = child - reset = vision == null + vision = child ?: NullVision } } + private fun build(visionManager: VisionManager): VisionChange = VisionChange( + vision, + if (propertyChange.isEmpty()) null else propertyChange, + if (children.isEmpty()) null else children.mapValues { it.value.build(visionManager) } + ) + /** * Isolate collected changes by creating detached copies of given visions */ - public fun deepCopy(): VisionChange = VisionChange( - reset, - vision?.deepCopy(), + public fun deepCopy(visionManager: VisionManager): VisionChange = VisionChange( + vision?.deepCopy(visionManager), if (propertyChange.isEmpty()) null else propertyChange.seal(), - if (children.isEmpty()) null else children.mapValues { it.value.deepCopy() } + if (children.isEmpty()) null else children.mapValues { it.value.deepCopy(visionManager) } + ) + + /** + * Transform current change directly to Json string without protective copy + */ + public fun toJsonString(visionManager: VisionManager): String = visionManager.encodeToString( + build(visionManager) ) } +public inline fun VisionManager.VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = + VisionChangeBuilder().apply(block).deepCopy(this) + + /** - * @param delete flag showing that this vision child should be removed - * @param vision a new value for vision content - * @param properties updated properties - * @param children a map of children changed in ths [VisionChange]. If a child to be removed, set [delete] flag to true. + * Collect changes that are made to [source] to [collector] using [mutex] as a synchronization lock. */ -@Serializable -public data class VisionChange( - public val delete: Boolean = false, - public val vision: Vision? = null, - @Serializable(MetaSerializer::class) public val properties: Meta? = null, - public val children: Map? = null, -) - -public inline fun VisionChange(block: VisionChangeBuilder.() -> Unit): VisionChange = - VisionChangeBuilder().apply(block).deepCopy() - - -@OptIn(DFExperimental::class) private fun CoroutineScope.collectChange( name: Name, source: Vision, - collector: () -> VisionChangeBuilder, + mutex: Mutex, + collector: VisionChangeBuilder, ) { //Collect properties change - source.onPropertyChange { propertyName -> - val newItem = source.meta[propertyName] - collector().propertyChanged(name, propertyName, newItem) + source.properties.changes.onEach { propertyName -> + val newItem = source.properties.own?.get(propertyName) + collector.propertyChanged(name, propertyName, newItem) + }.launchIn(this) + + val children = source.children + //Subscribe for children changes + children?.forEach { token, child -> + collectChange(name + token, child, mutex, collector) } - if (source is VisionGroup) { - //Subscribe for children changes - source.children.forEach { (token, child) -> - collectChange(name + token, child, collector) + //Subscribe for structure change + children?.changes?.onEach { changedName -> + val after = children[changedName] + val fullName = name + changedName + if (after != null) { + collectChange(fullName, after, mutex, collector) } - - //Subscribe for structure change - if (source is MutableVisionGroup) { - source.structureChanges.onEach { changedName -> - val after = source[changedName] - val fullName = name + changedName - if (after != null) { - collectChange(fullName, after, collector) - } - collector()[fullName] = after - }.launchIn(this) + mutex.withLock { + collector.setChild(fullName, after) } - } + }?.launchIn(this) } /** * Generate a flow of changes of this vision and its children + * + * @param sendInitial if true, send the initial vision state as first change */ public fun Vision.flowChanges( collectionDuration: Duration, + sendInitial: Boolean = false, ): Flow = flow { - - var collector = VisionChangeBuilder() + val manager = manager ?: error("Orphan vision could not collect changes") coroutineScope { - collectChange(Name.EMPTY, this@flowChanges) { collector } + val collector = VisionChangeBuilder() + val mutex = Mutex() + collectChange(Name.EMPTY, this@flowChanges, mutex, collector) - //Send initial vision state - val initialChange = VisionChange(vision = deepCopy()) - emit(initialChange) + if (sendInitial) { + //Send initial vision state + val initialChange = VisionChange(vision = deepCopy(manager)) + emit(initialChange) + } - while (currentCoroutineContext().isActive) { + while (true) { //Wait for changes to accumulate delay(collectionDuration) //Propagate updates only if something is changed if (!collector.isEmpty()) { - //emit changes - emit(collector.deepCopy()) - //Reset the collector - collector = VisionChangeBuilder() + mutex.withLock { + //emit changes + emit(collector.deepCopy(manager)) + //Reset the collector + collector.reset() + } } } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt new file mode 100644 index 00000000..9d6a5561 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionClient.kt @@ -0,0 +1,40 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.launch +import space.kscience.dataforge.context.Plugin +import space.kscience.dataforge.meta.MetaRepr +import space.kscience.dataforge.names.Name + +/** + * A feedback client that communicates with a server and provides ability to propagate events and changes back to the model + */ +public interface VisionClient: Plugin { + public val visionManager: VisionManager + + public suspend fun sendEvent(targetName: Name, event: VisionEvent) + +// public fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) +} + + +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Meta?) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), item) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Number) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: String) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} +// +//public fun VisionClient.notifyPropertyChanged(visionName: Name, propertyName: String, item: Boolean) { +// notifyPropertyChanged(visionName, propertyName.parseAsName(true), Meta(item)) +//} + +public fun VisionClient.sendEvent(targetName: Name, payload: MetaRepr): Unit { + context.launch { + sendEvent(targetName, VisionMetaEvent(payload.toMeta())) + } +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt new file mode 100644 index 00000000..c74f027d --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionContainer.kt @@ -0,0 +1,196 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.* +import kotlinx.coroutines.launch +import space.kscience.dataforge.names.* +import space.kscience.visionforge.VisionChildren.Companion.STATIC_TOKEN_BODY + +@DslMarker +public annotation class VisionBuilder + +public interface VisionContainer { + public fun getChild(name: Name): V? +} + +public interface MutableVisionContainer { + //TODO add documentation + public fun setChild(name: Name?, child: V?) +} + +/** + * A serializable representation of [Vision] children container + */ +public interface VisionChildren : VisionContainer { + public val parent: Vision? + + public val keys: Set + + public val values: Iterable get() = keys.map { get(it)!! } + + public val changes: Flow + + public operator fun get(token: NameToken): Vision? + + override fun getChild(name: Name): Vision? = when (name.length) { + 0 -> parent + 1 -> get(name.first()) + else -> get(name.first())?.children?.getChild(name.cutFirst()) + } + + public companion object { + public const val STATIC_TOKEN_BODY: String = "@static" + + public fun empty(owner: Vision): VisionChildren = object : VisionChildren { + override val parent: Vision get() = owner + override val keys: Set get() = emptySet() + override val changes: Flow get() = emptyFlow() + override fun get(token: NameToken): Vision? = null + } + } +} + +public operator fun VisionChildren.get(name: Name): Vision? = getChild(name) +public operator fun VisionChildren.get(name: String): Vision? = getChild(name) + + +public fun VisionChildren.isEmpty(): Boolean = keys.isEmpty() + +public inline fun VisionChildren.forEach(block: (NameToken, Vision) -> Unit) { + keys.forEach { block(it, get(it)!!) } +} + +public interface MutableVisionChildren : VisionChildren, MutableVisionContainer { + + public override val parent: MutableVisionGroup + + public operator fun set(token: NameToken, value: Vision?) + + override fun setChild(name: Name?, child: Vision?) { + when { + name == null -> { + if (child != null) { + static(child) + } + } + + name.isEmpty() -> error("Empty names are not allowed in VisionGroup::set") + name.length == 1 -> { + val token = name.tokens.first() + set(token, child) + } + + else -> { + val currentParent = get(name.first()) + if (currentParent != null && currentParent !is MutableVisionGroup) error("Can't assign a child to $currentParent") + val parent: MutableVisionGroup = currentParent as? MutableVisionGroup ?: parent.createGroup().also { + set(name.first(), it) + } + parent.children.setChild(name.cutFirst(), child) + } + } + } + + public fun clear() +} + +public operator fun MutableVisionChildren.set(name: Name?, vision: Vision?) { + setChild(name, vision) +} + +public operator fun MutableVisionChildren.set(name: String?, vision: Vision?) { + setChild(name, vision) +} + + +/** + * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. + */ +public fun MutableVisionChildren.static(child: Vision) { + set(NameToken(STATIC_TOKEN_BODY, index = child.hashCode().toString()), child) +} + +public fun VisionChildren.asSequence(): Sequence> = sequence { + keys.forEach { yield(it to get(it)!!) } +} + +public operator fun VisionChildren.iterator(): Iterator> = asSequence().iterator() + +public fun VisionContainer.getChild(str: String): V? = getChild(Name.parse(str)) + +public fun MutableVisionContainer.setChild( + str: String?, vision: V?, +): Unit = setChild(str?.parseAsName(), vision) + +internal abstract class VisionChildrenImpl( + override val parent: MutableVisionGroup, +) : MutableVisionChildren { + + private val updateJobs = HashMap() + + abstract var items: MutableMap? + + @JvmSynchronized + private fun buildItems(): MutableMap { + if (items == null) { + items = LinkedHashMap() + } + return items!! + } + + private val scope: CoroutineScope? get() = parent.manager?.context + + override val keys: Set get() = items?.keys ?: emptySet() + + override fun get(token: NameToken): Vision? = items?.get(token) + + private val _changes = MutableSharedFlow() + override val changes: SharedFlow get() = _changes + + private fun onChange(name: Name) { + scope?.launch { + _changes.emit(name) + } + } + + override operator fun set(token: NameToken, value: Vision?) { + //fast return if value equals existing + if (value == get(token)) return + + val currentUpdateJob = updateJobs[token] + if (currentUpdateJob != null) { + currentUpdateJob.cancel() + updateJobs.remove(token) + } + + if (value == null) { + items?.remove(token) + } else { + (items ?: buildItems())[token] = value + //check if parent already exists and is different from the current one + if (value.parent != null && value.parent != parent) error("Can't reassign parent Vision for $value") + //set parent + value.parent = parent + //start update jobs (only if the vision is rooted) + scope?.let { scope -> + val job = value.children?.changes?.onEach { + onChange(token + it) + }?.launchIn(scope) + if (job != null) { + updateJobs[token] = job + } + } + } + + onChange(token.asName()) + } + + override fun clear() { + items?.clear() + updateJobs.values.forEach { it.cancel() } + updateJobs.clear() + onChange(Name.EMPTY) + } +} + diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt new file mode 100644 index 00000000..de0b2643 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionEvent.kt @@ -0,0 +1,23 @@ +package space.kscience.visionforge + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.names.Name + +/** + * An event propagated from client to a server + */ +@Serializable +public sealed interface VisionEvent { + public companion object { + public val CLICK_EVENT_KEY: Name get() = Name.of("events", "click", "payload") + } +} + +/** + * An event that consists of custom meta + */ +@Serializable +@SerialName("meta") +public class VisionMetaEvent(public val meta: Meta) : VisionEvent \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt index a8ad1dcd..fd8aaa16 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroup.kt @@ -1,109 +1,133 @@ package space.kscience.visionforge -import kotlinx.coroutines.ExperimentalCoroutinesApi -import kotlinx.coroutines.channels.awaitClose -import kotlinx.coroutines.flow.Flow -import kotlinx.coroutines.flow.callbackFlow -import kotlinx.coroutines.launch -import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.names.* -import space.kscience.dataforge.provider.Provider - -@DslMarker -public annotation class VisionBuilder - -public interface VisionContainer { - public operator fun get(name: Name): V? -} - -/** - * Represents a group of [Vision] instances - */ -public interface VisionGroup : Provider, Vision, VisionContainer { - /** - * A map of top level named children - */ - public val children: Map - - override val defaultTarget: String get() = Vision.TYPE - - /** - * A map of direct children for specific target - * (currently "visual" or "style") - */ - override fun content(target: String): Map = - when (target) { - Vision.TYPE -> children.flatMap { (key, value) -> - val res: Map = if (value is VisionGroup) { - value.content(target).mapKeys { key + it.key } - } else { - mapOf(key.asName() to value) - } - res.entries - }.associate { it.toPair() } - STYLE_TARGET -> styleSheet.items?.mapKeys { it.key.asName() } ?: emptyMap() - else -> emptyMap() - } - - public override operator fun get(name: Name): Vision? { - return when { - name.isEmpty() -> this - name.length == 1 -> children[name.tokens.first()] - else -> (children[name.tokens.first()] as? VisionGroup)?.get(name.cutFirst()) - } - } - - public companion object { - public const val STYLE_TARGET: String = "style" - } -} - -/** - * Iterate over children of this group - */ -public operator fun VisionGroup.iterator(): Iterator = children.values.iterator() - -public fun VisionGroup.isEmpty(): Boolean = this.children.isEmpty() - -public interface VisionContainerBuilder { - //TODO add documentation - public operator fun set(name: Name?, child: V?) -} - -/** - * Mutable version of [VisionGroup] - */ -public interface MutableVisionGroup : VisionGroup, VisionContainerBuilder { - public fun onStructureChanged(owner: Any?, block: VisionGroup.(Name) -> Unit) - - public fun removeStructureListener(owner: Any?) -} +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.ValueType +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.plus +import space.kscience.visionforge.AbstractVisionGroup.Companion.updateProperties +import space.kscience.visionforge.Vision.Companion.STYLE_KEY -/** - * Flow structure changes of this group. Unconsumed changes are discarded - */ -@OptIn(ExperimentalCoroutinesApi::class) -@DFExperimental -public val MutableVisionGroup.structureChanges: Flow - get() = callbackFlow { - meta.onChange(this) { name -> - launch { - send(name) +public interface VisionGroup : Vision { + public val children: VisionChildren + + override fun update(change: VisionChange) { + change.children?.forEach { (name, change) -> + if (change.vision != null || change.vision == NullVision) { + error("VisionGroup is read-only") + } else { + children.getChild(name)?.update(change) } } - awaitClose { - removeStructureListener(this) + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } +} + +public interface MutableVisionGroup : VisionGroup { + + override val children: MutableVisionChildren + + public fun createGroup(): MutableVisionGroup + + override fun update(change: VisionChange) { + change.children?.forEach { (name, change) -> + when { + change.vision == NullVision -> children.setChild(name, null) + change.vision != null -> children.setChild(name, change.vision) + else -> children.getChild(name)?.update(change) + } + } + change.properties?.let { + updateProperties(it, Name.EMPTY) + } + } +} + +public val Vision.children: VisionChildren? get() = (this as? VisionGroup)?.children + +/** + * A full base implementation for a [Vision] + */ +@Serializable +public abstract class AbstractVisionGroup : AbstractVision(), MutableVisionGroup { + + @SerialName("children") + protected var childrenInternal: MutableMap? = null + + + init { + childrenInternal?.forEach { it.value.parent = this } + } + + override val children: MutableVisionChildren by lazy { + object : VisionChildrenImpl(this) { + override var items: MutableMap? + get() = this@AbstractVisionGroup.childrenInternal + set(value) { + this@AbstractVisionGroup.childrenInternal = value + } } } + abstract override fun createGroup(): AbstractVisionGroup -public operator fun VisionContainer.get(str: String): V? = get(Name.parse(str)) + public companion object { + public val descriptor: MetaDescriptor = MetaDescriptor { + value(STYLE_KEY, ValueType.STRING) { + multiple = true + } + } -public operator fun VisionContainerBuilder.set(token: NameToken, child: V?): Unit = - set(token.asName(), child) + public fun Vision.updateProperties(item: Meta, name: Name = Name.EMPTY) { + properties.setValue(name, item.value) + item.items.forEach { (token, item) -> + updateProperties(item, name + token) + } + } -public operator fun VisionContainerBuilder.set(key: String?, child: V?): Unit = - set(key?.let(Name::parse), child) + } +} -public fun MutableVisionGroup.removeAll(): Unit = children.keys.map { it.asName() }.forEach { this[it] = null } \ No newline at end of file +/** + * A simple vision group that just holds children. Nothing else. + */ +@Serializable +@SerialName("vision.group") +public class SimpleVisionGroup : AbstractVisionGroup(), MutableVisionContainer { + override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup() + + override fun setChild(name: Name?, child: Vision?) { + children.setChild(name, child) + } +} + +@VisionBuilder +public inline fun MutableVisionContainer.group( + name: Name? = null, + builder: SimpleVisionGroup.() -> Unit = {}, +): SimpleVisionGroup = SimpleVisionGroup().also { setChild(name, it) }.apply(builder) + +/** + * Define a group with given [name], attach it to this parent and return it. + */ +@VisionBuilder +public inline fun MutableVisionContainer.group( + name: String, + builder: SimpleVisionGroup.() -> Unit = {}, +): SimpleVisionGroup = group(name.parseAsName(), builder) + +//fun VisualObject.findStyle(styleName: Name): Meta? { +// if (this is VisualGroup) { +// val style = resolveStyle(styleName) +// if (style != null) return style +// } +// return parent?.findStyle(styleName) +//} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt deleted file mode 100644 index 7c2af29e..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionGroupBase.kt +++ /dev/null @@ -1,168 +0,0 @@ -package space.kscience.visionforge - -import kotlinx.serialization.EncodeDefault -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import kotlinx.serialization.Transient -import space.kscience.dataforge.names.* -import kotlin.jvm.Synchronized - -private class StructureChangeListener(val owner: Any?, val callback: VisionGroup.(Name) -> Unit) - -/** - * Abstract implementation of mutable group of [Vision] - * - * @param childrenInternal Internal mutable container for group children - */ -@Serializable -@SerialName("vision.group") -public open class VisionGroupBase( - @EncodeDefault @SerialName("children") protected val childrenInternal: MutableMap = LinkedHashMap(), -) : VisionBase(), MutableVisionGroup { - - /** - * A map of top level named children - */ - override val children: Map get() = childrenInternal - - init { - childrenInternal.forEach { (token, child) -> - if (child.parent != null && child.parent != this) error("Can't reassign existing parent for child $token") - child.parent = this - } - } - - override fun invalidateProperty(propertyName: Name) { - super.invalidateProperty(propertyName) - for (obj in this) { - obj.invalidateProperty(propertyName) - } - } - - @Transient - private val structureListeners = HashSet() - - @Synchronized - override fun onStructureChanged(owner: Any?, block: VisionGroup.(Name) -> Unit) { - structureListeners.add(StructureChangeListener(owner, block)) - } - - @Synchronized - override fun removeStructureListener(owner: Any?) { - structureListeners.removeAll { it.owner == owner } - } - - /** - * Propagate children change event upwards - */ - protected fun childrenChanged(name: Name) { - structureListeners.forEach { - it.callback(this, name) - } - } - - /** - * Add a static child. Statics could not be found by name, removed or replaced. Changing statics also do not trigger events. - */ - protected open fun addStatic(child: Vision): Unit { - attachChild(NameToken("@static", index = child.hashCode().toString()), child) - } - - /** - * Create a vision group of the same type as this vision group. Do not attach it. - */ - protected open fun createGroup(): VisionGroupBase = VisionGroupBase() - - /** - * Set parent for given child and attach it - */ - private fun attachChild(token: NameToken, child: Vision?) { - val before = childrenInternal[token] - when { - child == null -> { - childrenInternal.remove(token) - } - child.parent == null -> { - child.parent = this - childrenInternal[token] = child - } - child.parent !== this -> { - error("Can't reassign existing parent for child $token") - } - } - if (before != child) { - childrenChanged(token.asName()) - if (child is MutableVisionGroup) { - child.onStructureChanged(this) { changedName -> - this@VisionGroupBase.childrenChanged(token + changedName) - } - } - } - } - - /** - * Recursively create a child group - */ - private fun createGroups(name: Name): VisionGroupBase = when { - name.isEmpty() -> error("Should be unreachable") - name.length == 1 -> { - val token = name.tokens.first() - when (val current = children[token]) { - null -> createGroup().also { child -> - attachChild(token, child) - } - is VisionGroupBase -> current - else -> error("Can't create group with name $name because it exists and not a group") - } - } - else -> createGroups(name.tokens.first().asName()).createGroups(name.cutFirst()) - } - - /** - * Add named or unnamed child to the group. If key is null the child is considered unnamed. Both key and value are not - * allowed to be null in the same time. If name is present and [child] is null, the appropriate element is removed. - */ - override fun set(name: Name?, child: Vision?): Unit { - when { - name == null -> { - if (child != null) { - addStatic(child) - } - } - name.isEmpty() -> error("Empty names are not allowed in VisionGroup::set") - name.length == 1 -> { - val token = name.tokens.first() - attachChild(token, child) - } - else -> { - //TODO add safety check - val parent = (get(name.cutLast()) as? MutableVisionGroup) ?: createGroups(name.cutLast()) - parent[name.tokens.last().asName()] = child - } - } - } - - override fun update(change: VisionChange) { - change.children?.forEach { (name, change) -> - when { - change.delete -> set(name, null) - change.vision != null -> set(name, change.vision) - else -> get(name)?.update(change) - } - } - super.update(change) - } -} - -/** - * Non-serializable root group used to propagate manager to its children - */ -internal class RootVisionGroup(override val manager: VisionManager) : VisionGroupBase() - -/** - * Designate this [VisionGroup] as a root and assign a [VisionManager] as its parent - */ -public fun Vision.setAsRoot(manager: VisionManager) { - if (parent != null) error("Vision $this already has a parent. It could not be set as root") - parent = RootVisionGroup(manager) -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt index 118fd47c..8799a73f 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionManager.kt @@ -13,29 +13,25 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.toJson import space.kscience.dataforge.meta.toMeta import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.VisionOfCheckbox -import space.kscience.visionforge.html.VisionOfHtmlForm -import space.kscience.visionforge.html.VisionOfNumberField -import space.kscience.visionforge.html.VisionOfTextField -import kotlin.reflect.KClass +import space.kscience.visionforge.html.* -public class VisionManager(meta: Meta) : AbstractPlugin(meta) { +public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag /** * Combined [SerializersModule] for all registered visions */ - public val serializersModule: SerializersModule - get() = SerializersModule { + public val serializersModule: SerializersModule by lazy { + SerializersModule { include(defaultSerialModule) context.gather(VISION_SERIALIZER_MODULE_TARGET).values.forEach { include(it) } } + } public val jsonFormat: Json get() = Json(defaultJson) { - encodeDefaults = false serializersModule = this@VisionManager.serializersModule } @@ -57,22 +53,27 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { public fun encodeToMeta(vision: Vision, descriptor: MetaDescriptor? = null): Meta = encodeToJsonElement(vision).toMeta(descriptor) + override fun setChild(name: Name?, child: Vision?) { + child?.setAsRoot(this) + } + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision", group = PluginTag.DATAFORGE_GROUP) - override val type: KClass = VisionManager::class public const val VISION_SERIALIZER_MODULE_TARGET: String = "visionSerializerModule" - override fun invoke(meta: Meta, context: Context): VisionManager = VisionManager(meta) + override fun build(context: Context, meta: Meta): VisionManager = VisionManager(meta) private val defaultSerialModule: SerializersModule = SerializersModule { polymorphic(Vision::class) { - default { VisionBase.serializer() } - subclass(VisionBase.serializer()) - subclass(VisionGroupBase.serializer()) + defaultDeserializer { SimpleVisionGroup.serializer() } + subclass(NullVision.serializer()) + subclass(SimpleVisionGroup.serializer()) + subclass(VisionOfHtmlInput.serializer()) subclass(VisionOfNumberField.serializer()) subclass(VisionOfTextField.serializer()) subclass(VisionOfCheckbox.serializer()) + subclass(VisionOfRangeField.serializer()) subclass(VisionOfHtmlForm.serializer()) } } @@ -82,7 +83,6 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta) { serializersModule = defaultSerialModule prettyPrint = true useArrayPolymorphism = false - encodeDefaults = false ignoreUnknownKeys = true explicitNulls = false } @@ -105,7 +105,22 @@ public abstract class VisionPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(met /** * Fetch a [VisionManager] from this plugin or create a child plugin with a [VisionManager] */ -public val Context.visionManager: VisionManager get() = fetch(VisionManager) +public val Context.visionManager: VisionManager get() = request(VisionManager ) public fun Vision.encodeToString(): String = - manager?.encodeToString(this) ?: error("VisionManager not defined in Vision") \ No newline at end of file + manager?.encodeToString(this) ?: error("Orphan vision could not be encoded") + +/** + * A root vision attached to [VisionManager] + */ +public class RootVision(override val manager: VisionManager) : AbstractVisionGroup() { + override fun createGroup(): SimpleVisionGroup = SimpleVisionGroup() +} + +/** + * Designate this [Vision] as a root and assign a [VisionManager] as its parent + */ +public fun Vision.setAsRoot(manager: VisionManager) { + if (parent != null) error("Vision $this already has a parent. It could not be set as root") + parent = RootVision(manager) +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt new file mode 100644 index 00000000..3c375c62 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionProperties.kt @@ -0,0 +1,318 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.SharedFlow +import kotlinx.coroutines.launch +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.get +import space.kscience.dataforge.names.* + +public interface VisionProperties : MetaProvider { + + /** + * Raw Visions own properties without styles, defaults, etc. + */ + public val own: Meta? + + public val descriptor: MetaDescriptor? + + public fun getValue( + name: Name, + inherit: Boolean?, + includeStyles: Boolean? = null, + ): Value? + + override fun getValue(name: Name): Value? = getValue(name, null, null) + + /** + * Get property with given layer flags. + * @param inherit toggles parent node property lookup. Null means inference from descriptor. + * @param includeStyles toggles inclusion of properties from styles. + */ + public fun get( + name: Name, + inherit: Boolean?, + includeStyles: Boolean? = null, + ): Meta + + override fun get(name: Name): Meta? = get(name, null, null) + + + public val changes: Flow + + /** + * Notify all listeners that a property has been changed and should be invalidated. + * This method does not check that the property has actually changed. + */ + public fun invalidate(propertyName: Name) +} + +public interface MutableVisionProperties : VisionProperties, MutableMetaProvider { + + override fun get( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): MutableMeta = VisionPropertiesItem( + this, + name, + inherit, + includeStyles, + ) + + public fun set( + name: Name, + node: Meta?, + notify: Boolean, + ) + + public fun setValue( + name: Name, + value: Value?, + notify: Boolean, + ) + + override fun get(name: Name): MutableMeta = get(name, null, null) + + override fun set(name: Name, node: Meta?) { + set(name, node, true) + } + + override fun setValue(name: Name, value: Value?) { + setValue(name, value, true) + } +} + +public fun MutableVisionProperties.remove(name: Name) { + set(name, null) +} + +public fun MutableVisionProperties.remove(name: String) { + remove(name.parseAsName()) +} + +@VisionBuilder +public operator fun MutableVisionProperties.invoke(block: MutableMeta.() -> Unit) { + root(inherit = false, includeStyles = false).apply(block) +} + +private class VisionPropertiesItem( + val properties: MutableVisionProperties, + val nodeName: Name, + val inherit: Boolean? = null, + val useStyles: Boolean? = null, + val default: Meta? = null, +) : MutableMeta { + + val descriptor: MetaDescriptor? by lazy { properties.descriptor?.get(nodeName) } + + + override val items: Map + get() { + val metaKeys = properties.own?.get(nodeName)?.items?.keys ?: emptySet() + val descriptorKeys = descriptor?.children?.map { NameToken(it.key) } ?: emptySet() + val defaultKeys = default?.get(nodeName)?.items?.keys ?: emptySet() + val inheritFlag = descriptor?.inherited ?: inherit + val stylesFlag = descriptor?.usesStyles ?: useStyles + return (metaKeys + descriptorKeys + defaultKeys).associateWith { + VisionPropertiesItem( + properties, + nodeName + it, + inheritFlag, + stylesFlag, + default + ) + } + } + + override var value: Value? + get() { + val inheritFlag = descriptor?.inherited ?: inherit ?: false + val stylesFlag = descriptor?.usesStyles ?: useStyles ?: true + return properties.getValue(nodeName, inheritFlag, stylesFlag) ?: default?.getValue(nodeName) + } + set(value) { + properties.setValue(nodeName, value) + } + + override fun getOrCreate(name: Name): MutableMeta = VisionPropertiesItem( + properties, + nodeName + name, + inherit, + useStyles, + default + ) + + override fun set(name: Name, node: Meta?) { + properties[nodeName + name] = node + } + + override fun toString(): String = Meta.toString(this) + override fun equals(other: Any?): Boolean = Meta.equals(this, other as? Meta) + override fun hashCode(): Int = Meta.hashCode(this) +} + +/** + * A base implementation of [MutableVisionProperties] + */ +public abstract class AbstractVisionProperties( + public val vision: Vision, +) : MutableVisionProperties { + override val descriptor: MetaDescriptor? get() = vision.descriptor + + protected abstract var properties: MutableMeta? + + override val own: Meta? get() = properties + + @JvmSynchronized + protected fun getOrCreateProperties(): MutableMeta { + if (properties == null) { + //TODO check performance issues + val newProperties = MutableMeta() + properties = newProperties + } + return properties!! + } + + private val descriptorCache = HashMap() + + override fun getValue( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? { + own?.get(name)?.value?.let { return it } + + val descriptor = descriptor?.let { descriptor -> descriptorCache.getOrPut(name) { descriptor[name] } } + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true + + if (stylesFlag) { + vision.getStyleProperty(name)?.value?.let { return it } + } + + val inheritFlag = inherit ?: descriptor?.inherited ?: false + if (inheritFlag) { + vision.parent?.properties?.getValue(name, inheritFlag, stylesFlag)?.let { return it } + } + return descriptor?.defaultValue + } + + override fun set(name: Name, node: Meta?, notify: Boolean) { + //ignore if the value is the same as existing + if (own?.get(name) == node) return + + if (name.isEmpty()) { + properties = node?.asMutableMeta() + } else if (node == null) { + properties?.set(name, node) + } else { + getOrCreateProperties()[name] = node + } + if (notify) { + invalidate(name) + } + } + + override fun setValue(name: Name, value: Value?, notify: Boolean) { + //ignore if the value is the same as existing + if (own?.getValue(name) == value) return + + if (value == null) { + properties?.get(name)?.value = null + } else { + getOrCreateProperties().setValue(name, value) + } + if (notify) { + invalidate(name) + } + } + + @Transient + protected val changesInternal: MutableSharedFlow = MutableSharedFlow() + override val changes: SharedFlow get() = changesInternal + + override fun invalidate(propertyName: Name) { + //send update signal + @OptIn(DelicateCoroutinesApi::class) + (vision.manager?.context ?: GlobalScope).launch { + changesInternal.emit(propertyName) + } + + //notify children if there are any + if (vision is VisionGroup) { + vision.children.values.forEach { + it.properties.invalidate(propertyName) + } + } + + // update styles + if (propertyName == Vision.STYLE_KEY) { + vision.styles.asSequence() + .mapNotNull { vision.getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidate(it.key.asName()) + } + } + } +} + +public fun VisionProperties.getValue( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Value? = getValue(name.parseAsName(), inherit, includeStyles) + +/** + * Get [Vision] property using key as a String + */ +public fun VisionProperties.get( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Meta = get(name.parseAsName(), inherit, includeStyles) + +/** + * The root property node with given inheritance and style flags + * @param inherit - inherit properties from the [Vision] parent. If null, infer from descriptor + * @param includeStyles - include style information. If null, infer from descriptor + */ +public fun MutableVisionProperties.root( + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): MutableMeta = get(Name.EMPTY, inherit, includeStyles) + + +/** + * Get [Vision] property using key as a String + */ +public fun MutableVisionProperties.get( + name: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): MutableMeta = get(name.parseAsName(), inherit, includeStyles) + +// +//public operator fun MutableVisionProperties.set(name: Name, value: Number): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: Number): Unit = +// set(name.parseAsName(), value) +// +//public operator fun MutableVisionProperties.set(name: Name, value: Boolean): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: Boolean): Unit = +// set(name.parseAsName(), value) +// +//public operator fun MutableVisionProperties.set(name: Name, value: String): Unit = +// setValue(name, value.asValue()) +// +//public operator fun MutableVisionProperties.set(name: String, value: String): Unit = +// set(name.parseAsName(), value) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt deleted file mode 100644 index fed474fc..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/VisionPropertyContainer.kt +++ /dev/null @@ -1,34 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.meta.Configurable -import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Value - -/** - * Property containers are used to create a symmetric behaviors for vision properties and style builders - */ -public interface VisionPropertyContainer { - - public val meta: MutableMeta - - public fun getPropertyValue( - name: Name, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - ): Value? -} - -public open class SimpleVisionPropertyContainer( - override val meta: ObservableMutableMeta, -) : VisionPropertyContainer, Configurable { - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean - ): Value? = meta[name]?.value -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt new file mode 100644 index 00000000..60c39c20 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/flowProperty.kt @@ -0,0 +1,55 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.flow +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.Value +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.startsWith + +/** + * Create a flow of a specific property + */ +public fun Vision.flowProperty( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flow { + //Pass initial value. + emit(properties.get(propertyName, inherit, includeStyles)) + properties.changes.collect { name -> + if (name.startsWith(propertyName)) { + emit(properties.get(propertyName, inherit, includeStyles)) + } + } +} + +public fun Vision.flowProperty( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flowProperty(propertyName.parseAsName(), inherit, includeStyles) + +/** + * Flow the value of specific property + */ +public fun Vision.flowPropertyValue( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flow { + //Pass initial value. + emit(properties.getValue(propertyName, inherit, includeStyles)) + properties.changes.collect { name -> + if (name.startsWith(propertyName)) { + emit(properties.getValue(propertyName, inherit, includeStyles)) + } + } +} + +public fun Vision.flowPropertyValue( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, +): Flow = flowPropertyValue(propertyName.parseAsName(), inherit, includeStyles) diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt index b733e6a4..ec3f3605 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlFragment.kt @@ -4,19 +4,28 @@ import kotlinx.html.FlowContent import kotlinx.html.TagConsumer import kotlinx.html.stream.createHTML -public typealias HtmlFragment = TagConsumer<*>.() -> Unit - -public fun HtmlFragment.renderToString(): String = createHTML().apply(this).finalize() - -public fun TagConsumer<*>.fragment(fragment: HtmlFragment) { - fragment() +/** + * A standalone HTML fragment + */ +public fun interface HtmlFragment { + public fun TagConsumer<*>.append() } -public fun FlowContent.fragment(fragment: HtmlFragment) { - fragment(consumer) -} +/** + * Convenience method to append fragment to the given [consumer] + */ +public fun HtmlFragment.appendTo(consumer: TagConsumer<*>): Unit = consumer.append() -public operator fun HtmlFragment.plus(other: HtmlFragment): HtmlFragment = { - this@plus() - other() +/** + * Create a string from this [HtmlFragment] + */ +public fun HtmlFragment.renderToString(): String = createHTML().apply { append() }.finalize() + +public fun TagConsumer<*>.appendFragment(fragment: HtmlFragment): Unit = fragment.appendTo(this) + +public fun FlowContent.appendFragment(fragment: HtmlFragment): Unit = fragment.appendTo(consumer) + +public operator fun HtmlFragment.plus(other: HtmlFragment): HtmlFragment = HtmlFragment { + this@plus.appendTo(this) + other.appendTo(this) } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt index f5abdf42..d71e848a 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/HtmlVisionRenderer.kt @@ -1,50 +1,69 @@ package space.kscience.visionforge.html import kotlinx.html.* -import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.asName import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionManager -import kotlin.random.Random -import kotlin.random.nextUInt -public typealias HtmlVisionFragment = VisionTagConsumer<*>.() -> Unit - -@DFExperimental -public fun HtmlVisionFragment(content: VisionTagConsumer<*>.() -> Unit): HtmlVisionFragment = content - - -internal const val RENDER_FUNCTION_NAME = "renderAllVisionsById" +public fun interface HtmlVisionFragment{ + public fun VisionTagConsumer<*>.append() +} +public fun HtmlVisionFragment.appendTo(consumer: VisionTagConsumer<*>): Unit = consumer.append() /** * Render a fragment in the given consumer and return a map of extracted visions - * @param manager a VisionManager used for serialization + * @param context a context used to create a vision fragment * @param embedData embed Vision initial state in the HTML * @param fetchDataUrl fetch data after first render from given url - * @param fetchUpdatesUrl receive push updates from the server at given url + * @param updatesUrl receive push updates from the server at given url * @param idPrefix a prefix to be used before vision ids - * @param renderScript if true add rendering script after the fragment */ public fun TagConsumer<*>.visionFragment( - context: Context = Global, + visionManager: VisionManager, embedData: Boolean = true, fetchDataUrl: String? = null, - fetchUpdatesUrl: String? = null, + updatesUrl: String? = null, idPrefix: String? = null, - renderScript: Boolean = true, + onVisionRendered: (Name, Vision) -> Unit = { _, _ -> }, fragment: HtmlVisionFragment, -): Map { - val visionMap = HashMap() - val consumer = object : VisionTagConsumer(this@visionFragment, context, idPrefix) { - override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { - visionMap[name] = vision - // Toggle update mode +) { - fetchUpdatesUrl?.let { + val collector: MutableMap> = mutableMapOf() + + val consumer = object : VisionTagConsumer(this@visionFragment, visionManager, idPrefix) { + + override fun TagConsumer.vision(name: Name?, buildOutput: VisionOutput.() -> Vision): T { + //Avoid re-creating cached visions + val actualName = name ?: NameToken( + DEFAULT_VISION_NAME, + buildOutput.hashCode().toUInt().toString() + ).asName() + + val (output, vision) = collector.getOrPut(actualName) { + val output = VisionOutput(context, actualName) + val vision = output.buildOutput() + onVisionRendered(actualName, vision) + output to vision + } + + return addVision(actualName, output.visionManager, vision, output.meta) + } + + override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { + + val (_, actualVision) = collector.getOrPut(name) { + val output = VisionOutput(context, name) + onVisionRendered(name, vision) + output to vision + } + + + // Toggle update mode + updatesUrl?.let { attributes[OUTPUT_CONNECT_ATTRIBUTE] = it } @@ -57,42 +76,30 @@ public fun TagConsumer<*>.visionFragment( type = "text/json" attributes["class"] = OUTPUT_DATA_CLASS unsafe { - +"\n${manager.encodeToString(vision)}\n" + +"\n${manager.encodeToString(actualVision)}\n" } } } } } - if (renderScript) { - val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" - div { - this.id = id - fragment(consumer) - } - script { - type = "text/javascript" - unsafe { +"window.${RENDER_FUNCTION_NAME}(\"$id\");" } - } - } else { - fragment(consumer) - } - return visionMap + + fragment.appendTo(consumer) } public fun FlowContent.visionFragment( - context: Context = Global, + visionManager: VisionManager, embedData: Boolean = true, fetchDataUrl: String? = null, - fetchUpdatesUrl: String? = null, + updatesUrl: String? = null, + onVisionRendered: (Name, Vision) -> Unit = { _, _ -> }, idPrefix: String? = null, - renderScript: Boolean = true, fragment: HtmlVisionFragment, -): Map = consumer.visionFragment( - context, - embedData, - fetchDataUrl, - fetchUpdatesUrl, - idPrefix, - renderScript, - fragment +): Unit = consumer.visionFragment( + visionManager = visionManager, + embedData = embedData, + fetchDataUrl = fetchDataUrl, + updatesUrl = updatesUrl, + idPrefix = idPrefix, + onVisionRendered = onVisionRendered, + fragment = fragment ) \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt new file mode 100644 index 00000000..9cc223e5 --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtml.kt @@ -0,0 +1,119 @@ +package space.kscience.visionforge.html + +import kotlinx.html.InputType +import kotlinx.html.TagConsumer +import kotlinx.html.stream.createHTML +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.AbstractVision + + +@Serializable +public abstract class VisionOfHtml : AbstractVision() { + public var classes: List by properties.stringList(*emptyArray()) +} + +@Serializable +@SerialName("html.plain") +public class VisionOfPlainHtml : VisionOfHtml() { + public var content: String? by properties.string() +} + +public inline fun VisionOfPlainHtml.content(block: TagConsumer<*>.() -> Unit) { + content = createHTML().apply(block).finalize() +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.html( + block: VisionOfPlainHtml.() -> Unit, +): VisionOfPlainHtml = VisionOfPlainHtml().apply(block) + +@Serializable +public enum class InputFeedbackMode { + /** + * Fire feedback event on `onchange` event + */ + ONCHANGE, + + /** + * Fire feedback event on `oninput` event + */ + ONINPUT, + + /** + * provide only manual feedback + */ + NONE +} + +@Serializable +@SerialName("html.input") +public open class VisionOfHtmlInput( + public val inputType: String, + public val feedbackMode: InputFeedbackMode = InputFeedbackMode.ONCHANGE, +) : VisionOfHtml() { + public var value: Value? by properties.value() + public var disabled: Boolean by properties.boolean { false } + public var fieldName: String? by properties.string() +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlInput( + inputType: String, + block: VisionOfHtmlInput.() -> Unit = {}, +): VisionOfHtmlInput = VisionOfHtmlInput(inputType).apply(block) + +@Serializable +@SerialName("html.text") +public class VisionOfTextField : VisionOfHtmlInput(InputType.text.realValue) { + public var text: String? by properties.string(key = VisionOfHtmlInput::value.name.asName()) +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlTextField( + block: VisionOfTextField.() -> Unit = {}, +): VisionOfTextField = VisionOfTextField().apply(block) + + +@Serializable +@SerialName("html.checkbox") +public class VisionOfCheckbox : VisionOfHtmlInput(InputType.checkBox.realValue) { + public var checked: Boolean? by properties.boolean(key = VisionOfHtmlInput::value.name.asName()) +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlCheckBox( + block: VisionOfCheckbox.() -> Unit = {}, +): VisionOfCheckbox = VisionOfCheckbox().apply(block) + +@Serializable +@SerialName("html.number") +public class VisionOfNumberField : VisionOfHtmlInput(InputType.number.realValue) { + public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlNumberField( + block: VisionOfNumberField.() -> Unit = {}, +): VisionOfNumberField = VisionOfNumberField().apply(block) + +@Serializable +@SerialName("html.range") +public class VisionOfRangeField( + public val min: Double, + public val max: Double, + public val step: Double = 1.0, +) : VisionOfHtmlInput(InputType.range.realValue) { + public var number: Number? by properties.number(key = VisionOfHtmlInput::value.name.asName()) +} + +@Suppress("UnusedReceiverParameter") +public inline fun VisionOutput.htmlRangeField( + min: Double, + max: Double, + step: Double = 1.0, + block: VisionOfRangeField.() -> Unit = {}, +): VisionOfRangeField = VisionOfRangeField(min, max, step).apply(block) + diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt index 0ef6f54e..e56af874 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlForm.kt @@ -7,40 +7,23 @@ import kotlinx.html.id import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.get import space.kscience.dataforge.meta.node +/** + * @param formId an id of the element in rendered DOM, this form is bound to + */ @Serializable @SerialName("html.form") public class VisionOfHtmlForm( public val formId: String, -) : VisionOfHtmlInput() { - public var values: Meta? by meta.node() +) : VisionOfHtml() { + public var values: Meta? by properties.node() } -public class HtmlFormFragment internal constructor( - public val vision: VisionOfHtmlForm, - public val formBody: HtmlFragment, -){ - public val values: Meta? get() = vision.values - public operator fun get(valueName: String): Meta? = values?.get(valueName) -} - -public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { - val realId = id ?: "form[${builder.hashCode().toUInt()}]" - return HtmlFormFragment(VisionOfHtmlForm(realId)) { - form { - this.id = realId - builder() - } - } -} - -public fun TagConsumer.formFragment( - id: String? = null, +public fun TagConsumer.bindForm( + visionOfForm: VisionOfHtmlForm, builder: FORM.() -> Unit, -): VisionOfHtmlForm { - val formFragment = HtmlFormFragment(id, builder) - fragment(formFragment.formBody) - return formFragment.vision +): R = form { + this.id = visionOfForm.formId + builder() } \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt deleted file mode 100644 index 084c5b6b..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionOfHtmlInput.kt +++ /dev/null @@ -1,53 +0,0 @@ -package space.kscience.visionforge.html - -import kotlinx.serialization.SerialName -import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.boolean -import space.kscience.dataforge.meta.number -import space.kscience.dataforge.meta.string -import space.kscience.visionforge.VisionBase - -@Serializable -public abstract class VisionOfHtmlInput : VisionBase() { - public var disabled: Boolean by meta.boolean(false) -} - -@Serializable -@SerialName("html.text") -public class VisionOfTextField( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var text: String? by meta.string() -} - -@Serializable -@SerialName("html.checkbox") -public class VisionOfCheckbox( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var checked: Boolean? by meta.boolean() -} - -@Serializable -@SerialName("html.number") -public class VisionOfNumberField( - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var value: Number? by meta.number() -} - -@Serializable -@SerialName("html.range") -public class VisionOfRangeField( - public val min: Double, - public val max: Double, - public val step: Double = 1.0, - public val label: String? = null, - public val name: String? = null, -) : VisionOfHtmlInput() { - public var value: Number? by meta.number() -} - diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt similarity index 50% rename from visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt rename to visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt index bdd5e417..1ea216c5 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/Page.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionPage.kt @@ -1,32 +1,23 @@ package space.kscience.visionforge.html import kotlinx.html.* -import space.kscience.dataforge.context.Context +import space.kscience.visionforge.VisionManager -public data class Page( - public val context: Context, - public val headers: Map = emptyMap(), +/** + * A structure representing a single page with Visions to be rendered. + * + * @param pageHeaders static headers for this page. + */ +public data class VisionPage( + public val visionManager: VisionManager, + public val pageHeaders: Map = emptyMap(), public val content: HtmlVisionFragment, ) { - public fun render(root: TagConsumer): R = root.apply { - head { - meta { - charset = "utf-8" - } - headers.values.forEach { - fragment(it) - } - } - body { - visionFragment(context, fragment = content) - } - }.finalize() - public companion object{ /** * Use a script with given [src] as a global header for all pages. */ - public fun scriptHeader(src: String, block: SCRIPT.() -> Unit = {}): HtmlFragment = { + public fun scriptHeader(src: String, block: SCRIPT.() -> Unit = {}): HtmlFragment = HtmlFragment{ script { type = "text/javascript" this.src = src @@ -35,9 +26,9 @@ public data class Page( } /** - * Use css with given stylesheet link as a global header for all pages. + * Use css with the given stylesheet link as a global header for all pages. */ - public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = { + public fun styleSheetHeader(href: String, block: LINK.() -> Unit = {}): HtmlFragment = HtmlFragment{ link { rel = "stylesheet" this.href = href @@ -45,7 +36,7 @@ public data class Page( } } - public fun title(title:String): HtmlFragment = { + public fun title(title:String): HtmlFragment = HtmlFragment{ title(title) } } diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt index afdd686f..99a8ea0d 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/html/VisionTagConsumer.kt @@ -2,12 +2,12 @@ package space.kscience.visionforge.html import kotlinx.html.* import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaSerializer import space.kscience.dataforge.meta.MutableMeta import space.kscience.dataforge.meta.isEmpty -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.asName @@ -25,9 +25,8 @@ public annotation class VisionDSL /** * A placeholder object to attach inline vision builders. */ -@DFExperimental @VisionDSL -public class VisionOutput @PublishedApi internal constructor(public val context: Context, public val name: Name?) { +public class VisionOutput @PublishedApi internal constructor(override val context: Context, public val name: Name): ContextAware { public var meta: Meta = Meta.EMPTY private val requirements: MutableSet> = HashSet() @@ -36,8 +35,8 @@ public class VisionOutput @PublishedApi internal constructor(public val context: requirements.add(factory) } - internal fun buildVisionManager(): VisionManager = - if (requirements.all { req -> context.plugins.find(true) { it.tag == req.tag } != null }) { + public val visionManager: VisionManager + get() = if (requirements.all { req -> context.plugins.find(true) { it.tag == req.tag } != null }) { context.visionManager } else { val newContext = context.buildContext(NameToken(DEFAULT_VISION_NAME, name.toString()).asName()) { @@ -56,12 +55,13 @@ public class VisionOutput @PublishedApi internal constructor(public val context: * Modified [TagConsumer] that allows rendering output fragments and visions in them */ @VisionDSL -@OptIn(DFExperimental::class) public abstract class VisionTagConsumer( private val root: TagConsumer, - public val context: Context, + public val visionManager: VisionManager, private val idPrefix: String? = null, -) : TagConsumer by root { +) : TagConsumer by root, ContextAware { + + override val context: Context get() = visionManager.context public open fun resolveId(name: Name): String = (idPrefix ?: "output") + "[$name]" @@ -78,52 +78,66 @@ public abstract class VisionTagConsumer( * Create a placeholder for a vision output with optional [Vision] in it * TODO with multi-receivers could be replaced by [VisionTagConsumer, TagConsumer] extension */ - private fun TagConsumer.vision( + protected fun TagConsumer.addVision( name: Name, manager: VisionManager, - vision: Vision, + vision: Vision?, outputMeta: Meta = Meta.EMPTY, - ): T = div { + ): T = if (vision == null) div { + +"Empty Vision output" + } else div { id = resolveId(name) classes = setOf(OUTPUT_CLASS) - vision.setAsRoot(manager) + if (vision.parent == null) { + vision.setAsRoot(manager) + } attributes[OUTPUT_NAME_ATTRIBUTE] = name.toString() + renderVision(manager, name, vision, outputMeta) if (!outputMeta.isEmpty()) { //Hard-code output configuration script { + type = "text/json" attributes["class"] = OUTPUT_META_CLASS unsafe { - +manager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + +("\n" + manager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + "\n") } } } - renderVision(manager, name, vision, outputMeta) } /** * Insert a vision in this HTML. * TODO replace by multi-receiver */ - @OptIn(DFExperimental::class) - public fun TagConsumer.vision( + @VisionDSL + public open fun TagConsumer.vision( name: Name? = null, - @OptIn(DFExperimental::class) visionProvider: VisionOutput.() -> Vision, + buildOutput: VisionOutput.() -> Vision, ): T { - val output = VisionOutput(context, name) - val vision = output.visionProvider() - val actualName = name ?: NameToken(DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() - return vision(actualName, output.buildVisionManager(), vision, output.meta) + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, buildOutput.hashCode().toUInt().toString()).asName() + val output = VisionOutput(context, actualName) + val vision = output.buildOutput() + return addVision(actualName, output.visionManager, vision, output.meta) } /** * TODO to be replaced by multi-receiver */ - @OptIn(DFExperimental::class) @VisionDSL public fun TagConsumer.vision( name: String?, - @OptIn(DFExperimental::class) visionProvider: VisionOutput.() -> Vision, - ): T = vision(name?.parseAsName(), visionProvider) + buildOutput: VisionOutput.() -> Vision, + ): T = vision(name?.parseAsName(), buildOutput) + + @VisionDSL + public open fun TagConsumer.vision( + vision: Vision, + name: Name? = null, + outputMeta: Meta = Meta.EMPTY, + ) { + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, vision.hashCode().toUInt().toString()).asName() + addVision(actualName, context.visionManager, vision, outputMeta) + } /** * Process the resulting object produced by [TagConsumer] diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt new file mode 100644 index 00000000..8ffb272a --- /dev/null +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/useProperty.kt @@ -0,0 +1,67 @@ +package space.kscience.visionforge + +import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.Job +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.parseAsName +import space.kscience.dataforge.names.startsWith +import kotlin.reflect.KProperty1 + + +/** + * Call [callback] on initial value of the property and then on all subsequent values after change + */ +public fun Vision.useProperty( + propertyName: Name, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + scope: CoroutineScope? = manager?.context, + callback: (Meta) -> Unit, +): Job { + //Pass initial value. + callback(properties.get(propertyName, inherit, includeStyles)) + return properties.changes.onEach { name -> + if (name.startsWith(propertyName)) { + callback(properties.get(propertyName, inherit, includeStyles)) + } + }.launchIn(scope ?: error("Orphan Vision can't observe properties")) +} + +public fun Vision.useProperty( + propertyName: String, + inherit: Boolean? = null, + includeStyles: Boolean? = null, + scope: CoroutineScope? = manager?.context, + callback: (Meta) -> Unit, +): Job = useProperty(propertyName.parseAsName(), inherit, includeStyles, scope, callback) + +/** + * Observe changes to the specific property without passing the initial value. + */ +public fun V.onPropertyChange( + property: KProperty1, + scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties"), + callback: suspend V.(T) -> Unit, +): Job = properties.changes.onEach { name -> + if (name.startsWith(property.name.asName())) { + callback(property.get(this)) + } +}.launchIn(scope) + +public fun V.useProperty( + property: KProperty1, + scope: CoroutineScope = manager?.context ?: error("Orphan Vision can't observe properties"), + callback: V.(T) -> Unit, +): Job { + //Pass initial value. + callback(property.get(this)) + return properties.changes.onEach { name -> + if (name.startsWith(property.name.asName())) { + callback(property.get(this@useProperty)) + } + }.launchIn(scope) +} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt deleted file mode 100644 index 999bbb45..00000000 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDelegates.kt +++ /dev/null @@ -1,91 +0,0 @@ -package space.kscience.visionforge - -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.number -import kotlin.properties.ReadWriteProperty -import kotlin.reflect.KProperty - -//public fun Vision.propertyNode( -// name: Name? = null, -// inherit: Boolean = false, -// includeStyles: Boolean = true, -// includeDefaults: Boolean = true, -//): ReadWriteProperty = object : ReadWriteProperty { -// override fun getValue(thisRef: Any?, property: KProperty<*>): Meta? = -// getProperty(name ?: Name.parse(property.name), inherit, includeStyles, includeDefaults) -// -// override fun setValue(thisRef: Any?, property: KProperty<*>, value: Meta?) { -// meta.setMeta(name ?: Name.parse(property.name), value) -// } -//} -// -//public fun Vision.propertyNode( -// converter: MetaConverter, -// name: Name? = null, -// inherit: Boolean = false, -// includeStyles: Boolean = true, -// includeDefaults: Boolean = true, -//): ReadWriteProperty = object : ReadWriteProperty { -// override fun getValue(thisRef: Any?, property: KProperty<*>): T? = getProperty( -// name ?: Name.parse(property.name), -// inherit, -// includeStyles, -// includeDefaults -// )?.let(converter::metaToObject) -// -// override fun setValue(thisRef: Any?, property: KProperty<*>, value: T?) { -// meta.setMeta(name ?: Name.parse(property.name), value?.let(converter::objectToMeta)) -// } -//} - -public fun Vision.propertyValue( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): Value? = - getPropertyValue(name ?: Name.parse(property.name), inherit, includeStyles, includeDefaults) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: Value?) { - meta.setValue(name ?: Name.parse(property.name), value) - } -} - -public fun Vision.propertyValue( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - setter: (T) -> Value? = { it?.let(Value::of) }, - getter: (Value?) -> T, -): ReadWriteProperty = object : ReadWriteProperty { - override fun getValue(thisRef: Any?, property: KProperty<*>): T = getPropertyValue( - name ?: Name.parse(property.name), - inherit, - includeStyles, - includeDefaults - ).let(getter) - - override fun setValue(thisRef: Any?, property: KProperty<*>, value: T) { - meta.setValue(name ?: Name.parse(property.name), value?.let(setter)) - } -} - -public fun Vision.numberProperty( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true -): ReadWriteProperty = propertyValue(name, inherit, includeStyles, includeDefaults) { it?.number } - -public fun Vision.numberProperty( - name: Name? = null, - inherit: Boolean = false, - includeStyles: Boolean = true, - includeDefaults: Boolean = true, - default: () -> Number -): ReadWriteProperty = propertyValue(name, inherit, includeStyles, includeDefaults) { - it?.number ?: default() -} \ No newline at end of file diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt index 15ef9229..66ee43e0 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visionDescriptor.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.* -import space.kscience.dataforge.values.asValue +import space.kscience.dataforge.meta.set private const val INHERITED_DESCRIPTOR_ATTRIBUTE = "inherited" private const val STYLE_DESCRIPTOR_ATTRIBUTE = "useStyles" diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt index 0a60c3c0..5b989274 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/StatisticsVisitor.kt @@ -1,6 +1,5 @@ package space.kscience.visionforge.visitor -import kotlinx.coroutines.ExperimentalCoroutinesApi import kotlinx.coroutines.Job import kotlinx.coroutines.channels.awaitClose import kotlinx.coroutines.flow.Flow @@ -11,7 +10,6 @@ import space.kscience.visionforge.Vision import kotlin.reflect.KClass -@OptIn(ExperimentalCoroutinesApi::class) public suspend fun Vision.flowStatistics(statistics: (Name, Vision) -> T): Flow = callbackFlow { val visitor = object : VisionVisitor { override suspend fun visit(name: Name, vision: Vision){ diff --git a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt index 0533dc4e..4ceab3d9 100644 --- a/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt +++ b/visionforge-core/src/commonMain/kotlin/space/kscience/visionforge/visitor/VisionVisitor.kt @@ -6,7 +6,8 @@ import kotlinx.coroutines.launch import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.plus import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.children +import space.kscience.visionforge.forEach public interface VisionVisitor { /** @@ -19,30 +20,30 @@ public interface VisionVisitor { /** * Rearrange children of given group */ - public suspend fun visitChildren(name: Name, group: VisionGroup) { + public suspend fun visitChildren(name: Name, group: Vision) { //Do nothing by default } public fun skip(name: Name, vision: Vision): Boolean = false - public companion object{ + public companion object { private fun CoroutineScope.visitTreeAsync( visionVisitor: VisionVisitor, name: Name, - vision: Vision + vision: Vision, ): Job = launch { if (visionVisitor.skip(name, vision)) return@launch visionVisitor.visit(name, vision) - if (vision is VisionGroup) { - visionVisitor.visitChildren(name, vision) - for ((token, child) in vision.children) { - visitTreeAsync(visionVisitor, name + token, child) - } + visionVisitor.visitChildren(name, vision) + + vision.children?.forEach { token, child -> + visitTreeAsync(visionVisitor, name + token, child) } } + /** * Recursively visit this [Vision] and all children */ diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt index 42a9ba1f..20868b96 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/html/HtmlTagTest.kt @@ -4,13 +4,10 @@ import kotlinx.html.* import kotlinx.html.stream.createHTML import space.kscience.dataforge.context.Global import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.configure import space.kscience.dataforge.meta.set import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionBase -import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.* import kotlin.collections.set import kotlin.test.Test @@ -22,23 +19,24 @@ fun FlowContent.renderVisionFragment( fragment: HtmlVisionFragment, ): Map { val visionMap = HashMap() - val consumer = object : VisionTagConsumer(consumer, Global, idPrefix) { + val consumer = object : VisionTagConsumer(consumer, Global.visionManager, idPrefix) { override fun DIV.renderVision(manager: VisionManager, name: Name, vision: Vision, outputMeta: Meta) { visionMap[name] = vision renderer(name, vision, outputMeta) } } - fragment(consumer) + fragment.appendTo(consumer) return visionMap } +@DFExperimental +private fun VisionOutput.base(block: VisionGroup.() -> Unit) = context.visionManager.group().apply(block) + @DFExperimental class HtmlTagTest { - fun VisionOutput.base(block: VisionBase.() -> Unit) = VisionBase().apply(block) - - val fragment: HtmlVisionFragment = { + val fragment = HtmlVisionFragment{ div { h1 { +"Head" } vision("ddd") { @@ -46,10 +44,8 @@ class HtmlTagTest { "metaProperty" put 87 } base { - configure { - set("myProp", 82) - set("otherProp", false) - } + properties["myProp"] = 82 + properties["otherProp"] = false } } } @@ -59,7 +55,7 @@ class HtmlTagTest { div { h2 { +"Properties" } ul { - (vision as? VisionBase)?.meta?.items?.forEach { + vision.properties.own?.items?.forEach { li { a { +it.key.toString() } p { +it.value.toString() } diff --git a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt index 40b4c96e..b1ca970a 100644 --- a/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt +++ b/visionforge-core/src/commonTest/kotlin/space/kscience/visionforge/meta/VisionPropertyTest.kt @@ -1,44 +1,125 @@ package space.kscience.visionforge.meta +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.map +import kotlinx.coroutines.flow.take +import kotlinx.coroutines.flow.toList +import kotlinx.coroutines.launch +import kotlinx.coroutines.test.runTest +import space.kscience.dataforge.context.Global +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.* -import space.kscience.dataforge.values.asValue -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertNotEquals +import kotlin.time.Duration.Companion.milliseconds + + +private class TestScheme : Scheme() { + var ddd by int() + + companion object : SchemeSpec(::TestScheme) +} + +internal class VisionPropertyTest { + + private val manager = Global.request(VisionManager) -class VisionPropertyTest { @Test - fun testPropertyWrite(){ - val vision = VisionBase() - vision.meta["fff"] = 2 - vision.meta["fff.ddd"] = false + fun testPropertyWrite() { + val vision = manager.group() + vision.properties["fff"] = 2 + vision.properties["fff.ddd"] = false - assertEquals(2, vision.meta["fff"]?.int) - assertEquals(false, vision.meta["fff.ddd"]?.boolean) + assertEquals(2, vision.properties.getValue("fff")?.int) + assertEquals(false, vision.properties.getValue("fff.ddd")?.boolean) } @Test - fun testPropertyEdit(){ - val vision = VisionBase() - vision.meta.getOrCreate("fff.ddd").apply { + fun testPropertyEdit() { + val vision = manager.group() + vision.properties.get("fff.ddd").apply { value = 2.asValue() } - assertEquals(2, vision.meta["fff.ddd"]?.int) - assertNotEquals(true, vision.meta["fff.ddd"]?.boolean) - } - - internal class TestScheme: Scheme(){ - var ddd by int() - companion object: SchemeSpec(::TestScheme) + assertEquals(2, vision.properties.getValue("fff.ddd")?.int) + assertNotEquals(true, vision.properties.getValue("fff.ddd")?.boolean) } @Test - fun testPropertyUpdate(){ - val vision = VisionBase() - vision.meta.getOrCreate("fff").updateWith(TestScheme){ + fun testPropertyUpdate() { + val vision = manager.group() + vision.properties.get("fff").updateWith(TestScheme) { ddd = 2 } - assertEquals(2, vision.meta["fff.ddd"]?.int) + assertEquals(2, vision.properties.getValue("fff.ddd")?.int) + } + + @Test + fun testChildrenPropertyPropagation() = runTest(timeout = 200.milliseconds) { + val group = Global.request(VisionManager).group { + properties { + "test" put 11 + } + group("child") { + properties { + "test" put 22 + } + } + } + + val child = group.children["child"]!! + + val deferred: CompletableDeferred = CompletableDeferred() + + var callCounter = 0 + + val subscription = child.useProperty("test", inherit = true) { + deferred.complete(it.value) + callCounter++ + } + + assertEquals(22, deferred.await()?.int) + assertEquals(1, callCounter) + + child.properties.remove("test") + + assertEquals(11, child.properties.get("test", inherit = true).int) +// assertEquals(11, deferred.await()?.int) +// assertEquals(2, callCounter) + subscription.cancel() + } + + @Test + fun testChildrenPropertyFlow() = runTest(timeout = 200.milliseconds) { + val group = Global.request(VisionManager).group { + + properties { + "test" put 11 + } + + group("child") { + properties { + "test" put 22 + } + } + + } + + val child = group.children["child"]!! + + launch { + val list = child.flowPropertyValue("test", inherit = true).take(3).map { it?.int }.toList() + assertEquals(22, list.first()) + //assertEquals(11, list[1]) //a race + assertEquals(33, list.last()) + } + + //wait for subscription to be created + delay(5) + + child.properties.remove("test") + group.properties["test"] = 33 } } \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt index 5e1e2470..85ead127 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/Application.kt @@ -2,7 +2,7 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.coroutines.CoroutineScope -import kotlinx.dom.hasClass +import org.w3c.dom.Document import kotlin.coroutines.CoroutineContext import kotlin.coroutines.EmptyCoroutineContext @@ -36,7 +36,7 @@ public interface Application: CoroutineScope { * Starting point for an application. * @param state Initial state between Hot Module Replacement (HMR). */ - public fun start(state: Map) + public fun start(document: Document, state: Map) /** * Ending point for an application. @@ -46,17 +46,13 @@ public interface Application: CoroutineScope { } public fun startApplication(builder: () -> Application) { - fun start(state: dynamic): Application? { - return if (document.body?.hasClass("application") == true) { - val application = builder() + fun start(document: Document, state: dynamic): Application{ + val application = builder() - @Suppress("UnsafeCastFromDynamic") - application.start(state?.appState ?: emptyMap()) + @Suppress("UnsafeCastFromDynamic") + application.start(document, state?.appState ?: emptyMap()) - application - } else { - null - } + return application } var application: Application? = null @@ -73,9 +69,9 @@ public fun startApplication(builder: () -> Application) { } if (document.body != null) { - application = start(state) + application = start(document, state) } else { application = null - document.addEventListener("DOMContentLoaded", { application = start(state) }) + document.addEventListener("DOMContentLoaded", { application = start(document, state) }) } } \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt index bf9f00df..8e1254d9 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/ElementVisionRenderer.kt @@ -9,8 +9,8 @@ import kotlinx.serialization.serializerOrNull import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.misc.DfType import space.kscience.dataforge.misc.Named -import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.parseAsName @@ -20,13 +20,13 @@ import kotlin.reflect.cast /** * A browser renderer for a [Vision]. */ -@Type(ElementVisionRenderer.TYPE) +@DfType(ElementVisionRenderer.TYPE) public interface ElementVisionRenderer : Named { /** * Give a [vision] integer rating based on this renderer capabilities. [ZERO_RATING] or negative values means that this renderer * can't process a vision. The value of [DEFAULT_RATING] used for default renderer. Specialized renderers could specify - * higher value in order to "steal" rendering job + * higher value to "steal" rendering job */ public fun rateVision(vision: Vision): Int @@ -34,7 +34,7 @@ public interface ElementVisionRenderer : Named { * Display the [vision] inside a given [element] replacing its current content. * @param meta additional parameters for rendering container */ - public fun render(element: Element, vision: Vision, meta: Meta = Meta.EMPTY) + public fun render(element: Element, name: Name, vision: Vision, meta: Meta = Meta.EMPTY) public companion object { public const val TYPE: String = "elementVisionRenderer" @@ -49,7 +49,7 @@ public interface ElementVisionRenderer : Named { public class SingleTypeVisionRenderer( public val kClass: KClass, private val acceptRating: Int = ElementVisionRenderer.DEFAULT_RATING, - private val renderFunction: TagConsumer.(vision: T, meta: Meta) -> Unit, + private val renderFunction: TagConsumer.(name: Name, vision: T, meta: Meta) -> Unit, ) : ElementVisionRenderer { @OptIn(InternalSerializationApi::class, ExperimentalSerializationApi::class) @@ -60,15 +60,15 @@ public class SingleTypeVisionRenderer( override fun rateVision(vision: Vision): Int = if (vision::class == kClass) acceptRating else ElementVisionRenderer.ZERO_RATING - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { element.clear() element.append { - renderFunction(kClass.cast(vision), meta) + renderFunction(name, kClass.cast(vision), meta) } } } public inline fun ElementVisionRenderer( acceptRating: Int = ElementVisionRenderer.DEFAULT_RATING, - noinline renderFunction: TagConsumer.(vision: T, meta: Meta) -> Unit, + noinline renderFunction: TagConsumer.(name: Name, vision: T, meta: Meta) -> Unit, ): ElementVisionRenderer = SingleTypeVisionRenderer(T::class, acceptRating, renderFunction) diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt new file mode 100644 index 00000000..17958f97 --- /dev/null +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/JsVisionClient.kt @@ -0,0 +1,356 @@ +package space.kscience.visionforge + +import kotlinx.browser.document +import kotlinx.browser.window +import kotlinx.coroutines.Job +import kotlinx.coroutines.delay +import kotlinx.coroutines.flow.MutableSharedFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach +import kotlinx.coroutines.isActive +import kotlinx.coroutines.launch +import kotlinx.coroutines.sync.Mutex +import kotlinx.coroutines.sync.withLock +import org.w3c.dom.* +import org.w3c.dom.url.URL +import space.kscience.dataforge.context.* +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaSerializer +import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.parseAsName +import space.kscience.visionforge.html.VisionTagConsumer +import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE +import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE +import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_FETCH_ATTRIBUTE +import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_NAME_ATTRIBUTE +import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_RENDERED +import kotlin.time.Duration.Companion.milliseconds + +/** + * A Kotlin-browser plugin that renders visions based on provided renderers and governs communication with the server. + */ +public class JsVisionClient : AbstractPlugin(), VisionClient { + override val tag: PluginTag get() = Companion.tag + override val visionManager: VisionManager by require(VisionManager) + + /** + * Up-going tree traversal in search for endpoint attribute. If element is null, return window URL + */ + private fun resolveEndpoint(element: Element?): String { + if (element == null) return window.location.href + val attribute = element.attributes[OUTPUT_ENDPOINT_ATTRIBUTE] + return attribute?.value ?: resolveEndpoint(element.parentElement) + } + + private fun resolveName(element: Element): String? { + val attribute = element.attributes[OUTPUT_NAME_ATTRIBUTE] + return attribute?.value + } + + internal val renderers by lazy { context.gather(ElementVisionRenderer.TYPE).values } + + private fun findRendererFor(vision: Vision): ElementVisionRenderer? = renderers.mapNotNull { + val rating = it.rateVision(vision) + if (rating > 0) { + rating to it + } else { + null + } + }.maxByOrNull { it.first }?.second + + private fun Element.getEmbeddedData(className: String): String? = getElementsByClassName(className)[0]?.innerHTML + + private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null + +// private val mutex = Mutex() + + + +// /** +// * Communicate vision property changed from rendering engine to model +// */ +// private fun notifyPropertyChanged(visionName: Name, propertyName: Name, item: Meta?) { +// context.launch { +// mutex.withLock { +// changeCollector.propertyChanged(visionName, propertyName, item) +// } +// } +// } + + private val eventCollector by lazy { + MutableSharedFlow>(meta["feedback.eventCache"].int ?: 100) + } + + /** + * Send a custom feedback event + */ + override suspend fun sendEvent(targetName: Name, event: VisionEvent) { + eventCollector.emit(targetName to event) + } + + private fun renderVision(element: Element, name: Name, vision: Vision, outputMeta: Meta) { + vision.setAsRoot(visionManager) + val renderer = findRendererFor(vision) ?: error("Could not find renderer for ${vision::class}") + renderer.render(element, name, vision, outputMeta) + } + + private fun startVisionUpdate(element: Element, visionName: Name, vision: Vision, outputMeta: Meta) { + element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> + val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { + val endpoint = resolveEndpoint(element) + logger.info { "Vision server is resolved to $endpoint" } + URL(endpoint).apply { + pathname += "/ws" + } + } else { + URL(attr.value) + }.apply { + protocol = "ws" + searchParams.append("name", visionName.toString()) + } + + + logger.info { "Updating vision data from $wsUrl" } + + //Individual websocket for this vision + WebSocket(wsUrl.toString()).apply { + onmessage = { messageEvent -> + val stringData: String? = messageEvent.data as? String + if (stringData != null) { + val event: VisionEvent = visionManager.jsonFormat.decodeFromString( + VisionEvent.serializer(), + stringData + ) + + // If change contains root vision replacement, do it + if (event is VisionChange) { + event.vision?.let { vision -> + renderVision(element, visionName, vision, outputMeta) + } + } + + logger.debug { "Got $event for output with name $visionName" } + vision.receiveEvent(event) + } else { + logger.error { "WebSocket message data is not a string" } + } + } + + + //Backward change propagation + var feedbackJob: Job? = null + + //Feedback changes aggregation time in milliseconds + val feedbackAggregationTime = meta["feedback.aggregationTime"]?.int ?: 300 + + onopen = { + + + val mutex = Mutex() + + val changeCollector = VisionChangeBuilder() + + feedbackJob = visionManager.context.launch { + //launch a separate coroutine to send events to the backend + eventCollector.filter { it.first == visionName }.onEach { + send(visionManager.jsonFormat.encodeToString(VisionEvent.serializer(), it.second)) + }.launchIn(this) + + //launch backward property propagation + vision.properties.changes.onEach { propertyName: Name -> + changeCollector.propertyChanged(visionName, propertyName, vision.properties[propertyName]) + }.launchIn(this) + + //aggregate atomic changes + while (isActive) { + delay(feedbackAggregationTime.milliseconds) + if (!changeCollector.isEmpty()) { + mutex.withLock { + eventCollector.emit(visionName to changeCollector.deepCopy(visionManager)) + changeCollector.reset() + } + } + } + } + logger.info { "WebSocket feedback channel established for output '$visionName'" } + } + + onclose = { + feedbackJob?.cancel() + logger.info { "WebSocket feedback channel closed for output '$visionName'" } + } + onerror = { + feedbackJob?.cancel() + logger.error { "WebSocket feedback channel error for output '$visionName'" } + } + } + } + } + + /** + * Fetch from server and render a vision, described in a given with [VisionTagConsumer.OUTPUT_CLASS] class. + */ + public fun renderVisionIn(element: Element) { + if (!element.classList.contains(VisionTagConsumer.OUTPUT_CLASS)) error("The element $element is not an output element") + val name = resolveName(element)?.parseAsName() ?: error("The element is not a vision output") + + if (element.attributes[OUTPUT_RENDERED]?.value == "true") { + logger.info { "VF output in element $element is already rendered" } + return + } else { + logger.info { "Rendering VF output with name $name" } + } + + val outputMeta = element.getEmbeddedData(VisionTagConsumer.OUTPUT_META_CLASS)?.let { + VisionManager.defaultJson.decodeFromString(MetaSerializer, it).also { + logger.info { "Output meta for $name: $it" } + } + } ?: Meta.EMPTY + + when { + // fetch data if the path is provided + element.attributes[OUTPUT_FETCH_ATTRIBUTE] != null -> { + val attr = element.attributes[OUTPUT_FETCH_ATTRIBUTE]!! + + val fetchUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { + val endpoint = resolveEndpoint(element) + logger.info { "Vision server is resolved to $endpoint" } + URL(endpoint).apply { + pathname += "/data" + } + } else { + URL(attr.value) + }.apply { + searchParams.append("name", name.toString()) + } + + logger.info { "Fetching vision data from $fetchUrl" } + window.fetch(fetchUrl).then { response -> + if (response.ok) { + response.text().then { text -> + val vision = visionManager.decodeFromString(text) + renderVision(element, name, vision, outputMeta) + startVisionUpdate(element, name, vision, outputMeta) + } + } else { + logger.error { "Failed to fetch initial vision state from $fetchUrl" } + } + } + } + + // use embedded data if it is available + element.getElementsByClassName(VisionTagConsumer.OUTPUT_DATA_CLASS).length > 0 -> { + //Getting embedded vision data + val embeddedVision = element.getEmbeddedData(VisionTagConsumer.OUTPUT_DATA_CLASS)!!.let { + visionManager.decodeFromString(it) + } + logger.info { "Found embedded vision for output with name $name" } + renderVision(element, name, embeddedVision, outputMeta) + startVisionUpdate(element, name, embeddedVision, outputMeta) + } + + //Try to load vision via websocket +// element.attributes[OUTPUT_CONNECT_ATTRIBUTE] != null -> { +// startVisionUpdate(element, name, null, outputMeta) +// } + + else -> error("No embedded vision data / fetch url for $name") + } + element.setAttribute(OUTPUT_RENDERED, "true") + } + + override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) { + listOf( + htmlVisionRenderer, + inputVisionRenderer, + checkboxVisionRenderer, + numberVisionRenderer, + textVisionRenderer, + rangeVisionRenderer, + formVisionRenderer + ).associateByName() + } else super.content(target) + + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): JsVisionClient = JsVisionClient() + + override val tag: PluginTag = PluginTag(name = "vision.client.js", group = PluginTag.DATAFORGE_GROUP) + } +} + +private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { + if (document.body != null) { + block(document) + } else { + document.addEventListener("DOMContentLoaded", { block(document) }) + } +} + +/** + * Fetch and render visions for all elements with [VisionTagConsumer.OUTPUT_CLASS] class inside given [element]. + */ +public fun JsVisionClient.renderAllVisionsIn(element: Element) { + val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS) + logger.info { "Finished search for outputs. Found ${elements.length} items" } + elements.asList().forEach { child -> + renderVisionIn(child) + } +} + +/** + * Render all visions in an element with a given [id] + */ +public fun JsVisionClient.renderAllVisionsById(document: Document, id: String): Unit { + val element = document.getElementById(id) + if (element != null) { + renderAllVisionsIn(element) + } else { + logger.warn { "Element with id $id not found" } + } +} + + +/** + * Fetch visions from the server for all elements with [VisionTagConsumer.OUTPUT_CLASS] class in the document body + */ +public fun JsVisionClient.renderAllVisions(): Unit = whenDocumentLoaded { + val element = body ?: error("Document does not have a body") + renderAllVisionsIn(element) +} + +public class VisionClientApplication(public val context: Context) : Application { + private val client = context.request(JsVisionClient) + + override fun start(document: Document, state: Map) { + context.logger.info { + "Starting VisionClient with renderers: ${ + client.renderers.joinToString( + prefix = "\n\t", + separator = "\n\t" + ) { it.name.toString() } + }" + } + val element = document.body ?: error("Document does not have a body") + client.renderAllVisionsIn(element) + } +} + + +/** + * Create a vision client context and render all visions on the page. + */ +public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) { + Global.logger.info { "Starting VisionForge context" } + + val context = Context("VisionForge") { + plugin(JsVisionClient) + contextBuilder() + } + + startApplication { + VisionClientApplication(context) + } +} \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt deleted file mode 100644 index c437a5d6..00000000 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/VisionClient.kt +++ /dev/null @@ -1,266 +0,0 @@ -package space.kscience.visionforge - -import kotlinx.browser.document -import kotlinx.browser.window -import kotlinx.coroutines.Job -import kotlinx.coroutines.flow.launchIn -import kotlinx.coroutines.flow.onEach -import org.w3c.dom.* -import org.w3c.dom.url.URL -import space.kscience.dataforge.context.* -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.MetaSerializer -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.names.Name -import space.kscience.visionforge.html.RENDER_FUNCTION_NAME -import space.kscience.visionforge.html.VisionTagConsumer -import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_CONNECT_ATTRIBUTE -import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_ENDPOINT_ATTRIBUTE -import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_FETCH_ATTRIBUTE -import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_NAME_ATTRIBUTE -import space.kscience.visionforge.html.VisionTagConsumer.Companion.OUTPUT_RENDERED -import kotlin.reflect.KClass -import kotlin.time.Duration.Companion.milliseconds - -/** - * A Kotlin-browser plugin that renders visions based on provided renderers and governs communication with the server. - */ -public class VisionClient : AbstractPlugin() { - override val tag: PluginTag get() = Companion.tag - private val visionManager: VisionManager by require(VisionManager) - - //private val visionMap = HashMap() - - /** - * Up-going tree traversal in search for endpoint attribute. If element is null, return window URL - */ - private fun resolveEndpoint(element: Element?): String { - if (element == null) return window.location.href - val attribute = element.attributes[OUTPUT_ENDPOINT_ATTRIBUTE] - return attribute?.value ?: resolveEndpoint(element.parentElement) - } - - private fun resolveName(element: Element): String? { - val attribute = element.attributes[OUTPUT_NAME_ATTRIBUTE] - return attribute?.value - } - - private fun getRenderers() = context.gather(ElementVisionRenderer.TYPE).values - - private fun findRendererFor(vision: Vision): ElementVisionRenderer? { - return getRenderers().mapNotNull { - val rating = it.rateVision(vision) - if (rating > 0) { - rating to it - } else { - null - } - }.maxByOrNull { it.first }?.second - } - - private fun Element.getEmbeddedData(className: String): String? = getElementsByClassName(className)[0]?.innerHTML - - private fun Element.getFlag(attribute: String): Boolean = attributes[attribute]?.value != null - - private fun renderVision(name: String, element: Element, vision: Vision?, outputMeta: Meta) { - if (vision != null) { - val renderer = findRendererFor(vision) - ?: error("Could not find renderer for ${visionManager.encodeToString(vision)}") - renderer.render(element, vision, outputMeta) - - element.attributes[OUTPUT_CONNECT_ATTRIBUTE]?.let { attr -> - val wsUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { - val endpoint = resolveEndpoint(element) - logger.info { "Vision server is resolved to $endpoint" } - URL(endpoint).apply { - pathname += "/ws" - } - } else { - URL(attr.value) - }.apply { - protocol = "ws" - searchParams.append("name", name) - } - - logger.info { "Updating vision data from $wsUrl" } - - //Individual websocket for this element - WebSocket(wsUrl.toString()).apply { - onmessage = { messageEvent -> - val stringData: String? = messageEvent.data as? String - if (stringData != null) { - val change: VisionChange = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), - stringData - ) - - if (change.vision != null) { - renderer.render(element, vision, outputMeta) - } - - logger.debug { "Got update $change for output with name $name" } - vision.update(change) - } else { - console.error("WebSocket message data is not a string") - } - } - - - //Backward change propagation - var feedbackJob: Job? = null - - //Feedback changes aggregation time in milliseconds - val feedbackAggregationTime = meta["aggregationTime"]?.int ?: 300 - - onopen = { - feedbackJob = vision.flowChanges( - feedbackAggregationTime.milliseconds - ).onEach { change -> - send(visionManager.encodeToString(change)) - }.launchIn(visionManager.context) - - console.info("WebSocket update channel established for output '$name'") - } - - onclose = { - feedbackJob?.cancel() - console.info("WebSocket update channel closed for output '$name'") - } - onerror = { - feedbackJob?.cancel() - console.error("WebSocket update channel error for output '$name'") - } - } - } - } - } - - /** - * Fetch from server and render a vision, described in a given with [VisionTagConsumer.OUTPUT_CLASS] class. - */ - public fun renderVisionIn(element: Element) { - if (!element.classList.contains(VisionTagConsumer.OUTPUT_CLASS)) error("The element $element is not an output element") - val name = resolveName(element) ?: error("The element is not a vision output") - - if (element.attributes[OUTPUT_RENDERED]?.value == "true") { - logger.info { "VF output in element $element is already rendered" } - return - } else { - logger.info { "Rendering VF output with name $name" } - } - - val outputMeta = element.getEmbeddedData(VisionTagConsumer.OUTPUT_META_CLASS)?.let { - VisionManager.defaultJson.decodeFromString(MetaSerializer, it) - } ?: Meta.EMPTY - - //Trying to render embedded vision - val embeddedVision = element.getEmbeddedData(VisionTagConsumer.OUTPUT_DATA_CLASS)?.let { - visionManager.decodeFromString(it) - } - - when { - embeddedVision != null -> { - logger.info { "Found embedded vision for output with name $name" } - renderVision(name, element, embeddedVision, outputMeta) - } - element.attributes[OUTPUT_FETCH_ATTRIBUTE] != null -> { - val attr = element.attributes[OUTPUT_FETCH_ATTRIBUTE]!! - - val fetchUrl = if (attr.value.isBlank() || attr.value == VisionTagConsumer.AUTO_DATA_ATTRIBUTE) { - val endpoint = resolveEndpoint(element) - logger.info { "Vision server is resolved to $endpoint" } - URL(endpoint).apply { - pathname += "/data" - } - } else { - URL(attr.value) - }.apply { - searchParams.append("name", name) - } - - logger.info { "Fetching vision data from $fetchUrl" } - window.fetch(fetchUrl).then { response -> - if (response.ok) { - response.text().then { text -> - val vision = visionManager.decodeFromString(text) - renderVision(name, element, vision, outputMeta) - } - } else { - logger.error { "Failed to fetch initial vision state from $fetchUrl" } - } - } - } - else -> error("No embedded vision data / fetch url for $name") - } - element.setAttribute(OUTPUT_RENDERED, "true") - } - - override fun content(target: String): Map = if (target == ElementVisionRenderer.TYPE) mapOf( - numberVisionRenderer.name to numberVisionRenderer, - textVisionRenderer.name to textVisionRenderer, - formVisionRenderer.name to formVisionRenderer - ) else super.content(target) - - public companion object : PluginFactory { - - override fun invoke(meta: Meta, context: Context): VisionClient = VisionClient() - - override val tag: PluginTag = PluginTag(name = "vision.client", group = PluginTag.DATAFORGE_GROUP) - - override val type: KClass = VisionClient::class - } -} - - -private fun whenDocumentLoaded(block: Document.() -> Unit): Unit { - if (document.readyState == DocumentReadyState.COMPLETE) { - block(document) - } else { - document.addEventListener("DOMContentLoaded", { block(document) }) - } -} - -/** - * Fetch and render visions for all elements with [VisionTagConsumer.OUTPUT_CLASS] class inside given [element]. - */ -public fun VisionClient.renderAllVisionsIn(element: Element) { - val elements = element.getElementsByClassName(VisionTagConsumer.OUTPUT_CLASS) - console.info("Finished search for outputs. Found ${elements.length} items") - elements.asList().forEach { child -> - renderVisionIn(child) - } -} - -/** - * Render all visions in an element with a given [id] - */ -public fun VisionClient.renderAllVisionsById(id: String): Unit = whenDocumentLoaded { - val element = getElementById(id) - if (element != null) { - renderAllVisionsIn(element) - } else { - console.warn("Element with id $id not found") - } -} - - -/** - * Fetch visions from the server for all elements with [VisionTagConsumer.OUTPUT_CLASS] class in the document body - */ -public fun VisionClient.renderAllVisions(): Unit = whenDocumentLoaded { - val element = body ?: error("Document does not have a body") - renderAllVisionsIn(element) -} - -/** - * Create a vision client context and render all visions on the page. - */ -public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) { - console.info("Starting VisionForge context") - val context = Context("VisionForge", contextBuilder) - val visionClient = context.fetch(VisionClient) - window.asDynamic()[RENDER_FUNCTION_NAME] = visionClient::renderAllVisionsById - - //visionClient.renderAllVisions() -} \ No newline at end of file diff --git a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt index c6d87b19..e1410752 100644 --- a/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt +++ b/visionforge-core/src/jsMain/kotlin/space/kscience/visionforge/inputRenderers.kt @@ -2,66 +2,181 @@ package space.kscience.visionforge import kotlinx.browser.document import kotlinx.html.InputType +import kotlinx.html.div import kotlinx.html.js.input -import kotlinx.html.js.label -import kotlinx.html.js.onChangeFunction +import org.w3c.dom.HTMLElement import org.w3c.dom.HTMLFormElement import org.w3c.dom.HTMLInputElement +import org.w3c.dom.events.Event import org.w3c.dom.get import org.w3c.xhr.FormData -import space.kscience.dataforge.meta.DynamicMeta -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.valueSequence -import space.kscience.visionforge.html.VisionOfHtmlForm -import space.kscience.visionforge.html.VisionOfNumberField -import space.kscience.visionforge.html.VisionOfTextField +import space.kscience.dataforge.context.debug +import space.kscience.dataforge.context.logger +import space.kscience.dataforge.meta.* +import space.kscience.visionforge.html.* -public val textVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> - val name = vision.name ?: "input[${vision.hashCode().toUInt()}]" - vision.label?.let { - label { - htmlFor = name - +it - } - } - input { - type = InputType.text - this.name = name - vision.useProperty(VisionOfTextField::text) { - value = it ?: "" - } - onChangeFunction = { - vision.text = value - } +/** + * Subscribes the HTML element to a given vision. + * + * @param vision The vision to subscribe to. + */ +private fun HTMLElement.subscribeToVision(vision: VisionOfHtml) { + vision.useProperty(VisionOfHtml::classes) { + classList.value = classes.joinToString(separator = " ") } } -public val numberVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> - val name = vision.name ?: "input[${vision.hashCode().toUInt()}]" - vision.label?.let { - label { - htmlFor = name - +it - } - } - input { - type = InputType.text - this.name = name - vision.useProperty(VisionOfNumberField::value) { - value = it?.toDouble() ?: 0.0 - } - onChangeFunction = { - vision.value = value.toDoubleOrNull() - } + +/** + * Subscribes the HTML input element to a given vision. + * + * @param inputVision The input vision to subscribe to. + */ +private fun HTMLInputElement.subscribeToInput(inputVision: VisionOfHtmlInput) { + subscribeToVision(inputVision) + inputVision.useProperty(VisionOfHtmlInput::disabled) { + disabled = it } } +internal val htmlVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + div {}.also { div -> + div.subscribeToVision(vision) + vision.useProperty(VisionOfPlainHtml::content) { + div.textContent = it + } + } + } + +internal val inputVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer(acceptRating = ElementVisionRenderer.DEFAULT_RATING - 1) { _, vision, _ -> + input { + type = InputType.text + }.also { htmlInputElement -> + val onEvent: (Event) -> Unit = { + vision.value = htmlInputElement.value.asValue() + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent + InputFeedbackMode.NONE -> {} + } + + htmlInputElement.subscribeToInput(vision) + vision.useProperty(VisionOfHtmlInput::value) { + htmlInputElement.value = it?.string ?: "" + } + } + } + +internal val checkboxVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.checkBox + }.also { htmlInputElement -> + val onEvent: (Event) -> Unit = { + vision.checked = htmlInputElement.checked + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent + InputFeedbackMode.NONE -> {} + } + + htmlInputElement.subscribeToInput(vision) + vision.useProperty(VisionOfCheckbox::checked) { + htmlInputElement.checked = it ?: false + } + } + } + +internal val textVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.text + }.also { htmlInputElement -> + val onEvent: (Event) -> Unit = { + vision.text = htmlInputElement.value + } + + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent + InputFeedbackMode.NONE -> {} + } + + htmlInputElement.subscribeToInput(vision) + vision.useProperty(VisionOfTextField::text) { + htmlInputElement.value = it ?: "" + } + } + } + +internal val numberVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.text + }.also { htmlInputElement -> + + val onEvent: (Event) -> Unit = { + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } + } + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent + InputFeedbackMode.NONE -> {} + } + htmlInputElement.subscribeToInput(vision) + vision.useProperty(VisionOfNumberField::value) { + htmlInputElement.valueAsNumber = it?.double ?: 0.0 + } + } + } + +internal val rangeVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> + input { + type = InputType.text + min = vision.min.toString() + max = vision.max.toString() + step = vision.step.toString() + }.also { htmlInputElement -> + + val onEvent: (Event) -> Unit = { + htmlInputElement.value.toDoubleOrNull()?.let { vision.number = it } + } + + when (vision.feedbackMode) { + InputFeedbackMode.ONCHANGE -> htmlInputElement.onchange = onEvent + + InputFeedbackMode.ONINPUT -> htmlInputElement.oninput = onEvent + InputFeedbackMode.NONE -> {} + } + htmlInputElement.subscribeToInput(vision) + vision.useProperty(VisionOfRangeField::value) { + htmlInputElement.valueAsNumber = it?.double ?: 0.0 + } + } + } + internal fun FormData.toMeta(): Meta { @Suppress("UNUSED_VARIABLE") val formData = this //val res = js("Object.fromEntries(formData);") val `object` = js("{}") //language=JavaScript - js(""" + js( + """ formData.forEach(function(value, key){ // Reflect.has in favor of: object.hasOwnProperty(key) if(!Reflect.has(object, key)){ @@ -73,29 +188,34 @@ internal fun FormData.toMeta(): Meta { } object[key].push(value); }); - """) + """ + ) return DynamicMeta(`object`) } -public val formVisionRenderer: ElementVisionRenderer = ElementVisionRenderer { vision, _ -> +internal val formVisionRenderer: ElementVisionRenderer = + ElementVisionRenderer { _, vision, _ -> - val form = document.getElementById(vision.formId) as? HTMLFormElement - ?: error("An element with id = '${vision.formId} is not a form") + val form = document.getElementById(vision.formId) as? HTMLFormElement + ?: error("An element with id = '${vision.formId} is not a form") - console.info("Adding hooks to form '$form'") + form.subscribeToVision(vision) - vision.useProperty(VisionOfHtmlForm::values) { values -> - val inputs = form.getElementsByTagName("input") - values?.valueSequence()?.forEach { (token, value) -> - (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() + vision.manager?.logger?.debug { "Adding hooks to form with id = '$vision.formId'" } + + vision.useProperty(VisionOfHtmlForm::values) { values -> + vision.manager?.logger?.debug { "Updating form '${vision.formId}' with values $values" } + val inputs = form.getElementsByTagName("input") + values?.valueSequence()?.forEach { (token, value) -> + (inputs[token.toString()] as? HTMLInputElement)?.value = value.toString() + } } - } - form.onsubmit = { event -> - event.preventDefault() - val formData = FormData(form).toMeta() - //console.log(formData.toString()) - vision.values = formData - false - } -} \ No newline at end of file + form.onsubmit = { event -> + event.preventDefault() + val formData = FormData(form).toMeta() + vision.values = formData + console.info("Sent: ${formData.toMap()}") + false + } + } \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt new file mode 100644 index 00000000..fc8fed09 --- /dev/null +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/JvmSynchronized.kt @@ -0,0 +1,3 @@ +package space.kscience.visionforge + +public actual typealias JvmSynchronized = Synchronized \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt new file mode 100644 index 00000000..3796d436 --- /dev/null +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/HtmlVisionContext.kt @@ -0,0 +1,95 @@ +package space.kscience.visionforge.html + +import kotlinx.html.* +import space.kscience.dataforge.context.ContextAware +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.MetaSerializer +import space.kscience.dataforge.meta.isEmpty +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.NameToken +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.parseAsName +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.VisionTagConsumer.Companion.DEFAULT_VISION_NAME +import space.kscience.visionforge.setAsRoot +import space.kscience.visionforge.visionManager + +/** + * Rendering context for visions in HTML + */ +public interface HtmlVisionContext : ContextAware { + + /** + * Generate div id for vision div tag + */ + public fun generateId(name: Name): String = "vision[$name]" + + /** + * Render vision at given [DIV] + */ + public fun DIV.renderVision(name: Name, vision: Vision, outputMeta: Meta) +} + + +public typealias HtmlVisionContextFragment = context(HtmlVisionContext) TagConsumer<*>.() -> Unit + +//context(HtmlVisionContext) +//public fun HtmlVisionFragment( +// content: TagConsumer<*>.() -> Unit, +//): HtmlVisionFragment = HtmlVisionFragment { } + +context(HtmlVisionContext) +private fun TagConsumer.vision( + visionManager: VisionManager, + name: Name, + vision: Vision, + outputMeta: Meta = Meta.EMPTY, +): T = div { + id = generateId(name) + classes = setOf(VisionTagConsumer.OUTPUT_CLASS) + vision.setAsRoot(visionManager) + attributes[VisionTagConsumer.OUTPUT_NAME_ATTRIBUTE] = name.toString() + if (!outputMeta.isEmpty()) { + //Hard-code output configuration + script { + attributes["class"] = VisionTagConsumer.OUTPUT_META_CLASS + unsafe { + +visionManager.jsonFormat.encodeToString(MetaSerializer, outputMeta) + } + } + } + renderVision(name, vision, outputMeta) +} + +context(HtmlVisionContext) +private fun TagConsumer.vision( + name: Name, + vision: Vision, + outputMeta: Meta = Meta.EMPTY, +): T = vision(context.visionManager, name, vision, outputMeta) + +/** + * Insert a vision in this HTML. + */ +context(HtmlVisionContext) +@VisionDSL +public fun TagConsumer.vision( + name: Name? = null, + visionProvider: VisionOutput.() -> Vision, +): T { + val actualName = name ?: NameToken(DEFAULT_VISION_NAME, visionProvider.hashCode().toUInt().toString()).asName() + val output = VisionOutput(context, actualName) + val vision = output.visionProvider() + return vision(output.visionManager, actualName, vision, output.meta) +} + +/** + * Insert a vision in this HTML. + */ +context(HtmlVisionContext) +@VisionDSL +public fun TagConsumer.vision( + name: String?, + visionProvider: VisionOutput.() -> Vision, +): T = vision(name?.parseAsName(), visionProvider) \ No newline at end of file diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt index d8be2a39..bf880e84 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/headers.kt @@ -4,12 +4,10 @@ import kotlinx.html.link import kotlinx.html.script import kotlinx.html.unsafe import org.slf4j.LoggerFactory -import space.kscience.visionforge.VisionManager import java.nio.file.Files import java.nio.file.Path import java.nio.file.StandardOpenOption import java.security.MessageDigest -import kotlin.io.path.ExperimentalPathApi import kotlin.io.path.readText @@ -47,15 +45,14 @@ private fun ByteArray.toHexString() = asUByteArray().joinToString("") { it.toStr * Check if the asset exists in given local location and put it there if it does not * @param */ -@OptIn(ExperimentalPathApi::class) -internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): Path { +internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String, classLoader: ClassLoader): Path { val logger = LoggerFactory.getLogger("") logger.info("Resolving or storing resource file $resource") val fullPath = htmlPath.resolveSibling(filePath).toAbsolutePath().resolve(resource) logger.debug("Full path to resource file $resource: $fullPath") - val bytes = VisionManager.Companion::class.java.getResourceAsStream("/$resource")?.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)?.readAllBytes() ?: error("Resource $resource not found on classpath") val md = MessageDigest.getInstance("MD5") @@ -66,8 +63,20 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): if (!skip) { logger.debug("File $fullPath does not exist or wrong checksum. Writing file") Files.createDirectories(fullPath.parent) - Files.write(fullPath, bytes, StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) - Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE) + Files.write( + fullPath, + bytes, + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) + Files.write( + md5File, + checksum.encodeToByteArray(), + StandardOpenOption.CREATE, + StandardOpenOption.TRUNCATE_EXISTING, + StandardOpenOption.WRITE + ) } return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) { @@ -82,18 +91,18 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String): */ internal fun fileScriptHeader( path: Path, -): HtmlFragment = { +): HtmlFragment = HtmlFragment{ script { type = "text/javascript" src = path.toString() } } -internal fun embedScriptHeader(resource: String): HtmlFragment = { +internal fun embedScriptHeader(resource: String, classLoader: ClassLoader): HtmlFragment = HtmlFragment{ script { type = "text/javascript" unsafe { - val bytes = VisionManager::class.java.getResourceAsStream("/$resource")!!.readAllBytes() + val bytes = classLoader.getResourceAsStream(resource)!!.readAllBytes() +bytes.toString(Charsets.UTF_8) } } @@ -103,8 +112,9 @@ internal fun fileCssHeader( basePath: Path, cssPath: Path, resource: String, -): HtmlFragment = { - val relativePath = checkOrStoreFile(basePath, cssPath, resource) + classLoader: ClassLoader, +): HtmlFragment = HtmlFragment{ + val relativePath = checkOrStoreFile(basePath, cssPath, resource, classLoader) link { rel = "stylesheet" href = relativePath.toString() @@ -114,26 +124,30 @@ internal fun fileCssHeader( /** * Make a script header from a resource file, automatically copying file to appropriate location */ -public fun Page.Companion.importScriptHeader( +public fun VisionPage.Companion.importScriptHeader( scriptResource: String, resourceLocation: ResourceLocation, htmlPath: Path? = null, + classLoader: ClassLoader = Thread.currentThread().contextClassLoader, ): HtmlFragment { val targetPath = when (resourceLocation) { ResourceLocation.LOCAL -> checkOrStoreFile( htmlPath ?: Path.of("."), Path.of(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, + classLoader ) + ResourceLocation.SYSTEM -> checkOrStoreFile( Path.of("."), Path.of(System.getProperty("user.home")).resolve(VISIONFORGE_ASSETS_PATH), - scriptResource + scriptResource, classLoader ) + ResourceLocation.EMBED -> null } return if (targetPath == null) { - embedScriptHeader(scriptResource) + embedScriptHeader(scriptResource, classLoader) } else { fileScriptHeader(targetPath) } diff --git a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt index 63f405c3..e45dd9b5 100644 --- a/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt +++ b/visionforge-core/src/jvmMain/kotlin/space/kscience/visionforge/html/htmlExport.kt @@ -1,9 +1,12 @@ -package space.kscience.visionforge +package space.kscience.visionforge.html +import kotlinx.html.body +import kotlinx.html.head +import kotlinx.html.meta import kotlinx.html.stream.createHTML +import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.html.HtmlFragment -import space.kscience.visionforge.html.Page +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Files import java.nio.file.Path @@ -54,26 +57,41 @@ import java.nio.file.Path // } //} +/** + * Export a [VisionPage] to a file + * + * @param fileHeaders additional file system specific headers. + */ @DFExperimental -public fun Page.makeFile( +public fun VisionPage.makeFile( path: Path?, - defaultHeaders: ((Path) -> Map)? = null, + fileHeaders: ((Path) -> Map)? = null, ): Path { - val actualFile = path?.let { - Path.of(System.getProperty("user.home")).resolve(path) - } ?: Files.createTempFile("tempPlot", ".html") + val actualFile = path ?: Files.createTempFile("tempPlot", ".html") - val actualDefaultHeaders = defaultHeaders?.invoke(actualFile) - val actualPage = if (actualDefaultHeaders == null) this else copy(headers = actualDefaultHeaders + headers) + val actualDefaultHeaders = fileHeaders?.invoke(actualFile) + val actualHeaders = if (actualDefaultHeaders == null) pageHeaders else actualDefaultHeaders + pageHeaders - val htmlString = actualPage.render(createHTML()) + val htmlString = createHTML().apply { + head { + meta { + charset = "utf-8" + } + actualHeaders.values.forEach { + appendFragment(it) + } + } + body { + visionFragment(Global.visionManager, fragment = content) + } + }.finalize() Files.writeString(actualFile, htmlString) return actualFile } @DFExperimental -public fun Page.show(path: Path? = null) { +public fun VisionPage.show(path: Path? = null) { val actualPath = makeFile(path) Desktop.getDesktop().browse(actualPath.toFile().toURI()) } \ No newline at end of file diff --git a/visionforge-fx/build.gradle.kts b/visionforge-fx/build.gradle.kts index 26fa13c8..464c7af3 100644 --- a/visionforge-fx/build.gradle.kts +++ b/visionforge-fx/build.gradle.kts @@ -1,12 +1,12 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") } val dataforgeVersion: String by rootProject.extra val fxVersion: String by rootProject.extra kscience{ - useFx(ru.mipt.npm.gradle.FXModule.CONTROLS, version = fxVersion) + useFx(space.kscience.gradle.FXModule.CONTROLS, version = fxVersion) } dependencies { @@ -15,12 +15,12 @@ dependencies { api("org.fxyz3d:fxyz3d:0.5.4") { exclude(module = "slf4j-simple") } - api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${ru.mipt.npm.gradle.KScienceVersions.coroutinesVersion}") + api("org.jetbrains.kotlinx:kotlinx-coroutines-javafx:${space.kscience.gradle.KScienceVersions.coroutinesVersion}") implementation("eu.mihosoft.vrl.jcsg:jcsg:0.5.7") { exclude(module = "slf4j-simple") } } readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt index c571059c..4edc4f13 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/FXPlugin.kt @@ -95,8 +95,9 @@ public class FXPlugin(meta: Meta = Meta.EMPTY) : AbstractPlugin(meta) { public companion object : PluginFactory { override val type: KClass = FXPlugin::class override val tag: PluginTag = PluginTag("vis.fx", group = PluginTag.DATAFORGE_GROUP) - override fun invoke(meta: Meta, context: Context): FXPlugin = - FXPlugin(meta) + + override fun build(context: Context, meta: Meta): FXPlugin = FXPlugin(meta) + } } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt index 442c299f..1161d5bf 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ColorValueChooser.kt @@ -3,13 +3,9 @@ package space.kscience.visionforge.editor import javafx.scene.control.ColorPicker import javafx.scene.paint.Color import org.slf4j.LoggerFactory -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.string import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt index a99599ee..a4c4e583 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ComboBoxValueChooser.kt @@ -8,14 +8,10 @@ package space.kscience.visionforge.editor import javafx.collections.FXCollections import javafx.scene.control.ComboBox import javafx.util.StringConverter -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.allowedValues -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.parseValue -import space.kscience.dataforge.values.string import java.util.* public class ComboBoxValueChooser(public val values: Collection? = null) : ValueChooserBase>() { diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt index 7d8e71b2..8c3d2584 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/FXMetaModel.kt @@ -5,14 +5,10 @@ import javafx.beans.binding.BooleanBinding import javafx.beans.binding.ListBinding import javafx.beans.binding.ObjectBinding import javafx.collections.ObservableList -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.ObservableMeta -import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.meta.get import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt index 4563ade5..144b018e 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/MetaViewer.kt @@ -21,7 +21,7 @@ import javafx.scene.control.TreeSortMode import javafx.scene.control.TreeTableView import javafx.scene.layout.BorderPane import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.string import space.kscience.visionforge.dfIconView import tornadofx.* diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt index 9a1840ce..fd86ec72 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/TextValueChooser.kt @@ -9,11 +9,10 @@ import javafx.beans.value.ObservableValue import javafx.scene.control.TextField import javafx.scene.input.KeyCode import javafx.scene.input.KeyEvent -import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.validate import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.* import tornadofx.* public class TextValueChooser : ValueChooserBase() { diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt index a4e72871..c6d654f5 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueCallback.kt @@ -5,7 +5,7 @@ */ package space.kscience.visionforge.editor -import space.kscience.dataforge.values.Value +import space.kscience.dataforge.meta.Value /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt index f62513b0..ea43547c 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooser.kt @@ -10,14 +10,14 @@ import javafx.beans.value.ObservableValue import javafx.scene.Node import space.kscience.dataforge.context.Context import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.Null +import space.kscience.dataforge.meta.Value import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.allowedValues import space.kscience.dataforge.meta.descriptors.validate import space.kscience.dataforge.misc.Named import space.kscience.dataforge.misc.Type import space.kscience.dataforge.names.Name -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value import space.kscience.visionforge.widget import space.kscience.visionforge.widgetType import tornadofx.* diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt index e9b61886..a9adae8f 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/ValueChooserBase.kt @@ -8,9 +8,9 @@ package space.kscience.visionforge.editor import javafx.beans.property.SimpleObjectProperty import javafx.scene.Node import org.slf4j.LoggerFactory +import space.kscience.dataforge.meta.Null +import space.kscience.dataforge.meta.Value import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value import tornadofx.* /** diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt index bf1033ba..0fcc45f3 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionEditorFragment.kt @@ -6,12 +6,11 @@ import javafx.scene.Node import javafx.scene.Parent import javafx.scene.layout.VBox import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperties import space.kscience.visionforge.getStyle +import space.kscience.visionforge.root import space.kscience.visionforge.styles import tornadofx.* @@ -21,8 +20,8 @@ public class VisionEditorFragment : Fragment() { public var vision: Vision? by visionProperty public val descriptorProperty: SimpleObjectProperty = SimpleObjectProperty() - private val configProperty: Binding = visionProperty.objectBinding { vision -> - vision?.meta + private val configProperty: Binding = visionProperty.objectBinding { vision -> + vision?.properties?.root() } private val configEditorProperty: Binding = configProperty.objectBinding(descriptorProperty) { @@ -30,7 +29,7 @@ public class VisionEditorFragment : Fragment() { val node:FXMetaModel = FXMetaModel( meta, vision?.descriptor, - vision?.computeProperties(), + vision?.properties?.root(), Name.EMPTY, "Vision properties" ) diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt index 335b5a69..c0c1dfa4 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/editor/VisionTreeFragment.kt @@ -5,17 +5,17 @@ import javafx.scene.control.SelectionMode import javafx.scene.control.TreeItem import javafx.scene.layout.VBox import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionGroup +import space.kscience.visionforge.solid.SolidGroup import tornadofx.* private fun toTreeItem(vision: Vision, title: String): TreeItem> { return object : TreeItem>(title to vision) { init { - if (vision is VisionGroup) { + if (vision is SolidGroup) { //lazy populate the tree expandedProperty().onChange { expanded -> if (expanded && children.isEmpty()) { - children.setAll(vision.children.map { + children.setAll(vision.items.map { toTreeItem(it.value, it.key.toString()) }) } @@ -24,7 +24,7 @@ private fun toTreeItem(vision: Vision, title: String): TreeItem referenceFactory(obj, binding) + is SolidReference -> referenceFactory(obj, binding) is SolidGroup -> { - Group(obj.children.mapNotNull { (token, obj) -> + Group(obj.items.mapNotNull { (token, obj) -> (obj as? Solid)?.let { logger.info { token.toString() } buildNode(it).apply { @@ -77,7 +76,7 @@ public class FX3DPlugin : AbstractPlugin() { is PolyLine -> PolyLine3D( obj.points.map { Point3D(it.x, it.y, it.z) }, obj.thickness.toFloat(), - obj.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.color() + obj.properties.getProperty(SolidMaterial.MATERIAL_COLOR_KEY).color() ).apply { this.meshView.cullFace = CullFace.FRONT } @@ -98,6 +97,8 @@ public class FX3DPlugin : AbstractPlugin() { scaleYProperty().bind(binding[Solid.Y_SCALE_KEY].float(obj.scaleY.toFloat())) scaleZProperty().bind(binding[Solid.Z_SCALE_KEY].float(obj.scaleZ.toFloat())) + if(obj.quaternion!= null) TODO("Quaternion support not implemented") + val rotateX = Rotate(0.0, Rotate.X_AXIS).apply { angleProperty().bind(binding[Solid.X_ROTATION_KEY].float(obj.rotationX.toFloat()).multiply(180.0 / PI)) } @@ -138,7 +139,8 @@ public class FX3DPlugin : AbstractPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.fx3D", PluginTag.DATAFORGE_GROUP) override val type: KClass = FX3DPlugin::class - override fun invoke(meta: Meta, context: Context): FX3DPlugin = FX3DPlugin() + + override fun build(context: Context, meta: Meta): FX3DPlugin = FX3DPlugin() } } @@ -150,7 +152,7 @@ public interface FX3DFactory { public val type: KClass - public operator fun invoke(obj: T, binding: VisualObjectFXBinding): Node + public operator fun invoke(obj: T, binding: VisionFXBinding): Node public companion object { public const val TYPE: String = "fx3DFactory" diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt index 588f15cf..2e07527a 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXCompositeFactory.kt @@ -42,7 +42,7 @@ public class FXCompositeFactory(public val plugin: FX3DPlugin) : FX3DFactory get() = Composite::class - override fun invoke(obj: Composite, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: Composite, binding: VisionFXBinding): Node { val first = plugin.buildNode(obj.first) as? MeshView ?: error("Can't build node") val second = plugin.buildNode(obj.second) as? MeshView ?: error("Can't build node") val firstCSG = first.toCSG() diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt index 7bc44207..ddb342b0 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXConvexFactory.kt @@ -10,7 +10,7 @@ import kotlin.reflect.KClass public object FXConvexFactory : FX3DFactory { override val type: KClass get() = Convex::class - override fun invoke(obj: Convex, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: Convex, binding: VisionFXBinding): Node { val hull = HullUtil.hull( obj.points.map { Vector3d.xyz(it.x.toDouble(), it.y.toDouble(), it.z.toDouble()) }, PropertyStorage() diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt index ca5e6583..81bbad5b 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXMaterials.kt @@ -3,13 +3,7 @@ package space.kscience.visionforge.solid import javafx.scene.paint.Color import javafx.scene.paint.Material import javafx.scene.paint.PhongMaterial -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.double -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.int -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.int -import space.kscience.dataforge.values.string +import space.kscience.dataforge.meta.* import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.FXMaterials.GREY diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt index af00f7c5..a75771cb 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXReferenceFactory.kt @@ -8,20 +8,23 @@ import space.kscience.dataforge.names.firstOrNull import space.kscience.dataforge.names.isEmpty import space.kscience.visionforge.Vision import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX import kotlin.reflect.KClass -public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { - override val type: KClass get() = SolidReferenceGroup::class +public class FXReferenceFactory(public val plugin: FX3DPlugin) : FX3DFactory { + override val type: KClass get() = SolidReference::class - override fun invoke(obj: SolidReferenceGroup, binding: VisualObjectFXBinding): Node { + override fun invoke(obj: SolidReference, binding: VisionFXBinding): Node { val prototype = obj.prototype val node = plugin.buildNode(prototype) - obj.onPropertyChange { name-> - if (name.firstOrNull()?.body == SolidReferenceGroup.REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") + obj.onPropertyChange { name -> + if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") val propertyName = name.cutFirst() - val referenceChild = obj[childName] ?: error("Reference child with name '$childName' not found") + val referenceChild = + obj.children.getChild(childName) ?: error("Reference child with name '$childName' not found") val child = node.findChild(childName) ?: error("Object child with name '$childName' not found") child.updateProperty(referenceChild, propertyName) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt index 116075ce..d4d58db1 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/FXShapeFactory.kt @@ -11,7 +11,7 @@ import kotlin.reflect.KClass public object FXShapeFactory : FX3DFactory { override val type: KClass get() = GeometrySolid::class - override fun invoke(obj: GeometrySolid, binding: VisualObjectFXBinding): MeshView { + override fun invoke(obj: GeometrySolid, binding: VisionFXBinding): MeshView { val mesh = FXGeometryBuilder().apply { obj.toGeometry(this) }.build() return MeshView(mesh) } diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt index 2fe573e0..9c4ab664 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/OrbitControls.kt @@ -17,7 +17,7 @@ import kotlin.math.PI import kotlin.math.cos import kotlin.math.max import kotlin.math.sin -import space.kscience.visionforge.solid.specifications.Camera as CameraSpec +import space.kscience.visionforge.solid.specifications.CameraScheme as CameraSpec public class OrbitControls internal constructor(camera: Camera, canvas: SubScene, spec: CameraSpec) { diff --git a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt similarity index 88% rename from visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt rename to visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt index 607913d7..cc4f3637 100644 --- a/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisualObjectFXBinding.kt +++ b/visionforge-fx/src/main/kotlin/space/kscience/visionforge/solid/VisionFXBinding.kt @@ -5,16 +5,14 @@ import javafx.beans.binding.* import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.Value import space.kscience.visionforge.Vision -import space.kscience.visionforge.computePropertyNode import space.kscience.visionforge.onPropertyChange import tornadofx.* /** * A caching binding collection for [Vision] properties */ -public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { +public class VisionFXBinding(public val fx: FX3DPlugin, public val obj: Vision) { private val bindings = HashMap>() init { @@ -36,7 +34,7 @@ public class VisualObjectFXBinding(public val fx: FX3DPlugin, public val obj: Vi public operator fun get(key: Name): ObjectBinding { return bindings.getOrPut(key) { object : ObjectBinding() { - override fun computeValue(): Meta? = obj.computePropertyNode(key) + override fun computeValue(): Meta = obj.properties.getProperty(key) } } } @@ -58,4 +56,5 @@ public fun ObjectBinding.float(default: Float): FloatBinding = floatBindi public fun ObjectBinding.int(default: Int): IntegerBinding = integerBinding { it.int ?: default } public fun ObjectBinding.long(default: Long): LongBinding = longBinding { it.long ?: default } -public fun ObjectBinding.transform(transform: (Meta) -> T): Binding = objectBinding { it?.let(transform) } +public fun ObjectBinding.transform(transform: (Meta) -> T): Binding = + objectBinding { it?.let(transform) } diff --git a/visionforge-gdml/build.gradle.kts b/visionforge-gdml/build.gradle.kts index bfe711c8..cdf4ad47 100644 --- a/visionforge-gdml/build.gradle.kts +++ b/visionforge-gdml/build.gradle.kts @@ -1,17 +1,17 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } -kotlin { - js{ +kscience { + jvm() + js { binaries.library() } - sourceSets { - commonMain{ - dependencies { - api(projects.visionforgeSolid) - api("space.kscience:gdml:0.4.0") - } - } + dependencies { + api(projects.visionforgeSolid) + api("space.kscience:gdml:0.5.0") + } + dependencies(jvmTest) { + implementation(spclibs.logback.classic) } } \ No newline at end of file diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt index 442cde3c..2d3c18c9 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/GdmlLoaderOptions.kt @@ -4,9 +4,7 @@ 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.solid.* import space.kscience.visionforge.useStyle import kotlin.random.Random @@ -30,7 +28,7 @@ public class GdmlLoaderOptions { styleCache.getOrPut(Name.parse(name)) { Meta(builder) } - useStyle(name) + useStyle(name, false) } public fun Solid.transparent() { @@ -70,7 +68,7 @@ public class GdmlLoaderOptions { } private set - public fun configure(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) { + public fun solids(block: Solid.(parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial) -> Unit) { val oldConfigure = configureSolid configureSolid = { parent: GdmlVolume, solid: GdmlSolid, material: GdmlMaterial -> oldConfigure(parent, solid, material) @@ -79,6 +77,8 @@ public class GdmlLoaderOptions { } + public var light: LightSource? = AmbientLightSource() + public companion object { private val random: Random = Random(222) diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt index f80a5511..0c81d258 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/gdmlLoader.kt @@ -6,6 +6,7 @@ import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus import space.kscience.gdml.* +import space.kscience.kmath.geometry.RotationOrder import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.solid.* @@ -27,13 +28,13 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { /** * A special group for local templates */ - private val proto = SolidGroup() + private val templates = SolidGroup() - private val solids = proto.group(solidsName) { - setPropertyNode("edges.enabled", false) + private val solids = templates.solidGroup(solidsName) { + edges(false) } - private val referenceStore = HashMap>() + private val referenceStore = HashMap>() fun Solid.configureSolid(root: Gdml, parent: GdmlVolume, solid: GdmlSolid) { val material = parent.materialref.resolve(root) ?: GdmlElement(parent.materialref.ref) @@ -44,9 +45,9 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } - private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReferenceGroup { + private fun proxySolid(root: Gdml, group: SolidGroup, solid: GdmlSolid, name: String): SolidReference { val templateName = solidsName + name - if (proto[templateName] == null) { + if (templates[templateName] == null) { solids.addSolid(root, solid, name) } val ref = group.ref(templateName, name) @@ -59,10 +60,10 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { group: SolidGroup, physVolume: GdmlPhysVolume, volume: GdmlGroup, - ): SolidReferenceGroup { + ): SolidReference { val templateName = volumesName + volume.name.asName() - if (proto[templateName] == null) { - proto[templateName] = volume(root, volume) + if (templates[templateName] == null) { + templates.setChild(templateName, volume(root, volume)) } val ref = group.ref(templateName, physVolume.name).withPosition(root, physVolume) referenceStore.getOrPut(templateName) { ArrayList() }.add(ref) @@ -139,6 +140,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { angle = solid.deltaphi * aScale, name = name ) + is GdmlCone -> if (solid.rmin1.toDouble() == 0.0 && solid.rmin2.toDouble() == 0.0) { cone( bottomRadius = solid.rmax1 * lScale, @@ -160,6 +162,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { name = name ) } + is GdmlXtru -> extruded(name) { shape { solid.vertices.forEach { @@ -175,6 +178,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { ) } } + is GdmlScaledSolid -> { //Add solid with modified scale val innerSolid: GdmlSolid = solid.solidref.resolve(root) @@ -186,6 +190,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { scaleZ = solid.scale.z.toFloat() } } + is GdmlSphere -> sphereLayer( outerRadius = solid.rmax * lScale, innerRadius = solid.rmin * lScale, @@ -195,15 +200,16 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { thetaStart = solid.starttheta * aScale, name = name, ) + is GdmlOrb -> sphere(solid.r * lScale, name = name) is GdmlPolyhedra -> extruded(name) { //getting the radius of first require(solid.planes.size > 1) { "The polyhedron geometry requires at least two planes" } val baseRadius = solid.planes.first().rmax * lScale shape { - (0..solid.numsides).forEach { + (0.. @@ -211,6 +217,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { layer(plane.z * lScale, scale = plane.rmax * lScale / baseRadius) } } + is GdmlBoolSolid -> { val first: GdmlSolid = solid.first.resolve(root) ?: error("") val second: GdmlSolid = solid.second.resolve(root) ?: error("") @@ -235,22 +242,24 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } + is GdmlTrapezoid -> { val dxBottom = solid.x1.toDouble() / 2 val dxTop = solid.x2.toDouble() / 2 val dyBottom = solid.y1.toDouble() / 2 val dyTop = solid.y2.toDouble() / 2 val dz = solid.z.toDouble() / 2 - val node1 = Point3D(-dxBottom, -dyBottom, -dz) - val node2 = Point3D(dxBottom, -dyBottom, -dz) - val node3 = Point3D(dxBottom, dyBottom, -dz) - val node4 = Point3D(-dxBottom, dyBottom, -dz) - val node5 = Point3D(-dxTop, -dyTop, dz) - val node6 = Point3D(dxTop, -dyTop, dz) - val node7 = Point3D(dxTop, dyTop, dz) - val node8 = Point3D(-dxTop, dyTop, dz) + val node1 = Float32Vector3D(-dxBottom, -dyBottom, -dz) + val node2 = Float32Vector3D(dxBottom, -dyBottom, -dz) + val node3 = Float32Vector3D(dxBottom, dyBottom, -dz) + val node4 = Float32Vector3D(-dxBottom, dyBottom, -dz) + val node5 = Float32Vector3D(-dxTop, -dyTop, dz) + val node6 = Float32Vector3D(dxTop, -dyTop, dz) + val node7 = Float32Vector3D(dxTop, dyTop, dz) + val node8 = Float32Vector3D(-dxTop, dyTop, dz) hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name) } + is GdmlEllipsoid -> TODO("Renderer for $solid not supported yet") is GdmlElTube -> TODO("Renderer for $solid not supported yet") is GdmlElCone -> TODO("Renderer for $solid not supported yet") @@ -271,9 +280,11 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { GdmlLoaderOptions.Action.ADD -> { addSolid(root, solid, name) } + GdmlLoaderOptions.Action.PROTOTYPE -> { proxySolid(root, this, solid, name ?: solid.name) } + GdmlLoaderOptions.Action.REJECT -> { //ignore null @@ -302,11 +313,13 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { when (settings.volumeAction(volume)) { GdmlLoaderOptions.Action.ADD -> { val group: SolidGroup = volume(root, volume) - this[physVolume.name] = group.withPosition(root, physVolume) + this.setChild(physVolume.name, group.withPosition(root, physVolume)) } + GdmlLoaderOptions.Action.PROTOTYPE -> { proxyVolume(root, this, physVolume, volume) } + GdmlLoaderOptions.Action.REJECT -> { //ignore } @@ -321,7 +334,7 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { ?: error("Volume with ref ${divisionVolume.volumeref.ref} could not be resolved") //TODO add divisions - set(null, volume(root, volume)) + children.static(volume(root, volume)) } private fun volume( @@ -348,44 +361,45 @@ private class GdmlLoader(val settings: GdmlLoaderOptions) { } } - private fun finalize(final: SolidGroup): SolidGroup { - val rootStyle by final.style("gdml") { + fun transform(root: Gdml): SolidGroup { + val rootSolid = volume(root, root.world.resolve(root) ?: error("GDML root is not resolved")) + + val rootStyle by rootSolid.style("gdml") { Solid.ROTATION_ORDER_KEY put RotationOrder.ZXY } - final.useStyle(rootStyle) - final.prototypes { - proto.children.forEach { (token, item) -> + rootSolid.useStyle(rootStyle, false) + + rootSolid.prototypes { + templates.items.forEach { (token, item) -> item.parent = null - set(token.asName(), item as? Solid) + setChild(token.asName(), item as? Solid) } } settings.styleCache.forEach { - final.styleSheet { + rootSolid.styleSheet { define(it.key.toString(), it.value) } } - return final + return rootSolid } - - fun transform(root: Gdml): SolidGroup = - finalize(volume(root, root.world.resolve(root) ?: error("GDML root is not resolved"))) } public fun Gdml.toVision(block: GdmlLoaderOptions.() -> Unit = {}): SolidGroup { val settings = GdmlLoaderOptions().apply(block) - val context = GdmlLoader(settings) - return context.transform(this) + return GdmlLoader(settings).transform(this).also { + it.children["light"] = settings.light + } } /** * Append Gdml node to the group */ public fun SolidGroup.gdml(gdml: Gdml, key: String? = null, transformer: GdmlLoaderOptions.() -> Unit = {}) { - val visual = gdml.toVision(transformer) + val vision = gdml.toVision(transformer) //println(Visual3DPlugin.json.stringify(VisualGroup3D.serializer(), visual)) - set(key, visual) + children.setChild(key, vision) } @VisionBuilder diff --git a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt index befc69bb..7af53964 100644 --- a/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt +++ b/visionforge-gdml/src/commonMain/kotlin/space/kscience/visionforge/gdml/markLayers.kt @@ -1,15 +1,15 @@ package space.kscience.visionforge.gdml +import space.kscience.dataforge.context.Global import space.kscience.dataforge.context.info import space.kscience.dataforge.context.logger import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken import space.kscience.dataforge.names.length import space.kscience.dataforge.names.plus -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.SolidReferenceGroup +import space.kscience.visionforge.solid.SolidReference import space.kscience.visionforge.solid.layer @@ -23,15 +23,15 @@ private class VisionCounterTree( var selfCount = 1 val children: Map by lazy { - (vision as? VisionGroup)?.children?.mapValues { (key, vision) -> - if (vision is SolidReferenceGroup) { - prototypes.getOrPut(vision.refName) { - VisionCounterTree(vision.refName, vision.prototype, prototypes) + (vision as? SolidGroup)?.items?.mapValues { (key, vision) -> + if (vision is SolidReference) { + prototypes.getOrPut(vision.prototypeName) { + VisionCounterTree(vision.prototypeName, vision.prototype, prototypes) }.apply { selfCount += 1 } } else { - VisionCounterTree(name + key, vision as Solid, prototypes) + VisionCounterTree(name + key, vision, prototypes) } } ?: emptyMap() } @@ -51,10 +51,10 @@ private fun VisionCounterTree.topToBottom(): Sequence = seque } public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000, 50000)) { - val logger = manager?.context?.logger + val logger = manager?.context?.logger ?: Global.logger val counterTree = VisionCounterTree(Name.EMPTY, this, hashMapOf()) val totalCount = counterTree.childrenCount - if (totalCount > thresholds.firstOrNull() ?: 0) { + if (totalCount > (thresholds.firstOrNull() ?: 0)) { val allNodes = counterTree.topToBottom().distinct().toMutableList() //println("tree construction finished") allNodes.sortWith( @@ -77,7 +77,7 @@ public fun SolidGroup.markLayers(thresholds: List = listOf(500, 1000, 20000 node.vision.layer = layerIndex remaining -= node.selfCount * (node.children.size + 1) - logger?.apply { + logger.run { if (node.selfCount > 1) { info { "Prototype with name ${node.name} moved to layer $layerIndex. $remaining nodes remains" } } else { diff --git a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt index 0ca76fd1..aa262c45 100644 --- a/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt +++ b/visionforge-gdml/src/commonTest/kotlin/TestCubes.kt @@ -4,7 +4,7 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.names.Name import space.kscience.gdml.* import space.kscience.visionforge.Vision -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import space.kscience.visionforge.solid.* import space.kscience.visionforge.visionManager import kotlin.test.Test @@ -21,12 +21,12 @@ class TestCubes { @Test fun testCubesDirect() { - val vision = cubes.toVision() + val vision: SolidGroup = cubes.toVision() // println(Solids.encodeToString(vision)) val smallBoxPrototype = vision.getPrototype(Name.parse("solids.smallBox")) as? Box assertNotNull(smallBoxPrototype) assertEquals(30.0, smallBoxPrototype.xSize.toDouble()) - val smallBoxVision = vision["composite-111.smallBox"]?.unref as? Box + val smallBoxVision = vision.children.getChild("composite-111.smallBox")?.prototype as? Box assertNotNull(smallBoxVision) assertEquals(30.0, smallBoxVision.xSize.toDouble()) } @@ -55,7 +55,7 @@ class TestCubes { assertNotNull(this.prototype) } if (this is SolidGroup) { - children.forEach { + items.forEach { it.value.checkPrototypes() } } diff --git a/jupyter/README.md b/visionforge-jupyter/README.md similarity index 100% rename from jupyter/README.md rename to visionforge-jupyter/README.md diff --git a/visionforge-jupyter/build.gradle.kts b/visionforge-jupyter/build.gradle.kts new file mode 100644 index 00000000..49943631 --- /dev/null +++ b/visionforge-jupyter/build.gradle.kts @@ -0,0 +1,26 @@ +plugins { + id("space.kscience.gradle.mpp") +} + +description = "Common visionforge jupyter module" + +kscience { + useKtor() + jvm() + js() + jupyterLibrary() + dependencies { + api(projects.visionforgeCore) + } + dependencies(jvmMain){ + api("io.ktor:ktor-server-cio-jvm") + api("io.ktor:ktor-server-websockets-jvm") + api("io.ktor:ktor-server-cors-jvm") + api(projects.visionforgeServer) + } +} + + +readme { + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL +} \ No newline at end of file diff --git a/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt new file mode 100644 index 00000000..e095485c --- /dev/null +++ b/visionforge-jupyter/src/jsMain/kotlin/VFNotebookClient.kt @@ -0,0 +1,50 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.browser.window +import org.w3c.dom.Document +import org.w3c.dom.Element +import space.kscience.dataforge.context.AbstractPlugin +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.PluginFactory +import space.kscience.dataforge.context.PluginTag +import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.JsVisionClient +import space.kscience.visionforge.renderAllVisions +import space.kscience.visionforge.renderAllVisionsById +import space.kscience.visionforge.renderAllVisionsIn + +@JsExport +public class VFNotebookClient : AbstractPlugin() { + private val client by require(JsVisionClient) + + public fun renderAllVisionsIn(element: Element) { + client.renderAllVisionsIn(element) + } + + public fun renderAllVisionsById(document: Document, id: String) { + client.renderAllVisionsById(document, id) + } + + public fun renderAllVisions() { + client.renderAllVisions() + } + + + init { + console.info("Loading VisionForge global hooks") + //register VisionForge in the browser window + window.parent.asDynamic().vf = this + window.parent.asDynamic().VisionForge = this + } + + @Suppress("NON_EXPORTABLE_TYPE") + override val tag: PluginTag get() = Companion.tag + + @Suppress("NON_EXPORTABLE_TYPE") + public companion object : PluginFactory { + override fun build(context: Context, meta: Meta): VFNotebookClient = VFNotebookClient() + + override val tag: PluginTag = PluginTag(name = "vision.notebook", group = PluginTag.DATAFORGE_GROUP) + } + +} \ No newline at end of file diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt new file mode 100644 index 00000000..49d5fe23 --- /dev/null +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForge.kt @@ -0,0 +1,177 @@ +package space.kscience.visionforge.jupyter + +import io.ktor.http.URLProtocol +import io.ktor.server.application.install +import io.ktor.server.cio.CIO +import io.ktor.server.engine.ApplicationEngine +import io.ktor.server.engine.embeddedServer +import io.ktor.server.util.url +import io.ktor.server.websocket.WebSockets +import kotlinx.coroutines.CoroutineScope +import kotlinx.html.* +import kotlinx.html.stream.createHTML +import org.jetbrains.kotlinx.jupyter.api.* +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware +import space.kscience.dataforge.context.info +import space.kscience.dataforge.context.logger +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.HtmlVisionFragment +import space.kscience.visionforge.html.visionFragment +import space.kscience.visionforge.server.VisionRoute +import space.kscience.visionforge.server.serveVisionData +import kotlin.coroutines.CoroutineContext +import kotlin.random.Random +import kotlin.random.nextUInt + + +@Suppress("FunctionName") +internal inline fun HTML(isolated: Boolean = false, block: TagConsumer<*>.() -> Unit): MimeTypedResult = + HTML(createHTML().apply(block).finalize(), isolated) + +internal fun KotlinKernelHost.displayHtml(block: TagConsumer<*>.() -> Unit) { + display(HTML(false, block), null) +} + +public enum class VisionForgeCompatibility { + JUPYTER, + JUPYTER_LAB, + DATALORE, + IDEA +} + +/** + * A handler class that includes a server and common utilities + */ +@Suppress("ExtractKtorModule") +public class VisionForge( + public val visionManager: VisionManager, + public val notebook: Notebook, + meta: Meta = Meta.EMPTY, +) : ContextAware, CoroutineScope { + + override val context: Context get() = visionManager.context + + public val configuration: ObservableMutableMeta = meta.toMutableMeta() + + private var counter = 0 + + private var engine: ApplicationEngine? = null + + override val coroutineContext: CoroutineContext get() = context.coroutineContext + + + public fun isServerRunning(): Boolean = engine != null + + public fun getProperty(name: String): TypedMeta<*>? = configuration[name] ?: context.properties[name] + + internal fun startServer( + kernel: KotlinKernelHost, + host: String = getProperty("visionforge.host").string ?: "localhost", + port: Int = getProperty("visionforge.port").int ?: VisionRoute.DEFAULT_PORT, + ) { + engine?.let { + kernel.displayHtml { + p { + style = "color: red;" + +"Stopping current VisionForge server" + } + } + it.stop(1000, 2000) + } + + //val connector: EngineConnectorConfig = EngineConnectorConfig(host, port) + + + engine = context.embeddedServer(CIO, port, host) { + install(WebSockets) + }.start(false) + + kernel.displayHtml { + p { + style = "color: blue;" + +"Starting VisionForge server on port $port" + } + } + } + + internal fun stopServer(kernel: KotlinKernelHost) { + engine?.apply { + logger.info { "Stopping VisionForge server" } + stop(1000, 2000) + engine = null + } + + kernel.displayHtml { + p { + style = "color: red;" + +"VisionForge server stopped" + } + } + } + + internal fun TagConsumer<*>.renderScriptForId(id: String) { + script { + type = "text/javascript" + //language=JavaScript + unsafe { +"parent.VisionForge.renderAllVisionsById(document, \"$id\");" } + } + } + + + public fun produceHtml( + isolated: Boolean? = null, + fragment: HtmlVisionFragment, + ): MimeTypedResult { + val iframeIsolation = isolated ?: when (notebook.jupyterClientType) { + JupyterClientType.DATALORE, JupyterClientType.JUPYTER_NOTEBOOK -> true + else -> false + } + return HTML( + iframeIsolation + ) { + val id = "fragment[${fragment.hashCode()}/${Random.nextUInt()}]" + div { + this.id = id + val engine = engine + if (engine != null) { + //if server exist, serve dynamically + //server.serveVisionsFromFragment(consumer, "content-${counter++}", fragment) + val cellRoute = "content-${counter++}" + + val collector: MutableMap = mutableMapOf() + + val url = engine.environment.connectors.first().let { + url { + protocol = URLProtocol.WS + host = it.host + port = it.port + pathSegments = listOf(cellRoute, "ws") + } + } + + engine.application.serveVisionData(VisionRoute(cellRoute, visionManager), collector) + + visionFragment( + visionManager, + embedData = true, + updatesUrl = url, + onVisionRendered = { name, vision -> collector[name] = vision }, + fragment = fragment + ) + } else { + //if not, use static rendering + visionFragment(visionManager, fragment = fragment) + } + } + renderScriptForId(id) + } + } + + public fun form(builder: FORM.() -> Unit): HtmlFormFragment = + HtmlFormFragment("form[${counter++}]", builder = builder) +} + diff --git a/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt new file mode 100644 index 00000000..935f183c --- /dev/null +++ b/visionforge-jupyter/src/jvmMain/kotlin/VisionForgeIntegration.kt @@ -0,0 +1,131 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.html.* +import org.jetbrains.kotlinx.jupyter.api.KotlinKernelHost +import org.jetbrains.kotlinx.jupyter.api.MimeTypedResult +import org.jetbrains.kotlinx.jupyter.api.declare +import org.jetbrains.kotlinx.jupyter.api.libraries.JupyterIntegration +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionManager +import space.kscience.visionforge.html.* +import kotlin.random.Random +import kotlin.random.nextUInt + +/** + * A base class for different Jupyter VF integrations + */ +public abstract class VisionForgeIntegration( + public val visionManager: VisionManager, +) : JupyterIntegration(), ContextAware { + + override val context: Context get() = visionManager.context + + protected abstract fun Builder.afterLoaded(vf: VisionForge) + + final override fun Builder.onLoaded() { + + val vf: VisionForge = VisionForge(visionManager, notebook) + + onLoaded { + val kernel: KotlinKernelHost = this + declare("VisionForge" to vf, "vf" to vf) + vf.startServer(kernel) + vf.configuration.onChange(this) { name -> + if (name.toString() == "visionforge.port") { + kernel.displayHtml { + p { +"Property 'visionforge.port' changed. Restarting server" } + } + vf.startServer(kernel) + } + } + } + + + onShutdown { + vf.stopServer(this) + } + + import( + "kotlinx.html.*", + "space.kscience.visionforge.html.*", + "space.kscience.visionforge.jupyter.*" + ) +// +// render { fragment -> +// HTML(fragment.renderToString()) +// } +// +// render { fragment -> +// handler.produceHtml(fragment = fragment) +// } + + render { vision -> + vf.produceHtml { + vision(vision) + } + } + + render { page -> + HTML(true) { + head { + meta { + charset = "utf-8" + } + page.pageHeaders.values.forEach { + appendFragment(it) + } + } + body { + val id = "fragment[${page.hashCode()}/${Random.nextUInt()}]" + div { + this.id = id + visionFragment(visionManager, fragment = page.content) + } + with(vf) { + renderScriptForId(id) + } + } + } + } + + render { fragment -> + vf.produceHtml { + if (!vf.isServerRunning()) { + p { + style = "color: red;" + +"The server is not running. Forms are not interactive. Start server with `VisionForge.startServer()." + } + } + appendFragment(fragment.formBody) + vision(fragment.vision) + } + } + + afterLoaded(vf) + } +} + + +/** + * Create a fragment without a head to be embedded in the page + */ +@Suppress("UnusedReceiverParameter") +public fun VisionForge.html(body: TagConsumer<*>.() -> Unit): MimeTypedResult = HTML(false, body) + + +/** + * Create a fragment without a head to be embedded in the page + */ +public fun VisionForge.fragment(body: VisionTagConsumer<*>.() -> Unit): MimeTypedResult = produceHtml(false, body) + + +/** + * Create a standalone page in the notebook + */ +public fun VisionForge.page( + pageHeaders: Map = emptyMap(), + body: VisionTagConsumer<*>.() -> Unit, +): VisionPage = VisionPage(visionManager, pageHeaders, body) + diff --git a/visionforge-jupyter/src/jvmMain/kotlin/forms.kt b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt new file mode 100644 index 00000000..fe072887 --- /dev/null +++ b/visionforge-jupyter/src/jvmMain/kotlin/forms.kt @@ -0,0 +1,34 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.html.FORM +import kotlinx.html.form +import kotlinx.html.id +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.get +import space.kscience.visionforge.html.HtmlFragment +import space.kscience.visionforge.html.VisionOfHtmlForm + +public class HtmlFormFragment internal constructor( + public val vision: VisionOfHtmlForm, + public val formBody: HtmlFragment, +) { + public val values: Meta? get() = vision.values + public operator fun get(valueName: String): Meta? = values?.get(valueName) +} + +/** + * Top level function to create a form + */ +public fun HtmlFormFragment(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment { + val realId = id ?: "form[${builder.hashCode().toUInt()}]" + return HtmlFormFragment(VisionOfHtmlForm(realId)) { + form { + this.id = realId + builder() + } + } +} + + +public fun VisionForge.form(id: String? = null, builder: FORM.() -> Unit): HtmlFormFragment = + HtmlFormFragment(id, builder) \ No newline at end of file diff --git a/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts new file mode 100644 index 00000000..e6fd162b --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/build.gradle.kts @@ -0,0 +1,42 @@ +plugins { + id("space.kscience.gradle.mpp") +} + +description = "Jupyter api artifact including all common modules" + +kscience { + fullStack( + "js/visionforge-jupyter-common.js", + jsConfig = { useCommonJs() } + ) { + commonWebpackConfig { + sourceMaps = false + cssSupport { + enabled.set(false) + } + } + } + + dependencies { + api(projects.visionforgeSolid) + api(projects.visionforgePlotly) + api(projects.visionforgeTables) + api(projects.visionforgeMarkdown) + api(projects.visionforgeJupyter) + } + + jvmMain { + api(projects.visionforgeGdml) + } + + jsMain { + implementation(projects.ui.ring) + implementation(projects.visionforgeThreejs) + } + + jupyterLibrary("space.kscience.visionforge.jupyter.JupyterCommonIntegration") +} + +readme { + maturity = space.kscience.gradle.Maturity.EXPERIMENTAL +} \ No newline at end of file diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt new file mode 100644 index 00000000..e5fb4edd --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jsMain/kotlin/commonJupyter.kt @@ -0,0 +1,17 @@ +package space.kscience.visionforge.gdml.jupyter + +import space.kscience.visionforge.jupyter.VFNotebookClient +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.ring.ThreeWithControlsPlugin +import space.kscience.visionforge.runVisionClient +import space.kscience.visionforge.tables.TableVisionJsPlugin + +public fun main(): Unit = runVisionClient { + plugin(ThreeWithControlsPlugin) + plugin(PlotlyPlugin) + plugin(MarkupPlugin) + plugin(TableVisionJsPlugin) + plugin(VFNotebookClient) +} + diff --git a/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt new file mode 100644 index 00000000..2f7988f8 --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/src/jvmMain/kotlin/JupyterCommonIntegration.kt @@ -0,0 +1,89 @@ +package space.kscience.visionforge.jupyter + +import kotlinx.html.div +import kotlinx.html.p +import org.jetbrains.kotlinx.jupyter.api.libraries.resources +import space.kscience.dataforge.context.Context +import space.kscience.gdml.Gdml +import space.kscience.plotly.Plot +import space.kscience.plotly.PlotlyPage +import space.kscience.plotly.StaticPlotlyRenderer +import space.kscience.tables.Table +import space.kscience.visionforge.gdml.toVision +import space.kscience.visionforge.html.HtmlFragment +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.markup.MarkupPlugin +import space.kscience.visionforge.plotly.PlotlyPlugin +import space.kscience.visionforge.plotly.asVision +import space.kscience.visionforge.solid.Solids +import space.kscience.visionforge.tables.TableVisionPlugin +import space.kscience.visionforge.tables.toVision +import space.kscience.visionforge.visionManager + + +public class JupyterCommonIntegration : VisionForgeIntegration(CONTEXT.visionManager) { + + override fun Builder.afterLoaded(vf: VisionForge) { + + resources { + js("visionforge-common") { + classPath("js/visionforge-jupyter-common.js") + } + } + + import( + "space.kscience.gdml.*", + "space.kscience.visionforge.solid.*", + "space.kscience.tables.*", + "space.kscience.dataforge.meta.*", + "space.kscience.plotly.*", + "space.kscience.plotly.models.*", + "space.kscience.visionforge.plotly.plotly" + ) + + render { gdmlModel -> + vf.produceHtml { + vision { gdmlModel.toVision() } + } + } + + render> { table -> + vf.produceHtml { + vision { table.toVision() } + } + } + + render { plot -> + vf.produceHtml { + vision { plot.asVision() } + } + } + + + render { plotlyPage -> + val headers = plotlyPage.headers.associate { plotlyFragment -> + plotlyFragment.hashCode().toString(16) to HtmlFragment { + plotlyFragment.visit(this) + } + + } + VisionPage(visionManager, headers) { + div{ + p { +"Plotly page renderer is not recommended in VisionForge, use `vf.page{}`" } + } + div { + plotlyPage.fragment.render.invoke(this, StaticPlotlyRenderer) + } + } + } + } + + public companion object { + private val CONTEXT: Context = Context("Jupyter-common") { + plugin(Solids) + plugin(PlotlyPlugin) + plugin(TableVisionPlugin) + plugin(MarkupPlugin) + } + } +} diff --git a/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js new file mode 100644 index 00000000..cfb15cb8 --- /dev/null +++ b/visionforge-jupyter/visionforge-jupyter-common/webpack.config.d/01.ring.js @@ -0,0 +1,24 @@ +const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; + +const path = require('path'); + +config.module.rules.push(...ringConfig.module.rules) + +config.module.rules.push( + { + test: /\.css$/, + exclude: [ + path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui") + ], + use: [ + { + loader: 'style-loader', + options: {} + }, + { + loader: 'css-loader', + options: {} + } + ] + } +) \ No newline at end of file diff --git a/visionforge-markdown/build.gradle.kts b/visionforge-markdown/build.gradle.kts index 1a8e4efd..eb856d75 100644 --- a/visionforge-markdown/build.gradle.kts +++ b/visionforge-markdown/build.gradle.kts @@ -1,24 +1,18 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } -val markdownVersion = "0.2.4" +val markdownVersion = "0.5.2" kscience { - useSerialization() -} - -kotlin { + jvm() js { binaries.library() } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("org.jetbrains:markdown:$markdownVersion") - } - } + dependencies { + api(projects.visionforgeCore) + api("org.jetbrains:markdown:$markdownVersion") + api("org.jetbrains:annotations:24.0.0") } + useSerialization() } \ No newline at end of file diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt new file mode 100644 index 00000000..3508ba8b --- /dev/null +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -0,0 +1,8 @@ +package space.kscience.visionforge.markup + +import space.kscience.dataforge.context.PluginFactory +import space.kscience.visionforge.VisionPlugin + +public expect class MarkupPlugin: VisionPlugin{ + public companion object : PluginFactory +} \ No newline at end of file diff --git a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt index 87682978..f3e255df 100644 --- a/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt +++ b/visionforge-markdown/src/commonMain/kotlin/space/kscience/visionforge/markup/VisionOfMarkup.kt @@ -8,18 +8,21 @@ import kotlinx.serialization.modules.subclass import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName +import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.root @Serializable @SerialName("vision.markup") public class VisionOfMarkup( - public val format: String = COMMONMARK_FORMAT -) : VisionBase() { + public val format: String = COMMONMARK_FORMAT, +) : AbstractVision() { //TODO add templates - public var content: String? by meta.string(CONTENT_PROPERTY_KEY) + public var content: String? by properties.root().string(CONTENT_PROPERTY_KEY) public companion object { public val CONTENT_PROPERTY_KEY: Name = "content".asName() @@ -37,4 +40,16 @@ internal val markupSerializersModule = SerializersModule { polymorphic(Vision::class) { subclass(VisionOfMarkup.serializer()) } +} + +/** + * Embed a dynamic markdown block in a vision + */ +@VisionBuilder +public inline fun VisionOutput.markdown( + format: String = VisionOfMarkup.COMMONMARK_FORMAT, + block: VisionOfMarkup.() -> Unit, +): VisionOfMarkup { + requirePlugin(MarkupPlugin) + return VisionOfMarkup(format).apply(block) } \ No newline at end of file diff --git a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt index 4d7a1060..ef700466 100644 --- a/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt +++ b/visionforge-markdown/src/jsMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -11,13 +11,14 @@ import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName import space.kscience.visionforge.* import space.kscience.visionforge.markup.VisionOfMarkup.Companion.COMMONMARK_FORMAT import space.kscience.visionforge.markup.VisionOfMarkup.Companion.GFM_FORMAT -import kotlin.reflect.KClass -public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) +public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { + public val visionClient: JsVisionClient by require(JsVisionClient) override val tag: PluginTag get() = Companion.tag override val visionSerializersModule: SerializersModule get() = markupSerializersModule @@ -26,7 +27,7 @@ public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { else -> ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { require(vision is VisionOfMarkup) { "The vision is not a markup vision" } val div = document.createElement("div") val flavour = when (vision.format) { @@ -44,9 +45,15 @@ public class MarkupPlugin : VisionPlugin(), ElementVisionRenderer { element.append(div) } - public companion object : PluginFactory { - override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) - override val type: KClass = MarkupPlugin::class - override fun invoke(meta: Meta, context: Context): MarkupPlugin = MarkupPlugin() + override fun content(target: String): Map = when (target) { + ElementVisionRenderer.TYPE -> mapOf("markup".asName() to this) + else -> super.content(target) + } + + public actual companion object : PluginFactory { + override val tag: PluginTag = PluginTag("vision.markup.js", PluginTag.DATAFORGE_GROUP) + + override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() + } } \ No newline at end of file diff --git a/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt new file mode 100644 index 00000000..ce094ee9 --- /dev/null +++ b/visionforge-markdown/src/jvmMain/kotlin/space/kscience/visionforge/markup/MarkupPlugin.kt @@ -0,0 +1,26 @@ +package space.kscience.visionforge.markup + +import kotlinx.serialization.modules.SerializersModule +import org.intellij.lang.annotations.Language +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.PluginFactory +import space.kscience.dataforge.context.PluginTag +import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.VisionPlugin + +public actual class MarkupPlugin : VisionPlugin() { + override val visionSerializersModule: SerializersModule get() = markupSerializersModule + + override val tag: PluginTag get() = Companion.tag + + public actual companion object : PluginFactory { + override val tag: PluginTag = PluginTag("vision.markup.jvm", PluginTag.DATAFORGE_GROUP) + + override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() + + } +} + +public fun VisionOfMarkup.content(@Language("markdown") text: String) { + content = text +} \ No newline at end of file diff --git a/visionforge-plotly/build.gradle.kts b/visionforge-plotly/build.gradle.kts index caeb4e52..c4df8593 100644 --- a/visionforge-plotly/build.gradle.kts +++ b/visionforge-plotly/build.gradle.kts @@ -1,24 +1,17 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } -val plotlyVersion = "0.5.0" +val plotlyVersion = "0.6.1" kscience { - useSerialization() -} - -kotlin { + jvm() js { binaries.library() } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("space.kscience:plotlykt-core:${plotlyVersion}") - } - } + dependencies { + api(projects.visionforgeCore) + api("space.kscience:plotlykt-core:${plotlyVersion}") } + useSerialization() } \ No newline at end of file diff --git a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt index ebb4773c..19d98171 100644 --- a/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt +++ b/visionforge-plotly/src/commonMain/kotlin/space/kscience/visionforge/plotly/VisionOfPlotly.kt @@ -1,30 +1,97 @@ package space.kscience.visionforge.plotly +import kotlinx.coroutines.channels.awaitClose +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.callbackFlow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.misc.DFExperimental +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.names.Name import space.kscience.plotly.Plot import space.kscience.plotly.Plotly -import space.kscience.visionforge.VisionBase +import space.kscience.plotly.PlotlyConfig +import space.kscience.visionforge.MutableVisionProperties +import space.kscience.visionforge.Vision +import space.kscience.visionforge.VisionBuilder import space.kscience.visionforge.html.VisionOutput @Serializable @SerialName("vision.plotly") -public class VisionOfPlotly private constructor() : VisionBase() { +public class VisionOfPlotly private constructor( + @Serializable(MutableMetaSerializer::class) public val meta: MutableMeta, +) : Vision { + public constructor(plot: Plot) : this(plot.meta) + + public val plot: Plot get() = Plot(meta.asObservable()) + + @Transient + override var parent: Vision? = null + + @Transient + override val properties: MutableVisionProperties = object : MutableVisionProperties { + override fun set(name: Name, node: Meta?, notify: Boolean) { + meta[name] = node + } + + override fun setValue(name: Name, value: Value?, notify: Boolean) { + meta.setValue(name, value) + } + + override val own: Meta get() = meta + + override val descriptor: MetaDescriptor? get() = this@VisionOfPlotly.descriptor + + override fun get( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): MutableMeta = meta[name] ?: MutableMeta() + + override fun getValue( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? = meta.getValue(name) + + override val changes: Flow = if (meta is ObservableMeta) { + callbackFlow { + meta.onChange(this) { + launch { + send(it) + } + } + awaitClose { + meta.removeListener(this) + } + } + } else emptyFlow() + + + override fun invalidate(propertyName: Name) { + // Do nothing + } - public constructor(plot: Plot) : this() { - properties = plot.meta } - public val plot: Plot get() = Plot(meta) + + override val descriptor: MetaDescriptor? = null // TODO add descriptor for Plot } public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) -@DFExperimental +/** + * Embed a dynamic plotly plot in a vision + */ +@VisionBuilder public inline fun VisionOutput.plotly( + config: PlotlyConfig = PlotlyConfig(), block: Plot.() -> Unit, ): VisionOfPlotly { requirePlugin(PlotlyPlugin) + meta = config.meta return VisionOfPlotly(Plotly.plot(block)) } \ No newline at end of file diff --git a/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt b/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt new file mode 100644 index 00000000..7634e73d --- /dev/null +++ b/visionforge-plotly/src/commonTest/kotlin/space/kscience/visionforge/plotly/VisionOfPlotlyTest.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.plotly + +import space.kscience.plotly.Plotly +import space.kscience.plotly.scatter +import kotlin.test.Test +import kotlin.test.assertTrue + +class VisionOfPlotlyTest { + @Test + fun conversion(){ + val plot = Plotly.plot { + scatter { + x(1,2,3) + y(1,2,3) + } + } + val vision = VisionOfPlotly(plot) +// println(vision.plot.toJsonString()) +// println(vision.plot.data.toJsonString()) + assertTrue { vision.plot.data.first().x.doubles.size == 3} + } +} \ No newline at end of file diff --git a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt index 7406986b..074be6dc 100644 --- a/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt +++ b/visionforge-plotly/src/jsMain/kotlin/space/kscience/visionforge/plotly/plotlyJs.kt @@ -11,13 +11,12 @@ import space.kscience.dataforge.names.asName import space.kscience.plotly.PlotlyConfig import space.kscience.plotly.plot import space.kscience.visionforge.ElementVisionRenderer +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) + public val visionClient: JsVisionClient by require(JsVisionClient) override val tag: PluginTag get() = Companion.tag @@ -28,10 +27,10 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { else -> ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { val plot = (vision as? VisionOfPlotly)?.plot ?: error("VisionOfPlotly expected but ${vision::class} found") val config = PlotlyConfig.read(meta) - element.plot(plot, config) + element.plot(config, plot) } override fun content(target: String): Map = when (target) { @@ -41,7 +40,8 @@ public actual class PlotlyPlugin : VisionPlugin(), ElementVisionRenderer { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly.js", PluginTag.DATAFORGE_GROUP) - override val type: KClass = PlotlyPlugin::class - override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin() + + override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() + } } \ No newline at end of file diff --git a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt index ad7be4f3..b9a8d373 100644 --- a/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt +++ b/visionforge-plotly/src/jvmMain/kotlin/space/kscience/visionforge/plotly/plotlyJvm.kt @@ -2,12 +2,10 @@ package space.kscience.visionforge.plotly import kotlinx.serialization.modules.SerializersModule import space.kscience.dataforge.context.Context -import space.kscience.dataforge.context.Plugin import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public actual class PlotlyPlugin : VisionPlugin() { @@ -17,7 +15,8 @@ public actual class PlotlyPlugin : VisionPlugin() { public actual companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) - override val type: KClass = PlotlyPlugin::class - override fun invoke(meta: Meta, context: Context): PlotlyPlugin = PlotlyPlugin() + + override fun build(context: Context, meta: Meta): PlotlyPlugin = PlotlyPlugin() + } } \ No newline at end of file diff --git a/visionforge-server/build.gradle.kts b/visionforge-server/build.gradle.kts index ec77fa22..59034dd1 100644 --- a/visionforge-server/build.gradle.kts +++ b/visionforge-server/build.gradle.kts @@ -1,10 +1,15 @@ plugins { - id("ru.mipt.npm.gradle.jvm") + id("space.kscience.gradle.jvm") +} + +kscience{ + useKtor() + dependencies { + api(projects.visionforgeCore) + api("io.ktor:ktor-server-host-common") + api("io.ktor:ktor-server-html-builder") + api("io.ktor:ktor-server-websockets") + api("io.ktor:ktor-server-cors") + } } -dependencies { - api(project(":visionforge-core")) - api(npmlibs.ktor.server.cio) - api(npmlibs.ktor.html.builder) - api(npmlibs.ktor.websockets) -} \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt index 2abb6efb..3c5e397a 100644 --- a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/VisionServer.kt @@ -1,230 +1,65 @@ package space.kscience.visionforge.server -import io.ktor.application.* -import io.ktor.features.CORS -import io.ktor.features.CallLogging -import io.ktor.html.respondHtml import io.ktor.http.* -import io.ktor.http.cio.websocket.Frame -import io.ktor.http.content.resources -import io.ktor.http.content.static -import io.ktor.response.respond -import io.ktor.response.respondText -import io.ktor.routing.* -import io.ktor.server.cio.CIO -import io.ktor.server.engine.ApplicationEngine -import io.ktor.server.engine.embeddedServer -import io.ktor.util.getOrFail -import io.ktor.websocket.WebSockets -import io.ktor.websocket.webSocket -import kotlinx.coroutines.channels.consumeEach +import io.ktor.server.application.* +import io.ktor.server.engine.* +import io.ktor.server.html.* +import io.ktor.server.http.content.* +import io.ktor.server.plugins.* +import io.ktor.server.plugins.cors.routing.* +import io.ktor.server.request.* +import io.ktor.server.response.* +import io.ktor.server.routing.* +import io.ktor.server.util.* +import io.ktor.server.websocket.* +import io.ktor.util.pipeline.* +import io.ktor.websocket.* +import kotlinx.coroutines.flow.Flow import kotlinx.coroutines.flow.collect +import kotlinx.coroutines.flow.onEach import kotlinx.coroutines.launch import kotlinx.coroutines.withContext import kotlinx.html.* -import kotlinx.html.stream.createHTML +import space.kscience.dataforge.context.Context +import space.kscience.dataforge.context.ContextAware import space.kscience.dataforge.meta.* -import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name -import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionChange -import space.kscience.visionforge.VisionManager -import space.kscience.visionforge.flowChanges -import space.kscience.visionforge.html.HtmlFragment -import space.kscience.visionforge.html.HtmlVisionFragment -import space.kscience.visionforge.html.visionFragment -import space.kscience.visionforge.server.VisionServer.Companion.DEFAULT_PAGE -import java.awt.Desktop -import java.net.URI +import space.kscience.visionforge.* +import space.kscience.visionforge.html.* import kotlin.time.Duration.Companion.milliseconds -/** - * A ktor plugin container with given [routing] - * @param serverUrl a server url including root route - */ -public class VisionServer internal constructor( - private val visionManager: VisionManager, - private val serverUrl: Url, - private val root: Route, -) : Configurable { +public class VisionRoute( + public val route: String, + public val visionManager: VisionManager, + override val meta: ObservableMutableMeta = ObservableMutableMeta(), +) : Configurable, ContextAware { - public val application: Application get() = root.application + public enum class Mode { + /** + * Embed the initial state of the vision inside its html tag. + */ + EMBED, - override val meta: ObservableMutableMeta = MutableMeta() + /** + * Fetch data on vision load. Do not embed data. + */ + FETCH, + + /** + * Connect to server to get pushes. The address of the server is embedded in the tag. + */ + UPDATE + } + + override val context: Context get() = visionManager.context /** - * Update minimal interval between updates in milliseconds (if there are no updates, push will not happen + * Update the minimal interval between updates in milliseconds (if there are no updates, push will not happen */ public var updateInterval: Long by meta.long(300, key = UPDATE_INTERVAL_KEY) - /** - * Cache page fragments. If false, pages will be reconstructed on each call. Default: `true` - */ - public var cacheFragments: Boolean by meta.boolean(true) - - /** - * Embed the initial state of the vision inside its html tag. Default: `true` - */ - public var dataEmbed: Boolean by meta.boolean(true, Name.parse("data.embed")) - - /** - * Fetch data on vision load. Overrides embedded data. Default: `false` - */ - public var dataFetch: Boolean by meta.boolean(false, Name.parse("data.fetch")) - - /** - * Connect to server to get pushes. The address of the server is embedded in the tag. Default: `true` - */ - public var dataUpdate: Boolean by meta.boolean(true, Name.parse("data.update")) - - private fun HTML.visionPage( - title: String, - pagePath: String, - header: HtmlFragment, - visionFragment: HtmlVisionFragment, - ): Map { - var visionMap: Map? = null - - head { - meta { - charset = "utf-8" - header() - } - title(title) - } - body { - //Load the fragment and remember all loaded visions - visionMap = visionFragment( - context = visionManager.context, - embedData = true, - fetchUpdatesUrl = "$serverUrl$pagePath/ws", - fragment = visionFragment - ) - } - - return visionMap!! - } - - /** - * Server a map of visions without providing explicit html page for them - */ - @OptIn(DFExperimental::class) - private fun serveVisions(route: Route, visions: Map): Unit = route { - application.log.info("Serving visions $visions at $route") - - //Update websocket - webSocket("ws") { - val name: String = call.request.queryParameters.getOrFail("name") - application.log.debug("Opened server socket for $name") - val vision: Vision = visions[Name.parse(name)] ?: error("Plot with id='$name' not registered") - - launch { - incoming.consumeEach { - val change = visionManager.jsonFormat.decodeFromString( - VisionChange.serializer(), it.data.decodeToString() - ) - vision.update(change) - } - } - - try { - withContext(visionManager.context.coroutineContext) { - vision.flowChanges(updateInterval.milliseconds).collect { update -> - val json = visionManager.jsonFormat.encodeToString( - VisionChange.serializer(), - update - ) - outgoing.send(Frame.Text(json)) - } - } - } catch (t: Throwable) { - application.log.info("WebSocket update channel for $name is closed with exception: $t") - } - } - //Plots in their json representation - get("data") { - val name: String = call.request.queryParameters.getOrFail("name") - - val vision: Vision? = visions[Name.parse(name)] - if (vision == null) { - call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") - } else { - call.respondText( - visionManager.encodeToString(vision), - contentType = ContentType.Application.Json, - status = HttpStatusCode.OK - ) - } - } - } - - - /** - * Serve visions in a given [route] without providing a page template - */ - public fun serveVisions(route: String, visions: Map) { - root.route(route) { - serveVisions(this, visions) - } - } - - /** - * Compile a fragment to string and serve visions from it - */ - public fun serveVisionsFromFragment( - route: String, - fragment: HtmlVisionFragment, - ): String = createHTML().apply { - val visions = visionFragment( - visionManager.context, - embedData = true, - fetchUpdatesUrl = "$serverUrl$route/ws", - renderScript = true, - fragment = fragment - ) - serveVisions(route, visions) - }.finalize() - - /** - * Serve a page, potentially containing any number of visions at a given [pagePath] with given [headers]. - */ - public fun page( - pagePath: String = DEFAULT_PAGE, - title: String = "VisionForge server page '$pagePath'", - header: HtmlFragment = {}, - visionFragment: HtmlVisionFragment, - ) { - val visions = HashMap() - - val cachedHtml: String? = if (cacheFragments) { - //Create and cache page html and map of visions - createHTML(true).html { - visions.putAll(visionPage(title, pagePath, header, visionFragment)) - } - } else { - null - } - - root.route(pagePath) { - serveVisions(this, visions) - //filled pages - get { - if (cachedHtml == null) { - //re-create html and vision list on each call - call.respondHtml { - visions.clear() - visions.putAll(visionPage(title, pagePath, header, visionFragment)) - } - } else { - //Use cached html - call.respondText(cachedHtml, ContentType.Text.Html.withCharset(Charsets.UTF_8)) - } - } - } - - - } + public var dataMode: Mode by meta.enum(Mode.UPDATE) public companion object { public const val DEFAULT_PORT: Int = 7777 @@ -233,61 +68,166 @@ public class VisionServer internal constructor( } } + /** - * Attach VisionForge server application to given server + * Serve visions in a given [route] without providing a page template. + * [visions] could be changed during the service. + * + * @return a [Flow] of backward events, including vision change events */ -public fun Application.visionServer( +public fun Application.serveVisionData( + configuration: VisionRoute, + resolveVision: (Name) -> Vision?, +) { + require(WebSockets) + routing { + route(configuration.route) { + install(CORS) { + anyHost() + } + application.log.info("Serving visions at ${configuration.route}") + + //Update websocket + webSocket("ws") { + val name: String = call.request.queryParameters.getOrFail("name") + application.log.debug("Opened server socket for $name") + val vision: Vision = resolveVision(Name.parse(name)) ?: error("Vision with id='$name' not registered") + + launch { + for (frame in incoming) { + val data = frame.data.decodeToString() + application.log.debug("Received event for $name: \n$data") + val event = configuration.visionManager.jsonFormat.decodeFromString( + VisionEvent.serializer(), data + ) + + vision.receiveEvent(event) + } + } + + try { + withContext(configuration.context.coroutineContext) { + vision.flowChanges(configuration.updateInterval.milliseconds).onEach { event -> + val json = configuration.visionManager.jsonFormat.encodeToString( + VisionEvent.serializer(), + event + ) + application.log.debug("Sending update for $name: \n$json") + outgoing.send(Frame.Text(json)) + }.collect() + } + } catch (t: Throwable) { + this.application.log.info("WebSocket update channel for $name is closed with exception: $t") + } + } + //Plots in their json representation + get("data") { + val name: String = call.request.queryParameters.getOrFail("name") + + val vision: Vision? = resolveVision(Name.parse(name)) + if (vision == null) { + call.respond(HttpStatusCode.NotFound, "Vision with name '$name' not found") + } else { + call.respondText( + configuration.visionManager.encodeToString(vision), + contentType = ContentType.Application.Json, + status = HttpStatusCode.OK + ) + } + } + } + } +} + +public fun Application.serveVisionData( + configuration: VisionRoute, + data: Map, +): Unit = serveVisionData(configuration) { data[it] } + +/** + * Serve a page, potentially containing any number of visions at a given [route] with given [header]. + * + * @return a [Flow] containing backward propagated events, including vision change events + */ +public fun Application.visionPage( + route: String, + configuration: VisionRoute, + headers: Collection, + connector: EngineConnectorConfig? = null, + visionFragment: HtmlVisionFragment, +){ + require(WebSockets) + + val collector: MutableMap = mutableMapOf() + + //serve data + serveVisionData(configuration, collector) + + //filled pages + routing { + get(route) { + val host = connector?.host ?: call.request.host() + val port = connector?.port ?: call.request.port() + call.respondHtml { + head { + meta { + charset = "utf-8" + } + headers.forEach { headerContent -> + headerContent.appendTo(consumer) + } + } + body { + //Load the fragment and remember all loaded visions + visionFragment( + visionManager = configuration.visionManager, + embedData = configuration.dataMode == VisionRoute.Mode.EMBED, + fetchDataUrl = if (configuration.dataMode != VisionRoute.Mode.EMBED) { + url { + this.host = host + this.port = port + path(route, "data") + } + } else null, + updatesUrl = if (configuration.dataMode == VisionRoute.Mode.UPDATE) { + url { + protocol = URLProtocol.WS + this.host = host + this.port = port + path(route, "ws") + } + } else null, + onVisionRendered = { name, vision -> collector[name] = vision }, + fragment = visionFragment + ) + } + } + } + } +} + +public fun Application.visionPage( visionManager: VisionManager, - webServerUrl: Url, - path: String = DEFAULT_PAGE, -): VisionServer { - if (featureOrNull(WebSockets) == null) { - install(WebSockets) - } - - if (featureOrNull(CORS) == null) { - install(CORS) { - anyHost() - } - } - - if (featureOrNull(CallLogging) == null) { - install(CallLogging) - } - - val serverRoute = (featureOrNull(Routing) ?: install(Routing)).createRouteFromPath(path) - - serverRoute { - static { - resources() - } - } - - return VisionServer(visionManager, webServerUrl.copy(encodedPath = path), serverRoute) + vararg headers: HtmlFragment, + route: String = "/", + connector: EngineConnectorConfig? = null, + configurationBuilder: VisionRoute.() -> Unit = {}, + visionFragment: HtmlVisionFragment, +) { + val configuration = VisionRoute(route, visionManager).apply(configurationBuilder) + visionPage(route, configuration, listOf(*headers), connector, visionFragment) } /** - * Start a stand-alone VisionForge server at given host/port + * Render given [VisionPage] at server */ -public fun VisionManager.serve( - host: String = "localhost", - port: Int = VisionServer.DEFAULT_PORT, - block: VisionServer.() -> Unit, -): ApplicationEngine = context.embeddedServer(CIO, port, host) { - val url = URLBuilder(host = host, port = port).build() - visionServer(this@serve, url).apply(block) -}.start() - -/** - * Connect to a given Ktor server using browser - */ -public fun ApplicationEngine.openInBrowser() { - val connector = environment.connectors.first() - val uri = URI("http", null, connector.host, connector.port, null, null, null) - Desktop.getDesktop().browse(uri) +public fun Application.visionPage( + page: VisionPage, + route: String = "/", + connector: EngineConnectorConfig? = null, + configurationBuilder: VisionRoute.() -> Unit = {}, +) { + val configuration = VisionRoute(route, page.visionManager).apply(configurationBuilder) + visionPage(route, configuration, page.pageHeaders.values, connector, visionFragment = page.content) } -/** - * Stop the server with default timeouts - */ -public fun ApplicationEngine.close(): Unit = stop(1000, 5000) \ No newline at end of file diff --git a/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt new file mode 100644 index 00000000..81f6e3e7 --- /dev/null +++ b/visionforge-server/src/main/kotlin/space/kscience/visionforge/server/applicationExtensions.kt @@ -0,0 +1,39 @@ +package space.kscience.visionforge.server + +import io.ktor.server.application.ApplicationCall +import io.ktor.server.application.Plugin +import io.ktor.server.application.install +import io.ktor.server.application.pluginOrNull +import io.ktor.server.engine.ApplicationEngine +import io.ktor.server.engine.EngineConnectorBuilder +import io.ktor.server.engine.EngineConnectorConfig +import io.ktor.util.pipeline.Pipeline +import java.awt.Desktop +import java.net.URI + + +public fun

, B : Any, F : Any> P.require( + plugin: Plugin, +): F = pluginOrNull(plugin) ?: install(plugin) + + +/** + * Connect to a given Ktor server using browser + */ +public fun ApplicationEngine.openInBrowser() { + val connector = environment.connectors.first() + val host = if (connector.host == "0.0.0.0") "127.0.0.1" else connector.host + val uri = URI("http", null, host, connector.port, null, null, null) + Desktop.getDesktop().browse(uri) +} + +/** + * Stop the server with default timeouts + */ +public fun ApplicationEngine.close(): Unit = stop(1000, 5000) + + +public fun EngineConnectorConfig(host: String, port: Int): EngineConnectorConfig = EngineConnectorBuilder().apply { + this.host = host + this.port = port +} \ No newline at end of file diff --git a/visionforge-solid/api/visionforge-solid.api b/visionforge-solid/api/visionforge-solid.api index 34c11260..c763e3c8 100644 --- a/visionforge-solid/api/visionforge-solid.api +++ b/visionforge-solid/api/visionforge-solid.api @@ -717,7 +717,7 @@ public final class space/kscience/visionforge/solid/SolidMaterialKt { } public abstract interface class space/kscience/visionforge/solid/SolidReference : space/kscience/visionforge/VisionGroup { - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public abstract fun getPrototype ()Lspace/kscience/visionforge/solid/Solid; } @@ -728,7 +728,7 @@ public final class space/kscience/visionforge/solid/SolidReferenceGroup : space/ public fun (Lspace/kscience/dataforge/names/Name;)V public fun getChildren ()Ljava/util/Map; public fun getDescriptor ()Lspace/kscience/dataforge/meta/descriptors/MetaDescriptor; - public fun getPropertyValue (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; + public fun getProperty (Lspace/kscience/dataforge/names/Name;ZZZ)Lspace/kscience/dataforge/values/Value; public fun getPrototype ()Lspace/kscience/visionforge/solid/Solid; public final fun getRefName ()Lspace/kscience/dataforge/names/Name; public static final fun write$Self (Lspace/kscience/visionforge/solid/SolidReferenceGroup;Lkotlinx/serialization/encoding/CompositeEncoder;Lkotlinx/serialization/descriptors/SerialDescriptor;)V diff --git a/visionforge-solid/build.gradle.kts b/visionforge-solid/build.gradle.kts index e00830d5..f87cef77 100644 --- a/visionforge-solid/build.gradle.kts +++ b/visionforge-solid/build.gradle.kts @@ -1,23 +1,26 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } -kscience{ - useSerialization{ +val kmathVersion = "0.3.1" + +kscience { + jvm() + js() + native() + useSerialization { json() } -} - -kotlin { - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - } - } + useCoroutines() + dependencies { + api("space.kscience:kmath-geometry:0.3.1") + api(projects.visionforgeCore) + } + dependencies(jvmTest) { + implementation(spclibs.logback.classic) } } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.DEVELOPMENT +readme { + maturity = space.kscience.gradle.Maturity.DEVELOPMENT } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt index 57f868f2..14a22797 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ColorAccessor.kt @@ -1,15 +1,19 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.* import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.* import space.kscience.visionforge.Colors +import space.kscience.visionforge.Vision import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.root +import kotlin.properties.ReadOnlyProperty @VisionBuilder public class ColorAccessor( private val provider: MutableValueProvider, - private val colorKey: Name + private val colorKey: Name, ) : MutableValueProvider { public var value: Value? get() = provider.getValue(colorKey) @@ -24,33 +28,39 @@ public class ColorAccessor( } } -public var ColorAccessor?.string: String? - get() = this?.value?.let { if(it == Null) null else it.string } +public fun Vision.colorProperty( + propertyName: Name? = null, +): ReadOnlyProperty = ReadOnlyProperty { _, property -> + ColorAccessor(properties.root(true), propertyName ?: property.name.asName()) +} + +public var ColorAccessor.string: String? + get() = value?.let { if (it == Null) null else it.string } set(value) { - this?.value = value?.asValue() + this.value = value?.asValue() } /** * Set [webcolor](https://en.wikipedia.org/wiki/Web_colors) as string */ -public operator fun ColorAccessor?.invoke(webColor: String) { - this?.value = webColor.asValue() +public operator fun ColorAccessor.invoke(webColor: String) { + value = webColor.asValue() } /** * Set color as RGB integer */ -public operator fun ColorAccessor?.invoke(rgb: Int) { - this?.value = Colors.rgbToString(rgb).asValue() +public operator fun ColorAccessor.invoke(rgb: Int) { + value = Colors.rgbToString(rgb).asValue() } /** * Set color as RGB */ -public operator fun ColorAccessor?.invoke(r: UByte, g: UByte, b: UByte) { - this?.value = Colors.rgbToString(r, g, b).asValue() +public operator fun ColorAccessor.invoke(r: UByte, g: UByte, b: UByte) { + value = Colors.rgbToString(r, g, b).asValue() } -public fun ColorAccessor?.clear() { - this?.value = null +public fun ColorAccessor.clear() { + value = null } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt index d63e08b6..3ae6a681 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Composite.kt @@ -2,12 +2,11 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.isEmpty -import space.kscience.dataforge.meta.update +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild +import space.kscience.visionforge.static public enum class CompositeType { GROUP, // Dumb sum of meshes @@ -16,30 +15,33 @@ public enum class CompositeType { SUBTRACT } +/** + * A CSG-based composite solid + */ @Serializable @SerialName("solid.composite") public class Composite( public val compositeType: CompositeType, public val first: Solid, public val second: Solid, -) : SolidBase(), VisionPropertyContainer +) : SolidBase() @VisionBuilder -public inline fun VisionContainerBuilder.composite( +public inline fun MutableVisionContainer.composite( type: CompositeType, name: String? = null, - builder: SolidGroup.() -> Unit, + @VisionBuilder builder: SolidGroup.() -> Unit, ): Composite { val group = SolidGroup().apply(builder) - val children = group.children.values.filterIsInstance() - if (children.size != 2){ + val children = group.items.values.toList() + if (children.size != 2) { error("Composite requires exactly two children, but found ${children.size}") } val res = Composite(type, children[0], children[1]) - res.meta.update(group.meta) + res.properties[Name.EMPTY] = group.properties.own - set(name, res) + setChild(name, res) return res } @@ -50,38 +52,38 @@ public inline fun VisionContainerBuilder.composite( public fun SolidGroup.smartComposite( type: CompositeType, name: String? = null, - builder: SolidGroup.() -> Unit, + @VisionBuilder builder: SolidGroup.() -> Unit, ): Solid = if (type == CompositeType.GROUP) { - val group = SolidGroup(builder) - if (name == null && group.meta.isEmpty()) { + val group = SolidGroup().apply(builder) + if (name == null && group.properties.own == null) { //append directly to group if no properties are defined - group.children.forEach { (_, value) -> + group.items.forEach { (_, value) -> value.parent = null - set(null, value) + children.static(value) } this } else { - set(name, group) + children.setChild(name, group) group } } else { - composite(type, name, builder) + children.composite(type, name, builder) } @VisionBuilder -public inline fun VisionContainerBuilder.union( +public inline fun MutableVisionContainer.union( name: String? = null, - builder: SolidGroup.() -> Unit + builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.UNION, name, builder = builder) @VisionBuilder -public inline fun VisionContainerBuilder.subtract( +public inline fun MutableVisionContainer.subtract( name: String? = null, - builder: SolidGroup.() -> Unit + builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.SUBTRACT, name, builder = builder) @VisionBuilder -public inline fun VisionContainerBuilder.intersect( +public inline fun MutableVisionContainer.intersect( name: String? = null, builder: SolidGroup.() -> Unit, ): Composite = composite(CompositeType.INTERSECT, name, builder = builder) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt index 560ec496..7b2679cd 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSegment.kt @@ -2,9 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.cos import kotlin.math.sin @@ -18,79 +18,84 @@ public class ConeSegment( public val bottomRadius: Float, public val height: Float, public val topRadius: Float, - public val startAngle: Float = 0f, - public val angle: Float = PI2 -) : SolidBase(), GeometrySolid { + public val phiStart: Float = 0f, + public val phi: Float = PI2, +) : SolidBase(), GeometrySolid { + + + init { + require(bottomRadius > 0) { "Cone segment bottom radius must be positive" } + require(height > 0) { "Cone segment height must be positive" } + require(topRadius >= 0) { "Cone segment top radius must be non-negative" } + //require(startAngle >= 0) + require(phi in (0f..(PI2))) + } override fun toGeometry(geometryBuilder: GeometryBuilder) { val segments = detail ?: 32 - require(segments >= 4) { "The number of segments in cone segment is too small" } - val angleStep = angle / (segments - 1) + require(segments >= 4) { "The number of segments in cone is too small" } + val angleStep = phi / (segments - 1) - fun shape(r: Float, z: Float): List { - return (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) - } + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { //creating shape in x-y plane with z = 0 - val bottomOuterPoints = shape(topRadius, -height / 2) - val upperOuterPoints = shape(bottomRadius, height / 2) + val bottomPoints = shape(bottomRadius, -height / 2) + val topPoints = shape(topRadius, height / 2) //outer face - (1 until segments).forEach { - face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) + for (it in 1 until segments) { + face4(bottomPoints[it - 1], bottomPoints[it], topPoints[it], topPoints[it - 1]) } - if (angle == PI2) { - face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) + if (phi == PI2) { + face4(bottomPoints.last(), bottomPoints[0], topPoints[0], topPoints.last()) } - - val zeroBottom = Point3D(0f, 0f, 0f) - val zeroTop = Point3D(0f, 0f, height) - (1 until segments).forEach { - face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) - face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, +height / 2) + for (it in 1 until segments) { + face(bottomPoints[it - 1], zeroBottom, bottomPoints[it]) + face(topPoints[it - 1], topPoints[it], zeroTop) } - if (angle == PI2) { - face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) - face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) + if (phi == PI2) { + face(bottomPoints.last(), zeroBottom, bottomPoints[0]) + face(topPoints.last(), topPoints[0], zeroTop) } else { - face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0]) - face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last()) + face4(zeroTop, zeroBottom, bottomPoints[0], topPoints[0]) + face4(zeroTop, zeroBottom, bottomPoints.last(), topPoints.last()) } } } - } @VisionBuilder -public inline fun VisionContainerBuilder.cylinder( +public inline fun MutableVisionContainer.cylinder( r: Number, height: Number, name: String? = null, - block: ConeSegment.() -> Unit = {} + block: ConeSegment.() -> Unit = {}, ): ConeSegment = ConeSegment( r.toFloat(), height.toFloat(), r.toFloat() -).apply(block).also { set(name, it) } +).apply(block).also { setChild(name, it) } @VisionBuilder -public inline fun VisionContainerBuilder.cone( +public inline fun MutableVisionContainer.cone( bottomRadius: Number, height: Number, upperRadius: Number = 0.0, startAngle: Number = 0f, angle: Number = PI2, name: String? = null, - block: ConeSegment.() -> Unit = {} + block: ConeSegment.() -> Unit = {}, ): ConeSegment = ConeSegment( bottomRadius.toFloat(), height.toFloat(), topRadius = upperRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() -).apply(block).also { set(name, it) } \ No newline at end of file + phiStart = startAngle.toFloat(), + phi = angle.toFloat() +).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt index 25f79ee8..8ce9ba8c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/ConeSurface.kt @@ -2,10 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -22,27 +21,25 @@ public class ConeSurface( public val height: Float, public val topRadius: Float, public val topInnerRadius: Float, - public val startAngle: Float = 0f, - public val angle: Float = PI2, -) : SolidBase(), GeometrySolid, VisionPropertyContainer { + public val phiStart: Float = 0f, + public val phi: Float = PI2, +) : SolidBase(), GeometrySolid { init { require(bottomRadius > 0) { "Cone surface bottom radius must be positive" } require(height > 0) { "Cone surface height must be positive" } require(bottomInnerRadius >= 0) { "Cone surface bottom inner radius must be non-negative" } //require(startAngle >= 0) - require(angle in (0f..(PI2))) + require(phi in (0f..(PI2))) } override fun toGeometry(geometryBuilder: GeometryBuilder) { val segments = detail ?: 32 require(segments >= 4) { "The number of segments in tube is too small" } - val angleStep = angle / (segments - 1) + val angleStep = phi / (segments - 1) - fun shape(r: Float, z: Float): List { - return (0 until segments).map { i -> - Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) - } + fun shape(r: Float, z: Float): List = (0 until segments).map { i -> + Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z) } geometryBuilder.apply { @@ -51,21 +48,21 @@ public class ConeSurface( val bottomOuterPoints = shape(bottomRadius, -height / 2) val topOuterPoints = shape(topRadius, height / 2) //outer face - (1 until segments).forEach { + for (it in 1 until segments) { face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) } if (bottomInnerRadius == 0f) { - val zeroBottom = Point3D(0f, 0f, 0f) - val zeroTop = Point3D(0f, 0f, height) + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, height / 2) (1 until segments).forEach { face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) } - if (angle == PI2) { + if (phi == PI2) { face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(topOuterPoints.last(), topOuterPoints[0], zeroTop) } else { @@ -99,7 +96,7 @@ public class ConeSurface( topOuterPoints[it] ) } - if (angle == PI2) { + if (phi == PI2) { face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) face4( bottomInnerPoints.last(), @@ -124,7 +121,7 @@ public class ConeSurface( @VisionBuilder -public inline fun VisionContainerBuilder.tube( +public inline fun MutableVisionContainer.tube( radius: Number, height: Number, innerRadius: Number, @@ -138,12 +135,12 @@ public inline fun VisionContainerBuilder.tube( height = height.toFloat(), topRadius = radius.toFloat(), topInnerRadius = innerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() -).apply(block).also { set(name, it) } + phiStart = startAngle.toFloat(), + phi = angle.toFloat() +).apply(block).also { setChild(name, it) } @VisionBuilder -public inline fun VisionContainerBuilder.coneSurface( +public inline fun MutableVisionContainer.coneSurface( bottomOuterRadius: Number, bottomInnerRadius: Number, height: Number, @@ -159,6 +156,6 @@ public inline fun VisionContainerBuilder.coneSurface( height = height.toFloat(), topRadius = topOuterRadius.toFloat(), topInnerRadius = topInnerRadius.toFloat(), - startAngle = startAngle.toFloat(), - angle = angle.toFloat() -).apply(block).also { set(name, it) } \ No newline at end of file + phiStart = startAngle.toFloat(), + phi = angle.toFloat() +).apply(block).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt index 24d1ff16..bd449ce8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Convex.kt @@ -2,22 +2,26 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.setChild +/** + * A convex hull shape + */ @Serializable @SerialName("solid.convex") -public class Convex(public val points: List) : SolidBase(), VisionPropertyContainer +public class Convex(public val points: List) : SolidBase() -public inline fun VisionContainerBuilder.convex(name: String? = null, action: ConvexBuilder.() -> Unit = {}): Convex = - ConvexBuilder().apply(action).build().also { set(name, it) } +public inline fun MutableVisionContainer.convex( + name: String? = null, + action: ConvexBuilder.() -> Unit = {}, +): Convex = ConvexBuilder().apply(action).build().also { setChild(name, it) } public class ConvexBuilder { - private val points = ArrayList() + private val points = ArrayList() public fun point(x: Number, y: Number, z: Number) { - points.add(Point3D(x, y, z)) + points.add(Float32Vector3D(x, y, z)) } public fun build(): Convex { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt new file mode 100644 index 00000000..cc0ef614 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/CutTube.kt @@ -0,0 +1,168 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild +import kotlin.math.abs +import kotlin.math.cos +import kotlin.math.sin + +/** + * A tube section cut with two planes. + * The centers of the two sections are positioned + * along the central axis of the tube, at the top + * and at the bottom. + * + * The default segment number is 32. + */ +@Serializable +@SerialName("solid.cutTube") +public class CutTube( + public val outerRadius: Float, + public val innerRadius: Float, + public val height: Float, + public val phiStart: Float = 0f, + public val phi: Float = PI2, + public val nTop: Float32Vector3D, + public val nBottom: Float32Vector3D, +) : SolidBase(), GeometrySolid { + + init { + require(innerRadius >= 0) { "Tube inner radius must be non-negative" } + require(outerRadius >= 0) { "Tube outer radius must not be less than its inner radius" } + require(height >= 0) { "Tube height must be non-negative" } + //TODO implement more "subtle" section checks + require(abs(nTop.z) > 1e-5) { "Top section is almost vertical" } + require(abs(nBottom.z) > 1e-5) { "Bottom section is almost vertical" } + //require(phiStart >= 0) + require(phi in (0f..(PI2))) + } + + override fun toGeometry(geometryBuilder: GeometryBuilder) { + val segments = detail ?: 32 + require(segments >= 4) { "The number of segments in the tube is too small" } + val angleStep = phi / (segments - 1) + + fun section(r: Float, z: Float, n: Float32Vector3D): List = (0 until segments).map { i -> + val x = r * cos(phiStart + angleStep * i) + val y = r * sin(phiStart + angleStep * i) + Float32Vector3D(x, y, (n.z * z - n.x * x - n.y * y) / n.z) + } + + geometryBuilder.apply { + //creating top and bottom sections of the tube: + //shapes in planes defined with (0, 0, +-z) points and normal vectors + //TODO check for an intersection of the sections + val topOuterPoints = section(outerRadius, height / 2, nTop) + val bottomOuterPoints = section(outerRadius, -height / 2, nBottom) + + + //outer face + for (it in 1 until segments) { + face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) + } + if (phi == PI2) { + face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) + } + + if (innerRadius == 0f) { + val zeroBottom = Float32Vector3D(0f, 0f, -height / 2) + val zeroTop = Float32Vector3D(0f, 0f, height / 2) + (1 until segments).forEach { + face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) + face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop) + } + if (phi == PI2) { + face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) + face(topOuterPoints.last(), topOuterPoints[0], zeroTop) + } else { + face4(zeroTop, zeroBottom, bottomOuterPoints[0], topOuterPoints[0]) + face4(zeroTop, zeroBottom, bottomOuterPoints.last(), topOuterPoints.last()) + } + } else { + val topInnerPoints = section(innerRadius, height / 2, nTop) + val bottomInnerPoints = section(innerRadius, -height / 2, nBottom) + // inner face + (1 until segments).forEach { + // inner surface + face4( + bottomInnerPoints[it], + bottomInnerPoints[it - 1], + topInnerPoints[it - 1], + topInnerPoints[it] + ) + //bottom cup + face4( + bottomInnerPoints[it - 1], + bottomInnerPoints[it], + bottomOuterPoints[it], + bottomOuterPoints[it - 1] + ) + //upper cup + face4( + topInnerPoints[it], + topInnerPoints[it - 1], + topOuterPoints[it - 1], + topOuterPoints[it] + ) + } + if (phi == PI2) { + face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) + face4( + bottomInnerPoints.last(), + bottomInnerPoints[0], + bottomOuterPoints[0], + bottomOuterPoints.last() + ) + face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0]) + } else { + face4(bottomInnerPoints[0], bottomOuterPoints[0], topOuterPoints[0], topInnerPoints[0]) + face4( + bottomOuterPoints.last(), + bottomInnerPoints.last(), + topInnerPoints.last(), + topOuterPoints.last() + ) + } + } + } + } +} + + +/** + * Create a cut tube - a hollow cylinder (or a segment) cut with two planes. The axis of the cylinder + * is the Z axis. Each section is define by a center and a normal vector. The centers of the two sections + * are the points (0, 0, height / 2) and (0, 0, -height / 2). + * + * @param outerRadius outer radius of the tube + * @param innerRadius inner radius if the tube + * @param height height (length) of the tube. Essentially this is the length of the Z axis segment, + * contained between the top and bottom sections of the tube + * @param startAngle start angle of the segment (if this is a segment) + * @param angle angular magnitude of the segment + * @param topNormal normal vector of the top section + * @param bottomNormal normal vector of the bottom section + */ +@VisionBuilder +public inline fun MutableVisionContainer.cutTube( + outerRadius: Number, + innerRadius: Number, + height: Number, + startAngle: Number = 0f, + angle: Number = PI2, + topNormal: Float32Vector3D, + bottomNormal: Float32Vector3D, + name: String? = null, + block: CutTube.() -> Unit = {}, +): CutTube = CutTube( + outerRadius = outerRadius.toFloat(), + innerRadius = innerRadius.toFloat(), + height = height.toFloat(), + phiStart = startAngle.toFloat(), + phi = angle.toFloat(), + nTop = topNormal, + nBottom = bottomNormal +).apply(block).also { setChild(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt index 30ecb575..c2157480 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Extruded.kt @@ -3,71 +3,58 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.MutableMeta -import space.kscience.dataforge.meta.ObservableMutableMeta -import space.kscience.dataforge.meta.configure -import space.kscience.visionforge.* -import kotlin.math.PI -import kotlin.math.cos -import kotlin.math.sin +import space.kscience.dataforge.names.Name +import space.kscience.kmath.geometry.component1 +import space.kscience.kmath.geometry.component2 +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild -public typealias Shape2D = List - -@Serializable -public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { - - public fun point(x: Number, y: Number) { - points.add(Point2D(x, y)) - } - - public infix fun Number.to(y: Number): Unit = point(this, y) - - public fun build(): Shape2D = points -} - -public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { - require(vertices > 2) { "Polygon must have more than 2 vertices" } - val angle = 2 * PI / vertices - for (i in 0 until vertices) { - point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i)) - } -} - -@Serializable -public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) - +/** + * An extruded shape with the same number of points on each layer. + */ @Serializable @SerialName("solid.extrude") public class Extruded( - public val shape: List, - public val layers: List -) : SolidBase(), GeometrySolid, VisionPropertyContainer { + public val shape: Shape2D, + public val layers: List, +) : SolidBase(), GeometrySolid { + + /** + * A layer for extruded shape + */ + @Serializable + public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float) + + init { + require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" } + } override fun toGeometry(geometryBuilder: GeometryBuilder) { - val shape: Shape2D = shape - - if (shape.size < 3) error("Extruded shape requires more than 2 points per layer") /** * Expand the shape for specific layers */ - val layers: List> = layers.map { layer -> + val layers: List> = layers.map { layer -> shape.map { (x, y) -> val newX = layer.x + x * layer.scale val newY = layer.y + y * layer.scale - Point3D(newX, newY, layer.z) + Float32Vector3D(newX, newY, layer.z) } } if (layers.size < 2) error("Extruded shape requires more than one layer") var lowerLayer = layers.first() - var upperLayer: List + var upperLayer: List + + geometryBuilder.cap(layers.first().reversed()) for (i in (1 until layers.size)) { upperLayer = layers[i] for (j in (0 until shape.size - 1)) { - //counter clockwise + //counterclockwise geometryBuilder.face4( lowerLayer[j], lowerLayer[j + 1], @@ -85,37 +72,37 @@ public class Extruded( ) lowerLayer = upperLayer } - geometryBuilder.cap(layers.first().reversed()) + geometryBuilder.cap(layers.last()) } + public class Builder( + public var shape: List = emptyList(), + public var layers: MutableList = ArrayList(), + public val properties: MutableMeta = MutableMeta(), + ) { + @VisionBuilder + public fun shape(block: Shape2DBuilder.() -> Unit) { + this.shape = Shape2DBuilder().apply(block).build() + } + + @VisionBuilder + public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { + layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) + } + + internal fun build(): Extruded = Extruded(shape, layers).apply { + this.properties[Name.EMPTY] = this@Builder.properties + } + } + public companion object { public const val TYPE: String = "solid.extruded" } } -public class ExtrudeBuilder( - public var shape: List = emptyList(), - - public var layers: MutableList = ArrayList(), - - config: ObservableMutableMeta = MutableMeta() -) : SimpleVisionPropertyContainer(config) { - public fun shape(block: Shape2DBuilder.() -> Unit) { - this.shape = Shape2DBuilder().apply(block).build() - } - - public fun layer(z: Number, x: Number = 0.0, y: Number = 0.0, scale: Number = 1.0) { - layers.add(Layer(x.toFloat(), y.toFloat(), z.toFloat(), scale.toFloat())) - } - - internal fun build(): Extruded = Extruded(shape, layers).apply { - configure(this@ExtrudeBuilder.meta) - } -} - @VisionBuilder -public fun VisionContainerBuilder.extruded( +public fun MutableVisionContainer.extruded( name: String? = null, - action: ExtrudeBuilder.() -> Unit = {} -): Extruded = ExtrudeBuilder().apply(action).build().also { set(name, it) } \ No newline at end of file + action: Extruded.Builder.() -> Unit = {}, +): Extruded = Extruded.Builder().apply(action).build().also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt new file mode 100644 index 00000000..08c00d51 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean2DSpace.kt @@ -0,0 +1,70 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector2D +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Euclidean2DSpace.VectorSerializer::class) +public interface Float32Vector2D: Vector2D + +public object Float32Euclidean2DSpace : + GeometrySpace, + ScaleOperations { + + @Serializable + @SerialName("Float32Vector2D") + private data class Vector2DImpl( + override val x: Float, + override val y: Float, + ) : Float32Vector2D + + public object VectorSerializer : KSerializer { + private val proxySerializer = Vector2DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector2D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector2D) { + val vector = value as? Vector2DImpl ?: Vector2DImpl(value.x, value.y) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float): Float32Vector2D = + Vector2DImpl(x, y) + + public fun vector(x: Number, y: Number): Float32Vector2D = + vector(x.toFloat(), y.toFloat()) + + override val zero: Float32Vector2D by lazy { vector(0f, 0f) } + + override fun norm(arg: Float32Vector2D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2)).toDouble() + + public fun Float32Vector2D.norm(): Double = norm(this) + + override fun Float32Vector2D.unaryMinus(): Float32Vector2D = vector(-x, -y) + + override fun Float32Vector2D.distanceTo(other: Float32Vector2D): Double = (this - other).norm() + + override fun add(left: Float32Vector2D, right: Float32Vector2D): Float32Vector2D = + vector(left.x + right.x, left.y + right.y) + + override fun scale(a: Float32Vector2D, value: Double): Float32Vector2D = + vector(a.x * value, a.y * value) + + override fun Float32Vector2D.dot(other: Float32Vector2D): Double = + (x * other.x + y * other.y).toDouble() + + public val xAxis: Float32Vector2D = vector(1.0, 0.0) + public val yAxis: Float32Vector2D = vector(0.0, 1.0) +} + +public fun Float32Vector2D(x: Number, y: Number): Float32Vector2D = Float32Euclidean2DSpace.vector(x, y) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt new file mode 100644 index 00000000..04b3df35 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Float32Euclidean3DSpace.kt @@ -0,0 +1,113 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.KSerializer +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import kotlinx.serialization.descriptors.SerialDescriptor +import kotlinx.serialization.encoding.Decoder +import kotlinx.serialization.encoding.Encoder +import space.kscience.kmath.geometry.GeometrySpace +import space.kscience.kmath.geometry.Vector3D +import space.kscience.kmath.operations.ScaleOperations +import kotlin.math.pow +import kotlin.math.sqrt + +@Serializable(Float32Euclidean3DSpace.VectorSerializer::class) +public interface Float32Vector3D: Vector3D + + +public object Float32Euclidean3DSpace : + GeometrySpace, + ScaleOperations{ + + @Serializable + @SerialName("Float32Vector3D") + private data class Vector3DImpl( + override val x: Float, + override val y: Float, + override val z: Float, + ) : Float32Vector3D + + public object VectorSerializer : KSerializer { + private val proxySerializer = Vector3DImpl.serializer() + override val descriptor: SerialDescriptor get() = proxySerializer.descriptor + + override fun deserialize(decoder: Decoder): Float32Vector3D = decoder.decodeSerializableValue(proxySerializer) + + override fun serialize(encoder: Encoder, value: Float32Vector3D) { + val vector = value as? Vector3DImpl ?: Vector3DImpl(value.x, value.y, value.z) + encoder.encodeSerializableValue(proxySerializer, vector) + } + } + + public fun vector(x: Float, y: Float, z: Float): Float32Vector3D = + Vector3DImpl(x, y, z) + + public fun vector(x: Number, y: Number, z: Number): Float32Vector3D = + vector(x.toFloat(), y.toFloat(), z.toFloat()) + + override val zero: Float32Vector3D by lazy { vector(0.0, 0.0, 0.0) } + + override fun norm(arg: Float32Vector3D): Double = sqrt(arg.x.pow(2) + arg.y.pow(2) + arg.z.pow(2)).toDouble() + + public fun Float32Vector3D.norm(): Double = norm(this) + + override fun Float32Vector3D.unaryMinus(): Float32Vector3D = vector(-x, -y, -z) + + override fun Float32Vector3D.distanceTo(other: Float32Vector3D): Double = (this - other).norm() + + override fun add(left: Float32Vector3D, right: Float32Vector3D): Float32Vector3D = + vector(left.x + right.x, left.y + right.y, left.z + right.z) + + override fun scale(a: Float32Vector3D, value: Double): Float32Vector3D = + vector(a.x * value, a.y * value, a.z * value) + + override fun Float32Vector3D.dot(other: Float32Vector3D): Double = + (x * other.x + y * other.y + z * other.z).toDouble() + + private fun leviCivita(i: Int, j: Int, k: Int): Int = when { + // even permutation + i == 0 && j == 1 && k == 2 -> 1 + i == 1 && j == 2 && k == 0 -> 1 + i == 2 && j == 0 && k == 1 -> 1 + // odd permutations + i == 2 && j == 1 && k == 0 -> -1 + i == 0 && j == 2 && k == 1 -> -1 + i == 1 && j == 0 && k == 2 -> -1 + + else -> 0 + } + + /** + * Compute vector product of [first] and [second]. The basis is assumed to be right-handed. + */ + public fun vectorProduct( + first: Float32Vector3D, + second: Float32Vector3D, + ): Float32Vector3D { + var x = 0.0 + var y = 0.0 + var z = 0.0 + + for (j in (0..2)) { + for (k in (0..2)) { + x += leviCivita(0, j, k) * first[j] * second[k] + y += leviCivita(1, j, k) * first[j] * second[k] + z += leviCivita(2, j, k) * first[j] * second[k] + } + } + + return vector(x, y, z) + } + + /** + * Vector product in a right-handed basis + */ + public infix fun Float32Vector3D.cross(other: Float32Vector3D): Float32Vector3D = vectorProduct(this, other) + + public val xAxis: Float32Vector3D = vector(1.0, 0.0, 0.0) + public val yAxis: Float32Vector3D = vector(0.0, 1.0, 0.0) + public val zAxis: Float32Vector3D = vector(0.0, 0.0, 1.0) +} + +public fun Float32Vector3D(x: Number, y: Number, z: Number): Float32Vector3D = Float32Euclidean3DSpace.vector(x,y,z) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt index 3cfc5da9..ab24f8ce 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/GeometryBuilder.kt @@ -13,17 +13,17 @@ public interface GeometryBuilder { * @param normal optional external normal to the face * @param meta optional additional platform-specific parameters like color or texture index */ - public fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D? = null, meta: Meta = Meta.EMPTY) + public fun face(vertex1: Float32Vector3D, vertex2: Float32Vector3D, vertex3: Float32Vector3D, normal: Float32Vector3D? = null, meta: Meta = Meta.EMPTY) public fun build(): T } public fun GeometryBuilder<*>.face4( - vertex1: Point3D, - vertex2: Point3D, - vertex3: Point3D, - vertex4: Point3D, - normal: Point3D? = null, + vertex1: Float32Vector3D, + vertex2: Float32Vector3D, + vertex3: Float32Vector3D, + vertex4: Float32Vector3D, + normal: Float32Vector3D? = null, meta: Meta = Meta.EMPTY ) { face(vertex1, vertex2, vertex3, normal, meta) @@ -37,9 +37,9 @@ public interface GeometrySolid : Solid { public fun toGeometry(geometryBuilder: GeometryBuilder) } -public fun GeometryBuilder.cap(shape: List, normal: Point3D? = null) { +public fun GeometryBuilder.cap(shape: List, normal: Float32Vector3D? = null) { //FIXME won't work for non-convex shapes - val center = Point3D( + val center = Float32Vector3D( shape.map { it.x }.average(), shape.map { it.y }.average(), shape.map { it.z }.average() diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt index 7f42a3eb..12e661eb 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Hexagon.kt @@ -2,19 +2,19 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild public interface Hexagon : GeometrySolid { - public val node1: Point3D - public val node2: Point3D - public val node3: Point3D - public val node4: Point3D - public val node5: Point3D - public val node6: Point3D - public val node7: Point3D - public val node8: Point3D + public val node1: Float32Vector3D + public val node2: Float32Vector3D + public val node3: Float32Vector3D + public val node4: Float32Vector3D + public val node5: Float32Vector3D + public val node6: Float32Vector3D + public val node7: Float32Vector3D + public val node8: Float32Vector3D override fun toGeometry(geometryBuilder: GeometryBuilder) { geometryBuilder.face4(node1, node4, node3, node2) @@ -35,54 +35,54 @@ public class Box( public val xSize: Float, public val ySize: Float, public val zSize: Float, -) : SolidBase(), Hexagon { +) : SolidBase(), Hexagon { private inline val dx get() = xSize / 2 private inline val dy get() = ySize / 2 private inline val dz get() = zSize / 2 - override val node1: Point3D get() = Point3D(-dx, -dy, -dz) - override val node2: Point3D get() = Point3D(dx, -dy, -dz) - override val node3: Point3D get() = Point3D(dx, dy, -dz) - override val node4: Point3D get() = Point3D(-dx, dy, -dz) - override val node5: Point3D get() = Point3D(-dx, -dy, dz) - override val node6: Point3D get() = Point3D(dx, -dy, dz) - override val node7: Point3D get() = Point3D(dx, dy, dz) - override val node8: Point3D get() = Point3D(-dx, dy, dz) + override val node1: Float32Vector3D get() = Float32Vector3D(-dx, -dy, -dz) + override val node2: Float32Vector3D get() = Float32Vector3D(dx, -dy, -dz) + override val node3: Float32Vector3D get() = Float32Vector3D(dx, dy, -dz) + override val node4: Float32Vector3D get() = Float32Vector3D(-dx, dy, -dz) + override val node5: Float32Vector3D get() = Float32Vector3D(-dx, -dy, dz) + override val node6: Float32Vector3D get() = Float32Vector3D(dx, -dy, dz) + override val node7: Float32Vector3D get() = Float32Vector3D(dx, dy, dz) + override val node8: Float32Vector3D get() = Float32Vector3D(-dx, dy, dz) } @VisionBuilder -public inline fun VisionContainerBuilder.box( +public inline fun MutableVisionContainer.box( xSize: Number, ySize: Number, zSize: Number, name: String? = null, block: Box.() -> Unit = {}, -): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { set(name, it) } +): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { setChild(name, it) } @Serializable @SerialName("solid.hexagon") public class GenericHexagon( - override val node1: Point3D, - override val node2: Point3D, - override val node3: Point3D, - override val node4: Point3D, - override val node5: Point3D, - override val node6: Point3D, - override val node7: Point3D, - override val node8: Point3D, -) : SolidBase(), Hexagon + override val node1: Float32Vector3D, + override val node2: Float32Vector3D, + override val node3: Float32Vector3D, + override val node4: Float32Vector3D, + override val node5: Float32Vector3D, + override val node6: Float32Vector3D, + override val node7: Float32Vector3D, + override val node8: Float32Vector3D, +) : SolidBase(), Hexagon @VisionBuilder -public inline fun VisionContainerBuilder.hexagon( - node1: Point3D, - node2: Point3D, - node3: Point3D, - node4: Point3D, - node5: Point3D, - node6: Point3D, - node7: Point3D, - node8: Point3D, +public inline fun MutableVisionContainer.hexagon( + node1: Float32Vector3D, + node2: Float32Vector3D, + node3: Float32Vector3D, + node4: Float32Vector3D, + node5: Float32Vector3D, + node6: Float32Vector3D, + node7: Float32Vector3D, + node8: Float32Vector3D, name: String? = null, action: Hexagon.() -> Unit = {}, -): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { set(name, it) } \ No newline at end of file +): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt new file mode 100644 index 00000000..9f970bf0 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/LightSource.kt @@ -0,0 +1,75 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.ValueType +import space.kscience.dataforge.meta.descriptors.MetaDescriptor +import space.kscience.dataforge.meta.descriptors.node +import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.number +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.* + +@Serializable +public abstract class LightSource : MiscSolid() { + override val descriptor: MetaDescriptor get() = LightSource.descriptor + + public val color: ColorAccessor by colorProperty(SolidMaterial.COLOR_KEY) + public var intensity: Number by properties.root(includeStyles = false).number(INTENSITY_KEY) { 1.0 } + + public companion object { + public val INTENSITY_KEY: Name = "intensity".asName() + + public val descriptor: MetaDescriptor by lazy { + MetaDescriptor { + value(Vision.VISIBLE_KEY, ValueType.BOOLEAN) { + inherited = false + default(true) + } + + value(LightSource::color.name, ValueType.STRING, ValueType.NUMBER) { + inherited = false + widgetType = "color" + default(Colors.white) + } + + value(LightSource::intensity.name, ValueType.NUMBER) { + inherited = false + default(1.0) + } + + node(Solid.POSITION_KEY) { + hide() + } + } + } + } +} + +@Serializable +@SerialName("solid.light.ambient") +public class AmbientLightSource : LightSource() + +@VisionBuilder +public fun MutableVisionContainer.ambientLight( + name: String? = "@ambientLight", + block: AmbientLightSource.() -> Unit = {}, +): AmbientLightSource = AmbientLightSource().apply(block).also { setChild(name, it) } + +@Serializable +@SerialName("solid.light.point") +public class PointLightSource : LightSource() + + +@VisionBuilder +public fun MutableVisionContainer.pointLight( + x: Number, + y: Number, + z: Number, + name: String? = null, + block: PointLightSource.() -> Unit = {}, +): PointLightSource = PointLightSource().apply(block).also { + it.position = Float32Vector3D(x, y, z) + setChild(name, it) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt new file mode 100644 index 00000000..6a2fdb08 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/MiscSolid.kt @@ -0,0 +1,33 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild + +/** + * Utility solids + */ +@Serializable +public abstract class MiscSolid: SolidBase() + +/** + * X-Y-Z axes + */ +@Serializable +@SerialName("solid.axes") +public class AxesSolid(public val size: Double): MiscSolid(){ + public companion object{ + public const val AXES_NAME: String = "@axes" + } +} + +@VisionBuilder +public fun MutableVisionContainer.axes( + size: Number, + name: String = "@axes", + block: AxesSolid.() -> Unit = {}, +): AxesSolid = AxesSolid(size.toDouble()).apply(block).also { + setChild(name, it) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt index 05d58744..0ead1642 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/PolyLine.kt @@ -2,28 +2,30 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.plus -import space.kscience.visionforge.* +import space.kscience.dataforge.meta.number +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.root +import space.kscience.visionforge.setChild @Serializable @SerialName("solid.line") -public class PolyLine(public val points: List) : SolidBase(), VisionPropertyContainer { +public class PolyLine(public val points: List) : SolidBase() { //var lineType by string() - public var thickness: Number by numberProperty(name = SolidMaterial.MATERIAL_KEY + THICKNESS_KEY) { 1.0 } - + public var thickness: Number by properties.root( + inherit = false, + includeStyles = true + ).number { DEFAULT_THICKNESS } public companion object { - public val THICKNESS_KEY: Name = "thickness".asName() + public const val DEFAULT_THICKNESS: Double = 1.0 } - } @VisionBuilder -public fun VisionContainerBuilder.polyline( - vararg points: Point3D, +public fun MutableVisionContainer.polyline( + vararg points: Float32Vector3D, name: String? = null, action: PolyLine.() -> Unit = {}, -): PolyLine = PolyLine(points.toList()).apply(action).also { set(name, it) } \ No newline at end of file +): PolyLine = PolyLine(points.toList()).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt deleted file mode 100644 index 617c7a38..00000000 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Quaternion.kt +++ /dev/null @@ -1,11 +0,0 @@ -package space.kscience.visionforge.solid - -import kotlin.jvm.JvmInline - -@JvmInline -public value class Quaternion(public val values: DoubleArray) - -public operator fun Quaternion.component1(): Double = values[0] -public operator fun Quaternion.component2(): Double = values[1] -public operator fun Quaternion.component3(): Double = values[2] -public operator fun Quaternion.component4(): Double = values[3] \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt new file mode 100644 index 00000000..a73b97e0 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Shape2D.kt @@ -0,0 +1,29 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.Serializable +import kotlin.math.PI +import kotlin.math.cos +import kotlin.math.sin + +public typealias Shape2D = List + +/** + * A builder for 2D shapes + */ +@Serializable +public class Shape2DBuilder(private val points: ArrayList = ArrayList()) { + + public fun point(x: Number, y: Number) { + points.add(Float32Vector2D(x, y)) + } + + public fun build(): Shape2D = points +} + +public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) { + require(vertices > 2) { "Polygon must have more than 2 vertices" } + val angle = 2 * PI / vertices + for (i in 0 until vertices) { + point(radius.toDouble() * cos(angle * i), radius.toDouble() * sin(angle * i)) + } +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt index 2b9c883b..aab583a0 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solid.kt @@ -1,21 +1,20 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.enum import space.kscience.dataforge.meta.descriptors.node import space.kscience.dataforge.meta.descriptors.value -import space.kscience.dataforge.meta.float -import space.kscience.dataforge.meta.get -import space.kscience.dataforge.meta.number import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.* +import space.kscience.kmath.complex.Quaternion +import space.kscience.kmath.complex.QuaternionField +import space.kscience.kmath.geometry.* import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision.Companion.VISIBLE_KEY import space.kscience.visionforge.hide import space.kscience.visionforge.inherited -import space.kscience.visionforge.setProperty import space.kscience.visionforge.solid.Solid.Companion.DETAIL_KEY import space.kscience.visionforge.solid.Solid.Companion.IGNORE_KEY import space.kscience.visionforge.solid.Solid.Companion.LAYER_KEY @@ -38,7 +37,7 @@ import kotlin.properties.ReadWriteProperty import kotlin.reflect.KProperty /** - * Interface for 3-dimensional [Vision] + * Interface for a [Vision] representing a 3D object */ public interface Solid : Vision { @@ -119,101 +118,142 @@ public interface Solid : Vision { * Get the layer number this solid belongs to. Return 0 if layer is not defined. */ public var Solid.layer: Int - get() = getPropertyValue(LAYER_KEY, inherit = true)?.int ?: 0 + get() = properties.getValue(LAYER_KEY, inherit = true)?.int ?: 0 set(value) { - setProperty(LAYER_KEY, value) + properties[LAYER_KEY] = value } // Common properties -public enum class RotationOrder { - XYZ, - YZX, - ZXY, - XZY, - YXZ, - ZYX -} - /** * Rotation order */ public var Solid.rotationOrder: RotationOrder - get() = getPropertyValue(Solid.ROTATION_ORDER_KEY)?.enum() ?: RotationOrder.XYZ - set(value) = meta.setValue(Solid.ROTATION_ORDER_KEY, value.name.asValue()) + get() = properties.getValue(Solid.ROTATION_ORDER_KEY)?.enum() ?: RotationOrder.XYZ + set(value) = properties.setValue(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 */ public var Solid.detail: Int? - get() = getPropertyValue(DETAIL_KEY, false)?.int - set(value) = meta.setValue(DETAIL_KEY, value?.asValue()) + get() = properties.getValue(DETAIL_KEY, inherit = false)?.int + set(value) = properties.setValue(DETAIL_KEY, value?.asValue()) /** * If this property is true, the object will be ignored on render. * Property is not inherited. */ public var Vision.ignore: Boolean? - get() = getPropertyValue(IGNORE_KEY, false)?.boolean - set(value) = meta.setValue(IGNORE_KEY, value?.asValue()) + get() = properties.getValue(IGNORE_KEY, inherit = false, includeStyles = false)?.boolean + set(value) = properties.setValue(IGNORE_KEY, value?.asValue()) //var VisualObject.selected: Boolean? // get() = getProperty(SELECTED_KEY).boolean // set(value) = setProperty(SELECTED_KEY, value) -internal fun float(name: Name, default: Number): ReadWriteProperty = +/** + *A [Float] solid property delegate + */ +internal fun float32(name: Name, default: Number): ReadWriteProperty = object : ReadWriteProperty { override fun getValue(thisRef: Solid, property: KProperty<*>): Number { - return thisRef.meta.getMeta(name)?.number ?: default + return thisRef.properties.getValue(name)?.number ?: default } override fun setValue(thisRef: Solid, property: KProperty<*>, value: Number) { - thisRef.setProperty(name, value) + thisRef.properties.setValue(name, value.asValue()) } } -internal fun point(name: Name, default: Float): ReadWriteProperty = - object : ReadWriteProperty { - override fun getValue(thisRef: Solid, property: KProperty<*>): Point3D? { - val item = thisRef.meta.getMeta(name) ?: return null - return object : Point3D { - override val x: Float get() = item[X_KEY]?.float ?: default - override val y: Float get() = item[Y_KEY]?.float ?: default - override val z: Float get() = item[Z_KEY]?.float ?: default +/** + * A [Float32Vector3D] solid property delegate + */ +internal fun float32Vector( + name: Name, + defaultX: Float, + defaultY: Float = defaultX, + defaultZ: Float = defaultX, +): ReadWriteProperty = + object : ReadWriteProperty { + override fun getValue(thisRef: Solid, property: KProperty<*>): Float32Vector3D? { + val item = thisRef.properties.own?.get(name) ?: return null + //using dynamic property accessor because values could change + return object : Float32Vector3D { + override val x: Float get() = item[X_KEY]?.float ?: defaultX + override val y: Float get() = item[Y_KEY]?.float ?: defaultY + override val z: Float get() = item[Z_KEY]?.float ?: defaultZ + + override fun toString(): String = item.toString() } } - override fun setValue(thisRef: Solid, property: KProperty<*>, value: Point3D?) { + override fun setValue(thisRef: Solid, property: KProperty<*>, value: Float32Vector3D?) { if (value == null) { - thisRef.meta.setMeta(name, null) + thisRef.properties[name] = null } else { - thisRef.setProperty(name + X_KEY, value.x) - thisRef.setProperty(name + Y_KEY, value.y) - thisRef.setProperty(name + Z_KEY, value.z) + thisRef.properties[name + X_KEY] = value.x + thisRef.properties[name + Y_KEY] = value.y + thisRef.properties[name + Z_KEY] = value.z } } } -public var Solid.position: Point3D? by point(POSITION_KEY, 0f) -public var Solid.rotation: Point3D? by point(ROTATION_KEY, 0f) -public var Solid.scale: Point3D? by point(SCALE_KEY, 1f) +public var Solid.position: Float32Vector3D? by float32Vector(POSITION_KEY, 0f) +public var Solid.rotation: Float32Vector3D? by float32Vector(ROTATION_KEY, 0f) +public var Solid.scale: Float32Vector3D? by float32Vector(SCALE_KEY, 1f) -public var Solid.x: Number by float(X_POSITION_KEY, 0f) -public var Solid.y: Number by float(Y_POSITION_KEY, 0f) -public var Solid.z: Number by float(Z_POSITION_KEY, 0f) +public var Solid.x: Number by float32(X_POSITION_KEY, 0f) +public var Solid.y: Number by float32(Y_POSITION_KEY, 0f) +public var Solid.z: Number by float32(Z_POSITION_KEY, 0f) -public var Solid.rotationX: Number by float(X_ROTATION_KEY, 0f) -public var Solid.rotationY: Number by float(Y_ROTATION_KEY, 0f) -public var Solid.rotationZ: Number by float(Z_ROTATION_KEY, 0f) +public var Solid.rotationX: Number by float32(X_ROTATION_KEY, 0f) +public var Solid.rotationY: Number by float32(Y_ROTATION_KEY, 0f) +public var Solid.rotationZ: Number by float32(Z_ROTATION_KEY, 0f) -//public var Solid.quaternion: Quaternion? -// get() = meta[Solid::quaternion.name]?.value?.doubleArray?.let { Quaternion(it) } -// set(value) { -// meta[Solid::quaternion.name] = value?.values?.asValue() -// } +/** + * Raw quaternion value defined in properties + */ +public var Solid.quaternionOrNull: Quaternion? + get() = properties.getValue(ROTATION_KEY)?.list?.let { + require(it.size == 4) { "Quaternion must be a number array of 4 elements" } + Quaternion(it[0].float, it[1].float, it[2].float, it[3].float) + } + set(value) { + properties.setValue( + ROTATION_KEY, + value?.let { + ListValue( + value.w, + value.x, + value.y, + value.z + ) + } + ) + } +/** + * Quaternion value including information from euler angles + */ +public var Solid.quaternion: Quaternion + get() = quaternionOrNull ?: Quaternion.fromEuler( + rotationX.radians, + rotationY.radians, + rotationZ.radians, + rotationOrder + ) + set(value) { + quaternionOrNull = value + } -public var Solid.scaleX: Number by float(X_SCALE_KEY, 1f) -public var Solid.scaleY: Number by float(Y_SCALE_KEY, 1f) -public var Solid.scaleZ: Number by float(Z_SCALE_KEY, 1f) \ No newline at end of file +public var Solid.scaleX: Number by float32(X_SCALE_KEY, 1f) +public var Solid.scaleY: Number by float32(Y_SCALE_KEY, 1f) +public var Solid.scaleZ: Number by float32(Z_SCALE_KEY, 1f) + +/** + * Add rotation with given [angle] relative to given [axis] + */ +public fun Solid.rotate(angle: Angle, axis: DoubleVector3D): Unit = with(QuaternionField) { + quaternion = Quaternion.fromRotation(angle, axis)*quaternion +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt index 70e2501e..49452bf3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidBase.kt @@ -3,10 +3,13 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.AbstractVision +/** + * An abstract solid that is both [Solid] and [AbstractVision] + */ @Serializable @SerialName("solid") -public open class SolidBase : VisionBase(), Solid { +public open class SolidBase : AbstractVision(), Solid { override val descriptor: MetaDescriptor get() = Solid.descriptor } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt index a501f7a0..d36057d3 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidGroup.kt @@ -5,17 +5,22 @@ import kotlinx.serialization.Serializable import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.NameToken -import space.kscience.visionforge.* +import space.kscience.dataforge.names.parseAsName +import space.kscience.visionforge.AbstractVisionGroup +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.MutableVisionGroup +import space.kscience.visionforge.VisionBuilder + /** * A container with prototype support */ public interface PrototypeHolder { /** - * Build or update prototype tree + * Build or update the prototype tree */ @VisionBuilder - public fun prototypes(builder: VisionContainerBuilder.() -> Unit) + public fun prototypes(builder: MutableVisionContainer.() -> Unit) /** * Resolve a prototype from this container. Should never return a ref. @@ -23,20 +28,30 @@ public interface PrototypeHolder { public fun getPrototype(name: Name): Solid? } + /** - * Represents 3-dimensional Visual Group - * @param prototypes A container for templates visible inside this group + * A [Solid] group with additional accessor methods */ @Serializable @SerialName("group.solid") -public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { +public class SolidGroup : AbstractVisionGroup(), Solid, PrototypeHolder, MutableVisionGroup, + MutableVisionContainer { - override val children: Map get() = super.childrenInternal.filter { it.key != PROTOTYPES_TOKEN } + public val items: Map + get() = children.keys.mapNotNull { + val value = children[it] as? Solid ?: return@mapNotNull null + it to value + }.toMap() - private var prototypes: MutableVisionGroup? - get() = childrenInternal[PROTOTYPES_TOKEN] as? MutableVisionGroup + /** + * Get a child solid with given relative [name] if it exists + */ + public operator fun get(name: Name): Solid? = children.getChild(name) as? Solid + + private var prototypes: SolidGroup? + get() = items[PROTOTYPES_TOKEN] as? SolidGroup set(value) { - set(PROTOTYPES_TOKEN, value) + children[PROTOTYPES_TOKEN] = value } @@ -44,47 +59,53 @@ public class SolidGroup : VisionGroupBase(), Solid, PrototypeHolder { /** * Get a prototype redirecting the request to the parent if prototype is not found. - * If prototype is a ref, then it is unfolded automatically. + * If a prototype is a ref, then it is unfolded automatically. */ override fun getPrototype(name: Name): Solid? = - prototypes?.get(name)?.unref ?: (parent as? PrototypeHolder)?.getPrototype(name) + prototypes?.get(name)?.prototype ?: (parent as? PrototypeHolder)?.getPrototype(name) /** * Create or edit prototype node as a group */ - override fun prototypes(builder: VisionContainerBuilder.() -> Unit): Unit { - (prototypes ?: SolidGroup().also { - prototypes = it - }).run(builder) + override fun prototypes(builder: MutableVisionContainer.() -> Unit): Unit { + (prototypes ?: SolidGroup().also { prototypes = it }).children.run(builder) } override fun createGroup(): SolidGroup = SolidGroup() - // // override fun update(change: VisionChange) { // updatePosition(change.properties) // super.update(change) // } + override fun setChild(name: Name?, child: Solid?) { + children.setChild(name, child) + } + public companion object { public val PROTOTYPES_TOKEN: NameToken = NameToken("@prototypes") } } -@Suppress("FunctionName") -public fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup { - return SolidGroup().apply(block) -} +public operator fun SolidGroup.get(name:String): Solid? = get(name.parseAsName()) @VisionBuilder -public fun VisionContainerBuilder.group( +public inline fun MutableVisionContainer.solidGroup( name: Name? = null, builder: SolidGroup.() -> Unit = {}, -): SolidGroup = SolidGroup().apply(builder).also { set(name, it) } +): SolidGroup = SolidGroup().also { setChild(name, it) }.apply(builder) +//root first, update later /** * Define a group with given [name], attach it to this parent and return it. */ @VisionBuilder -public fun VisionContainerBuilder.group(name: String, action: SolidGroup.() -> Unit = {}): SolidGroup = - SolidGroup().apply(action).also { set(name, it) } +public inline fun MutableVisionContainer.solidGroup( + name: String, + action: SolidGroup.() -> Unit = {}, +): SolidGroup = solidGroup(name.parseAsName(), action) + +/** + * Create a [SolidGroup] using given configuration [block] + */ +public inline fun SolidGroup(block: SolidGroup.() -> Unit): SolidGroup = SolidGroup().apply(block) \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt index 8cf27881..2e59c1f8 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidLabel.kt @@ -2,10 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild @Serializable @SerialName("solid.label") @@ -13,13 +12,13 @@ public class SolidLabel( public val text: String, public val fontSize: Double, public val fontFamily: String, -) : SolidBase(), VisionPropertyContainer +) : SolidBase() @VisionBuilder -public fun VisionContainerBuilder.label( +public fun MutableVisionContainer.label( text: String, fontSize: Number = 20, fontFamily: String = "Arial", name: String? = null, action: SolidLabel.() -> Unit = {}, -): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { set(name, it) } \ No newline at end of file +): SolidLabel = SolidLabel(text, fontSize.toDouble(), fontFamily).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt index fa5b0d76..c411cf4c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidMaterial.kt @@ -3,17 +3,18 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.plus -import space.kscience.dataforge.values.ValueType -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.number import space.kscience.visionforge.* import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_OPACITY_KEY +/** + * A scheme for vision material + */ @VisionBuilder public class SolidMaterial : Scheme() { @@ -27,7 +28,7 @@ public class SolidMaterial : Scheme() { */ public val specularColor: ColorAccessor = ColorAccessor(meta, SPECULAR_COLOR_KEY) - public val emissiveColor: ColorAccessor = ColorAccessor(meta, "emissiveColor".asName()) + public val emissiveColor: ColorAccessor = ColorAccessor(meta, EMISSIVE_COLOR_KEY) /** * Opacity @@ -43,19 +44,33 @@ public class SolidMaterial : Scheme() { public val MATERIAL_KEY: Name = "material".asName() public val COLOR_KEY: Name = "color".asName() - public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY + public val TYPE_KEY: Name = "type".asName() public val SPECULAR_COLOR_KEY: Name = "specularColor".asName() - public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY + public val EMISSIVE_COLOR_KEY: Name = "emissiveColor".asName() public val OPACITY_KEY: Name = "opacity".asName() public val MATERIAL_OPACITY_KEY: Name = MATERIAL_KEY + OPACITY_KEY public val WIREFRAME_KEY: Name = "wireframe".asName() + public val MATERIAL_COLOR_KEY: Name = MATERIAL_KEY + COLOR_KEY + public val MATERIAL_EMISSIVE_COLOR_KEY: Name = MATERIAL_KEY + EMISSIVE_COLOR_KEY + public val MATERIAL_SPECULAR_COLOR_KEY: Name = MATERIAL_KEY + SPECULAR_COLOR_KEY public val MATERIAL_WIREFRAME_KEY: Name = MATERIAL_KEY + WIREFRAME_KEY + public val EDGES_KEY: Name = "edges".asName() + public val ENABLED_KEY: Name = "enabled".asName() + public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY + public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + MATERIAL_KEY + public override val descriptor: MetaDescriptor by lazy { //must be lazy to avoid initialization bug MetaDescriptor { inherited = true + value(TYPE_KEY, ValueType.STRING){ + inherited = true + allowedValues = listOf("default".asValue(), "simple".asValue()) + default("default") + } + value(COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { inherited = true widgetType = "color" @@ -67,6 +82,12 @@ public class SolidMaterial : Scheme() { hide() } + value(EMISSIVE_COLOR_KEY, ValueType.STRING, ValueType.NUMBER) { + inherited = true + widgetType = "color" + hide() + } + value(OPACITY_KEY, ValueType.NUMBER) { inherited = true default(1.0) @@ -86,19 +107,26 @@ public class SolidMaterial : Scheme() { } public val Solid.color: ColorAccessor - get() = ColorAccessor(computePropertyValues(), MATERIAL_COLOR_KEY) + get() = ColorAccessor(properties.root(true), MATERIAL_COLOR_KEY) public var Solid.material: SolidMaterial? - get() = computePropertyNode(MATERIAL_KEY)?.let { SolidMaterial.read(it) } - set(value) = meta.setMeta(MATERIAL_KEY, value?.meta) + get() = SolidMaterial.read(properties[MATERIAL_KEY]) + set(value) = properties.set(MATERIAL_KEY, value?.meta) @VisionBuilder public fun Solid.material(builder: SolidMaterial.() -> Unit) { - meta.getOrCreate(MATERIAL_KEY).updateWith(SolidMaterial, builder) + properties[MATERIAL_KEY].updateWith(SolidMaterial, builder) } public var Solid.opacity: Number? - get() = getPropertyValue(MATERIAL_OPACITY_KEY, inherit = true)?.number + get() = properties.getValue(MATERIAL_OPACITY_KEY, inherit = true)?.number set(value) { - meta.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) - } \ No newline at end of file + properties.setValue(MATERIAL_OPACITY_KEY, value?.asValue()) + } + + +@VisionBuilder +public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { + properties[SolidMaterial.EDGES_ENABLED_KEY] = enabled + SolidMaterial.write(properties[SolidMaterial.EDGES_MATERIAL_KEY]).apply(block) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt index 04c54907..b832865c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SolidReference.kt @@ -1,182 +1,243 @@ package space.kscience.visionforge.solid +import kotlinx.coroutines.DelicateCoroutinesApi +import kotlinx.coroutines.GlobalScope +import kotlinx.coroutines.flow.Flow +import kotlinx.coroutines.flow.emptyFlow +import kotlinx.coroutines.flow.filter +import kotlinx.coroutines.launch import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable -import space.kscience.dataforge.meta.ObservableMutableMeta +import kotlinx.serialization.Transient +import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor -import space.kscience.dataforge.meta.get +import space.kscience.dataforge.meta.descriptors.get import space.kscience.dataforge.names.* -import space.kscience.dataforge.values.Value import space.kscience.visionforge.* - - -public interface SolidReference : VisionGroup { - /** - * The prototype for this reference. - */ - public val prototype: Solid - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean - ): Value? { - meta[name]?.value?.let { return it } - if (includeStyles) { - getStyleProperty(name)?.let { return it } - } - prototype.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - if (inherit) { - parent?.getPropertyValue(name, inherit, includeStyles, includeDefaults)?.let { return it } - } - return null - } -} +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX /** * Get a vision prototype if it is a [SolidReference] or vision itself if it is not. * Unref is recursive, so it always returns a non-reference. */ -public val Vision.unref: Solid +@Suppress("RecursivePropertyAccessor") +public val Vision.prototype: Solid get() = when (this) { - is SolidReference -> prototype.unref + is SolidReference -> prototype.prototype + is SolidReferenceChild -> prototype.prototype is Solid -> this else -> error("This Vision is neither Solid nor SolidReference") } -private fun childToken(childName: Name): NameToken = - NameToken(SolidReferenceGroup.REFERENCE_CHILD_PROPERTY_PREFIX, childName.toString()) - -private fun childPropertyName(childName: Name, propertyName: Name): Name = - childToken(childName) + propertyName - -/** - * A reference [Solid] to reuse a template object - */ @Serializable @SerialName("solid.ref") -public class SolidReferenceGroup( - public val refName: Name, -) : VisionBase(), SolidReference, VisionGroup, Solid { +public class SolidReference( + @SerialName("prototype") public val prototypeName: Name, +) : VisionGroup, Solid { + + @Transient + override var parent: Vision? = null /** - * Recursively search for defined template in the parent + * The prototype for this reference. */ - override val prototype: Solid by lazy { - if (parent == null) error("No parent is present for SolidReferenceGroup") + public val prototype: Solid by lazy { + //Recursively search for defined template in the parent + if (parent == null) error("No parent is present for SolidReference") if (parent !is PrototypeHolder) error("Parent does not hold prototypes") - (parent as? PrototypeHolder)?.getPrototype(refName) ?: error("Prototype with name $refName not found") + (parent as? PrototypeHolder)?.getPrototype(prototypeName) + ?: error("Prototype with name $prototypeName not found") } - - override val children: Map - get() = (prototype as? VisionGroup)?.children - ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } - ?.mapValues { - ReferenceChild(this, it.key.asName()) - } ?: emptyMap() - - override fun getPropertyValue( - name: Name, - inherit: Boolean, - includeStyles: Boolean, - includeDefaults: Boolean - ): Value? = super.getPropertyValue(name, inherit, includeStyles, includeDefaults) - override val descriptor: MetaDescriptor get() = prototype.descriptor + @SerialName("properties") + private var propertiesInternal: MutableMeta? = null - /** - * A ProxyChild is created temporarily only to interact with properties, it does not store any values - * (properties are stored in external cache) and created and destroyed on-demand). - */ - private class ReferenceChild( - val owner: SolidReferenceGroup, - private val refName: Name - ) : SolidReference, VisionGroup, Solid { + override val properties: MutableVisionProperties by lazy { + object : AbstractVisionProperties(this) { + override var properties: MutableMeta? + get() = propertiesInternal + set(value) { + propertiesInternal = value + } - override val prototype: Solid by lazy { - if (refName.isEmpty()) { - owner.prototype - } else { - val proto = (owner.prototype as? VisionGroup)?.get(refName) - ?: error("Prototype with name $refName not found in SolidReferenceGroup ${owner.refName}") - proto as? Solid ?: error("Prototype with name $refName is ${proto::class} but expected Solid") -// proto.unref as? Solid -// ?: error("Prototype with name $refName is ${proto::class} but expected Solid") - } - } + override fun getValue(name: Name, inherit: Boolean?, includeStyles: Boolean?): Value? { + if (name == Vision.STYLE_KEY) { + return buildList { + properties?.getValue(Vision.STYLE_KEY)?.list?.forEach { + add(it) + } + prototype.styles.forEach { + add(it.asValue()) + } + }.distinct().asValue() + } + //1. resolve own properties + properties?.getValue(name)?.let { return it } - override val meta: ObservableMutableMeta by lazy { - owner.meta.getOrCreate(childToken(refName).asName()) - } + val descriptor = descriptor?.get(name) + val inheritFlag = inherit ?: descriptor?.inherited ?: false + val stylesFlag = includeStyles ?: descriptor?.usesStyles ?: true - override val children: Map - get() = (prototype as? VisionGroup)?.children - ?.filter { it.key != SolidGroup.PROTOTYPES_TOKEN } - ?.mapValues { (key, _) -> - ReferenceChild(owner, refName + key.asName()) - } ?: emptyMap() + //2. Resolve prototype onw properties + prototype.properties.own?.getValue(name)?.let { return it } - override var parent: VisionGroup? - get() { - val parentName = refName.cutLast() - return if (parentName.isEmpty()) owner else ReferenceChild(owner, parentName) - } - set(_) { - error("Setting a parent for a reference child is not possible") + if (stylesFlag) { + //3. own styles + own?.getValue(Vision.STYLE_KEY)?.list?.forEach { styleName -> + getStyle(styleName.string)?.getValue(name)?.let { return it } + } + //4. prototype styles + prototype.getStyleProperty(name)?.value?.let { return it } + } + + if (inheritFlag) { + //5. own inheritance + parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } + //6. prototype inheritance + prototype.parent?.properties?.getValue(name, inheritFlag, includeStyles)?.let { return it } + } + + return descriptor?.defaultValue } - override fun invalidateProperty(propertyName: Name) { - owner.invalidateProperty(childPropertyName(refName, propertyName)) - } - override fun update(change: VisionChange) { - change.properties?.let { - updateProperties(Name.EMPTY, it) + override fun invalidate(propertyName: Name) { + //send update signal + @OptIn(DelicateCoroutinesApi::class) + (manager?.context ?: GlobalScope).launch { + changesInternal.emit(propertyName) + } + + // update styles + if (propertyName == Vision.STYLE_KEY) { + styles.asSequence() + .mapNotNull { getStyle(it) } + .flatMap { it.items.asSequence() } + .distinctBy { it.key } + .forEach { + invalidate(it.key.asName()) + } + } } } - - override val descriptor: MetaDescriptor get() = prototype.descriptor - } + override val children: VisionChildren + get() = object : VisionChildren { + override val parent: Vision get() = this@SolidReference + + override val keys: Set get() = prototype.children?.keys ?: emptySet() + + override val changes: Flow get() = emptyFlow() + + override fun get(token: NameToken): SolidReferenceChild? { + if (token !in (prototype.children?.keys ?: emptySet())) return null + return SolidReferenceChild(this@SolidReference, this@SolidReference, token.asName()) + } + } + public companion object { public const val REFERENCE_CHILD_PROPERTY_PREFIX: String = "@child" } } /** - * Create ref for existing prototype + * @param childName A name of reference child relative to prototype root */ -public fun SolidGroup.ref( - templateName: Name, - name: String? = null, -): SolidReferenceGroup = SolidReferenceGroup(templateName).also { set(name, it) } +internal class SolidReferenceChild( + val owner: SolidReference, + override var parent: Vision?, + val childName: Name, +) : Solid, VisionGroup { -public fun SolidGroup.ref( - templateName: String, - name: String? = null, -): SolidReferenceGroup = ref(Name.parse(templateName), name) + val prototype: Solid + get() = owner.prototype.children?.getChild(childName) as? Solid + ?: error("Prototype with name $childName not found") + + override val descriptor: MetaDescriptor get() = prototype.descriptor + + @Transient + override val properties: MutableVisionProperties = object : MutableVisionProperties { + override val descriptor: MetaDescriptor get() = this@SolidReferenceChild.descriptor + + override val own: MutableMeta by lazy { owner.properties[childToken(childName).asName()] } + + override fun getValue( + name: Name, + inherit: Boolean?, + includeStyles: Boolean?, + ): Value? = own.getValue(name) ?: prototype.properties.getValue(name, inherit, includeStyles) + + override fun set(name: Name, node: Meta?, notify: Boolean) { + own[name] = node + } + + override fun setValue(name: Name, value: Value?, notify: Boolean) { + own.setValue(name, value) + } + + override val changes: Flow get() = owner.properties.changes.filter { it.startsWith(childToken(childName)) } + + override fun invalidate(propertyName: Name) { + owner.properties.invalidate(childPropertyName(childName, propertyName)) + } + } + + override val children: VisionChildren = object : VisionChildren { + override val parent: Vision get() = this@SolidReferenceChild + + override val keys: Set get() = prototype.children?.keys ?: emptySet() + + override val changes: Flow get() = emptyFlow() + + override fun get(token: NameToken): SolidReferenceChild? { + if (token !in (prototype.children?.keys ?: emptySet())) return null + return SolidReferenceChild(this@SolidReferenceChild.owner, this@SolidReferenceChild, childName + token) + } + } + + companion object { + + private fun childToken(childName: Name): NameToken = + NameToken(REFERENCE_CHILD_PROPERTY_PREFIX, childName.toString()) + + private fun childPropertyName(childName: Name, propertyName: Name): Name = + childToken(childName) + propertyName + + } +} /** - * Add new [SolidReferenceGroup] wrapping given object and automatically adding it to the prototypes. - * One must ensure that [prototypeHolder] is a parent of this group. + * Create ref for existing prototype + */ +public fun MutableVisionContainer.ref( + templateName: Name, + name: Name? = null, +): SolidReference = SolidReference(templateName).also { setChild(name, it) } + +public fun MutableVisionContainer.ref( + templateName: Name, + name: String, +): SolidReference = ref(templateName, name.parseAsName()) + +/** + * Add new [SolidReference] wrapping given object and automatically adding it to the prototypes. */ public fun SolidGroup.newRef( name: String?, obj: Solid, - prototypeHolder: PrototypeHolder = this, - templateName: Name = Name.parse(name ?: obj.toString()), -): SolidReferenceGroup { - val existing = getPrototype(templateName) + prototypeHolder: SolidGroup = this, + prototypeName: Name = Name.parse(name ?: obj.toString()), +): SolidReference { + val existing = prototypeHolder.getPrototype(prototypeName) if (existing == null) { prototypeHolder.prototypes { - set(templateName, obj) + setChild(prototypeName, obj) } } else if (existing != obj) { error("Can't add different prototype on top of existing one") } - return ref(templateName, name) -} + return children.ref(prototypeName, name?.parseAsName()) +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt index 12a22ab6..d6f992ec 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Solids.kt @@ -6,29 +6,34 @@ import kotlinx.serialization.modules.PolymorphicModuleBuilder import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.polymorphic import kotlinx.serialization.modules.subclass +import kotlinx.serialization.serializer import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name import space.kscience.visionforge.* import space.kscience.visionforge.html.VisionOutput -import kotlin.reflect.KClass +import space.kscience.visionforge.solid.specifications.Canvas3DOptions -public class Solids(meta: Meta) : VisionPlugin(meta) { +public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer { override val tag: PluginTag get() = Companion.tag override val visionSerializersModule: SerializersModule get() = serializersModuleForSolids + override fun setChild(name: Name?, child: Solid?) { + child?.setAsRoot(visionManager) + } + public companion object : PluginFactory { override val tag: PluginTag = PluginTag(name = "vision.solid", group = PluginTag.DATAFORGE_GROUP) - override val type: KClass = Solids::class - override fun invoke(meta: Meta, context: Context): Solids = Solids(meta) + + override fun build(context: Context, meta: Meta): Solids = Solids(meta) private fun PolymorphicModuleBuilder.solids() { subclass(SolidGroup.serializer()) - subclass(SolidReferenceGroup.serializer()) + subclass(SolidReference.serializer()) subclass(Composite.serializer()) subclass(Box.serializer()) subclass(GenericHexagon.serializer()) @@ -36,20 +41,28 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { subclass(ConeSurface.serializer()) subclass(Convex.serializer()) subclass(Extruded.serializer()) + subclass(Surface.serializer()) subclass(PolyLine.serializer()) subclass(SolidLabel.serializer()) subclass(Sphere.serializer()) + subclass(SphereLayer.serializer()) + subclass(CutTube.serializer()) + + subclass(AmbientLightSource.serializer()) + subclass(PointLightSource.serializer()) + + subclass(AxesSolid.serializer()) } public val serializersModuleForSolids: SerializersModule = SerializersModule { + polymorphic(Vision::class) { - subclass(VisionBase.serializer()) - subclass(VisionGroupBase.serializer()) + subclass(SimpleVisionGroup.serializer()) solids() } polymorphic(Solid::class) { - default { SolidBase.serializer() } + defaultDeserializer { SolidBase.serializer(serializer()) } solids() } } @@ -64,12 +77,26 @@ public class Solids(meta: Meta) : VisionPlugin(meta) { public fun decodeFromString(str: String): Solid = jsonForSolids.decodeFromString(PolymorphicSerializer(Solid::class), str) + +// override fun setChild(name: Name?, child: Solid?) { +// default.setChild(name, child) +// } } } @VisionBuilder -@DFExperimental -public inline fun VisionOutput.solid(block: SolidGroup.() -> Unit): SolidGroup { +public inline fun VisionOutput.solid(options: Canvas3DOptions? = null, block: SolidGroup.() -> Unit): SolidGroup { requirePlugin(Solids) - return SolidGroup().apply(block) + options?.let { + meta = options.meta + } + return SolidGroup().apply(block).apply { + if (children.values.none { it is LightSource }) { + ambientLight() + } + } } + +@VisionBuilder +public inline fun VisionOutput.solid(options: Canvas3DOptions.() -> Unit, block: SolidGroup.() -> Unit): SolidGroup = + solid(Canvas3DOptions(options), block) diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt index bae8d83d..224e8bba 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Sphere.kt @@ -2,10 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.VisionPropertyContainer -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -17,16 +16,16 @@ public class Sphere( public val phiStart: Float = 0f, public val phi: Float = PI2, public val thetaStart: Float = 0f, - public val theta: Float = PI .toFloat(), -) : SolidBase(), GeometrySolid, VisionPropertyContainer { + public val theta: Float = PI.toFloat(), +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder) { - fun point3DfromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) val x = -r * sin(theta) * cos(phi) - return Point3D(x, y, z) + return Float32Vector3D(x, y, z) } val segments = this.detail ?: 32 @@ -39,10 +38,10 @@ public class Sphere( for (j in 0 until segments) { // phi iteration val phi1 = phiStart + j * phiStep val phi2 = phi1 + phiStep - val point1 = point3DfromSphCoord(radius, theta1, phi1) - val point2 = point3DfromSphCoord(radius, theta1, phi2) - val point3 = point3DfromSphCoord(radius, theta2, phi2) - val point4 = point3DfromSphCoord(radius, theta2, phi1) + val point1 = point3dFromSphCoord(radius, theta1, phi1) + val point2 = point3dFromSphCoord(radius, theta1, phi2) + val point3 = point3dFromSphCoord(radius, theta2, phi2) + val point4 = point3dFromSphCoord(radius, theta2, phi1) geometryBuilder.apply { // 1-2-3-4 gives the same face but with opposite orientation face4(point1, point4, point3, point2) @@ -53,10 +52,10 @@ public class Sphere( } @VisionBuilder -public inline fun VisionContainerBuilder.sphere( +public inline fun MutableVisionContainer.sphere( radius: Number, name: String? = null, action: Sphere.() -> Unit = {}, ): Sphere = Sphere( radius.toFloat(), -).apply(action).also { set(name, it) } \ No newline at end of file +).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt index 05149e2e..fa025df2 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/SphereLayer.kt @@ -2,9 +2,9 @@ package space.kscience.visionforge.solid import kotlinx.serialization.SerialName import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer import space.kscience.visionforge.VisionBuilder -import space.kscience.visionforge.VisionContainerBuilder -import space.kscience.visionforge.set +import space.kscience.visionforge.setChild import kotlin.math.PI import kotlin.math.cos import kotlin.math.sin @@ -21,18 +21,18 @@ public class SphereLayer( public val phi: Float = PI2, public val thetaStart: Float = 0f, public val theta: Float = PI.toFloat(), -) : SolidBase(), GeometrySolid { +) : SolidBase(), GeometrySolid { override fun toGeometry(geometryBuilder: GeometryBuilder): Unit = geometryBuilder.run { require(outerRadius > 0) { "Outer radius must be positive" } require(innerRadius >= 0) { "inner radius must be non-negative" } - fun point3DfromSphCoord(r: Float, theta: Float, phi: Float): Point3D { + fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D { // This transformation matches three.js sphere implementation val y = r * cos(theta) val z = r * sin(theta) * sin(phi) val x = -r * sin(theta) * cos(phi) - return Point3D(x, y, z) + return Float32Vector3D(x, y, z) } val segments = detail ?: 32 @@ -46,17 +46,17 @@ public class SphereLayer( val phi1 = phiStart + j * phiStep val phi2 = phi1 + phiStep //outer points - val outerPoint1 = point3DfromSphCoord(outerRadius, theta1, phi1) - val outerPoint2 = point3DfromSphCoord(outerRadius, theta1, phi2) - val outerPoint3 = point3DfromSphCoord(outerRadius, theta2, phi2) - val outerPoint4 = point3DfromSphCoord(outerRadius, theta2, phi1) + val outerPoint1 = point3dFromSphCoord(outerRadius, theta1, phi1) + val outerPoint2 = point3dFromSphCoord(outerRadius, theta1, phi2) + val outerPoint3 = point3dFromSphCoord(outerRadius, theta2, phi2) + val outerPoint4 = point3dFromSphCoord(outerRadius, theta2, phi1) // 1-2-3-4 gives the same face but with opposite orientation face4(outerPoint1, outerPoint4, outerPoint3, outerPoint2) if (innerRadius > 0) { - val innerPoint1 = point3DfromSphCoord(innerRadius, theta1, phi1) - val innerPoint2 = point3DfromSphCoord(innerRadius, theta1, phi2) - val innerPoint3 = point3DfromSphCoord(innerRadius, theta2, phi2) - val innerPoint4 = point3DfromSphCoord(innerRadius, theta2, phi1) + val innerPoint1 = point3dFromSphCoord(innerRadius, theta1, phi1) + val innerPoint2 = point3dFromSphCoord(innerRadius, theta1, phi2) + val innerPoint3 = point3dFromSphCoord(innerRadius, theta2, phi2) + val innerPoint4 = point3dFromSphCoord(innerRadius, theta2, phi1) face4(innerPoint1, innerPoint2, innerPoint3, innerPoint4) //the cup if (i == segments - 1 && theta != PI.toFloat() && innerRadius != outerRadius) { @@ -69,7 +69,7 @@ public class SphereLayer( } @VisionBuilder -public inline fun VisionContainerBuilder.sphereLayer( +public inline fun MutableVisionContainer.sphereLayer( outerRadius: Number, innerRadius: Number, phiStart: Number = 0f, @@ -85,4 +85,4 @@ public inline fun VisionContainerBuilder.sphereLayer( phi.toFloat(), thetaStart.toFloat(), theta.toFloat() -).apply(action).also { set(name, it) } \ No newline at end of file +).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlSolid.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlSolid.kt new file mode 100644 index 00000000..b9d9d835 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/StlSolid.kt @@ -0,0 +1,25 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild + + +public sealed class StlSolid: SolidBase() + +@Serializable +@SerialName("solid.stl.url") +public class StlUrlSolid(public val url: String) : StlSolid() + +@Serializable +@SerialName("solid.stl.binary") +public class StlBinarySolid(public val data: ByteArray) : StlSolid() + +@VisionBuilder +public inline fun MutableVisionContainer.stl( + url: String, + name: String? = null, + action: StlSolid.() -> Unit = {}, +): StlSolid = StlUrlSolid(url).apply(action).also { setChild(name, it) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt new file mode 100644 index 00000000..cf442c62 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/Surface.kt @@ -0,0 +1,173 @@ +package space.kscience.visionforge.solid + +import kotlinx.serialization.SerialName +import kotlinx.serialization.Serializable +import space.kscience.dataforge.meta.MutableMeta +import space.kscience.dataforge.names.Name +import space.kscience.kmath.geometry.component1 +import space.kscience.kmath.geometry.component2 +import space.kscience.kmath.structures.Float32 +import space.kscience.visionforge.MutableVisionContainer +import space.kscience.visionforge.VisionBuilder +import space.kscience.visionforge.setChild + + +private inline fun Iterable.sumOf(selector: (T) -> Float32): Float32 { + var sum = 0f + for (element in this) { + sum += selector(element) + } + return sum +} + +/** + * A layered solid with a hole inside + */ +@Serializable +@SerialName("solid.surface") +public class Surface( + public val layers: List, +) : SolidBase(), GeometrySolid { + + @Serializable + public data class Layer(val z: Float32, val outer: Shape2D, val inner: Shape2D?) { + init { + require(outer.size >= 3) { "Extruded shape requires more than 2 points per layer" } + require(inner == null || inner.size == outer.size) { "Outer shape size is ${outer.size}, but inner is ${inner?.size}" } + } + + public fun outerPoints(): List = outer.map { (x, y) -> Float32Vector3D(x, y, z) } + + public fun innerPoints(): List? = inner?.map { (x, y) -> Float32Vector3D(x, y, z) } + + public val center: Float32Vector3D by lazy { + Float32Vector3D( + outer.sumOf { it.x } / size, + outer.sumOf { it.y } / size, + z + ) + } + + + val size: Int get() = outer.size + } + + init { + require(layers.size > 1) { "Number of layers must be 2 or more" } + require(layers.all { it.size == layers.first().size }) { "All layers must have the same size" } + } + + override fun toGeometry(geometryBuilder: GeometryBuilder) { + + geometryBuilder.apply { + //outer and inner + for (i in 0 until layers.size - 1) { + val bottom = layers[i] + val top = layers[i + 1] + + //creating shape in x-y plane with z = 0 + val bottomOuterPoints = bottom.outerPoints() + val topOuterPoints = top.outerPoints() + + for (it in 1 until bottomOuterPoints.size) { + //outer face + face4( + bottomOuterPoints[it - 1], + bottomOuterPoints[it], + topOuterPoints[it], + topOuterPoints[it - 1] + ) + } + + //outer face last segment + face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last()) + + val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center } + val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center } + + for (it in 1 until bottomInnerPoints.size) { + //inner face + face4( + bottomInnerPoints[it], + bottomInnerPoints[it - 1], + topInnerPoints[it - 1], + topInnerPoints[it] + ) + } + + //inner face last segment + face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0]) + } + + val bottom = layers.first() + val top = layers.last() + val bottomOuterPoints = bottom.outerPoints() + val topOuterPoints = top.outerPoints() + val bottomInnerPoints = bottom.innerPoints() ?: bottom.outerPoints().map { bottom.center } + val topInnerPoints = top.innerPoints() ?: top.outerPoints().map { top.center } + + (1 until bottom.size).forEach { + + //bottom cup + face4( + bottomInnerPoints[it - 1], + bottomInnerPoints[it], + bottomOuterPoints[it], + bottomOuterPoints[it - 1] + ) + //upper cup + face4( + topInnerPoints[it], + topInnerPoints[it - 1], + topOuterPoints[it - 1], + topOuterPoints[it] + ) + + + face4( + bottomInnerPoints.last(), + bottomInnerPoints[0], + bottomOuterPoints[0], + bottomOuterPoints.last() + ) + face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0]) + } + } + } + + public class Builder( + public var layers: MutableList = ArrayList(), + public val properties: MutableMeta = MutableMeta(), + ) { + + public fun layer( + z: Number, + innerBuilder: (Shape2DBuilder.() -> Unit)? = null, + outerBuilder: Shape2DBuilder.() -> Unit, + ) { + layers.add( + Layer( + z.toFloat(), + outer = Shape2DBuilder().apply(outerBuilder).build(), + inner = innerBuilder?.let { Shape2DBuilder().apply(innerBuilder).build() } + ) + ) + } + + internal fun build(): Surface = Surface(layers).apply { + properties[Name.EMPTY] = this@Builder.properties + } + } + + + public companion object { + public const val TYPE: String = "solid.surface" + } +} + + +@VisionBuilder +public fun MutableVisionContainer.surface( + name: String? = null, + action: Surface.Builder.() -> Unit = {}, +): Surface = Surface.Builder().apply(action).build().also { setChild(name, it) } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt index a0ad09a0..8f799f2e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/geometry.kt @@ -1,10 +1,5 @@ package space.kscience.visionforge.solid -import kotlinx.serialization.KSerializer -import kotlinx.serialization.Serializable -import kotlinx.serialization.descriptors.SerialDescriptor -import kotlinx.serialization.encoding.Decoder -import kotlinx.serialization.encoding.Encoder import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.MetaProvider import space.kscience.dataforge.meta.float @@ -13,108 +8,51 @@ import space.kscience.visionforge.solid.Solid.Companion.X_KEY import space.kscience.visionforge.solid.Solid.Companion.Y_KEY import space.kscience.visionforge.solid.Solid.Companion.Z_KEY import kotlin.math.PI -import kotlin.math.pow -import kotlin.math.sqrt public const val PI2: Float = 2 * PI.toFloat() -@Serializable -public data class Point2D(public var x: Float, public var y: Float) - -public fun Point2D(x: Number, y: Number): Point2D = Point2D(x.toFloat(), y.toFloat()) - -public fun Point2D.toMeta(): Meta = Meta { +public fun Float32Vector2D.toMeta(): Meta = Meta { X_KEY put x Y_KEY put y } -internal fun Meta.point2D(): Point2D = Point2D(this["x"].float ?: 0f, this["y"].float ?: 0f) +internal fun Meta.toVector2D(): Float32Vector2D = + Float32Vector2D(this["x"].float ?: 0f, this["y"].float ?: 0f) -@Serializable(Point3DSerializer::class) -public interface Point3D { - public val x: Float - public val y: Float - public val z: Float +//@Suppress("SERIALIZER_TYPE_INCOMPATIBLE") +//@Serializable(Point3DSerializer::class) +//public interface MutablePoint3D : Float32Vector3D { +// override var x: Float +// override var y: Float +// override var z: Float +//} +// +// +//public fun MutablePoint3D.normalizeInPlace() { +// val norm = sqrt(x.pow(2) + y.pow(2) + z.pow(2)) +// x /= norm +// y /= norm +// z /= norm +//} - public companion object { - public val ZERO: Point3D = Point3D(0.0, 0.0, 0.0) - public val ONE: Point3D = Point3D(1.0, 1.0, 1.0) - } -} - -@Suppress("SERIALIZER_TYPE_INCOMPATIBLE") -@Serializable(Point3DSerializer::class) -public interface MutablePoint3D : Point3D { - override var x: Float - override var y: Float - override var z: Float -} - -@Serializable -private class Point3DImpl(override var x: Float, override var y: Float, override var z: Float) : MutablePoint3D - -internal object Point3DSerializer : KSerializer { - - override val descriptor: SerialDescriptor = Point3DImpl.serializer().descriptor - - override fun deserialize(decoder: Decoder): MutablePoint3D = decoder.decodeSerializableValue(Point3DImpl.serializer()) - - override fun serialize(encoder: Encoder, value: Point3D) { - val impl: Point3DImpl = (value as? Point3DImpl) ?: Point3DImpl(value.x, value.y, value.z) - encoder.encodeSerializableValue(Point3DImpl.serializer(), impl) - } -} - -public fun Point3D(x: Number, y: Number, z: Number): Point3D = Point3DImpl(x.toFloat(), y.toFloat(), z.toFloat()) - -public operator fun Point3D.plus(other: Point3D): Point3D = Point3D( - this.x + other.x, - this.y + other.y, - this.z + other.z +internal fun MetaProvider.point3D(default: Float = 0f) = Float32Euclidean3DSpace.vector( + get(X_KEY).float ?: default, + get(Y_KEY).float ?: default, + get(Z_KEY).float ?: default ) -public operator fun Point3D.minus(other: Point3D): Point3D = Point3D( - this.x - other.x, - this.y - other.y, - this.z - other.z -) -public operator fun Point3D.unaryMinus(): Point3D = Point3D( - -x, - -y, - -z -) - -public infix fun Point3D.cross(other: Point3D): Point3D = Point3D( - y * other.z - z * other.y, - z * other.x - x * other.z, - x * other.y - y * other.x -) - -public fun MutablePoint3D.normalizeInPlace() { - val norm = sqrt(x.pow(2) + y.pow(2) + z.pow(2)) - x /= norm - y /= norm - z /= norm -} - -internal fun MetaProvider.point3D(default: Float = 0f) = object : Point3D { - override val x: Float by float(default) - override val y: Float by float(default) - override val z: Float by float(default) -} - -public fun Point3D.toMeta(): Meta = Meta { +public fun Float32Vector3D.toMeta(): Meta = Meta { X_KEY put x Y_KEY put y Z_KEY put z } -internal 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 +internal fun Meta.toVector3D(default: Float = 0f) = Float32Vector3D( + this[X_KEY].float ?: default, + this[Y_KEY].float ?: default, + this[Z_KEY].float ?: default ) //internal fun Solid.updatePosition(meta: Meta?) { diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt similarity index 74% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt index 485cc8bd..0ed9126e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Axes.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/AxesScheme.kt @@ -7,24 +7,26 @@ import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.value import space.kscience.dataforge.meta.double -public class Axes : Scheme() { +@Deprecated("Use separate axes object instead") +public class AxesScheme : Scheme() { public var visible: Boolean by boolean(false) public var size: Double by double(AXIS_SIZE) public var width: Double by double(AXIS_WIDTH) - public companion object : SchemeSpec(::Axes) { + @Suppress("DEPRECATION") + public companion object : SchemeSpec(::AxesScheme) { public const val AXIS_SIZE: Double = 1000.0 public const val AXIS_WIDTH: Double = 3.0 override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - value(Axes::visible){ + value(AxesScheme::visible){ default(false) } - value(Axes::size){ + value(AxesScheme::size){ default(AXIS_SIZE) } - value(Axes::width){ + value(AxesScheme::width){ default(AXIS_WIDTH) } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt similarity index 77% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt index b8cb05d4..f884bc1e 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Camera.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/CameraScheme.kt @@ -8,7 +8,7 @@ import space.kscience.dataforge.meta.double import space.kscience.dataforge.meta.int import kotlin.math.PI -public class Camera : Scheme() { +public class CameraScheme : Scheme() { public var fov: Int by int(FIELD_OF_VIEW) //var aspect by double(1.0) @@ -19,7 +19,7 @@ public class Camera : Scheme() { public var azimuth: Double by double(INITIAL_AZIMUTH) public var latitude: Double by double(INITIAL_LATITUDE) - public companion object : SchemeSpec(::Camera) { + public companion object : SchemeSpec(::CameraScheme) { public const val INITIAL_DISTANCE: Double = 300.0 public const val INITIAL_AZIMUTH: Double = 0.0 public const val INITIAL_LATITUDE: Double = PI / 6 @@ -29,22 +29,22 @@ public class Camera : Scheme() { override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - value(Camera::fov) { + value(CameraScheme::fov) { default(FIELD_OF_VIEW) } - value(Camera::nearClip) { + value(CameraScheme::nearClip) { default(NEAR_CLIP) } - value(Camera::farClip) { + value(CameraScheme::farClip) { default(FAR_CLIP) } - value(Camera::distance) { + value(CameraScheme::distance) { default(INITIAL_DISTANCE) } - value(Camera::azimuth) { + value(CameraScheme::azimuth) { default(INITIAL_AZIMUTH) } - value(Camera::latitude) { + value(CameraScheme::latitude) { default(INITIAL_LATITUDE) } } @@ -52,4 +52,4 @@ public class Camera : Scheme() { } } -public val Camera.zenith: Double get() = PI / 2 - latitude \ No newline at end of file +public val CameraScheme.zenith: Double get() = PI / 2 - latitude \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt index 4a819ff7..b24c9b75 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Canvas3DOptions.kt @@ -4,42 +4,39 @@ import space.kscience.dataforge.meta.* import space.kscience.dataforge.meta.descriptors.MetaDescriptor import space.kscience.dataforge.meta.descriptors.scheme import space.kscience.dataforge.meta.descriptors.value +import space.kscience.dataforge.meta.set import space.kscience.dataforge.names.Name import space.kscience.visionforge.hide import space.kscience.visionforge.widgetType -public class Clipping : Scheme() { - public var x: Double? by double() - public var y: Double? by double() - public var z: Double? by double() - public companion object : SchemeSpec(::Clipping) { - override val descriptor: MetaDescriptor = MetaDescriptor { - value(Clipping::x) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } - value(Clipping::y) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } - value(Clipping::z) { - widgetType = "range" - attributes["min"] = 0.0 - attributes["max"] = 1.0 - attributes["step"] = 0.01 - default(1.0) - } +public object Clipping : SchemeSpec(::PointScheme) { + override val descriptor: MetaDescriptor = MetaDescriptor { + value(PointScheme::x) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) + } + value(PointScheme::y) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) + } + value(PointScheme::z) { + widgetType = "range" + attributes["min"] = 0.0 + attributes["max"] = 1.0 + attributes["step"] = 0.01 + default(1.0) } } } + public class CanvasSize : Scheme() { public var minSize: Int by int(400) public var minWith: Number by number { minSize } @@ -62,16 +59,16 @@ public class CanvasSize : Scheme() { } public class Canvas3DOptions : Scheme() { - public var axes: Axes by spec(Axes) - public var light: Light by spec(Light) - public var camera: Camera by spec(Camera) - public var controls: Controls by spec(Controls) + @Suppress("DEPRECATION") + public var axes: AxesScheme by spec(AxesScheme) + public var camera: CameraScheme by spec(CameraScheme) + public var controls: ControlsScheme by spec(ControlsScheme) public var size: CanvasSize by spec(CanvasSize) public var layers: List by numberList(0) - public var clipping: Clipping by spec(Clipping) + public var clipping: PointScheme by spec(Clipping) public var onSelect: ((Name?) -> Unit)? = null @@ -79,7 +76,8 @@ public class Canvas3DOptions : Scheme() { public companion object : SchemeSpec(::Canvas3DOptions) { override val descriptor: MetaDescriptor by lazy { MetaDescriptor { - scheme(Canvas3DOptions::axes, Axes) + @Suppress("DEPRECATION") + scheme(Canvas3DOptions::axes, AxesScheme) value(Canvas3DOptions::layers) { multiple = true @@ -90,15 +88,11 @@ public class Canvas3DOptions : Scheme() { scheme(Canvas3DOptions::clipping, Clipping) - scheme(Canvas3DOptions::light, Light){ + scheme(Canvas3DOptions::camera, CameraScheme) { hide() } - scheme(Canvas3DOptions::camera, Camera) { - hide() - } - - scheme(Canvas3DOptions::controls, Controls) { + scheme(Canvas3DOptions::controls, ControlsScheme) { hide() } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt similarity index 56% rename from visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt rename to visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt index ee8ebb9d..5e68f37c 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Controls.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/ControlsScheme.kt @@ -4,6 +4,6 @@ import space.kscience.dataforge.meta.Scheme import space.kscience.dataforge.meta.SchemeSpec -public class Controls : Scheme() { - public companion object : SchemeSpec(::Controls) +public class ControlsScheme : Scheme() { + public companion object : SchemeSpec(::ControlsScheme) } \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt deleted file mode 100644 index 39b79466..00000000 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/Light.kt +++ /dev/null @@ -1,8 +0,0 @@ -package space.kscience.visionforge.solid.specifications - -import space.kscience.dataforge.meta.Scheme -import space.kscience.dataforge.meta.SchemeSpec - -public class Light : Scheme() { - public companion object : SchemeSpec(::Light) -} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt new file mode 100644 index 00000000..33b8c180 --- /dev/null +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/specifications/PointScheme.kt @@ -0,0 +1,19 @@ +package space.kscience.visionforge.solid.specifications + +import space.kscience.dataforge.meta.Scheme +import space.kscience.dataforge.meta.SchemeSpec +import space.kscience.dataforge.meta.double + +public class PointScheme: Scheme(){ + public var x: Double? by double() + public var y: Double? by double() + public var z: Double? by double() + + public companion object: SchemeSpec(::PointScheme) +} + +public operator fun PointScheme.invoke(x: Number?, y: Number?, z: Number?){ + this.x = x?.toDouble() + this.y = y?.toDouble() + this.z = z?.toDouble() +} \ No newline at end of file diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt index 39aadbf1..bcf3baa9 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/RemoveSingleChild.kt @@ -1,31 +1,25 @@ package space.kscience.visionforge.solid.transform -import space.kscience.dataforge.meta.configure -import space.kscience.dataforge.meta.update import space.kscience.dataforge.misc.DFExperimental +import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName -import space.kscience.visionforge.* +import space.kscience.kmath.complex.QuaternionField +import space.kscience.visionforge.root import space.kscience.visionforge.solid.* private operator fun Number.plus(other: Number) = toFloat() + other.toFloat() private operator fun Number.times(other: Number) = toFloat() * other.toFloat() @DFExperimental -internal fun Vision.updateFrom(other: Vision): Vision { - if (this is Solid && other is Solid) { - x += other.x - y += other.y - z += other.y - rotationX += other.rotationX - rotationY += other.rotationY - rotationZ += other.rotationZ - scaleX *= other.scaleX - scaleY *= other.scaleY - scaleZ *= other.scaleZ - configure{ - update(other.meta) - } - } +internal fun Solid.updateFrom(other: Solid): Solid { + x += other.x + y += other.y + z += other.y + quaternion = with(QuaternionField) { other.quaternion * quaternion } + scaleX *= other.scaleX + scaleY *= other.scaleY + scaleZ *= other.scaleZ + properties[Name.EMPTY] = other.properties.root() return this } @@ -34,17 +28,17 @@ internal fun Vision.updateFrom(other: Vision): Vision { internal object RemoveSingleChild : VisualTreeTransform() { override fun SolidGroup.transformInPlace() { - fun MutableVisionGroup.replaceChildren() { - children.forEach { (childName, parent) -> - if (parent is SolidReferenceGroup) return@forEach //ignore refs - if (parent is MutableVisionGroup) { + fun SolidGroup.replaceChildren() { + items.forEach { (childName, parent) -> + if (parent is SolidReference) return@forEach //ignore refs + if (parent is SolidGroup) { parent.replaceChildren() } - if (parent is VisionGroup && parent.children.size == 1) { - val child = parent.children.values.first() + if (parent is SolidGroup && parent.items.size == 1) { + val child: Solid = parent.items.values.first() val newParent = child.updateFrom(parent) newParent.parent = null - set(childName.asName(), newParent) + children.setChild(childName.asName(), newParent) } } } diff --git a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt index 890c8291..72fa1a76 100644 --- a/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt +++ b/visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid/transform/UnRef.kt @@ -2,41 +2,41 @@ package space.kscience.visionforge.solid.transform import space.kscience.dataforge.misc.DFExperimental import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.visionforge.MutableVisionGroup -import space.kscience.visionforge.VisionGroup import space.kscience.visionforge.solid.SolidGroup -import space.kscience.visionforge.solid.SolidReferenceGroup +import space.kscience.visionforge.solid.SolidReference +import kotlin.collections.component1 +import kotlin.collections.component2 +import kotlin.collections.set @DFExperimental internal object UnRef : VisualTreeTransform() { - private fun VisionGroup.countRefs(): Map { - return children.values.fold(HashMap()) { reducer, obj -> - if (obj is VisionGroup) { - val counter = obj.countRefs() + private fun SolidGroup.countRefs(): Map { + return items.values.fold(HashMap()) { reducer, vision -> + if (vision is SolidGroup) { + val counter = vision.countRefs() counter.forEach { (key, value) -> reducer[key] = (reducer[key] ?: 0) + value } - } else if (obj is SolidReferenceGroup) { - reducer[obj.refName] = (reducer[obj.refName] ?: 0) + 1 + } else if (vision is SolidReference) { + reducer[vision.prototypeName] = (reducer[vision.prototypeName] ?: 0) + 1 } return reducer } } - private fun MutableVisionGroup.unref(name: Name) { + private fun SolidGroup.unref(name: Name) { (this as? SolidGroup)?.prototypes{ - set(name, null) + setChild(name, null) } - children.filter { (it.value as? SolidReferenceGroup)?.refName == name }.forEach { (key, value) -> - val reference = value as SolidReferenceGroup + items.filter { (it.value as? SolidReference)?.prototypeName == name }.forEach { (key, value) -> + val reference = value as SolidReference val newChild = reference.prototype.updateFrom(reference) newChild.parent = null - set(key.asName(), newChild) // replace proxy with merged object + children[key] = newChild // replace proxy with merged object } - children.values.filterIsInstance().forEach { it.unref(name) } + items.values.filterIsInstance().forEach { it.unref(name) } } override fun SolidGroup.transformInPlace() { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt index 411aa75b..a7c1c688 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/CompositeTest.kt @@ -8,7 +8,7 @@ class CompositeTest { @Test fun testCompositeBuilder(){ lateinit var composite: Composite - SolidGroup { + testSolids.solidGroup { composite = composite(CompositeType.INTERSECT) { y = 300 box(100, 100, 100) { diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt index a7133006..8d838f6b 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/ConvexTest.kt @@ -1,18 +1,14 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.meta.getIndexed -import space.kscience.dataforge.meta.node import space.kscience.dataforge.meta.toMeta -import space.kscience.dataforge.misc.DFExperimental import kotlin.test.Test import kotlin.test.assertEquals class ConvexTest { - @OptIn(DFExperimental::class) - @Suppress("UNUSED_VARIABLE") @Test fun testConvexBuilder() { - val group = SolidGroup().apply { + val group = testSolids.solidGroup { convex { point(50, 50, -50) point(50, -50, -50) @@ -25,7 +21,7 @@ class ConvexTest { } } - val convex = group.children.values.first() as Convex + val convex = group.items.values.first() as Convex val json = Solids.jsonForSolids.encodeToJsonElement(Convex.serializer(), convex) val meta = json.toMeta() diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt index 6f004f5c..87527802 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/DescriptorTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid +import space.kscience.dataforge.meta.ValueType import space.kscience.dataforge.meta.descriptors.get -import space.kscience.dataforge.values.ValueType import space.kscience.visionforge.solid.specifications.Canvas3DOptions import kotlin.test.Test import kotlin.test.assertNotNull diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt index 4e78e340..78e2f03c 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/GroupTest.kt @@ -1,7 +1,7 @@ package space.kscience.visionforge.solid import space.kscience.visionforge.Colors -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.math.PI import kotlin.test.Test import kotlin.test.assertEquals @@ -9,7 +9,7 @@ import kotlin.test.assertEquals class GroupTest { @Test fun testGroupWithComposite() { - val group = SolidGroup().apply { + val group = testSolids.solidGroup{ union("union") { box(100, 100, 100) { z = 100 @@ -44,8 +44,8 @@ class GroupTest { } } - assertEquals(3, group.children.count()) - assertEquals(300.0, (group["intersect"] as Solid).y.toDouble()) - assertEquals(-300.0, (group["subtract"] as Solid).y.toDouble()) + assertEquals(3, group.items.count()) + assertEquals(300.0, (group.children.getChild("intersect") as Solid).y.toDouble()) + assertEquals(-300.0, (group.children.getChild("subtract") as Solid).y.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt index f8af54a0..e3069647 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SerializationTest.kt @@ -1,8 +1,8 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.names.Name -import space.kscience.visionforge.MutableVisionGroup -import space.kscience.visionforge.get +import space.kscience.visionforge.Colors +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals @@ -13,10 +13,10 @@ import kotlin.test.assertEquals fun SolidGroup.refGroup( name: String, templateName: Name = Name.parse(name), - block: MutableVisionGroup.() -> Unit -): SolidReferenceGroup { + block: SolidGroup.() -> Unit +): SolidReference { val group = SolidGroup().apply(block) - return newRef(name, group, templateName = templateName) + return newRef(name, group, prototypeName = templateName) } @@ -31,7 +31,7 @@ class SerializationTest { val string = Solids.encodeToString(cube) println(string) val newCube = Solids.decodeFromString(string) - assertEquals(cube.meta, newCube.meta) + assertEquals(cube.properties.own, newCube.properties.own) } @Test @@ -41,7 +41,7 @@ class SerializationTest { x = 100 z = -100 } - val group = SolidGroup { + val group = testSolids.solidGroup { newRef("cube", cube) refGroup("pg", Name.parse("pg.content")) { sphere(50) { @@ -52,7 +52,21 @@ class SerializationTest { val string = Solids.encodeToString(group) println(string) val reconstructed = Solids.decodeFromString(string) as SolidGroup - assertEquals(group["cube"]?.meta, reconstructed["cube"]?.meta) + assertEquals(group.children.getChild("cube")?.properties?.own, reconstructed.children.getChild("cube")?.properties?.own) + } + + @Test + fun lightSerialization(){ + val group = testSolids.solidGroup { + ambientLight { + color(Colors.white) + intensity = 100.0 + } + } + val serialized = Solids.encodeToString(group) + + val reconstructed = Solids.decodeFromString(serialized) as SolidGroup + assertEquals(100.0, (reconstructed.children.getChild("@ambientLight") as AmbientLightSource).intensity.toDouble()) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt index 23a48a63..ba8dce18 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPluginTest.kt @@ -1,14 +1,16 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals +internal val testSolids = Global.request(Solids) + class SolidPluginTest { - val vision = SolidGroup { + val vision = testSolids.solidGroup { box(100, 100, 100, name = "aBox") sphere(100, name = "aSphere") { @@ -19,11 +21,14 @@ class SolidPluginTest { @DFExperimental @Test fun testPluginConverter() { - val visionManager = Global.fetch(Solids).visionManager + val visionManager = Global.request(Solids).visionManager val meta = visionManager.encodeToMeta(vision) val reconstructed = visionManager.decodeFromMeta(meta) as SolidGroup - assertEquals(visionManager.encodeToJsonElement(vision["aBox"]!!), visionManager.encodeToJsonElement(reconstructed["aBox"]!!)) + assertEquals( + visionManager.encodeToJsonElement(vision.children.getChild("aBox")!!), + visionManager.encodeToJsonElement(reconstructed.children.getChild("aBox")!!) + ) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt similarity index 51% rename from visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt rename to visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt index ec58e4d2..4991c12d 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/PropertyTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidPropertyTest.kt @@ -1,72 +1,82 @@ package space.kscience.visionforge.solid -import space.kscience.dataforge.meta.get +import kotlinx.coroutines.CompletableDeferred +import kotlinx.coroutines.ExperimentalCoroutinesApi +import kotlinx.coroutines.delay +import kotlinx.coroutines.test.runTest +import space.kscience.dataforge.meta.int +import space.kscience.dataforge.meta.set import space.kscience.dataforge.meta.string import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.int import space.kscience.visionforge.* import kotlin.test.Test import kotlin.test.assertEquals +import kotlin.time.Duration.Companion.milliseconds +@OptIn(ExperimentalCoroutinesApi::class) @Suppress("UNUSED_VARIABLE") -class PropertyTest { +class SolidPropertyTest { @Test - fun testColor(){ - val box = Box(10.0f, 10.0f,10.0f) + fun testColor() { + val box = Box(10.0f, 10.0f, 10.0f) box.material { //meta["color"] = "pink" color("pink") } - assertEquals("pink", box.meta["material.color"]?.string) + assertEquals("pink", box.properties.getValue("material.color")?.string) assertEquals("pink", box.color.string) } @Test - fun testColorUpdate(){ - val box = Box(10.0f, 10.0f,10.0f) + fun testColorUpdate() = runTest(timeout = 200.milliseconds) { + val box = Box(10.0f, 10.0f, 10.0f) - var c: String? = null - box.onPropertyChange { - if(it == SolidMaterial.MATERIAL_COLOR_KEY){ - c = box.color.string + val c = CompletableDeferred() + + + val subscription = box.onPropertyChange(this) { key -> + if (key == SolidMaterial.MATERIAL_COLOR_KEY) { + c.complete(box.color.string) } } + delay(5) box.material { color("pink") } - assertEquals("pink", c) + assertEquals("pink", c.await()) + subscription.cancel() } @Test fun testInheritedProperty() { var box: Box? = null val group = SolidGroup().apply { - setPropertyNode("test", 22) - group { + properties["test"] = 22 + solidGroup { box = box(100, 100, 100) } } - assertEquals(22, box?.getPropertyValue("test", inherit = true)?.int) + assertEquals(22, box?.properties?.getValue("test", inherit = true)?.int) } @Test fun testStyleProperty() { var box: Box? = null - val group = SolidGroup().apply { + val group = testSolids.solidGroup { styleSheet { - set("testStyle") { + update("testStyle") { "test" put 22 } } - group { - box = box(100, 100, 100).apply { + solidGroup { + box = box(100, 100, 100) { useStyle("testStyle") } } } - assertEquals(22, box?.getPropertyValue("test")?.int) + assertEquals(22, box?.properties?.getValue("test")?.int) } @Test @@ -74,25 +84,25 @@ class PropertyTest { var box: Box? = null val group = SolidGroup().apply { styleSheet { - set("testStyle") { + update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" } } - group { + solidGroup { box = box(100, 100, 100) { useStyle("testStyle") } } } - assertEquals("#555555", box?.color.string) + assertEquals("#555555", box?.color?.string) } @Test fun testReferenceStyleProperty() { - var box: SolidReferenceGroup? = null - val group = SolidGroup{ + var box: SolidReference? = null + val group = testSolids.solidGroup { styleSheet { - set("testStyle") { + update("testStyle") { SolidMaterial.MATERIAL_COLOR_KEY put "#555555" } } @@ -101,10 +111,10 @@ class PropertyTest { styles = listOf("testStyle") } } - group { + solidGroup { box = ref("box".asName()) } } - assertEquals("#555555", box?.color.string) + assertEquals("#555555", box!!.color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt index cfdd73f0..512f3807 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/SolidReferenceTest.kt @@ -2,7 +2,8 @@ package space.kscience.visionforge.solid import kotlinx.serialization.json.encodeToJsonElement import space.kscience.dataforge.misc.DFExperimental -import space.kscience.visionforge.get +import space.kscience.dataforge.names.get +import space.kscience.visionforge.getChild import space.kscience.visionforge.style import space.kscience.visionforge.useStyle import kotlin.test.Test @@ -10,7 +11,7 @@ import kotlin.test.assertEquals @DFExperimental class SolidReferenceTest { - val groupWithReference = SolidGroup { + val groupWithReference = testSolids.solidGroup { val theStyle by style { SolidMaterial.MATERIAL_COLOR_KEY put "red" } @@ -23,13 +24,14 @@ class SolidReferenceTest { @Test fun testReferenceProperty(){ - assertEquals("blue", (groupWithReference["test"] as Solid).color.string) + assertEquals("blue", (groupWithReference.children.getChild("test") as Solid).color.string) } @Test fun testReferenceSerialization(){ val serialized = Solids.jsonForSolids.encodeToJsonElement(groupWithReference) val deserialized = Solids.jsonForSolids.decodeFromJsonElement(SolidGroup.serializer(), serialized) - assertEquals("blue", (deserialized["test"] as Solid).color.string) + assertEquals(groupWithReference.items["test"]?.color?.string, deserialized.items["test"]?.color?.string) + assertEquals("blue", (deserialized.children.getChild("test") as Solid).color.string) } } \ No newline at end of file diff --git a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt index 26b4b40d..0e495aaa 100644 --- a/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt +++ b/visionforge-solid/src/commonTest/kotlin/space/kscience/visionforge/solid/VisionUpdateTest.kt @@ -1,45 +1,48 @@ package space.kscience.visionforge.solid import space.kscience.dataforge.context.Global -import space.kscience.dataforge.context.fetch +import space.kscience.dataforge.context.request import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.asValue import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.asValue import space.kscience.visionforge.VisionChange -import space.kscience.visionforge.get +import space.kscience.visionforge.getChild import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertTrue -class VisionUpdateTest { - val solidManager = Global.fetch(Solids) +internal class VisionUpdateTest { + val solidManager = Global.request(Solids) val visionManager = solidManager.visionManager @Test - fun testVisionUpdate(){ - val targetVision = SolidGroup { - box(200,200,200, name = "origin") + fun testVisionUpdate() { + val targetVision = testSolids.solidGroup { + box(200, 200, 200, name = "origin") } - val dif = VisionChange{ - group("top") { + val dif = visionManager.VisionChange { + solidGroup("top") { color(123) - box(100,100,100) + box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) } targetVision.update(dif) - assertTrue { targetVision["top"] is SolidGroup } - assertEquals("red", (targetVision["origin"] as Solid).color.string) // Should work - assertEquals("#00007b", (targetVision["top"] as Solid).color.string) // new item always takes precedence + assertTrue { targetVision.children.getChild("top") is SolidGroup } + assertEquals("red", (targetVision.children.getChild("origin") as Solid).color.string) // Should work + assertEquals( + "#00007b", + (targetVision.children.getChild("top") as Solid).color.string + ) // new item always takes precedence } @Test - fun testVisionChangeSerialization(){ - val change = VisionChange{ - group("top") { + fun testVisionChangeSerialization() { + val change = visionManager.VisionChange { + solidGroup("top") { color(123) - box(100,100,100) + box(100, 100, 100) } propertyChanged("top".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) propertyChanged("origin".asName(), SolidMaterial.MATERIAL_COLOR_KEY, Meta("red".asValue())) @@ -47,6 +50,6 @@ class VisionUpdateTest { val serialized = visionManager.jsonFormat.encodeToString(VisionChange.serializer(), change) println(serialized) val reconstructed = visionManager.jsonFormat.decodeFromString(VisionChange.serializer(), serialized) - assertEquals(change.properties,reconstructed.properties) + assertEquals(change.properties, reconstructed.properties) } } \ No newline at end of file diff --git a/visionforge-tables/build.gradle.kts b/visionforge-tables/build.gradle.kts index 55c367c5..f4197864 100644 --- a/visionforge-tables/build.gradle.kts +++ b/visionforge-tables/build.gradle.kts @@ -1,40 +1,33 @@ plugins { - id("ru.mipt.npm.gradle.mpp") + id("space.kscience.gradle.mpp") } -val tablesVersion = "0.1.4" +val tablesVersion = "0.3.0" kscience { - useSerialization() -} - -kotlin { + jvm() js { useCommonJs() binaries.library() - browser{ - commonWebpackConfig{ - cssSupport.enabled = true + browser { + commonWebpackConfig { + cssSupport { + enabled.set(true) + } } } } - - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-core")) - api("space.kscience:tables-kt:${tablesVersion}") - } - } - jsMain { - dependencies { - implementation(npm("tabulator-tables", "5.0.1")) - implementation(npm("@types/tabulator-tables", "5.0.1")) - } - } + dependencies { + api(projects.visionforgeCore) + api("space.kscience:tables-kt:${tablesVersion}") } + dependencies(jsMain) { + implementation(npm("tabulator-tables", "5.5.2")) + implementation(npm("@types/tabulator-tables", "5.5.3")) + } + useSerialization() } -readme{ - maturity = ru.mipt.npm.gradle.Maturity.PROTOTYPE +readme { + maturity = space.kscience.gradle.Maturity.PROTOTYPE } \ No newline at end of file diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt index 6e632147..d6bc9b1d 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/TableVisionPlugin.kt @@ -8,9 +8,7 @@ import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.meta.Meta import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionManager import space.kscience.visionforge.VisionPlugin -import kotlin.reflect.KClass public class TableVisionPlugin : VisionPlugin() { override val tag: PluginTag get() = Companion.tag @@ -24,7 +22,7 @@ public class TableVisionPlugin : VisionPlugin() { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table", PluginTag.DATAFORGE_GROUP) - override val type: KClass = TableVisionPlugin::class - override fun invoke(meta: Meta, context: Context): TableVisionPlugin = TableVisionPlugin() + + override fun build(context: Context, meta: Meta): TableVisionPlugin = TableVisionPlugin() } } \ No newline at end of file diff --git a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt index 95888f67..3e4f9da8 100644 --- a/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt +++ b/visionforge-tables/src/commonMain/kotlin/space/kscience/visionforge/tables/VisionOfTable.kt @@ -8,12 +8,10 @@ import kotlinx.serialization.encoding.Decoder import kotlinx.serialization.encoding.Encoder import space.kscience.dataforge.meta.* import space.kscience.dataforge.misc.DFExperimental -import space.kscience.dataforge.values.Null -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue import space.kscience.tables.* -import space.kscience.visionforge.VisionBase +import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.html.VisionOutput +import space.kscience.visionforge.root import kotlin.jvm.JvmName import kotlin.reflect.typeOf @@ -41,12 +39,17 @@ public val ColumnHeader.properties: ValueColumnScheme get() = ValueColumn @SerialName("vision.table") public class VisionOfTable( override val headers: List<@Serializable(ColumnHeaderSerializer::class) ColumnHeader>, -) : VisionBase(), Rows { +) : AbstractVision(), Rows { public var data: List - get() = meta.getIndexed("rows").entries.sortedBy { it.key?.toInt() }.map { it.value } + get() = properties.root().getIndexed("rows").entries.sortedBy { + it.key?.toInt() + }.map { + it.value + } set(value) { - meta["rows"] = value + //TODO Make it better + properties.root()["rows"] = value } public val rows: List get() = data.map(::MetaRow) @@ -83,10 +86,15 @@ public fun Table.toVision(): VisionOfTable = toVision { (it ?: "").asVal @JvmName("numberTableToVision") public fun Table.toVision(): VisionOfTable = toVision { (it ?: Double.NaN).asValue() } +@JvmName("anyTableToVision") +public fun Table.toVision(): VisionOfTable = toVision { + (it as? Number)?.asValue() ?: it?.toString()?.asValue() ?: Null +} + @DFExperimental public inline fun VisionOutput.table( vararg headers: ColumnHeader, - block: MutableRowTable.() -> Unit, + block: RowTableBuilder.() -> Unit, ): VisionOfTable { requirePlugin(TableVisionPlugin) return RowTable(*headers, block = block).toVision() @@ -94,8 +102,8 @@ public inline fun VisionOutput.table( @DFExperimental public inline fun VisionOutput.columnTable( - columnSize: UInt, - block: MutableColumnTable.() -> Unit, + columnSize: Int, + block: ColumnTableBuilder.() -> Unit, ): VisionOfTable = ColumnTable(columnSize, block).toVision() @DFExperimental diff --git a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt index 5796d8e2..def7017b 100644 --- a/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt +++ b/visionforge-tables/src/commonTest/kotlin/space/kscience/visionforge/tables/VisionOfTableTest.kt @@ -1,11 +1,12 @@ package space.kscience.visionforge.tables -import space.kscience.dataforge.values.Value -import space.kscience.dataforge.values.asValue -import space.kscience.dataforge.values.double -import space.kscience.dataforge.values.int +import space.kscience.dataforge.meta.Value +import space.kscience.dataforge.meta.asValue +import space.kscience.dataforge.meta.double +import space.kscience.dataforge.meta.int import space.kscience.tables.ColumnHeader import space.kscience.tables.ColumnTable +import space.kscience.tables.fill import space.kscience.tables.get import kotlin.math.pow import kotlin.test.Test @@ -17,8 +18,8 @@ internal class VisionOfTableTest { val x by ColumnHeader.typed() val y by ColumnHeader.typed() - val table = ColumnTable(100U) { - x.fill { it.asValue() } + val table = ColumnTable(100) { + fill(x, null) { it.asValue() } y.values = x.values.map { it?.double?.pow(2)?.asValue() } } @@ -27,6 +28,6 @@ internal class VisionOfTableTest { val rows = vision.rowSequence().toList() - assertEquals(50, rows[50][x]?.int) + assertEquals(50, rows[50][x].int) } } \ No newline at end of file diff --git a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt index 42525847..75977d79 100644 --- a/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt +++ b/visionforge-tables/src/jsMain/kotlin/space/kscience/visionforge/tables/TableVisionJsPlugin.kt @@ -1,34 +1,32 @@ package space.kscience.visionforge.tables -import kotlinext.js.jso +import js.core.jso import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.AbstractPlugin import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginTag -import space.kscience.dataforge.meta.DynamicMeta import space.kscience.dataforge.meta.Meta import space.kscience.dataforge.meta.toDynamic import space.kscience.dataforge.names.Name import space.kscience.dataforge.names.asName import space.kscience.visionforge.ElementVisionRenderer +import space.kscience.visionforge.JsVisionClient import space.kscience.visionforge.Vision -import space.kscience.visionforge.VisionClient import tabulator.Tabulator import tabulator.TabulatorFull -import kotlin.reflect.KClass public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { - public val visionClient: VisionClient by require(VisionClient) + public val visionClient: JsVisionClient by require(JsVisionClient) public val tablesBase: TableVisionPlugin by require(TableVisionPlugin) override val tag: PluginTag get() = Companion.tag override fun attach(context: Context) { super.attach(context) - kotlinext.js.require("tabulator-tables/dist/css/tabulator.min.css") - kotlinext.js.require("tabulator-tables/src/js/modules/ResizeColumns/ResizeColumns.js") + kotlinext.js.require("tabulator-tables/dist/css/tabulator.min.css") + kotlinext.js.require("tabulator-tables/src/js/modules/ResizeColumns/ResizeColumns.js") } override fun rateVision(vision: Vision): Int = when (vision) { @@ -36,7 +34,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { else -> ElementVisionRenderer.ZERO_RATING } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { val table: VisionOfTable = (vision as? VisionOfTable) ?: error("VisionOfTable expected but ${vision::class} found") @@ -49,15 +47,15 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { } }.toTypedArray() - columns = Array(table.headers.size + 1){ - if(it==0){ + columns = Array(table.headers.size + 1) { + if (it == 0) { jso { field = "@index" title = "#" resizable = false } } else { - val header = table.headers[it-1] + val header = table.headers[it - 1] jso { field = header.name title = header.properties.title ?: header.name @@ -67,7 +65,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { } - data = table.rows.mapIndexed { index, row-> + data = table.rows.mapIndexed { index, row -> val d = row.meta.toDynamic() d["@index"] = index d @@ -90,7 +88,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer { public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.table.js", PluginTag.DATAFORGE_GROUP) - override val type: KClass = TableVisionJsPlugin::class - override fun invoke(meta: Meta, context: Context): TableVisionJsPlugin = TableVisionJsPlugin() + + override fun build(context: Context, meta: Meta): TableVisionJsPlugin = TableVisionJsPlugin() } } \ No newline at end of file diff --git a/visionforge-threejs/build.gradle.kts b/visionforge-threejs/build.gradle.kts index 5ae86f41..41714618 100644 --- a/visionforge-threejs/build.gradle.kts +++ b/visionforge-threejs/build.gradle.kts @@ -1,15 +1,23 @@ plugins { - id("ru.mipt.npm.gradle.js") + id("space.kscience.gradle.mpp") } kotlin{ + explicitApi = org.jetbrains.kotlin.gradle.dsl.ExplicitApiMode.Disabled +} + +kscience{ js{ binaries.library() } + jsMain{ + dependencies { + api(projects.visionforgeSolid) + implementation(npm("three", "0.143.0")) + implementation(npm("three-csg-ts", "3.1.10")) + implementation(npm("three.meshline","1.4.0")) + } + } } -dependencies { - api(project(":visionforge-solid")) - implementation(npm("three", "0.130.1")) - implementation(npm("three-csg-ts", "3.1.9")) -} + diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt new file mode 100644 index 00000000..f15f2c78 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAmbientLightFactory.kt @@ -0,0 +1,35 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.names.Name +import space.kscience.visionforge.Vision +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.AmbientLightSource +import space.kscience.visionforge.solid.LightSource +import space.kscience.visionforge.solid.SolidMaterial +import space.kscience.visionforge.visible +import three.lights.AmbientLight +import three.math.Color +import kotlin.reflect.KClass + +public object ThreeAmbientLightFactory : ThreeFactory { + override val type: KClass get() = AmbientLightSource::class + + override suspend fun build(three: ThreePlugin, vision: AmbientLightSource, observe: Boolean): AmbientLight { + val res = AmbientLight().apply { + color = vision.color.threeColor() ?: Color(0x404040) + intensity = vision.intensity.toDouble() + } + + if (observe) { + vision.onPropertyChange(three.context) { propertyName: Name -> + when (propertyName) { + Vision.VISIBLE_KEY -> res.visible = vision.visible ?: true + SolidMaterial.COLOR_KEY -> res.color = vision.color.threeColor() ?: Color(0x404040) + LightSource.INTENSITY_KEY -> res.intensity = vision.intensity.toDouble() + } + } + } + + return res + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt new file mode 100644 index 00000000..8af445b9 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeAxesFactory.kt @@ -0,0 +1,22 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.AxesSolid +import three.helpers.AxesHelper +import kotlin.reflect.KClass + +public object ThreeAxesFactory : ThreeFactory { + override val type: KClass get() = AxesSolid::class + + override suspend fun build(three: ThreePlugin, vision: AxesSolid, observe: Boolean): AxesHelper { + val res = AxesHelper(vision.size.toInt()) + + if (observe) { + vision.onPropertyChange(three.context) { propertyName -> + res.updateProperty(vision, propertyName) + } + } + + return res + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt similarity index 65% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt index a5b50688..d6840f75 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeBoxFactory.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.geometries.BoxGeometry import space.kscience.visionforge.solid.Box import space.kscience.visionforge.solid.detail +import three.geometries.BoxGeometry -public object ThreeBoxFactory : MeshThreeFactory(Box::class) { - override fun buildGeometry(obj: Box): BoxGeometry = +public object ThreeBoxFactory : ThreeMeshFactory(Box::class) { + override suspend fun buildGeometry(obj: Box): BoxGeometry = obj.detail?.let { detail -> BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail) } ?: BoxGeometry(obj.xSize, obj.ySize, obj.zSize) diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt similarity index 69% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt index ef9944e0..b65d1fce 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvas.kt @@ -1,23 +1,7 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.WebGLRenderer -import info.laht.threekt.cameras.PerspectiveCamera -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.external.controls.OrbitControls -import info.laht.threekt.external.controls.TrackballControls -import info.laht.threekt.geometries.EdgesGeometry -import info.laht.threekt.helpers.AxesHelper -import info.laht.threekt.lights.AmbientLight -import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.math.Box3 -import info.laht.threekt.math.Plane -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh -import info.laht.threekt.scenes.Scene import kotlinx.browser.window +import kotlinx.coroutines.launch import org.w3c.dom.Element import org.w3c.dom.HTMLCanvasElement import org.w3c.dom.Node @@ -29,13 +13,27 @@ import space.kscience.dataforge.names.* import space.kscience.visionforge.Colors import space.kscience.visionforge.solid.Solid import space.kscience.visionforge.solid.specifications.* -import space.kscience.visionforge.solid.three.ThreeMaterials.HIGHLIGHT_MATERIAL -import space.kscience.visionforge.solid.three.ThreeMaterials.SELECTED_MATERIAL +import three.WebGLRenderer +import three.cameras.PerspectiveCamera +import three.core.Object3D +import three.core.Raycaster +import three.external.controls.OrbitControls +import three.external.controls.TrackballControls +import three.geometries.EdgesGeometry +import three.helpers.AxesHelper +import three.materials.Material +import three.math.* +import three.meshline.MeshLine +import three.meshline.MeshLineMaterial +import three.meshline.isMeshLineMaterial +import three.objects.LineSegments +import three.objects.Mesh +import three.scenes.Scene import kotlin.math.cos import kotlin.math.sin /** - * + * A canvas for three-js rendering */ public class ThreeCanvas( public val three: ThreePlugin, @@ -59,20 +57,10 @@ public class ThreeCanvas( axesObject.name = AXES_NAME add(axesObject) } - - //Set up light - options.useProperty(Canvas3DOptions::light, this) { lightConfig -> - //remove old light if present - getObjectByName(LIGHT_NAME)?.let { remove(it) } - //add new light - val lightObject = buildLight(lightConfig) - lightObject.name = LIGHT_NAME - add(lightObject) - } } - private fun buildCamera(spec: Camera) = PerspectiveCamera( + private fun buildCamera(spec: CameraScheme) = PerspectiveCamera( spec.fov, 1.0, spec.nearClip, @@ -112,7 +100,7 @@ public class ThreeCanvas( } /** - * Force camera aspect ration and renderer size recalculation + * Force camera aspect ratio and renderer size recalculation */ private fun updateSize() { val width = element.clientWidth @@ -135,8 +123,8 @@ public class ThreeCanvas( element.appendChild(canvas) updateSize() canvas.addEventListener("pointerdown", { - val picked = pick() - options.onSelect?.invoke(picked?.fullName()) + val newPicked = pick() + options.onSelect?.invoke(newPicked?.fullName()) }, false) //Attach listener to track mouse changes @@ -155,12 +143,12 @@ public class ThreeCanvas( addControls(canvas, options.controls) renderer.setAnimationLoop { - val picked = pick() + val newPicked = pick() - if (picked != null && this.picked != picked) { - this.picked?.toggleHighlight(false, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) - picked.toggleHighlight(true, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) - this.picked = picked + if (newPicked != null && picked !== newPicked) { + picked?.toggleHighlight(false, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) + newPicked.toggleHighlight(true, HIGHLIGHT_NAME, HIGHLIGHT_MATERIAL) + picked = newPicked } renderer.render(scene, camera) @@ -204,7 +192,7 @@ public class ThreeCanvas( } /** - * Resolve full name of the object relative to the global root + * Resolve the full name of the object relative to the global root */ private fun Object3D.fullName(): Name { if (root == null) error("Can't resolve element name without the root") @@ -215,8 +203,8 @@ public class ThreeCanvas( } } - //find first non-static parent in this object ancestry - private fun Object3D?.upTrace(): Object3D? = if (this?.name?.startsWith("@") == true) parent else this + //find the first non-static parent in this object ancestry + private tailrec fun Object3D.upTrace(): Object3D? = if (!name.startsWith("@")) this else parent?.upTrace() private fun pick(): Object3D? { // update the picking ray with the camera and mouse position @@ -226,14 +214,29 @@ public class ThreeCanvas( return root?.let { root -> val intersects = raycaster.intersectObject(root, true) //skip invisible objects - val obj = intersects.map { it.`object` }.firstOrNull { it.visible } - obj.upTrace() + val obj: Object3D? = intersects.map { it.`object` }.firstOrNull { it.visible } + obj?.upTrace() } } - private fun buildLight(spec: Light?): info.laht.threekt.lights.Light = AmbientLight(0x404040) +// private fun buildLight(spec: AmbientLightScheme?): info.laht.threekt.lights.Light = when (spec?.type) { +// AmbientLightScheme.Type.POINT -> PointLight().apply { +// position.x = spec.position.x ?: 0.0 +// position.y = spec.position.y ?: 0.0 +// position.z = spec.position.z ?: 0.0 +// } +// else -> AmbientLight().apply { +// +// } +// }.apply { +// this.color = spec?.color?.threeColor() ?: Color(0x404040) +// +// spec?.intensity?.coerceIn(0.0, 1.0)?.let { +// this.intensity = it +// } +// } - private fun addControls(element: Node, controls: Controls) { + private fun addControls(element: Node, controls: ControlsScheme) { when (controls.meta["type"].string) { "trackball" -> TrackballControls(camera, element) else -> OrbitControls(camera, element) @@ -252,11 +255,13 @@ public class ThreeCanvas( scene.findChild("@root".asName())?.let { scene.remove(it) } root?.dispose() } + three.context.launch { + val object3D = three.buildObject3D(vision) - val object3D = three.buildObject3D(vision) - object3D.name = "@root" - scene.add(object3D) - root = object3D + object3D.name = "@root" + scene.add(object3D) + root = object3D + } } private var selected: Object3D? = null @@ -267,22 +272,29 @@ public class ThreeCanvas( private fun Object3D.toggleHighlight( highlight: Boolean, edgesName: String, - material: LineBasicMaterial = SELECTED_MATERIAL, + material: Material, ) { + if (userData[DO_NOT_HIGHLIGHT_TAG] == true) { return } - if (this is Mesh) { - val edges = getObjectByName(edgesName) ?: LineSegments( - EdgesGeometry(geometry), - material - ).also { + + if (isMesh(this)) { + val highlightMesh = getObjectByName(edgesName) ?: if (isMeshLineMaterial(material)) { + Mesh( + MeshLine(EdgesGeometry(geometry)), + material + ) + } else { + LineSegments(EdgesGeometry(geometry), material) + }.also { it.name = edgesName add(it) } - edges.visible = highlight + highlightMesh.visible = highlight } else { - children.filter { it.name != edgesName }.forEach { + //ignore service objects if they are not statics + children.filter { it.name.startsWith("@static") || !it.name.startsWith("@") }.forEach { it.toggleHighlight(highlight, edgesName, material) } } @@ -306,12 +318,35 @@ public class ThreeCanvas( } public companion object { + public val SELECTED_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { + color.set(Colors.ivory) + thickness = 2f + cached = true + } + + public val HIGHLIGHT_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply { + color.set(Colors.blue) + thickness = 1f + cached = true + } +// +// public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { +// color.set(Colors.ivory) +// cached = true +// } +// +// public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { +// color.set(Colors.blue) +// cached = true +// } + + public const val DO_NOT_HIGHLIGHT_TAG: String = "doNotHighlight" private const val HIGHLIGHT_NAME = "@highlight" private const val SELECT_NAME = "@select" private const val LIGHT_NAME = "@light" private const val AXES_NAME = "@axes" - private const val CLIP_HELPER_NAME = "@clipping" + //private const val CLIP_HELPER_NAME = "@clipping" } } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt new file mode 100644 index 00000000..93bf170b --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt @@ -0,0 +1,63 @@ +package space.kscience.visionforge.solid.three + +import kotlinx.browser.document +import org.w3c.dom.CanvasRenderingContext2D +import org.w3c.dom.CanvasTextBaseline +import org.w3c.dom.HTMLCanvasElement +import org.w3c.dom.MIDDLE +import space.kscience.visionforge.solid.SolidLabel +import space.kscience.visionforge.solid.SolidMaterial +import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG +import three.DoubleSide +import three.core.Object3D +import three.geometries.PlaneGeometry +import three.materials.MeshBasicMaterial +import three.objects.Mesh +import three.textures.Texture +import kotlin.reflect.KClass + +/** + * Using example from http://stemkoski.github.io/Three.js/Texture-From-Canvas.html + */ +public object ThreeCanvasLabelFactory : ThreeFactory { + override val type: KClass get() = SolidLabel::class + + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + val canvas = document.createElement("canvas") as HTMLCanvasElement + canvas.width = 200 + canvas.height = 200 + + canvas.getContext("2d").apply { + this as CanvasRenderingContext2D + font = "Bold ${vision.fontSize}pt ${vision.fontFamily}" + fillStyle = vision.properties.getValue( + SolidMaterial.MATERIAL_COLOR_KEY, + inherit = false, + includeStyles = true + )?.value ?: "black" + textBaseline = CanvasTextBaseline.MIDDLE + val metrics = measureText(vision.text) + //canvas.width = metrics.width.toInt() + fillText(vision.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) + } + + + // canvas contents will be used for a texture + val texture = Texture(canvas) + texture.needsUpdate = true + + val mesh = Mesh( + PlaneGeometry(canvas.width, canvas.height), + MeshBasicMaterial().apply { + map = texture + side = DoubleSide + transparent = true + } + ) + + mesh.updatePosition(vision) + + mesh.userData[DO_NOT_HIGHLIGHT_TAG] = true + return mesh + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt index f57530b3..e6e9641c 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeCompositeFactory.kt @@ -1,11 +1,12 @@ package space.kscience.visionforge.solid.three import CSG -import info.laht.threekt.objects.Mesh import space.kscience.dataforge.names.startsWith import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.Composite import space.kscience.visionforge.solid.CompositeType +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY +import three.objects.Mesh import kotlin.reflect.KClass /** @@ -37,21 +38,26 @@ public class ThreeCompositeFactory(public val three: ThreePlugin) : ThreeFactory override val type: KClass get() = Composite::class - override fun invoke(three: ThreePlugin, obj: Composite): Mesh { - val first = three.buildObject3D(obj.first) as? Mesh ?: error("First part of composite is not a mesh") - val second = three.buildObject3D(obj.second) as? Mesh ?: error("Second part of composite is not a mesh") - return when (obj.compositeType) { + override suspend fun build(three: ThreePlugin, vision: Composite, observe: Boolean): Mesh { + val first = three.buildObject3D(vision.first, observe).takeIfMesh() + ?: error("First part of composite is not a mesh") + val second = three.buildObject3D(vision.second, observe).takeIfMesh() + ?: error("Second part of composite is not a mesh") + return when (vision.compositeType) { CompositeType.GROUP, CompositeType.UNION -> CSG.union(first, second) CompositeType.INTERSECT -> CSG.intersect(first, second) CompositeType.SUBTRACT -> CSG.subtract(first, second) }.apply { - updatePosition(obj) - applyProperties(obj) - obj.onPropertyChange { name -> - when { - //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(MeshThreeFactory.EDGES_KEY) -> applyEdges(obj) - else -> updateProperty(obj, name) + updatePosition(vision) + applyProperties(vision) + + if (observe) { + vision.onPropertyChange { name -> + when { + //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) + name.startsWith(EDGES_KEY) -> applyEdges(vision) + else -> updateProperty(vision, name) + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt similarity index 68% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt index 5789c30e..bcc147c7 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConeFactory.kt @@ -1,14 +1,14 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.CylinderGeometry import space.kscience.visionforge.solid.ConeSegment import space.kscience.visionforge.solid.detail +import three.core.BufferGeometry +import three.geometries.CylinderGeometry import kotlin.math.PI import kotlin.math.pow -public object ThreeConeFactory : MeshThreeFactory(ConeSegment::class) { - override fun buildGeometry(obj: ConeSegment): BufferGeometry { +public object ThreeConeFactory : ThreeMeshFactory(ConeSegment::class) { + override suspend fun buildGeometry(obj: ConeSegment): BufferGeometry { val cylinder = obj.detail?.let { val segments = it.toDouble().pow(0.5).toInt() CylinderGeometry( @@ -18,16 +18,16 @@ public object ThreeConeFactory : MeshThreeFactory(ConeSegment::clas radialSegments = segments, heightSegments = segments, openEnded = false, - thetaStart = obj.startAngle, - thetaLength = obj.angle + thetaStart = obj.phiStart, + thetaLength = obj.phi ) } ?: CylinderGeometry( radiusTop = obj.topRadius, radiusBottom = obj.bottomRadius, height = obj.height, openEnded = false, - thetaStart = obj.startAngle, - thetaLength = obj.angle + thetaStart = obj.phiStart, + thetaLength = obj.phi ) return cylinder.rotateX(PI/2) } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt similarity index 53% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt index fe08b1cf..b772c1bf 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeConvexFactory.kt @@ -1,10 +1,10 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.external.geometries.ConvexBufferGeometry import space.kscience.visionforge.solid.Convex +import three.external.geometries.ConvexBufferGeometry -public object ThreeConvexFactory : MeshThreeFactory(Convex::class) { - override fun buildGeometry(obj: Convex): ConvexBufferGeometry { +public object ThreeConvexFactory : ThreeMeshFactory(Convex::class) { + override suspend fun buildGeometry(obj: Convex): ConvexBufferGeometry { val vectors = obj.points.map { it.toVector() }.toTypedArray() return ConvexBufferGeometry(vectors) } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt new file mode 100644 index 00000000..09b81053 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt @@ -0,0 +1,90 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.misc.DfType +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.startsWith +import space.kscience.visionforge.Vision +import space.kscience.visionforge.solid.* +import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY +import space.kscience.visionforge.solid.three.ThreeFactory.Companion.TYPE +import space.kscience.visionforge.visible +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Euler +import three.math.Quaternion +import kotlin.reflect.KClass + +/** + * Builder and updater for three.js object + */ +@DfType(TYPE) +public interface ThreeFactory { + + public val type: KClass + + /** + * Build an [Object3D] from [vision]. + * @param observe if false, does not observe the changes in [vision] after render (useful for statics). + */ + public suspend fun build(three: ThreePlugin, vision: T, observe: Boolean = true): Object3D + + public companion object { + public const val TYPE: String = "threeFactory" + } +} + +/** + * Update position, rotation and visibility + */ +public fun Object3D.updatePosition(vision: Vision) { +// visible = vision.visible ?: true + if (vision is Solid) { + position.set(vision.x, vision.y, vision.z) + + val quaternion = vision.quaternionOrNull + + if (quaternion != null) { + setRotationFromQuaternion( + Quaternion( + quaternion.x, + quaternion.y, + quaternion.z, + quaternion.w + ) + ) + } else { + setRotationFromEuler(Euler(vision.rotationX, vision.rotationY, vision.rotationZ, vision.rotationOrder.name)) + } + + scale.set(vision.scaleX, vision.scaleY, vision.scaleZ) + updateMatrix() + } +} + +/** + * Update non-position non-geometry property + */ +public fun Object3D.updateProperty(source: Vision, propertyName: Name) { + // console.log("$source updated $propertyName with ${source.computeProperty(propertyName)}") + if (isMesh(this) && propertyName.startsWith(MATERIAL_KEY)) { + updateMaterialProperty(source, propertyName) + } else if ( + propertyName.startsWith(Solid.POSITION_KEY) + || propertyName.startsWith(Solid.ROTATION_KEY) + || propertyName.startsWith(Solid.SCALE_KEY) + ) { + //update position of mesh using this object + updatePosition(source) + } else if (propertyName == Vision.VISIBLE_KEY) { + visible = source.visible ?: true + } +} + +/** + * Generic factory for elements which provide inside geometry builder + */ +public object ThreeShapeFactory : ThreeMeshFactory(GeometrySolid::class) { + override suspend fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply { + obj.toGeometry(this) + }.build() +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt similarity index 66% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt index fc226de6..7a5f3c49 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeGeometryBuilder.kt @@ -1,15 +1,14 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Float32BufferAttribute -import info.laht.threekt.math.Vector3 import space.kscience.dataforge.meta.Meta +import space.kscience.visionforge.solid.Float32Euclidean3DSpace +import space.kscience.visionforge.solid.Float32Vector3D import space.kscience.visionforge.solid.GeometryBuilder -import space.kscience.visionforge.solid.Point3D -import space.kscience.visionforge.solid.cross -import space.kscience.visionforge.solid.minus +import three.core.BufferGeometry +import three.core.Float32BufferAttribute +import three.math.Vector3 -internal fun Point3D.toVector() = Vector3(x, y, z) +internal fun Float32Vector3D.toVector() = Vector3(x, y, z) internal fun MutableList.add(vararg values: T) { values.forEach { @@ -27,10 +26,10 @@ public class ThreeGeometryBuilder : GeometryBuilder { private val normals = ArrayList() // private val colors = ArrayList() - private val vertexCache = HashMap() + private val vertexCache = HashMap() private var counter: Short = -1 - private fun vertex(vertex: Point3D, normal: Point3D): Short = vertexCache.getOrPut(vertex) { + private fun vertex(vertex: Float32Vector3D, normal: Float32Vector3D): Short = vertexCache.getOrPut(vertex) { //add vertex and update cache if needed positions.add(vertex.x, vertex.y, vertex.z) normals.add(normal.x, vertex.y, vertex.z) @@ -39,8 +38,14 @@ public class ThreeGeometryBuilder : GeometryBuilder { counter } - override fun face(vertex1: Point3D, vertex2: Point3D, vertex3: Point3D, normal: Point3D?, meta: Meta) { - val actualNormal: Point3D = normal ?: ((vertex3 - vertex2) cross (vertex1 - vertex2)) + override fun face( + vertex1: Float32Vector3D, + vertex2: Float32Vector3D, + vertex3: Float32Vector3D, + normal: Float32Vector3D?, + meta: Meta, + ) = with(Float32Euclidean3DSpace) { + val actualNormal: Float32Vector3D = normal ?: ((vertex3 - vertex2) cross (vertex1 - vertex2)) indices.add( vertex(vertex1, actualNormal), vertex(vertex2, actualNormal), diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt similarity index 51% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt index 27a5da44..6f6e166a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeJsVision.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D import space.kscience.visionforge.solid.SolidBase +import three.core.Object3D /** * A custom visual object that has its own Three.js renderer */ -public abstract class ThreeJsVision : SolidBase() { - public abstract fun render(three: ThreePlugin): Object3D +public abstract class ThreeJsVision : SolidBase() { + public abstract suspend fun render(three: ThreePlugin): Object3D } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt similarity index 50% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt index 02586120..45068a3a 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLabelFactory.kt @@ -1,15 +1,14 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.TextBufferGeometry -import info.laht.threekt.objects.Mesh -import kotlinext.js.jsObject -import kotlinext.js.jso +import js.core.jso import space.kscience.dataforge.context.logger import space.kscience.dataforge.context.warn import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.SolidLabel +import three.core.Object3D +import three.geometries.TextBufferGeometry +import three.objects.Mesh import kotlin.reflect.KClass /** @@ -18,19 +17,21 @@ import kotlin.reflect.KClass public object ThreeLabelFactory : ThreeFactory { override val type: KClass get() = SolidLabel::class - override fun invoke(three: ThreePlugin, obj: SolidLabel): Object3D { - val textGeo = TextBufferGeometry(obj.text, jso { - font = obj.fontFamily + override suspend fun build(three: ThreePlugin, vision: SolidLabel, observe: Boolean): Object3D { + val textGeo = TextBufferGeometry(vision.text, jso { + font = vision.fontFamily size = 20 height = 1 curveSegments = 1 }) return Mesh(textGeo, ThreeMaterials.DEFAULT).apply { - updateMaterial(obj) - updatePosition(obj) - obj.onPropertyChange { _ -> - //TODO - three.logger.warn { "Label parameter change not implemented" } + setMaterial(vision) + updatePosition(vision) + if(observe) { + vision.onPropertyChange(three.context) { + //TODO + three.logger.warn { "Label parameter change not implemented" } + } } } } diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt similarity index 53% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt index ee36d74b..68bfd7b2 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeLineFactory.kt @@ -1,43 +1,44 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color -import info.laht.threekt.objects.LineSegments -import space.kscience.visionforge.computePropertyNode import space.kscience.visionforge.onPropertyChange import space.kscience.visionforge.solid.PolyLine import space.kscience.visionforge.solid.SolidMaterial import space.kscience.visionforge.solid.color import space.kscience.visionforge.solid.string import space.kscience.visionforge.solid.three.ThreeMaterials.DEFAULT_LINE_COLOR +import three.core.BufferGeometry +import three.core.Object3D +import three.math.Color +import three.objects.LineSegments import kotlin.math.ceil import kotlin.reflect.KClass public object ThreeLineFactory : ThreeFactory { override val type: KClass get() = PolyLine::class - override fun invoke(three: ThreePlugin, obj: PolyLine): Object3D { + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { val geometry = BufferGeometry().apply { - setFromPoints(Array((obj.points.size - 1) * 2) { - obj.points[ceil(it / 2.0).toInt()].toVector() + setFromPoints(Array((vision.points.size - 1) * 2) { + vision.points[ceil(it / 2.0).toInt()].toVector() }) } val material = ThreeMaterials.getLineMaterial( - obj.computePropertyNode(SolidMaterial.MATERIAL_KEY), + vision.properties[SolidMaterial.MATERIAL_KEY], false ) - material.linewidth = obj.thickness.toDouble() - material.color = obj.color.string?.let { Color(it) } ?: DEFAULT_LINE_COLOR + material.linewidth = vision.thickness.toDouble() + material.color = vision.color.string?.let { Color(it) } ?: DEFAULT_LINE_COLOR return LineSegments(geometry, material).apply { - updatePosition(obj) + updatePosition(vision) //layers.enable(obj.layer) //add listener to object properties - obj.onPropertyChange { propertyName -> - updateProperty(obj, propertyName) + if(observe) { + vision.onPropertyChange(three.context) { propertyName -> + updateProperty(vision, propertyName) + } } } } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt new file mode 100644 index 00000000..8e1b2e3f --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt @@ -0,0 +1,192 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.meta.* +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.asName +import space.kscience.dataforge.names.plus +import space.kscience.visionforge.Colors +import space.kscience.visionforge.Vision +import space.kscience.visionforge.getStyleNodes +import space.kscience.visionforge.solid.ColorAccessor +import space.kscience.visionforge.solid.SolidMaterial +import space.kscience.visionforge.solid.SolidReference +import three.materials.LineBasicMaterial +import three.materials.Material +import three.materials.MeshBasicMaterial +import three.materials.MeshStandardMaterial +import three.math.Color +import three.objects.Mesh + + +public object ThreeMaterials { + public val DEFAULT_COLOR: Color = Color(Colors.darkgreen) + + public val DEFAULT: MeshStandardMaterial = MeshStandardMaterial().apply { + color.set(DEFAULT_COLOR) + cached = true + } + + public val BLACK_COLOR: Color = Color(Colors.black) + + public val DEFAULT_EMISSIVE_COLOR: Color = BLACK_COLOR + + public val DEFAULT_LINE_COLOR: Color get() = BLACK_COLOR + + public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply { + color.set(DEFAULT_LINE_COLOR) + cached = true + } + + private val lineMaterialCache = HashMap() + + private fun buildLineMaterial(meta: Meta): LineBasicMaterial = LineBasicMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_LINE_COLOR + opacity = meta[SolidMaterial.OPACITY_KEY].double ?: 1.0 + transparent = opacity < 1.0 + linewidth = meta["thickness"].double ?: 1.0 + } + + public fun getLineMaterial(meta: Meta?, cache: Boolean): LineBasicMaterial { + if (meta == null) return DEFAULT_LINE + return if (cache) { + lineMaterialCache.getOrPut(meta.hashCode()) { buildLineMaterial(meta) } + } else { + buildLineMaterial(meta) + } + } + + internal fun buildMaterial(meta: Meta): Material = when (meta[SolidMaterial.TYPE_KEY]?.string) { + "simple" -> MeshBasicMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + + else -> MeshStandardMaterial().apply { + color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR + emissive = meta[SolidMaterial.EMISSIVE_COLOR_KEY]?.threeColor() ?: DEFAULT_EMISSIVE_COLOR + wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false + } + }.apply { + opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 + transparent = opacity < 1.0 + needsUpdate = true + } + +// private val materialCache = HashMap() +// +// internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta.hashCode()) { +// buildMaterial(meta).apply { +// cached = true +// } +// } + + private val visionMaterialCache = HashMap() + + internal fun cacheMaterial(vision: Vision): Material = visionMaterialCache.getOrPut(vision) { + buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]).apply { + cached = true + } + } +} + +/** + * Compute color + */ +public fun Meta.threeColor(): Color? { + value?.let { value -> + return when { + value === Null -> null + value.type == ValueType.NUMBER -> Color(value.int) + else -> Color(value.string) + } + } + val red = getValue(Colors.RED_KEY.asName())?.int + val green = getValue(Colors.GREEN_KEY.asName())?.int + val blue = getValue(Colors.BLUE_KEY.asName())?.int + return if (red == null && green == null && blue == null) null else Color(red ?: 0, green ?: 0, blue ?: 0) +} + +public fun ColorAccessor.threeColor(): Color? { + val value = value + return when { + value == null -> null + value === Null -> null + value.type == ValueType.NUMBER -> Color(value.int) + else -> Color(value.string) + } +} + +internal var Material.cached: Boolean + get() = userData["cached"] == true + set(value) { + userData["cached"] = value + } + +public fun Mesh.setMaterial(vision: Vision) { + if ( + vision.properties.own?.get(SolidMaterial.MATERIAL_KEY) == null + && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty() + ) { + //if this is a reference, use material of the prototype + if (vision is SolidReference) { + ThreeMaterials.cacheMaterial(vision.prototype) + } else { + material = vision.parent?.let { parent -> + //TODO cache parent material + ThreeMaterials.buildMaterial(parent.properties[SolidMaterial.MATERIAL_KEY]) + } ?: ThreeMaterials.cacheMaterial(vision) + } + } else { + material = ThreeMaterials.buildMaterial(vision.properties[SolidMaterial.MATERIAL_KEY]) + } +} + +public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { + if ( + material.cached + || propertyName == SolidMaterial.MATERIAL_KEY + || propertyName == SolidMaterial.MATERIAL_KEY + SolidMaterial.TYPE_KEY + ) { + //generate a new material since cached material should not be changed + setMaterial(vision) + } else { + when (propertyName) { + SolidMaterial.MATERIAL_COLOR_KEY -> { + material.asDynamic().color = + vision.properties[SolidMaterial.MATERIAL_COLOR_KEY].threeColor() + ?: ThreeMaterials.DEFAULT_COLOR + } + + SolidMaterial.SPECULAR_COLOR_KEY -> { + material.asDynamic().specular = + vision.properties[SolidMaterial.SPECULAR_COLOR_KEY].threeColor() + ?: ThreeMaterials.DEFAULT_COLOR + } + + SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY -> { + material.asDynamic().emissive = vision.properties[SolidMaterial.MATERIAL_EMISSIVE_COLOR_KEY] + .threeColor() + ?: ThreeMaterials.BLACK_COLOR + } + + SolidMaterial.MATERIAL_OPACITY_KEY -> { + val opacity = vision.properties.getValue( + SolidMaterial.MATERIAL_OPACITY_KEY, + inherit = true, + )?.double ?: 1.0 + material.opacity = opacity + material.transparent = opacity < 1.0 + } + + SolidMaterial.MATERIAL_WIREFRAME_KEY -> { + material.asDynamic().wireframe = vision.properties.getValue( + SolidMaterial.MATERIAL_WIREFRAME_KEY, + inherit = true, + )?.boolean ?: false + } + + else -> console.warn("Unrecognized material property: $propertyName") + } + material.needsUpdate = true + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt new file mode 100644 index 00000000..2e5fc0ca --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshFactory.kt @@ -0,0 +1,98 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.meta.boolean +import space.kscience.dataforge.names.startsWith +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_ENABLED_KEY +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_KEY +import space.kscience.visionforge.solid.SolidMaterial.Companion.EDGES_MATERIAL_KEY +import space.kscience.visionforge.solid.layer +import space.kscience.visionforge.solid.three.ThreeMeshFactory.Companion.EDGES_OBJECT_NAME +import three.core.BufferGeometry +import three.geometries.EdgesGeometry +import three.objects.LineSegments +import three.objects.Mesh +import kotlin.reflect.KClass + +/** + * Basic geometry-based factory + */ +public abstract class ThreeMeshFactory( + override val type: KClass, +) : ThreeFactory { + + /** + * Build a geometry for an object + */ + public abstract suspend fun buildGeometry(obj: T): BufferGeometry + + override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh { + val geometry = buildGeometry(vision) + + val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { + matrixAutoUpdate = false + //set position for mesh + updatePosition(vision) + applyProperties(vision) + } + + if (observe) { + //add listener to object properties + vision.onPropertyChange(three.context) { name -> + when { + name.startsWith(Solid.GEOMETRY_KEY) -> { + val oldGeometry = mesh.geometry + val newGeometry = buildGeometry(vision) + oldGeometry.attributes = newGeometry.attributes + + mesh.applyEdges(vision) + newGeometry.dispose() + } + name.startsWith(EDGES_KEY) -> mesh.applyEdges(vision) + else -> mesh.updateProperty(vision, name) + } + } + } + + return mesh + } + + public companion object { + internal const val EDGES_OBJECT_NAME: String = "@edges" + } +} + +internal fun Mesh.applyProperties(vision: Solid): Mesh = apply { + setMaterial(vision) + applyEdges(vision) + layers.set(vision.layer) + children.forEach { + it.layers.set(vision.layer) + } +} + +public fun Mesh.applyEdges(vision: Solid) { + val edges = children.find { it.name == EDGES_OBJECT_NAME } as? LineSegments + //inherited edges definition, enabled by default + if (vision.properties.getValue(EDGES_ENABLED_KEY, inherit = false)?.boolean != false) { + val material = ThreeMaterials.getLineMaterial(vision.properties[EDGES_MATERIAL_KEY], true) + if (edges == null) { + add( + LineSegments( + EdgesGeometry(geometry), + material + ).apply { + name = EDGES_OBJECT_NAME + } + ) + } else { + edges.material = material + } + } else { + edges?.let { + remove(it) + it.dispose() + } + } +} diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt new file mode 100644 index 00000000..4a94823b --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeMeshLineFactory.kt @@ -0,0 +1,41 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.PolyLine +import space.kscience.visionforge.solid.color +import space.kscience.visionforge.solid.string +import three.core.Object3D +import three.math.Color +import three.meshline.MeshLine +import three.meshline.MeshLineMaterial +import three.objects.Mesh +import kotlin.math.ceil +import kotlin.reflect.KClass + +public object ThreeMeshLineFactory : ThreeFactory { + override val type: KClass get() = PolyLine::class + + override suspend fun build(three: ThreePlugin, vision: PolyLine, observe: Boolean): Object3D { + val geometry = MeshLine( + Array((vision.points.size - 1) * 2) { + vision.points[ceil(it / 2.0).toInt()].toVector() + } + ) + + val material = MeshLineMaterial().apply { + thickness = vision.thickness.toFloat() + color = vision.color.string?.let { Color(it) } ?: ThreeMaterials.DEFAULT_LINE_COLOR + } + + return Mesh(geometry, material).apply { + updatePosition(vision) + //layers.enable(obj.layer) + //add listener to object properties + if (observe) { + vision.onPropertyChange(three.context) { propertyName -> + updateProperty(vision, propertyName) + } + } + } + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt similarity index 52% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt index aa5c2a14..7051f887 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePlugin.kt @@ -1,43 +1,44 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.Object3D -import kotlinx.coroutines.CoroutineScope +import kotlinx.coroutines.flow.launchIn +import kotlinx.coroutines.flow.onEach import org.w3c.dom.Element import org.w3c.dom.HTMLElement import space.kscience.dataforge.context.* import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.update import space.kscience.dataforge.names.* -import space.kscience.visionforge.ElementVisionRenderer -import space.kscience.visionforge.Vision -import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.* import space.kscience.visionforge.solid.* import space.kscience.visionforge.solid.specifications.Canvas3DOptions import space.kscience.visionforge.solid.three.set -import space.kscience.visionforge.visible +import three.core.Object3D import kotlin.collections.set import kotlin.reflect.KClass -import info.laht.threekt.objects.Group as ThreeGroup +import three.objects.Group as ThreeGroup public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { override val tag: PluginTag get() = Companion.tag public val solids: Solids by require(Solids) + public val client: VisionClient? get() = context.plugins.get() + private val objectFactories = HashMap, ThreeFactory<*>>() private val compositeFactory = ThreeCompositeFactory(this) - //TODO generate a separate supervisor update scope - internal val updateScope: CoroutineScope get() = context +// internal val updateScope: CoroutineScope get() = context init { //Add specialized factories here objectFactories[Box::class] = ThreeBoxFactory objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Sphere::class] = ThreeSphereFactory - objectFactories[ConeSegment::class] = ThreeConeFactory - objectFactories[PolyLine::class] = ThreeLineFactory + objectFactories[PolyLine::class] = ThreeSmartLineFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory + objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory + objectFactories[PointLightSource::class] = ThreePointLightFactory + objectFactories[StlSolid::class] = ThreeStlFactory + objectFactories[AxesSolid::class] = ThreeAxesFactory } @Suppress("UNCHECKED_CAST") @@ -47,68 +48,77 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { as ThreeFactory? } - public fun buildObject3D(obj: Solid): Object3D = when (obj) { - is ThreeJsVision -> obj.render(this) - is SolidReferenceGroup -> ThreeReferenceFactory(this, obj) + public suspend fun buildObject3D(vision: Solid, observe: Boolean = true): Object3D = when (vision) { + is ThreeJsVision -> vision.render(this) + is SolidReference -> ThreeReferenceFactory.build(this, vision, observe) is SolidGroup -> { val group = ThreeGroup() - obj.children.forEach { (token, child) -> - if (child is Solid && token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { + vision.items.forEach { (token, child) -> + if (token != SolidGroup.PROTOTYPES_TOKEN && child.ignore != true) { try { - val object3D = buildObject3D(child) + val object3D = buildObject3D( + child, + if (token.body == VisionChildren.STATIC_TOKEN_BODY) false else observe + ) + // disable tracking changes for statics group[token] = object3D } catch (ex: Throwable) { logger.error(ex) { "Failed to render $child" } - ex.printStackTrace() } } } group.apply { - updatePosition(obj) + updatePosition(vision) //obj.onChildrenChange() - - obj.onPropertyChange { name -> - if ( - name.startsWith(Solid.POSITION_KEY) || - name.startsWith(Solid.ROTATION_KEY) || - name.startsWith(Solid.SCALE_KEY) - ) { - //update position of mesh using this object - updatePosition(obj) - } else if (name == Vision.VISIBLE_KEY) { - visible = obj.visible ?: true - } - } - - obj.onStructureChanged(this){ childName -> - val child = get(childName) - - //removing old object - findChild(childName)?.let { oldChild -> - oldChild.parent?.remove(oldChild) - } - - //adding new object - if (child != null && child is Solid) { - try { - val object3D = buildObject3D(child) - set(childName, object3D) - } catch (ex: Throwable) { - logger.error(ex) { "Failed to render $child" } + if (observe) { + vision.properties.changes.onEach { name -> + if ( + name.startsWith(Solid.POSITION_KEY) || + name.startsWith(Solid.ROTATION_KEY) || + name.startsWith(Solid.SCALE_KEY) + ) { + //update position of mesh using this object + updatePosition(vision) + } else if (name == Vision.VISIBLE_KEY) { + visible = vision.visible ?: true } - } + }.launchIn(context) + + vision.children.changes.onEach { childName -> + if (childName.isEmpty()) return@onEach + + val child = vision.children.getChild(childName) + + logger.debug { "Changing vision $childName to $child" } + + //removing old object + findChild(childName)?.let { oldChild -> + oldChild.parent?.remove(oldChild) + } + + //adding new object + if (child != null && child is Solid) { + try { + val object3D = buildObject3D(child) + set(childName, object3D) + } catch (ex: Throwable) { + logger.error(ex) { "Failed to render $child" } + } + } + }.launchIn(context) } } } - is Composite -> compositeFactory(this, obj) + + is Composite -> compositeFactory.build(this, vision, observe) else -> { - //find specialized factory for this type if it is present - val factory: ThreeFactory? = findObjectFactory(obj::class) + //find a specialized factory for this type if it is present + val factory: ThreeFactory? = findObjectFactory(vision::class) when { - factory != null -> factory(this, obj) - obj is GeometrySolid -> ThreeShapeFactory(this, obj) - else -> error("Renderer for ${obj::class} not found") + factory != null -> factory.build(this, vision, observe) + vision is GeometrySolid -> ThreeShapeFactory.build(this, vision, observe) + else -> error("Renderer for ${vision::class} not found") } } } @@ -117,7 +127,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { public fun getOrCreateCanvas( element: Element, - options: Canvas3DOptions = Canvas3DOptions(), + options: Canvas3DOptions, ): ThreeCanvas = canvasCache.getOrPut(element) { ThreeCanvas(this, element, options) } @@ -135,23 +145,23 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer { internal fun renderSolid( element: Element, vision: Solid, - ): ThreeCanvas = getOrCreateCanvas(element).apply { + options: Canvas3DOptions, + ): ThreeCanvas = getOrCreateCanvas(element, options).apply { render(vision) } - override fun render(element: Element, vision: Vision, meta: Meta) { + override fun render(element: Element, name: Name, vision: Vision, meta: Meta) { renderSolid( element, vision as? Solid ?: error("Solid expected but ${vision::class} found"), - ).apply { - options.meta.update(meta) - } + Canvas3DOptions.read(meta) + ) } public companion object : PluginFactory { override val tag: PluginTag = PluginTag("vision.threejs", PluginTag.DATAFORGE_GROUP) - override val type: KClass = ThreePlugin::class - override fun invoke(meta: Meta, context: Context): ThreePlugin = ThreePlugin() + + override fun build(context: Context, meta: Meta): ThreePlugin = ThreePlugin() } } @@ -159,7 +169,7 @@ public fun ThreePlugin.render( element: HTMLElement, obj: Solid, optionsBuilder: Canvas3DOptions.() -> Unit = {}, -): ThreeCanvas = renderSolid(element, obj).apply { +): ThreeCanvas = renderSolid(element, obj, Canvas3DOptions(optionsBuilder)).apply { options.apply(optionsBuilder) } @@ -173,11 +183,12 @@ internal fun Object3D.getOrCreateGroup(name: Name): Object3D { name.isEmpty() -> this name.length == 1 -> { val token = name.tokens.first() - children.find { it.name == token.toString() } ?: info.laht.threekt.objects.Group().also { group -> + children.find { it.name == token.toString() } ?: ThreeGroup().also { group -> group.name = token.toString() this.add(group) } } + else -> getOrCreateGroup(name.tokens.first().asName()).getOrCreateGroup(name.cutFirst()) } } diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt new file mode 100644 index 00000000..b0a0bfeb --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreePointLightFactory.kt @@ -0,0 +1,37 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.names.asName +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.LightSource +import space.kscience.visionforge.solid.PointLightSource +import three.lights.PointLight +import three.math.Color +import kotlin.reflect.KClass + +public object ThreePointLightFactory : ThreeFactory { + override val type: KClass get() = PointLightSource::class + + private val DEFAULT_COLOR = Color(0x404040) + + override suspend fun build(three: ThreePlugin, vision: PointLightSource, observe: Boolean): PointLight { + val res = PointLight().apply { + matrixAutoUpdate = false + color = vision.color.threeColor() ?: DEFAULT_COLOR + intensity = vision.intensity.toDouble() + updatePosition(vision) + } + + if(observe) { + vision.onPropertyChange(three.context) { name -> + when (name) { + LightSource::color.name.asName() -> res.color = vision.color.threeColor() ?: DEFAULT_COLOR + LightSource::intensity.name.asName() -> res.intensity = vision.intensity.toDouble() + else -> res.updateProperty(vision, name) + } + } + } + + return res + } + +} \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt new file mode 100644 index 00000000..beb59df8 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt @@ -0,0 +1,69 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.names.Name +import space.kscience.dataforge.names.cutFirst +import space.kscience.dataforge.names.firstOrNull +import space.kscience.visionforge.onPropertyChange +import space.kscience.visionforge.solid.Solid +import space.kscience.visionforge.solid.SolidReference +import space.kscience.visionforge.solid.SolidReference.Companion.REFERENCE_CHILD_PROPERTY_PREFIX +import three.core.Object3D +import three.objects.Mesh +import kotlin.reflect.KClass + +public object ThreeReferenceFactory : ThreeFactory { + private val cache = HashMap() + + override val type: KClass = SolidReference::class + + private fun Object3D.replicate(): Object3D = when { + isMesh(this) -> Mesh(geometry, material).also { + //clone geometry + it.material.cached = true + it.applyMatrix4(matrix) + } + + else -> clone(false) + }.also { obj: Object3D -> + obj.name = this.name + children.forEach { child: Object3D -> + obj.add(child.replicate()) + } + } + + override suspend fun build(three: ThreePlugin, vision: SolidReference, observe: Boolean): Object3D { + val template = vision.prototype + val cachedObject = cache.getOrPut(template) { + three.buildObject3D(template) + } + + val object3D: Object3D = cachedObject.replicate() + object3D.updatePosition(vision) + + if (isMesh(object3D)) { + //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) + object3D.applyProperties(vision) + } + + //TODO apply child properties + + if (observe) { + vision.onPropertyChange(three.context) { name -> + if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { + val childName = name.firstOrNull()?.index?.let(Name::parse) + ?: error("Wrong syntax for reference child property: '$name'") + val propertyName = name.cutFirst() + val referenceChild = + vision.children.getChild(childName) ?: error("Reference child with name '$childName' not found") + val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") + child.updateProperty(referenceChild, propertyName) + } else { + object3D.updateProperty(vision, name) + } + } + } + + + return object3D + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt new file mode 100644 index 00000000..b3609b66 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSmartLineFactory.kt @@ -0,0 +1,19 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.visionforge.solid.PolyLine +import three.core.Object3D +import kotlin.reflect.KClass + +public object ThreeSmartLineFactory : ThreeFactory { + override val type: KClass get() = PolyLine::class + + override suspend fun build( + three: ThreePlugin, + vision: PolyLine, + observe: Boolean, + ): Object3D = if (vision.thickness == 1.0) { + ThreeLineFactory.build(three, vision, observe) + } else { + ThreeMeshLineFactory.build(three, vision, observe) + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt similarity index 69% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt index 8932a6c8..9753f9ad 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeSphereFactory.kt @@ -1,13 +1,13 @@ package space.kscience.visionforge.solid.three -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.SphereGeometry import space.kscience.visionforge.solid.Sphere import space.kscience.visionforge.solid.detail +import three.core.BufferGeometry +import three.geometries.SphereGeometry -public object ThreeSphereFactory : MeshThreeFactory(Sphere::class) { - override fun buildGeometry(obj: Sphere): BufferGeometry { - return obj.detail?.let {detail -> +public object ThreeSphereFactory : ThreeMeshFactory(Sphere::class) { + override suspend fun buildGeometry(obj: Sphere): BufferGeometry { + return obj.detail?.let { detail -> SphereGeometry( radius = obj.radius, phiStart = obj.phiStart, @@ -17,7 +17,7 @@ public object ThreeSphereFactory : MeshThreeFactory(Sphere::class) { widthSegments = detail, heightSegments = detail ) - }?: SphereGeometry( + } ?: SphereGeometry( radius = obj.radius, phiStart = obj.phiStart, phiLength = obj.phi, diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt new file mode 100644 index 00000000..e3fb676f --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/ThreeStlFactory.kt @@ -0,0 +1,38 @@ +package space.kscience.visionforge.solid.three + +import org.khronos.webgl.ArrayBuffer +import org.khronos.webgl.Int8Array +import space.kscience.visionforge.solid.StlBinarySolid +import space.kscience.visionforge.solid.StlSolid +import space.kscience.visionforge.solid.StlUrlSolid +import three.core.BufferGeometry +import three.external.loaders.STLLoader +import kotlin.coroutines.resume +import kotlin.coroutines.resumeWithException +import kotlin.coroutines.suspendCoroutine + +fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast() + +public object ThreeStlFactory : ThreeMeshFactory(StlSolid::class) { + + private val loader = STLLoader().apply { + requestHeader = listOf("Access-Control-Allow-Origin: *") + } + + override suspend fun buildGeometry(obj: StlSolid): BufferGeometry = when (obj) { + is StlBinarySolid -> loader.parse(obj.data) + is StlUrlSolid -> suspendCoroutine { continuation -> + loader.load( + url = obj.url, + onLoad = { + continuation.resume(it) + }, + onError = { + continuation.resumeWithException(RuntimeException("Failed to load STL object from ${obj.url}")) + } + ) + } + } + + +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/csg.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt rename to visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/csg.kt index ac2fefc0..0d7f774d 100644 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/csg.kt +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/csg.kt @@ -3,17 +3,16 @@ "OVERRIDING_FINAL_MEMBER", "RETURN_TYPE_MISMATCH_ON_OVERRIDE", "CONFLICTING_OVERLOADS", - "EXTERNAL_DELEGATION", - "NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING" + "EXTERNAL_DELEGATION" ) @file:JsModule("three-csg-ts") @file:JsNonModule -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Mesh +import three.core.BufferGeometry +import three.math.Matrix4 +import three.math.Vector3 +import three.objects.Mesh public external class CSG { public fun clone(): CSG diff --git a/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/three.kt new file mode 100644 index 00000000..f3fc0594 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/space/kscience/visionforge/solid/three/three.kt @@ -0,0 +1,49 @@ +package space.kscience.visionforge.solid.three + +import space.kscience.dataforge.meta.Meta +import space.kscience.dataforge.meta.float +import space.kscience.dataforge.meta.get +import three.core.BufferGeometry +import three.core.Layers +import three.core.Object3D +import three.external.controls.OrbitControls +import three.materials.Material +import three.math.Vector3 +import three.objects.Mesh +import three.textures.Texture +import kotlin.contracts.contract + +public val Meta.vector: Vector3 get() = Vector3(this["x"].float ?: 0f, this["y"].float ?: 0f, this["z"].float ?: 0f) + + +internal fun Any.dispose() { + when (this) { + is BufferGeometry -> dispose() + is Material -> dispose() + is Mesh -> { + geometry.dispose() + material.dispose() + } + is OrbitControls -> dispose() + is Texture -> dispose() + } +} + +public fun Layers.check(layer: Int): Boolean = (mask shr (layer) and 0x00000001) > 0 + + +internal fun isMesh(object3D: Object3D): Boolean{ + contract { + returns(true) implies (object3D is Mesh) + } + return object3D.asDynamic().isMesh as? Boolean ?: false +} + +internal fun Object3D.takeIfMesh(): Mesh? { + val d = asDynamic() + return if(d.isMesh as Boolean){ + d.unsafeCast() + } else { + null + } +} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt b/visionforge-threejs/src/jsMain/kotlin/three/THREE.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt rename to visionforge-threejs/src/jsMain/kotlin/three/THREE.kt index 3f8028cb..4dca1f62 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/THREE.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/THREE.kt @@ -26,7 +26,7 @@ @file:JsNonModule @file:Suppress("NO_EXPLICIT_VISIBILITY_IN_API_MODE_WARNING", "unused") -package info.laht.threekt +package three external val REVISION: String diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationAction.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationAction.kt index d0e9b073..185793ff 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationAction.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationAction.kt @@ -2,9 +2,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation -import info.laht.threekt.core.Object3D +import three.core.Object3D external class AnimationAction( mixer: AnimationMixer, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationClip.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationClip.kt index 262f02dc..dfb1df5a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationClip.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationClip.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation /** * An AnimationClip is a reusable set of keyframe tracks which represent an animation. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationMixer.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationMixer.kt index 383f88f7..45932e59 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationMixer.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationMixer.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * The AnimationMixer is a player for animations on a particular object in the scene. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationUtils.kt similarity index 70% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationUtils.kt index 34a9633b..c0e05b3a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/AnimationUtils.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/animation/AnimationUtils.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation external object AnimationUtils { //TODO diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt b/visionforge-threejs/src/jsMain/kotlin/three/animation/KeyFrameTrack.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt rename to visionforge-threejs/src/jsMain/kotlin/three/animation/KeyFrameTrack.kt index 478fd1f6..2f3f3436 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/animation/KeyFrameTrack.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/animation/KeyFrameTrack.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.animation +package three.animation import org.khronos.webgl.Float32Array diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/Audio.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/Audio.kt index f6266c41..95918ede 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/Audio.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/audio/Audio.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * Create a non-positional ( global ) audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioContext.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/AudioContext.kt index 3bccd0ac..3908a548 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioContext.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioContext.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * This contains methods for setting up an AudioContext. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioListener.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/AudioListener.kt index e99b9b13..cbdb06f1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/AudioListener.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/audio/AudioListener.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * Create a non-positional ( global ) audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt b/visionforge-threejs/src/jsMain/kotlin/three/audio/PositionalAudio.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt rename to visionforge-threejs/src/jsMain/kotlin/three/audio/PositionalAudio.kt index 19c17bea..7c1006f4 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/audio/PositionalAudio.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/audio/PositionalAudio.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.audio +package three.audio /** * Create a positional audio object. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/Camera.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/Camera.kt index 6ab80298..5f1ba54f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/Camera.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/cameras/Camera.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector3 +import three.core.Object3D +import three.math.Matrix4 +import three.math.Vector3 external interface View { var enabled: Boolean diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/OrthographicCamera.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/OrthographicCamera.kt index 320d71b5..706c8746 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/OrthographicCamera.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/cameras/OrthographicCamera.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras external class OrthographicCamera( varleft: Int, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt b/visionforge-threejs/src/jsMain/kotlin/three/cameras/PerspectiveCamera.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt rename to visionforge-threejs/src/jsMain/kotlin/three/cameras/PerspectiveCamera.kt index 4deee300..a5b12de8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/cameras/PerspectiveCamera.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/cameras/PerspectiveCamera.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.cameras +package three.cameras external class PerspectiveCamera(fov: Int, aspect: Double, near: Number, far: Number) : Camera { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferAttribute.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/BufferAttribute.kt index 6a773330..e045b2d6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferAttribute.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferAttribute.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 -import info.laht.threekt.math.Vector4 +import three.math.Color +import three.math.Vector2 +import three.math.Vector3 +import three.math.Vector4 abstract external class BufferAttribute protected constructor( array: dynamic, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferGeometry.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/BufferGeometry.kt index 251627a7..5038aee7 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/BufferGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/BufferGeometry.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Box3 -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Sphere -import info.laht.threekt.math.Vector3 +import three.math.Box3 +import three.math.Matrix4 +import three.math.Sphere +import three.math.Vector3 /** * This class is an efficient alternative to Geometry, because it stores all data, including vertex positions, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Clock.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Clock.kt index 8cce902c..e5925f56 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Clock.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Clock.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core /** * Object for keeping track of time. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/EventDispatcher.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/EventDispatcher.kt index 459da88b..1646775e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/EventDispatcher.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/EventDispatcher.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external open class EventDispatcher { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Face3.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Face3.kt index ff48d022..a7ec7f0b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Face3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Face3.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector3 +import three.math.Color +import three.math.Vector3 external class Face3 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/InstancedBufferGeometry.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/InstancedBufferGeometry.kt index 92137432..99c4df70 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/InstancedBufferGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/InstancedBufferGeometry.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external class InstancedBufferGeometry : BufferGeometry { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Layers.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Layers.kt index 503878d1..6d29399c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Layers.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Layers.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core /** * A Layers object assigns an Object3D to 1 or more of 32 layers numbered 0 to 31 - internally the diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Object3D.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Object3D.kt index e49add5e..86739f76 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Object3D.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Object3D.kt @@ -26,9 +26,9 @@ @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.math.* +import three.math.* /** * This is the base class for most objects in three.js and provides a set of properties and methods for manipulating objects in 3D space. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Raycaster.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Raycaster.kt index 2e2944af..e03844f6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Raycaster.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Raycaster.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Ray -import info.laht.threekt.math.Vector2 -import info.laht.threekt.math.Vector3 +import three.cameras.Camera +import three.math.Ray +import three.math.Vector2 +import three.math.Vector3 external interface Params { var Mesh: dynamic diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt b/visionforge-threejs/src/jsMain/kotlin/three/core/Uniform.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt rename to visionforge-threejs/src/jsMain/kotlin/three/core/Uniform.kt index a92cdf2a..a2bef114 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/core/Uniform.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/core/Uniform.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.core +package three.core external class Uniform { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/Detector.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/Detector.kt index 716e5d74..3dc1ed28 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/Detector.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/Detector.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/ImprovedNoise.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/ImprovedNoise.kt index bc380022..4ee3942d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/ImprovedNoise.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/ImprovedNoise.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external external object ImprovedNoise { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/SimplexNoise.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/SimplexNoise.kt index f8ab5a82..6856c354 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/SimplexNoise.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/SimplexNoise.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external +package three.external external object SimplexNoise { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/FlyControls.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/FlyControls.kt index 11e25207..77de67e0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/FlyControls.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/FlyControls.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/controls/FlyControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D import org.w3c.dom.Node +import three.core.Object3D external class FlyControls(`object`: Object3D, domElement: Node = definedExternally) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/OrbitControls.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/OrbitControls.kt index db7f2ac9..94223fc4 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/OrbitControls.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/OrbitControls.kt @@ -25,11 +25,11 @@ @file:JsModule("three/examples/jsm/controls/OrbitControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Vector3 import org.w3c.dom.Node +import three.core.Object3D +import three.math.Vector3 /** * This set of controls performs orbiting, dollying (zooming), and panning. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TrackballControls.kt similarity index 90% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/TrackballControls.kt index b128553e..64998dc2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TrackballControls.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TrackballControls.kt @@ -9,13 +9,13 @@ @file:JsModule("three/examples/jsm/controls/TrackballControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.cameras.Camera -import info.laht.threekt.core.EventDispatcher -import info.laht.threekt.math.Vector3 import org.w3c.dom.HTMLElement import org.w3c.dom.Node +import three.cameras.Camera +import three.core.EventDispatcher +import three.math.Vector3 external interface `T$0` { var left: Number diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TransformControls.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/controls/TransformControls.kt index 0a1c7a43..e03da682 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/controls/TransformControls.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/controls/TransformControls.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/controls/TransformControls.js") @file:JsNonModule -package info.laht.threekt.external.controls +package three.external.controls -import info.laht.threekt.core.Object3D import org.w3c.dom.Node +import three.core.Object3D external class TransformControls(`object`: Object3D, domElement: Node = definedExternally) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/OBJExporter.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/exporters/OBJExporter.kt index 36eefa9f..843a9f72 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/OBJExporter.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/OBJExporter.kt @@ -25,9 +25,9 @@ @file:JsModule("three/examples/jsm/exporters/OBJExporter.js") @file:JsNonModule -package info.laht.threekt.external.exporters +package three.external.exporters -import info.laht.threekt.core.Object3D +import three.core.Object3D external class OBJExporter { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/STLExporter.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/exporters/STLExporter.kt index 4c6e3fb1..a89c1179 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/exporters/STLExporter.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/exporters/STLExporter.kt @@ -25,10 +25,10 @@ @file:JsModule("three/examples/jsm/exporters/STLExporter.js") @file:JsNonModule -package info.laht.threekt.external.exporters +package three.external.exporters -import info.laht.threekt.core.Object3D import org.khronos.webgl.DataView +import three.core.Object3D external class STLExporter { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/geometries/ConvexGeometry.kt similarity index 61% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/geometries/ConvexGeometry.kt index cbc0fbb5..6c981460 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/geometries/ConvexGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/geometries/ConvexGeometry.kt @@ -1,10 +1,10 @@ @file:JsModule("three/examples/jsm/geometries/ConvexGeometry.js") @file:JsNonModule -package info.laht.threekt.external.geometries +package three.external.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.math.Vector3 +import three.core.BufferGeometry +import three.math.Vector3 external class ConvexGeometry(points: Array) : BufferGeometry diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/GUIParams.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/GUIParams.kt index 13d08a29..4b48bcc2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/GUIParams.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/GUIParams.kt @@ -1,4 +1,4 @@ -package info.laht.threekt.external.libs +package three.external.libs /** * @param name The name of this GUI diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/Stats.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/Stats.kt index a6c2e86f..fd72886e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/Stats.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/Stats.kt @@ -25,7 +25,7 @@ @file:JsModule("three/examples/jsm/libs/stats.module.js") @file:JsNonModule -package info.laht.threekt.external.libs +package three.external.libs import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/datgui.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/libs/datgui.kt index c3496ea0..345d0cf5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/libs/datgui.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/libs/datgui.kt @@ -24,7 +24,7 @@ @file:JsModule("three/examples/jsm/libs/dat.gui.module.js") @file:JsNonModule -package info.laht.threekt.external.libs +package three.external.libs import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/BabylonLoader.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/BabylonLoader.kt index 2eae2988..437beba6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/BabylonLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/BabylonLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager external class BabylonLoader( manager: LoadingManager = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/GLTFLoader.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/GLTFLoader.kt index e353372e..40fdd556 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/GLTFLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/GLTFLoader.kt @@ -1,14 +1,14 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.animation.AnimationClip -import info.laht.threekt.cameras.Camera -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.scenes.Scene import org.khronos.webgl.ArrayBuffer import org.w3c.xhr.XMLHttpRequest +import three.animation.AnimationClip +import three.cameras.Camera +import three.loaders.LoadingManager +import three.scenes.Scene external interface GLTFOnLoadCallback { val animations: Array diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/LoaderSupport.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/LoaderSupport.kt index de1bafcd..5636fdc9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/LoaderSupport.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/LoaderSupport.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders external object LoaderSupport { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/MTLLoader.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/MTLLoader.kt index 9af877f5..1eecd588 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/MTLLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/MTLLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager external class MTLLoader( loadingManager: LoadingManager = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader.kt index ff4f2150..0bddd83a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.Object3D -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.objects.Mesh import org.w3c.xhr.XMLHttpRequest +import three.core.Object3D +import three.loaders.LoadingManager +import three.objects.Mesh /** * A loader for loading a .obj resource. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader2.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader2.kt index 009e5e81..e12ad3fe 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/OBJLoader2.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/OBJLoader2.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.loaders.LoadingManager -import info.laht.threekt.objects.Mesh import org.w3c.xhr.XMLHttpRequest +import three.loaders.LoadingManager +import three.objects.Mesh external interface Detail { var loaderRootNode: Mesh diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/STLLoader.kt similarity index 80% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/loaders/STLLoader.kt index 707fdc0c..e3e6133f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/loaders/STLLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/loaders/STLLoader.kt @@ -22,17 +22,19 @@ * THE SOFTWARE. */ -@file:JsModule("three") +@file:JsModule("three/examples/jsm/loaders/STLLoader.js") @file:JsNonModule -package info.laht.threekt.external.loaders +package three.external.loaders -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D +import org.khronos.webgl.ArrayBuffer import org.w3c.xhr.XMLHttpRequest +import three.core.BufferGeometry external class STLLoader { + var requestHeader: List + fun load( url: String, onLoad: (BufferGeometry) -> Unit, @@ -40,7 +42,10 @@ external class STLLoader { onError: () -> Unit = definedExternally ) - fun parse(data: String): Object3D - fun parse(data: ByteArray): Object3D + fun parse(data: String): BufferGeometry + + fun parse(data: ByteArray): BufferGeometry + + fun parse(data: ArrayBuffer): BufferGeometry } \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Sky.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/Sky.kt index 47ad39ef..c7272138 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Sky.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Sky.kt @@ -25,8 +25,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.objects.Mesh +import three.objects.Mesh external class Sky : Mesh \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Water.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/Water.kt index 9ad3f043..9a886a95 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/Water.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/Water.kt @@ -25,8 +25,8 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.objects.Mesh +import three.objects.Mesh external class Water(width: Int, height: Int, options: WaterOptions = definedExternally) : Mesh \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/WaterOptions.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt rename to visionforge-threejs/src/jsMain/kotlin/three/external/objects/WaterOptions.kt index 74434846..498f9883 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/external/objects/WaterOptions.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/external/objects/WaterOptions.kt @@ -22,10 +22,10 @@ * THE SOFTWARE. */ -package info.laht.threekt.external.objects +package three.external.objects -import info.laht.threekt.math.Vector3 -import info.laht.threekt.textures.Texture +import three.math.Vector3 +import three.textures.Texture data class WaterOptions( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/SceneUtils.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/SceneUtils.kt index fb4338fd..1ad837d0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/SceneUtils.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/SceneUtils.kt @@ -1,13 +1,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras +package three.extras -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material -import info.laht.threekt.objects.Group -import info.laht.threekt.scenes.Scene +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material +import three.objects.Group +import three.scenes.Scene /** * A class containing useful utility functions for scene manipulation. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Curve.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/Curve.kt index f5a8ced6..4b688b1a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Curve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Curve.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core external abstract class Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/CurvePath.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/CurvePath.kt index 18ae2165..5a05ab14 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/CurvePath.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/CurvePath.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core open external class CurvePath : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Path.kt similarity index 61% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/core/Path.kt index 7b944a7c..bd78a31d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Path.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Path.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.core +package three.extras.core -import info.laht.threekt.math.Vector2 +import three.math.Vector2 open external class Path : CurvePath { diff --git a/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Shape.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Shape.kt new file mode 100644 index 00000000..d05486b5 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/Shape.kt @@ -0,0 +1,8 @@ +@file:JsModule("three") +@file:JsNonModule + +package three.extras.core + +import three.math.Vector2 + +external class Shape(points: Array) : Path \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/three/extras/core/ShapePath.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/ShapePath.kt new file mode 100644 index 00000000..5ea28758 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/core/ShapePath.kt @@ -0,0 +1,6 @@ +@file:JsModule("three") +@file:JsNonModule + +package three.extras.core + +external class ShapePath \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/ArcCurve.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/ArcCurve.kt index a6f2d172..c3891ff1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/ArcCurve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/ArcCurve.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves external class ArcCurve( aX: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/CatmullRomCurve3.kt similarity index 79% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/CatmullRomCurve3.kt index 93a5d931..e968cfb0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/CatmullRomCurve3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/CatmullRomCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class CatmullRomCurve3( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/EllipseCurve.kt similarity index 85% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/EllipseCurve.kt index d3ead4c5..dbcaec3f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/EllipseCurve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/EllipseCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 open external class EllipseCurve( aX: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve.kt similarity index 66% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve.kt index ca9dc41b..74c2d239 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class LineCurve( v1: Vector2 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve3.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve3.kt index 90218d60..68f14b72 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/LineCurve3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/LineCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class LineCurve3( v1: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve.kt similarity index 74% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve.kt index aa7b2a95..849b41c0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class QuadricBezierCurve : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve3.kt similarity index 74% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve3.kt index b4b30426..0da5444f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/QuadricBezierCurve3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/QuadricBezierCurve3.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.extras.core.Curve +import three.math.Vector3 external class QuadricBezierCurve3 : Curve { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/SplineCurve.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt rename to visionforge-threejs/src/jsMain/kotlin/three/extras/curves/SplineCurve.kt index df3fb8cd..357cf50f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/curves/SplineCurve.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/extras/curves/SplineCurve.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.extras.curves +package three.extras.curves -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector2 +import three.extras.core.Curve +import three.math.Vector2 external class SplineCurve( points: Array = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/BoxGeometry.kt similarity index 77% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/BoxGeometry.kt index 8d0e5ec5..d80a96a2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/BoxGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/BoxGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class BoxGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ConeGeometry.kt similarity index 79% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/ConeGeometry.kt index f98ad2dd..7492d5ec 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ConeGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ConeGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class ConeGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/CylinderGeometry.kt similarity index 78% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/CylinderGeometry.kt index b10e5c11..f2f1160c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/CylinderGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/CylinderGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class CylinderGeometry( radiusTop: Number, diff --git a/visionforge-threejs/src/jsMain/kotlin/three/geometries/EdgesGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/EdgesGeometry.kt new file mode 100644 index 00000000..fe53213e --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/EdgesGeometry.kt @@ -0,0 +1,8 @@ +@file:JsModule("three") +@file:JsNonModule + +package three.geometries + +import three.core.BufferGeometry + +public external class EdgesGeometry(geometry: BufferGeometry, thresholdAngle: Int = definedExternally) : BufferGeometry \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ExtrudeGeometry.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/ExtrudeGeometry.kt index 4b30e7af..5c256878 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/ExtrudeGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/ExtrudeGeometry.kt @@ -8,11 +8,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.extras.core.Shape -import info.laht.threekt.math.Vector2 +import three.core.BufferGeometry +import three.extras.core.Shape +import three.math.Vector2 external interface ExtrudeGeometryOptions { var curveSegments: Number? diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/PlaneGeometry.kt similarity index 67% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/PlaneGeometry.kt index 0b1072ef..aff535a2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/PlaneGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/PlaneGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class PlaneGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/SphereGeometry.kt similarity index 78% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/SphereGeometry.kt index 5b0c9fc6..2b9e5279 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/SphereGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/SphereGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class SphereGeometry( radius: Number, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TextGeometry.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TextGeometry.kt index b8c935f3..aab53955 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TextGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TextGeometry.kt @@ -1,7 +1,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries external interface TextGeometryParameters { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TorusGeometry.kt similarity index 73% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TorusGeometry.kt index 0a53525f..493b7984 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TorusGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TorusGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry external class TorusGeometry( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TubeGeometry.kt similarity index 72% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/TubeGeometry.kt index 36afa6ae..e1dc9a75 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/TubeGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/TubeGeometry.kt @@ -1,8 +1,8 @@ -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.extras.core.Curve -import info.laht.threekt.math.Vector3 +import three.core.BufferGeometry +import three.extras.core.Curve +import three.math.Vector3 /** diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt b/visionforge-threejs/src/jsMain/kotlin/three/geometries/WireframeGeometry.kt similarity index 68% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt rename to visionforge-threejs/src/jsMain/kotlin/three/geometries/WireframeGeometry.kt index f52c61cc..622ef80d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/WireframeGeometry.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/geometries/WireframeGeometry.kt @@ -1,9 +1,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.geometries +package three.geometries -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry /** * This can be used as a helper object to view a Geometry object as a wireframe. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/ArrowHelper.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/ArrowHelper.kt index ea1764dd..18c0d8de 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/ArrowHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/ArrowHelper.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Line -import info.laht.threekt.objects.Mesh +import three.core.Object3D +import three.math.Color +import three.math.Vector3 +import three.objects.Line +import three.objects.Mesh external class ArrowHelper( dir: Vector3, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/AxesHelper.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/AxesHelper.kt index d4b515be..5927991f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/AxesHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/AxesHelper.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.objects.LineSegments +import three.objects.LineSegments external class AxesHelper( size: Int = definedExternally diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/Box3Helper.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/Box3Helper.kt index 27aef631..1eefb43b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/Box3Helper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/Box3Helper.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.math.Box3 -import info.laht.threekt.objects.LineSegments +import three.math.Box3 +import three.objects.LineSegments /** * Helper object to visualize a Box3. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/CameraHelper.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/CameraHelper.kt index 6b199f3f..716f8234 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/CameraHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/CameraHelper.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.objects.LineSegments +import three.cameras.Camera +import three.objects.LineSegments external class CameraHelper( camera: Camera diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/GridHelper.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/GridHelper.kt index 0d987ae5..0c080ead 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/GridHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/GridHelper.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.objects.LineSegments +import three.objects.LineSegments external class GridHelper( size: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/HemisphereLightHelper.kt similarity index 91% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/HemisphereLightHelper.kt index 4351faa7..23f21837 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/HemisphereLightHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/HemisphereLightHelper.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.core.Object3D -import info.laht.threekt.lights.HemisphereLight -import info.laht.threekt.lights.Light +import three.core.Object3D +import three.lights.HemisphereLight +import three.lights.Light /** * Creates a visual aid consisting of a spherical Mesh for a HemisphereLight. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt b/visionforge-threejs/src/jsMain/kotlin/three/helpers/PlaneHelper.kt similarity index 58% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt rename to visionforge-threejs/src/jsMain/kotlin/three/helpers/PlaneHelper.kt index dbe6dc8d..338c9593 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/helpers/PlaneHelper.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/helpers/PlaneHelper.kt @@ -1,10 +1,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.helpers +package three.helpers -import info.laht.threekt.math.Color -import info.laht.threekt.math.Plane -import info.laht.threekt.objects.LineSegments +import three.math.Color +import three.math.Plane +import three.objects.LineSegments /** * Helper object to visualize a [Plane]. diff --git a/visionforge-threejs/src/jsMain/kotlin/three/ktutils.kt b/visionforge-threejs/src/jsMain/kotlin/three/ktutils.kt new file mode 100644 index 00000000..d0735c84 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/ktutils.kt @@ -0,0 +1,9 @@ +@file:Suppress("FunctionName") + +package three + +import three.renderers.WebGLRenderer +import three.renderers.WebGLRendererParams + +fun WebGLRenderer(builder: WebGLRendererParams.() -> Unit): WebGLRenderer = + WebGLRenderer(WebGLRendererParams().apply(builder)) \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/AmbientLight.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/AmbientLight.kt index 0d2cae66..b5ddd88d 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/AmbientLight.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/AmbientLight.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights /** * This light globally illuminates all objects in the scene equally. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLight.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLight.kt index f85d3e24..482fd628 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLight.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D +import three.core.Object3D external class DirectionalLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLightShadow.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLightShadow.kt index e2886e0b..205c46bb 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/DirectionalLightShadow.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/DirectionalLightShadow.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class DirectionalLightShadow : LightShadow { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/HemisphereLight.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/HemisphereLight.kt index c98fbd5d..bf761479 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/HemisphereLight.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/HemisphereLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.math.Color +import three.math.Color /** * A light source positioned directly above the scene, with color fading from the sky color to the ground color. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/Light.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/Light.kt index 6ffd9a2d..d0c07d15 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/Light.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/Light.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Color +import three.core.Object3D +import three.math.Color /** * Abstract base class for lights - all other light types inherit the properties and methods described here. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/LightShadow.kt similarity index 90% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/LightShadow.kt index ef62b843..b7fc1f12 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/LightShadow.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/LightShadow.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Matrix4 -import info.laht.threekt.math.Vector2 +import three.cameras.Camera +import three.math.Matrix4 +import three.math.Vector2 open external class LightShadow(camera: Camera) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/PointLight.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/PointLight.kt index 6a708e58..9ff6627a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/PointLight.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/PointLight.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class PointLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLight.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLight.kt index 70c14e6a..ebd422f7 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLight.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLight.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights -import info.laht.threekt.core.Object3D +import three.core.Object3D external class SpotLight( color: Int = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLightShadow.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt rename to visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLightShadow.kt index 8d8e052f..14df1315 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/lights/SpotLightShadow.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/lights/SpotLightShadow.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.lights +package three.lights external class SpotLightShadow : LightShadow { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Cache.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/Cache.kt index 1424d8e7..38278cf1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Cache.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Cache.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders external object Cache { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/CompressedTextureLoader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/CompressedTextureLoader.kt index 889c5d18..d827d4a5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/CompressedTextureLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/CompressedTextureLoader.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.textures.Texture /** * Abstract base class for block based textures loader (dds, pvr, ...). diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/ImageLoader.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/ImageLoader.kt index ade47d72..555f268b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/ImageLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/ImageLoader.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders import org.w3c.dom.Element import org.w3c.xhr.XMLHttpRequest diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/JSONLoader.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/JSONLoader.kt index db38edb6..8871b540 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/JSONLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/JSONLoader.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material import org.w3c.xhr.XMLHttpRequest +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material /** * A loader for loading objects in JSON format. This uses the FileLoader internally for loading files. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Loader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/Loader.kt index 2d60ee93..d094b6d9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/Loader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/Loader.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders /** * Base class for implementing loaders. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/LoadingManager.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/LoadingManager.kt index ebf5d2bc..e9180dad 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/LoadingManager.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/LoadingManager.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders external object DefaultLoadingManager : LoadingManager diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/MaterialLoader.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/MaterialLoader.kt index ef30c71f..f294ffd5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/MaterialLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/MaterialLoader.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.materials.Material -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.materials.Material +import three.textures.Texture external class MaterialLoader { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt b/visionforge-threejs/src/jsMain/kotlin/three/loaders/TextureLoader.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt rename to visionforge-threejs/src/jsMain/kotlin/three/loaders/TextureLoader.kt index 5d57ab88..5ddac48b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/loaders/TextureLoader.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/loaders/TextureLoader.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.loaders +package three.loaders -import info.laht.threekt.textures.Texture import org.w3c.xhr.XMLHttpRequest +import three.textures.Texture /** * Class for loading a texture. This uses the ImageLoader internally for loading files. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineBasicMaterial.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/LineBasicMaterial.kt index 308e5a52..1445c427 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineBasicMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineBasicMaterial.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color +import three.math.Color open external class LineBasicMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineDashedMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/LineDashedMaterial.kt index 79ad5ada..aa2a5d6a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/LineDashedMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/LineDashedMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class LineDashedMaterial : LineBasicMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/Material.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/Material.kt index 9a2b72d0..2edbca90 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/Material.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/Material.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials @JsName("Material") open external class Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshBasicMaterial.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshBasicMaterial.kt index 96eae5e0..f1ee1f27 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshBasicMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshBasicMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class MeshBasicMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshDepthMaterial.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshDepthMaterial.kt index 185dce93..584bcab6 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshDepthMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshDepthMaterial.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.textures.Texture +import three.textures.Texture external class MeshDepthMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshLambertMaterial.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshLambertMaterial.kt index dcd0670a..089c96c1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshLambertMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshLambertMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class MeshLambertMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshNormalMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshNormalMaterial.kt index ea7c0960..5972a702 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshNormalMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshNormalMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Vector2 +import three.textures.Texture external class MeshNormalMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhongMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhongMaterial.kt index 693ba8b4..eaabf8ca 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhongMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhongMaterial.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Color +import three.math.Vector2 +import three.textures.Texture external class MeshPhongMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhysicalMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhysicalMaterial.kt index 42fef98f..e6674917 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshPhysicalMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshPhysicalMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class MeshPhysicalMaterial : MeshStandardMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshStandardMaterial.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/MeshStandardMaterial.kt index 19b6901e..137ee095 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/MeshStandardMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/MeshStandardMaterial.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.math.Vector2 -import info.laht.threekt.textures.Texture +import three.math.Color +import three.math.Vector2 +import three.textures.Texture open external class MeshStandardMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/PointsMaterial.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/PointsMaterial.kt index bb9c4bd8..a46fb65e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/PointsMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/PointsMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class PointsMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/RawShaderMaterial.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/RawShaderMaterial.kt index 2a096459..d1f53c16 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/RawShaderMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/RawShaderMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials external class RawShaderMaterial : ShaderMaterial { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/ShaderMaterial.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/ShaderMaterial.kt index 016520eb..3ca841db 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/ShaderMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/ShaderMaterial.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials open external class ShaderMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt b/visionforge-threejs/src/jsMain/kotlin/three/materials/SpriteMaterial.kt similarity index 92% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt rename to visionforge-threejs/src/jsMain/kotlin/three/materials/SpriteMaterial.kt index 32056537..13587157 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/materials/SpriteMaterial.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/materials/SpriteMaterial.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.materials +package three.materials -import info.laht.threekt.math.Color -import info.laht.threekt.textures.Texture +import three.math.Color +import three.textures.Texture external class SpriteMaterial : Material { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Box2.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Box2.kt index c00da8eb..5b446e3c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box2.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Box2.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Box2( min: Vector2 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Box3.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Box3.kt index a34622fa..25730ad2 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Box3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Box3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.Object3D +import three.core.Object3D /** * Represents a box or cube in 3D space. The main purpose of this is to represent the Minimum Bounding Boxes for objects. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Color.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Color.kt index 26a2a760..485d04f1 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Color.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Color.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Color { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/ColorConstants.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/ColorConstants.kt index 34475bd1..e60aba4a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/ColorConstants.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/ColorConstants.kt @@ -23,7 +23,7 @@ */ -package info.laht.threekt.math +package three.math object ColorConstants { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Cylindrical.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Cylindrical.kt index 9e0cd8ba..bee46185 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Cylindrical.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Cylindrical.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Cylindrical( radius: Number, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Euler.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Euler.kt index 5b8dc1ce..5cd2f5cf 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Euler.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Euler.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Euler( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Frustrum.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Frustrum.kt index cce6a0bc..8d6fe374 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Frustrum.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Frustrum.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Frustrum( p0: Plane = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Line3.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Line3.kt index 6bb1b4e2..4596edd9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Line3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Line3.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Line3( start: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Math.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Math.kt index 9bae9dba..7a340d51 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Math.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Math.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Math { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix3.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Matrix3.kt index 6f31380b..f5ea461a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.BufferAttribute +import three.core.BufferAttribute external class Matrix3 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix4.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Matrix4.kt index 49ed3bfe..20e03eae 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Matrix4.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Matrix4.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry /** * A class representing a 4x4 matrix. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Plane.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Plane.kt index 2848938d..41568fc8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Plane.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Plane.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Plane() { constructor(normal: Vector3, constant: Double) diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Quaternion.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Quaternion.kt index a3a0af8b..b1916723 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Quaternion.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Quaternion.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Quaternion( diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Ray.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Ray.kt index 731a3d2b..707985b9 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Ray.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Ray.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Ray { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Sphere.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Sphere.kt index cbbc24c4..abea7add 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Sphere.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Sphere.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Sphere { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Spherical.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Spherical.kt index 187dcd94..1596bd25 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Spherical.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Spherical.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Spherical { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Triangle.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Triangle.kt index 9dd99c52..890d1f87 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Triangle.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Triangle.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Triangle( a: Vector3 = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector2.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector2.kt index 86049df0..c508421a 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector2.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector2.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Vector2( x: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector3.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector3.kt index 85f1c74b..881bc586 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector3.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector3.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math -import info.laht.threekt.cameras.Camera +import three.cameras.Camera /** * Class representing a 3D vector. A 3D vector is an ordered triplet of numbers (labeled x, y, and z), which can be used to represent a number of things, such as: diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector4.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/Vector4.kt index f017f4d4..5bd672d5 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/Vector4.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/Vector4.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.math +package three.math external class Vector4( x: Number = definedExternally, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt b/visionforge-threejs/src/jsMain/kotlin/three/math/operators.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt rename to visionforge-threejs/src/jsMain/kotlin/three/math/operators.kt index b30baf00..245cc83f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/math/operators.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/math/operators.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.math +package three.math operator fun Vector3.unaryMinus() = this.clone().negate() operator fun Vector3.plusAssign(v: Vector3) = this.let { add(v); Unit } diff --git a/visionforge-threejs/src/jsMain/kotlin/three/meshline/MeshLine.kt b/visionforge-threejs/src/jsMain/kotlin/three/meshline/MeshLine.kt new file mode 100644 index 00000000..21e0ce34 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/meshline/MeshLine.kt @@ -0,0 +1,37 @@ +@file:JsModule("three.meshline") +@file:JsNonModule + +package three.meshline + +import three.core.BufferGeometry +import three.materials.ShaderMaterial +import three.math.Color +import three.math.Vector3 +import three.textures.Texture + +/* + * https://github.com/spite/THREE.MeshLine + */ + +public external class MeshLine : BufferGeometry { + public fun setGeometry(geometry: BufferGeometry) + public fun setPoints(points: Array) +} + +public external class MeshLineMaterial : ShaderMaterial { + @JsName("lineWidth") + public var thickness: Float + public var color: Color + + public var map: Texture? + public var useMap: Boolean + public var alphaMap: Texture? + public var useAlphaMap: Boolean + + public var repeat: dynamic // - THREE.Vector2 to define the texture tiling (applies to map and alphaMap - MIGHT CHANGE IN THE FUTURE) + public var dashArray: dynamic //- the length and space between dashes. (0 - no dash) + public var dashOffset: dynamic // - defines the location where the dash will begin. Ideal to animate the line. + public var dashRatio: dynamic // - defines the ratio between that is visible or not (0 - more visible, 1 - more invisible). + public var resolution: dynamic // - THREE.Vector2 specifying the canvas size (REQUIRED) + public var sizeAttenuation: Int // - makes the line width constant regardless distance (1 unit is 1px on screen) (0 - attenuate, 1 - don't attenuate) +} \ No newline at end of file diff --git a/visionforge-threejs/src/jsMain/kotlin/three/meshline/meshLineExt.kt b/visionforge-threejs/src/jsMain/kotlin/three/meshline/meshLineExt.kt new file mode 100644 index 00000000..60047884 --- /dev/null +++ b/visionforge-threejs/src/jsMain/kotlin/three/meshline/meshLineExt.kt @@ -0,0 +1,11 @@ +package three.meshline + +import three.core.BufferGeometry +import three.materials.Material +import three.math.Vector3 + +public fun MeshLine(geometry: BufferGeometry): MeshLine = MeshLine().apply { setGeometry(geometry) } + +public fun MeshLine(points: Array): MeshLine = MeshLine().apply { setPoints(points) } + +internal fun isMeshLineMaterial(material: Material): Boolean = material.asDynamic().isMeshLineMaterial == true \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Group.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Group.kt index e5420f29..a280a11f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Group.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/Group.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Object3D +import three.core.Object3D external class Group : Object3D diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LOD.kt similarity index 88% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LOD.kt index 89e405ac..4eec3195 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LOD.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/LOD.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.cameras.Camera -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster +import three.cameras.Camera +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster external class LOD : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Line.kt similarity index 85% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Line.kt index e0a217bc..799884f8 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Line.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/Line.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material open external class Line(geometry: BufferGeometry, material: Material) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineLoop.kt similarity index 90% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LineLoop.kt index 50aa390e..e3e8cbc3 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineLoop.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineLoop.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.materials.Material external class LineLoop(geometry: BufferGeometry, material: Material) : Line \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineSegments.kt similarity index 89% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/LineSegments.kt index 03bef34e..2ffd85ee 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/LineSegments.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/LineSegments.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Object3D +import three.materials.Material open external class LineSegments(geometry: BufferGeometry, material: Material) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Mesh.kt similarity index 86% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Mesh.kt index fc91e333..867b8000 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Mesh.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/Mesh.kt @@ -25,13 +25,13 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.BufferGeometry +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material open external class Mesh(geometry: BufferGeometry?, material: Material?) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Points.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Points.kt index f296937a..7fede72c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Points.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/Points.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material external class Points : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt b/visionforge-threejs/src/jsMain/kotlin/three/objects/Sprite.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt rename to visionforge-threejs/src/jsMain/kotlin/three/objects/Sprite.kt index 60e2d0de..c9e06bac 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/objects/Sprite.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/objects/Sprite.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.objects +package three.objects -import info.laht.threekt.core.Intersect -import info.laht.threekt.core.Object3D -import info.laht.threekt.core.Raycaster -import info.laht.threekt.materials.Material +import three.core.Intersect +import three.core.Object3D +import three.core.Raycaster +import three.materials.Material external class Sprite(material: Material = definedExternally) : Object3D { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2Renderer.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2Renderer.kt index 1c5208ad..7ca6120f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2Renderer.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2Renderer.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.scenes.Scene +import three.cameras.Camera +import three.scenes.Scene external class WebGL2Renderer { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2RendererParams.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2RendererParams.kt index a2ef9eaf..8379d142 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGL2RendererParams.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGL2RendererParams.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTarget.kt similarity index 93% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTarget.kt index 08c44a36..2cbd272b 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTarget.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTarget.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.math.Vector4 -import info.laht.threekt.textures.Texture +import three.math.Vector4 +import three.textures.Texture external class WebGLRenderTarget { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTargetOptions.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTargetOptions.kt index 4ba8b941..145431ce 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderTargetOptions.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderTargetOptions.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers data class WebGLRenderTargetOptions( val wrapS: Int? = undefined, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderer.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderer.kt index aa95f1ba..45fc212e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRenderer.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRenderer.kt @@ -25,12 +25,12 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers +package three.renderers -import info.laht.threekt.cameras.Camera -import info.laht.threekt.math.Plane -import info.laht.threekt.scenes.Scene import org.w3c.dom.Node +import three.cameras.Camera +import three.math.Plane +import three.scenes.Scene external class WebGLRenderer(params: WebGLRendererParams = definedExternally) { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRendererParams.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRendererParams.kt index e6800673..6b979e8f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/WebGLRendererParams.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/WebGLRendererParams.kt @@ -22,7 +22,7 @@ * THE SOFTWARE. */ -package info.laht.threekt.renderers +package three.renderers import org.w3c.dom.Node diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderChunk.kt similarity index 99% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderChunk.kt index f70c7137..ccf4d37f 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderChunk.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderChunk.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders external object ShaderChunk { val alphamap_fragment: String diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderLib.kt similarity index 96% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderLib.kt index f168f740..67ed1215 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/ShaderLib.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/ShaderLib.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders external object ShaderLib { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/UniformsUtil.kt similarity index 94% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt rename to visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/UniformsUtil.kt index fb68d712..3d68f177 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/renderers/shaders/UniformsUtil.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/renderers/shaders/UniformsUtil.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.renderers.shaders +package three.renderers.shaders -import info.laht.threekt.core.Uniform +import three.core.Uniform external object UniformsUtil { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Fog.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/Fog.kt index c5682f36..87b67fb0 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Fog.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Fog.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.math.Color +import three.math.Color external class Fog { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/FogExp2.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/FogExp2.kt index 017fd34b..fed2c580 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/FogExp2.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/scenes/FogExp2.kt @@ -25,9 +25,9 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.math.Color +import three.math.Color external class FogExp2 { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Scene.kt similarity index 95% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt rename to visionforge-threejs/src/jsMain/kotlin/three/scenes/Scene.kt index 16e5e3cd..41fc011c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/scenes/Scene.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/scenes/Scene.kt @@ -25,10 +25,10 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.scenes +package three.scenes -import info.laht.threekt.core.Object3D -import info.laht.threekt.materials.Material +import three.core.Object3D +import three.materials.Material /** * Scenes allow you to set up what and where is to be rendered by three.js. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/CompressedTexture.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/CompressedTexture.kt index 1d25e61d..10b72f45 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CompressedTexture.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/textures/CompressedTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures /** * Creates a texture based on data in compressed form, for example from a DDS file. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/CubeTexture.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/CubeTexture.kt index b5eb6e89..b386f264 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/CubeTexture.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/textures/CubeTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures import org.w3c.dom.Element diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/DepthTexture.kt similarity index 97% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/DepthTexture.kt index 0ce9a308..eabc7d9c 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/DepthTexture.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/textures/DepthTexture.kt @@ -25,7 +25,7 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures external class DepthTexture( width: Int, diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt b/visionforge-threejs/src/jsMain/kotlin/three/textures/Texture.kt similarity index 98% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt rename to visionforge-threejs/src/jsMain/kotlin/three/textures/Texture.kt index b936c2f5..853ae54e 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/textures/Texture.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/textures/Texture.kt @@ -25,11 +25,11 @@ @file:JsModule("three") @file:JsNonModule -package info.laht.threekt.textures +package three.textures -import info.laht.threekt.math.Matrix3 -import info.laht.threekt.math.Vector2 import org.w3c.dom.Element +import three.math.Matrix3 +import three.math.Vector2 /** * Create a texture to apply to a surface or as a reflection or refraction map. diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt b/visionforge-threejs/src/jsMain/kotlin/three/utils/BufferGeometryUtils.kt similarity index 87% rename from visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt rename to visionforge-threejs/src/jsMain/kotlin/three/utils/BufferGeometryUtils.kt index dd15b514..9c52f8be 100644 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/utils/BufferGeometryUtils.kt +++ b/visionforge-threejs/src/jsMain/kotlin/three/utils/BufferGeometryUtils.kt @@ -1,8 +1,8 @@ @file:JsModule("three/examples/jsm/utils/BufferGeometryUtils") @file:JsNonModule -package info.laht.threekt.utils +package three.utils -import info.laht.threekt.core.BufferGeometry +import three.core.BufferGeometry public external object BufferGeometryUtils { diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt b/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt deleted file mode 100644 index 0b584f1f..00000000 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/Shape.kt +++ /dev/null @@ -1,8 +0,0 @@ -@file:JsModule("three") -@file:JsNonModule - -package info.laht.threekt.extras.core - -import info.laht.threekt.math.Vector2 - -external class Shape(points: Array) : Path \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt b/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt deleted file mode 100644 index bd6e69b9..00000000 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/extras/core/ShapePath.kt +++ /dev/null @@ -1,6 +0,0 @@ -@file:JsModule("three") -@file:JsNonModule - -package info.laht.threekt.extras.core - -external class ShapePath \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt b/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt deleted file mode 100644 index b0a5c91b..00000000 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/geometries/EdgesGeometry.kt +++ /dev/null @@ -1,8 +0,0 @@ -@file:JsModule("three") -@file:JsNonModule - -package info.laht.threekt.geometries - -import info.laht.threekt.core.BufferGeometry - -public external class EdgesGeometry(geometry: BufferGeometry, thresholdAngle: Int = definedExternally) : BufferGeometry \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt b/visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt deleted file mode 100644 index a0ef343e..00000000 --- a/visionforge-threejs/src/main/kotlin/info/laht/threekt/ktutils.kt +++ /dev/null @@ -1,9 +0,0 @@ -@file:Suppress("FunctionName") - -package info.laht.threekt - -import info.laht.threekt.renderers.WebGLRenderer -import info.laht.threekt.renderers.WebGLRendererParams - -fun WebGLRenderer(builder: WebGLRendererParams.() -> Unit): WebGLRenderer = - WebGLRenderer(WebGLRendererParams().apply(builder)) \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt deleted file mode 100644 index 1d5fd3d9..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/MeshThreeFactory.kt +++ /dev/null @@ -1,138 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.geometries.EdgesGeometry -import info.laht.threekt.objects.LineSegments -import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.meta.updateWith -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.names.plus -import space.kscience.dataforge.names.startsWith -import space.kscience.dataforge.values.boolean -import space.kscience.visionforge.computePropertyNode -import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.setProperty -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidMaterial -import space.kscience.visionforge.solid.layer -import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_ENABLED_KEY -import space.kscience.visionforge.solid.three.MeshThreeFactory.Companion.EDGES_MATERIAL_KEY -import kotlin.reflect.KClass - -/** - * Basic geometry-based factory - */ -public abstract class MeshThreeFactory( - override val type: KClass, -) : ThreeFactory { - /** - * Build a geometry for an object - */ - public abstract fun buildGeometry(obj: T): BufferGeometry - - override fun invoke(three: ThreePlugin, obj: T): Mesh { - val geometry = buildGeometry(obj) - - //val meshMeta: Meta = obj.properties[Material3D.MATERIAL_KEY]?.node ?: Meta.empty - - val mesh = Mesh(geometry, ThreeMaterials.DEFAULT).apply { - matrixAutoUpdate = false - //set position for mesh - updatePosition(obj) - applyProperties(obj) - } - - //add listener to object properties - obj.onPropertyChange { name -> - when { - name.startsWith(Solid.GEOMETRY_KEY) -> { - val oldGeometry = mesh.geometry - val newGeometry = buildGeometry(obj) - oldGeometry.attributes = newGeometry.attributes - //mesh.applyWireFrame(obj) - mesh.applyEdges(obj) - newGeometry.dispose() - } - //name.startsWith(WIREFRAME_KEY) -> mesh.applyWireFrame(obj) - name.startsWith(EDGES_KEY) -> mesh.applyEdges(obj) - else -> mesh.updateProperty(obj, name) - } - } - - return mesh - } - - public companion object { - public val EDGES_KEY: Name = "edges".asName() - - //public val WIREFRAME_KEY: Name = "wireframe".asName() - public val ENABLED_KEY: Name = "enabled".asName() - public val EDGES_ENABLED_KEY: Name = EDGES_KEY + ENABLED_KEY - public val EDGES_MATERIAL_KEY: Name = EDGES_KEY + SolidMaterial.MATERIAL_KEY - //public val WIREFRAME_ENABLED_KEY: Name = WIREFRAME_KEY + ENABLED_KEY - //public val WIREFRAME_MATERIAL_KEY: Name = WIREFRAME_KEY + SolidMaterial.MATERIAL_KEY - } -} - -public fun Solid.edges(enabled: Boolean = true, block: SolidMaterial.() -> Unit = {}) { - setProperty(EDGES_ENABLED_KEY, enabled) - meta.getOrCreate(EDGES_MATERIAL_KEY).updateWith(SolidMaterial, block) -} - -internal fun Mesh.applyProperties(obj: Solid): Mesh = apply { - updateMaterial(obj) - applyEdges(obj) - //applyWireFrame(obj) - layers.set(obj.layer) - children.forEach { - it.layers.set(obj.layer) - } -} - -public fun Mesh.applyEdges(obj: Solid) { - val edges = children.find { it.name == "@edges" } as? LineSegments - //inherited edges definition, enabled by default - if (obj.getPropertyValue(EDGES_ENABLED_KEY, inherit = true)?.boolean != false) { - val bufferGeometry = geometry as? BufferGeometry ?: return - val material = ThreeMaterials.getLineMaterial(obj.computePropertyNode(EDGES_MATERIAL_KEY), true) - if (edges == null) { - add( - LineSegments( - EdgesGeometry(bufferGeometry), - material - ).apply { - name = "@edges" - } - ) - } else { - edges.material = material - } - } else { - edges?.let { - remove(it) - it.dispose() - } - } -} - -//public fun Mesh.applyWireFrame(obj: Solid) { -// children.find { it.name == "@wireframe" }?.let { -// remove(it) -// (it as LineSegments).dispose() -// } -// //inherited wireframe definition, disabled by default -// if (obj.getProperty(MeshThreeFactory.WIREFRAME_ENABLED_KEY).boolean == true) { -// val bufferGeometry = geometry as? BufferGeometry ?: return -// val material = -// ThreeMaterials.getLineMaterial(obj.getProperty(MeshThreeFactory.WIREFRAME_MATERIAL_KEY).node, true) -// add( -// LineSegments( -// WireframeGeometry(bufferGeometry), -// material -// ).apply { -// name = "@wireframe" -// } -// ) -// } -//} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt deleted file mode 100644 index 7dd30a34..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeCanvasLabelFactory.kt +++ /dev/null @@ -1,58 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.DoubleSide -import info.laht.threekt.core.Object3D -import info.laht.threekt.geometries.PlaneGeometry -import info.laht.threekt.materials.MeshBasicMaterial -import info.laht.threekt.objects.Mesh -import info.laht.threekt.textures.Texture -import kotlinx.browser.document -import org.w3c.dom.CanvasRenderingContext2D -import org.w3c.dom.CanvasTextBaseline -import org.w3c.dom.HTMLCanvasElement -import org.w3c.dom.MIDDLE -import space.kscience.visionforge.solid.SolidLabel -import space.kscience.visionforge.solid.SolidMaterial -import space.kscience.visionforge.solid.three.ThreeCanvas.Companion.DO_NOT_HIGHLIGHT_TAG -import kotlin.reflect.KClass - -/** - * Using example from http://stemkoski.github.io/Three.js/Texture-From-Canvas.html - */ -public object ThreeCanvasLabelFactory : ThreeFactory { - override val type: KClass get() = SolidLabel::class - - override fun invoke(three: ThreePlugin, obj: SolidLabel): Object3D { - val canvas = document.createElement("canvas") as HTMLCanvasElement - val context = canvas.getContext("2d") as CanvasRenderingContext2D - context.font = "Bold ${obj.fontSize}pt ${obj.fontFamily}" - context.fillStyle = obj.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.value ?: "black" - context.textBaseline = CanvasTextBaseline.MIDDLE - val metrics = context.measureText(obj.text) - //canvas.width = metrics.width.toInt() - - - context.fillText(obj.text, (canvas.width - metrics.width) / 2, 0.5 * canvas.height) - - - // canvas contents will be used for a texture - val texture = Texture(canvas) - texture.needsUpdate = true - - val material = MeshBasicMaterial().apply { - map = texture - side = DoubleSide - transparent = true - } - - val mesh = Mesh( - PlaneGeometry(canvas.width, canvas.height), - material - ) - - mesh.updatePosition(obj) - - mesh.userData[DO_NOT_HIGHLIGHT_TAG] = true - return mesh - } -} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt deleted file mode 100644 index df9f2c94..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeFactory.kt +++ /dev/null @@ -1,83 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Object3D -import info.laht.threekt.math.Euler -import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.misc.Type -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.startsWith -import space.kscience.visionforge.Vision -import space.kscience.visionforge.computeProperty -import space.kscience.visionforge.solid.* -import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_KEY -import space.kscience.visionforge.solid.three.ThreeFactory.Companion.TYPE -import space.kscience.visionforge.visible -import kotlin.reflect.KClass - -/** - * Builder and updater for three.js object - */ -@Type(TYPE) -public interface ThreeFactory { - - public val type: KClass - - public operator fun invoke(three: ThreePlugin, obj: T): Object3D - - public companion object { - public const val TYPE: String = "threeFactory" - } -} - -/** - * Update position, rotation and visibility - */ -public fun Object3D.updatePosition(obj: Vision) { - visible = obj.visible ?: true - if (obj is Solid) { - position.set(obj.x, obj.y, obj.z) - -// val quaternion = obj.quaternion -// -// if (quaternion != null) { -// val (x, y, z, w) = quaternion -// setRotationFromQuaternion(Quaternion(x, y, z, w)) -// } else { -// setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) -// } - - setRotationFromEuler( Euler(obj.rotationX, obj.rotationY, obj.rotationZ, obj.rotationOrder.name)) - - scale.set(obj.scaleX, obj.scaleY, obj.scaleZ) - updateMatrix() - } -} - -/** - * Update non-position non-geometry property - */ -public fun Object3D.updateProperty(source: Vision, propertyName: Name) { - console.log("$source updated $propertyName with ${source.computeProperty(propertyName)}") - if (this is Mesh && propertyName.startsWith(MATERIAL_KEY)) { - updateMaterialProperty(source, propertyName) - } else if ( - propertyName.startsWith(Solid.POSITION_KEY) - || propertyName.startsWith(Solid.ROTATION_KEY) - || propertyName.startsWith(Solid.SCALE_KEY) - ) { - //update position of mesh using this object - updatePosition(source) - } else if (propertyName == Vision.VISIBLE_KEY) { - visible = source.visible ?: true - } -} - -/** - * Generic factory for elements which provide inside geometry builder - */ -public object ThreeShapeFactory : MeshThreeFactory(GeometrySolid::class) { - override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply { - obj.toGeometry(this) - }.build() -} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt deleted file mode 100644 index 522c0362..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeMaterials.kt +++ /dev/null @@ -1,171 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.materials.LineBasicMaterial -import info.laht.threekt.materials.Material -import info.laht.threekt.materials.MeshBasicMaterial -import info.laht.threekt.math.Color -import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.meta.* -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.asName -import space.kscience.dataforge.values.* -import space.kscience.visionforge.Colors -import space.kscience.visionforge.Vision -import space.kscience.visionforge.computePropertyNode -import space.kscience.visionforge.getStyleNodes -import space.kscience.visionforge.solid.SolidMaterial -import space.kscience.visionforge.solid.SolidReference - - -public object ThreeMaterials { - public val DEFAULT_COLOR: Color = Color(Colors.darkgreen) - public val DEFAULT: MeshBasicMaterial = MeshBasicMaterial().apply { - color.set(DEFAULT_COLOR) - cached = true - } - public val DEFAULT_LINE_COLOR: Color = Color(Colors.black) - public val DEFAULT_LINE: LineBasicMaterial = LineBasicMaterial().apply { - color.set(DEFAULT_LINE_COLOR) - } - - public val SELECTED_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { - color.set(Colors.ivory) - linewidth = 8.0 - } - - public val HIGHLIGHT_MATERIAL: LineBasicMaterial = LineBasicMaterial().apply { - color.set(Colors.blue) - linewidth = 8.0 - } - - private val lineMaterialCache = HashMap() - - private fun buildLineMaterial(meta: Meta): LineBasicMaterial = LineBasicMaterial().apply { - color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_LINE_COLOR - opacity = meta[SolidMaterial.OPACITY_KEY].double ?: 1.0 - transparent = opacity < 1.0 - linewidth = meta["thickness"].double ?: 1.0 - } - - public fun getLineMaterial(meta: Meta?, cache: Boolean): LineBasicMaterial { - if (meta == null) return DEFAULT_LINE - return if (cache) { - lineMaterialCache.getOrPut(meta) { buildLineMaterial(meta) } - } else { - buildLineMaterial(meta) - } - } - - private val materialCache = HashMap() - - internal fun buildMaterial(meta: Meta): Material = MeshBasicMaterial().apply { - color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR - opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 - transparent = opacity < 1.0 - wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false - needsUpdate = true - } -// val material = SolidMaterial.read(meta) -// return meta[SolidMaterial.SPECULAR_COLOR_KEY]?.let { specularColor -> -// MeshPhongMaterial().apply { -// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR -// specular = specularColor.threeColor() -// emissive = material.emissiveColor.threeColor() ?: specular -// reflectivity = 0.5 -// refractionRatio = 1.0 -// shininess = 100.0 -// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 -// transparent = opacity < 1.0 -// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false -// needsUpdate = true -// } -// } ?: MeshBasicMaterial().apply { -// color = meta[SolidMaterial.COLOR_KEY]?.threeColor() ?: DEFAULT_COLOR -// opacity = meta[SolidMaterial.OPACITY_KEY]?.double ?: 1.0 -// transparent = opacity < 1.0 -// wireframe = meta[SolidMaterial.WIREFRAME_KEY].boolean ?: false -// needsUpdate = true -// } - - internal fun cacheMaterial(meta: Meta): Material = materialCache.getOrPut(meta) { - buildMaterial(meta).apply { - cached = true - } - } -} - -/** - * Compute color - */ -public fun Meta.threeColor(): Color? { - val value = getValue(Name.EMPTY) - return if (isLeaf) { - when { - value == null -> null - value === Null -> null - value.type == ValueType.NUMBER -> Color(value.int) - else -> Color(value.string) - } - } else { - Color( - getValue(Colors.RED_KEY.asName())?.int ?: 0, - getValue(Colors.GREEN_KEY.asName())?.int ?: 0, - getValue(Colors.BLUE_KEY.asName())?.int ?: 0 - ) - } -} - -private var Material.cached: Boolean - get() = userData["cached"] == true - set(value) { - userData["cached"] = value - } - -public fun Mesh.updateMaterial(vision: Vision) { - val ownMaterialMeta = vision.meta.getMeta(SolidMaterial.MATERIAL_KEY) - if (ownMaterialMeta == null) { - if (vision is SolidReference && vision.getStyleNodes(SolidMaterial.MATERIAL_KEY).isEmpty()) { - updateMaterial(vision.prototype) - } else { - material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let { - ThreeMaterials.cacheMaterial(it) - } ?: ThreeMaterials.DEFAULT - } - } else { - material = vision.computePropertyNode(SolidMaterial.MATERIAL_KEY)?.let { - ThreeMaterials.buildMaterial(it) - } ?: ThreeMaterials.DEFAULT - } -} - -public fun Mesh.updateMaterialProperty(vision: Vision, propertyName: Name) { - if (material.cached || propertyName == SolidMaterial.MATERIAL_KEY) { - //generate a new material since cached material should not be changed - updateMaterial(vision) - } else { - when (propertyName) { - SolidMaterial.MATERIAL_COLOR_KEY -> { - material.asDynamic().color = vision.computePropertyNode(SolidMaterial.MATERIAL_COLOR_KEY)?.threeColor() - ?: ThreeMaterials.DEFAULT_COLOR - material.needsUpdate = true - } - SolidMaterial.MATERIAL_OPACITY_KEY -> { - val opacity = vision.getPropertyValue( - SolidMaterial.MATERIAL_OPACITY_KEY, - inherit = true, - )?.double ?: 1.0 - material.opacity = opacity - material.transparent = opacity < 1.0 - material.needsUpdate = true - } - SolidMaterial.MATERIAL_WIREFRAME_KEY -> { - material.asDynamic().wireframe = vision.getPropertyValue( - SolidMaterial.MATERIAL_WIREFRAME_KEY, - inherit = true, - )?.boolean ?: false - material.needsUpdate = true - } - else -> console.warn("Unrecognized material property: $propertyName") - } - } -} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt deleted file mode 100644 index aa779e46..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/ThreeReferenceFactory.kt +++ /dev/null @@ -1,64 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.core.Object3D -import info.laht.threekt.objects.Mesh -import space.kscience.dataforge.names.Name -import space.kscience.dataforge.names.cutFirst -import space.kscience.dataforge.names.firstOrNull -import space.kscience.visionforge.onPropertyChange -import space.kscience.visionforge.solid.Solid -import space.kscience.visionforge.solid.SolidReferenceGroup -import space.kscience.visionforge.solid.SolidReferenceGroup.Companion.REFERENCE_CHILD_PROPERTY_PREFIX -import kotlin.reflect.KClass - -public object ThreeReferenceFactory : ThreeFactory { - private val cache = HashMap() - - override val type: KClass = SolidReferenceGroup::class - - private fun Object3D.replicate(): Object3D { - return when (this) { - is Mesh -> Mesh(geometry, material).also { - it.applyMatrix4(matrix) - } - else -> clone(false) - }.also { obj: Object3D -> - obj.name = this.name - children.forEach { child: Object3D -> - obj.add(child.replicate()) - } - } - } - - override fun invoke(three: ThreePlugin, obj: SolidReferenceGroup): Object3D { - val template = obj.prototype - val cachedObject = cache.getOrPut(template) { - three.buildObject3D(template) - } - - val object3D: Object3D = cachedObject.replicate() - object3D.updatePosition(obj) - - if(object3D is Mesh){ - //object3D.material = ThreeMaterials.buildMaterial(obj.getProperty(SolidMaterial.MATERIAL_KEY).node!!) - object3D.applyProperties(obj) - } - - //TODO apply child properties - - obj.onPropertyChange { name-> - if (name.firstOrNull()?.body == REFERENCE_CHILD_PROPERTY_PREFIX) { - val childName = name.firstOrNull()?.index?.let(Name::parse) ?: error("Wrong syntax for reference child property: '$name'") - val propertyName = name.cutFirst() - val referenceChild = obj[childName] ?: error("Reference child with name '$childName' not found") - val child = object3D.findChild(childName) ?: error("Object child with name '$childName' not found") - child.updateProperty(referenceChild, propertyName) - } else { - object3D.updateProperty(obj, name) - } - } - - - return object3D - } -} \ No newline at end of file diff --git a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt b/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt deleted file mode 100644 index 447cf4b6..00000000 --- a/visionforge-threejs/src/main/kotlin/space/kscience/visionforge/solid/three/three.kt +++ /dev/null @@ -1,34 +0,0 @@ -package space.kscience.visionforge.solid.three - -import info.laht.threekt.core.BufferGeometry -import info.laht.threekt.core.Layers -import info.laht.threekt.external.controls.OrbitControls -import info.laht.threekt.materials.Material -import info.laht.threekt.math.Vector3 -import info.laht.threekt.objects.Mesh -import info.laht.threekt.textures.Texture -import space.kscience.dataforge.meta.Meta -import space.kscience.dataforge.meta.float -import space.kscience.dataforge.meta.get -import kotlin.math.PI - -public val Meta.vector: Vector3 get() = Vector3(this["x"].float ?: 0f, this["y"].float ?: 0f, this["z"].float ?: 0f) - - -internal fun Double.toRadians() = this * PI / 180 - - -internal fun Any.dispose() { - when (this) { - is BufferGeometry -> dispose() - is Material -> dispose() - is Mesh -> { - geometry.dispose() - material.dispose() - } - is OrbitControls -> dispose() - is Texture -> dispose() - } -} - -public fun Layers.check(layer: Int): Boolean = (mask shr(layer) and 0x00000001) > 0 \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts index 696b30cf..059f3784 100644 --- a/visionforge-threejs/visionforge-threejs-server/build.gradle.kts +++ b/visionforge-threejs/visionforge-threejs-server/build.gradle.kts @@ -1,45 +1,29 @@ plugins { - id("ru.mipt.npm.gradle.mpp") - } + id("space.kscience.gradle.mpp") +} val ktorVersion: String by rootProject.extra -kotlin { - js{ - browser { - webpackTask { - this.outputFileName = "js/visionforge-three.js" - } - } - binaries.executable() - } - - afterEvaluate { - val jsBrowserDistribution by tasks.getting - - tasks.getByName("jvmProcessResources") { - dependsOn(jsBrowserDistribution) - afterEvaluate { - from(jsBrowserDistribution) +kscience { + fullStack("js/visionforge-three.js") { + commonWebpackConfig { + cssSupport { + enabled.set(false) } } } - sourceSets { - commonMain { - dependencies { - api(project(":visionforge-solid")) - } - } - jvmMain { - dependencies { - api(project(":visionforge-server")) - } - } - jsMain { - dependencies { - api(project(":visionforge-threejs")) - } - } + dependencies { + api(projects.visionforgeSolid) + } + + dependencies(jvmMain) { + api(projects.visionforgeServer) + } + + dependencies(jsMain) { + api(projects.visionforgeThreejs) + api(projects.ui.ring) + compileOnly(npm("webpack-bundle-analyzer","4.5.0")) } } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt index ed2908f5..d1635ddf 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jsMain/kotlin/space/kscience/visionforge/three/jsMain.kt @@ -1,11 +1,11 @@ package space.kscience.visionforge.three import space.kscience.dataforge.misc.DFExperimental +import space.kscience.visionforge.ring.ThreeWithControlsPlugin import space.kscience.visionforge.runVisionClient -import space.kscience.visionforge.solid.three.ThreePlugin @DFExperimental public fun main(): Unit = runVisionClient { - plugin(ThreePlugin) + plugin(ThreeWithControlsPlugin) } \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt index 6c70e0ed..28f04f8d 100644 --- a/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmMain/kotlin/space/kscience/visionforge/three/serverExtensions.kt @@ -3,13 +3,12 @@ package space.kscience.visionforge.three import space.kscience.dataforge.context.Global import space.kscience.dataforge.misc.DFExperimental import space.kscience.visionforge.html.* -import space.kscience.visionforge.makeFile +import space.kscience.visionforge.visionManager import java.awt.Desktop import java.nio.file.Path -public val Page.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") - +public val VisionPage.Companion.threeJsHeader: HtmlFragment get() = scriptHeader("js/visionforge-three.js") @DFExperimental public fun makeThreeJsFile( @@ -19,10 +18,14 @@ public fun makeThreeJsFile( show: Boolean = true, content: HtmlVisionFragment, ): Unit { - val actualPath = Page(Global, content = content).makeFile(path) { actualPath -> + val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath -> mapOf( - "title" to Page.title(title), - "threeJs" to Page.importScriptHeader("js/visionforge-three.js", resourceLocation, actualPath) + "title" to VisionPage.title(title), + "threeJs" to VisionPage.importScriptHeader( + "js/visionforge-three.js", + resourceLocation, + actualPath, + ) ) } if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI()) diff --git a/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt new file mode 100644 index 00000000..95d9e6f7 --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/src/jvmTest/kotlin/space/kscience/visionforge/three/TestServerExtensions.kt @@ -0,0 +1,25 @@ +package space.kscience.visionforge.three + +import kotlinx.html.stream.createHTML +import space.kscience.visionforge.html.ResourceLocation +import space.kscience.visionforge.html.VisionPage +import space.kscience.visionforge.html.appendTo +import space.kscience.visionforge.html.importScriptHeader +import kotlin.test.Test + +class TestServerExtensions { + + @Suppress("UNUSED_VARIABLE") + @Test + fun testServerHeader(){ + val string = createHTML().apply { + VisionPage.importScriptHeader( + "js/visionforge-three.js", + ResourceLocation.SYSTEM + ).appendTo(this) + }.finalize() + + + //println(string) + } +} \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js new file mode 100644 index 00000000..b3cc4770 --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/01.ring.js @@ -0,0 +1,23 @@ +const ringConfig = require('@jetbrains/ring-ui/webpack.config').config; +const path = require('path'); + +config.module.rules.push(...ringConfig.module.rules) + +config.module.rules.push( + { + test: /\.css$/, + exclude: [ + path.resolve(__dirname, "../../node_modules/@jetbrains/ring-ui") + ], + use: [ + { + loader: 'style-loader', + options: {} + }, + { + loader: 'css-loader', + options: {} + } + ] + } +) \ No newline at end of file diff --git a/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js new file mode 100644 index 00000000..947253ca --- /dev/null +++ b/visionforge-threejs/visionforge-threejs-server/webpack.config.d/02.bundle.js @@ -0,0 +1,10 @@ +const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPlugin; + +module.exports = { + plugins: [ + new BundleAnalyzerPlugin({ + analyzerMode: "static", + reportFilename: "bundle-report.html" + }) + ] +} \ No newline at end of file