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 8b67c108..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 @@ -42,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) @@ -51,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) } } } @@ -62,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) @@ -90,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 ef72de52..e2e662da 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,6 +1,8 @@ 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.names.Name import space.kscience.dataforge.names.parseAsName import space.kscience.dataforge.names.plus @@ -44,39 +46,32 @@ private fun Solid.translate(trans: DoubleArray) { position = Float32Vector3D(x, y, z) } -private fun Solid.useMatrix(matrix: DGeoMatrix?) { - if (matrix == null) return - when (matrix.typename) { - "TGeoIdentity" -> { - //do nothing +private fun Solid.scale(s: DoubleArray) { + scale = Float32Vector3D(s[0], s[1], s[2]) +} + +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) } - "TGeoTranslation" -> { - val fTranslation by matrix.meta.doubleArray() - translate(fTranslation) + is DGeoCombiTrans -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } } - "TGeoRotation" -> { - val fRotationMatrix by matrix.meta.doubleArray() - rotate(fRotationMatrix) - } - - "TGeoCombiTrans" -> { - val fTranslation by matrix.meta.doubleArray() - - translate(fTranslation) - matrix.meta["fRotation.fRotationMatrix"]?.value?.let { - rotate(it.doubleArray) - } - } - - "TGeoHMatrix" -> { - val fTranslation by matrix.meta.doubleArray() - val fRotationMatrix by matrix.meta.doubleArray() - val fScale by matrix.meta.doubleArray() - translate(fTranslation) - rotate(fRotationMatrix) - scale = Float32Vector3D(fScale[0], fScale[1], fScale[2]) + is DGeoHMatrix -> { + translate(matrix.fTranslation) + matrix.fRotation?.fRotationMatrix?.let { rotate(it) } + scale(matrix.fScale) } } } @@ -99,10 +94,10 @@ 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) } @@ -286,7 +281,7 @@ 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) } 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/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_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