Compare commits
2 Commits
ae12084dee
...
af2539eed2
Author | SHA1 | Date | |
---|---|---|---|
af2539eed2 | |||
4b91e5d62b |
@ -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<CbmStsTrack>,
|
||||
public val bmnGlobalTracks: List<BmnGlobalTrack>,
|
||||
)
|
||||
|
||||
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<CbmStsTrack> =
|
||||
json.decodeFromJsonElement(ListSerializer(CbmStsTrack.serializer()), jsonArray[0])
|
||||
val bmnGlobalTracks: List<BmnGlobalTrack> =
|
||||
json.decodeFromJsonElement(ListSerializer(BmnGlobalTrack.serializer()), jsonArray[1])
|
||||
return BmnEventContainer(cbmTracks, bmnGlobalTracks)
|
||||
}
|
||||
}
|
@ -113,8 +113,8 @@ private fun SolidGroup.addShape(
|
||||
val fScale by shape.meta.doubleArray()
|
||||
|
||||
extruded(name = name) {
|
||||
(0 until fNvert).forEach { index ->
|
||||
shape {
|
||||
(0 until fNvert).forEach { index ->
|
||||
point(fX[index], fY[index])
|
||||
}
|
||||
}
|
||||
@ -181,10 +181,9 @@ private fun SolidGroup.addShape(
|
||||
name = name,
|
||||
) {
|
||||
z = (fZ[1] + fZ[0]) / 2
|
||||
|
||||
}.apply(block)
|
||||
} else {
|
||||
TODO()
|
||||
TODO("Polycone is not implemented")
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,18 +1,17 @@
|
||||
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.Solids
|
||||
import space.kscience.visionforge.solid.ambientLight
|
||||
import space.kscience.visionforge.solid.invoke
|
||||
import space.kscience.visionforge.solid.solid
|
||||
import space.kscience.visionforge.solid.*
|
||||
import java.util.zip.ZipInputStream
|
||||
import kotlin.io.path.Path
|
||||
import kotlin.io.path.writeText
|
||||
@ -39,6 +38,8 @@ fun main() {
|
||||
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)
|
||||
@ -49,6 +50,30 @@ fun main() {
|
||||
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)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
7912
demo/playground/src/jvmMain/resources/root/event_0.json
Normal file
7912
demo/playground/src/jvmMain/resources/root/event_0.json
Normal file
File diff suppressed because it is too large
Load Diff
215
demo/playground/src/jvmMain/resources/root/event_1.json
Normal file
215
demo/playground/src/jvmMain/resources/root/event_1.json
Normal file
@ -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
|
||||
}]
|
||||
]
|
5150
demo/playground/src/jvmMain/resources/root/event_2.json
Normal file
5150
demo/playground/src/jvmMain/resources/root/event_2.json
Normal file
File diff suppressed because it is too large
Load Diff
1370
demo/playground/src/jvmMain/resources/root/event_3.json
Normal file
1370
demo/playground/src/jvmMain/resources/root/event_3.json
Normal file
File diff suppressed because it is too large
Load Diff
@ -34,20 +34,27 @@ public fun Shape2DBuilder.polygon(vertices: Int, radius: Number) {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A layer for extruded shape
|
||||
*/
|
||||
@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<Float32Vector2D>,
|
||||
public val shape: Shape2D,
|
||||
public val layers: List<Layer>,
|
||||
) : SolidBase<Extruded>(), GeometrySolid {
|
||||
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
val shape: Shape2D = shape
|
||||
init {
|
||||
require(shape.size > 2) { "Extruded shape requires more than 2 points per layer" }
|
||||
}
|
||||
|
||||
if (shape.size < 3) error("Extruded shape requires more than 2 points per layer")
|
||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
|
||||
/**
|
||||
* Expand the shape for specific layers
|
||||
@ -90,16 +97,11 @@ public class Extruded(
|
||||
geometryBuilder.cap(layers.last())
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "solid.extruded"
|
||||
}
|
||||
}
|
||||
|
||||
public class ExtrudeBuilder(
|
||||
public class Builder(
|
||||
public var shape: List<Float32Vector2D> = emptyList(),
|
||||
public var layers: MutableList<Layer> = ArrayList(),
|
||||
public val properties: MutableMeta = MutableMeta(),
|
||||
) {
|
||||
) {
|
||||
public fun shape(block: Shape2DBuilder.() -> Unit) {
|
||||
this.shape = Shape2DBuilder().apply(block).build()
|
||||
}
|
||||
@ -109,12 +111,17 @@ public class ExtrudeBuilder(
|
||||
}
|
||||
|
||||
internal fun build(): Extruded = Extruded(shape, layers).apply {
|
||||
this.properties.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties)
|
||||
this.properties.setProperty(Name.EMPTY, this@Builder.properties)
|
||||
}
|
||||
}
|
||||
|
||||
public companion object {
|
||||
public const val TYPE: String = "solid.extruded"
|
||||
}
|
||||
}
|
||||
|
||||
@VisionBuilder
|
||||
public fun MutableVisionContainer<Solid>.extruded(
|
||||
name: String? = null,
|
||||
action: ExtrudeBuilder.() -> Unit = {},
|
||||
): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) }
|
||||
action: Extruded.Builder.() -> Unit = {},
|
||||
): Extruded = Extruded.Builder().apply(action).build().also { setChild(name, it) }
|
@ -15,7 +15,6 @@ import kotlin.math.sqrt
|
||||
@Serializable(Float32Euclidean2DSpace.VectorSerializer::class)
|
||||
public interface Float32Vector2D: Vector2D<Float>
|
||||
|
||||
|
||||
public object Float32Euclidean2DSpace :
|
||||
GeometrySpace<Float32Vector2D>,
|
||||
ScaleOperations<Float32Vector2D> {
|
||||
|
@ -0,0 +1,136 @@
|
||||
package space.kscience.visionforge.solid
|
||||
|
||||
import kotlinx.serialization.SerialName
|
||||
import kotlinx.serialization.Serializable
|
||||
import space.kscience.kmath.geometry.component1
|
||||
import space.kscience.kmath.geometry.component2
|
||||
import space.kscience.kmath.structures.Float32
|
||||
|
||||
|
||||
private inline fun <T> Iterable<T>.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 LayersSurface(
|
||||
public val layers: List<Layer>,
|
||||
) : SolidBase<Extruded>(), 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<Float32Vector3D> = outer.map { (x, y) -> Float32Vector3D(x, y, z) }
|
||||
|
||||
public fun innerPoints(): List<Float32Vector3D>? = 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 <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
||||
|
||||
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 companion object {
|
||||
public const val TYPE: String = "solid.surface"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user