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()
|
val fScale by shape.meta.doubleArray()
|
||||||
|
|
||||||
extruded(name = name) {
|
extruded(name = name) {
|
||||||
(0 until fNvert).forEach { index ->
|
shape {
|
||||||
shape {
|
(0 until fNvert).forEach { index ->
|
||||||
point(fX[index], fY[index])
|
point(fX[index], fY[index])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -181,10 +181,9 @@ private fun SolidGroup.addShape(
|
|||||||
name = name,
|
name = name,
|
||||||
) {
|
) {
|
||||||
z = (fZ[1] + fZ[0]) / 2
|
z = (fZ[1] + fZ[0]) / 2
|
||||||
|
|
||||||
}.apply(block)
|
}.apply(block)
|
||||||
} else {
|
} else {
|
||||||
TODO()
|
TODO("Polycone is not implemented")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,17 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
|
import ru.mipt.npm.root.BMN
|
||||||
import ru.mipt.npm.root.DGeoManager
|
import ru.mipt.npm.root.DGeoManager
|
||||||
import ru.mipt.npm.root.rootGeo
|
import ru.mipt.npm.root.rootGeo
|
||||||
import ru.mipt.npm.root.serialization.TGeoManager
|
import ru.mipt.npm.root.serialization.TGeoManager
|
||||||
|
import ru.mipt.npm.root.toVector
|
||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.isLeaf
|
import space.kscience.dataforge.meta.isLeaf
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.visionforge.Colors
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.ambientLight
|
|
||||||
import space.kscience.visionforge.solid.invoke
|
|
||||||
import space.kscience.visionforge.solid.solid
|
|
||||||
import java.util.zip.ZipInputStream
|
import java.util.zip.ZipInputStream
|
||||||
import kotlin.io.path.Path
|
import kotlin.io.path.Path
|
||||||
import kotlin.io.path.writeText
|
import kotlin.io.path.writeText
|
||||||
@ -39,6 +38,8 @@ fun main() {
|
|||||||
println(it)
|
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) {
|
makeVisionFile(path = Path("data/output.html"), resourceLocation = ResourceLocation.EMBED) {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
requirePlugin(Solids)
|
requirePlugin(Solids)
|
||||||
@ -49,6 +50,30 @@ fun main() {
|
|||||||
rootGeo(geo,"BM@N", ignoreRootColors = true).also {
|
rootGeo(geo,"BM@N", ignoreRootColors = true).also {
|
||||||
Path("data/BM@N.vf.json").writeText(Solids.encodeToString(it))
|
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
|
@Serializable
|
||||||
public data class Layer(var x: Float, var y: Float, var z: Float, var scale: Float)
|
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
|
@Serializable
|
||||||
@SerialName("solid.extrude")
|
@SerialName("solid.extrude")
|
||||||
public class Extruded(
|
public class Extruded(
|
||||||
public val shape: List<Float32Vector2D>,
|
public val shape: Shape2D,
|
||||||
public val layers: List<Layer>,
|
public val layers: List<Layer>,
|
||||||
) : SolidBase<Extruded>(), GeometrySolid {
|
) : SolidBase<Extruded>(), GeometrySolid {
|
||||||
|
|
||||||
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
|
init {
|
||||||
val shape: Shape2D = shape
|
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
|
* Expand the shape for specific layers
|
||||||
@ -90,31 +97,31 @@ public class Extruded(
|
|||||||
geometryBuilder.cap(layers.last())
|
geometryBuilder.cap(layers.last())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
|
||||||
|
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.setProperty(Name.EMPTY, this@Builder.properties)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public companion object {
|
public companion object {
|
||||||
public const val TYPE: String = "solid.extruded"
|
public const val TYPE: String = "solid.extruded"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ExtrudeBuilder(
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
|
|
||||||
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.setProperty(Name.EMPTY, this@ExtrudeBuilder.properties)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
@VisionBuilder
|
@VisionBuilder
|
||||||
public fun MutableVisionContainer<Solid>.extruded(
|
public fun MutableVisionContainer<Solid>.extruded(
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: ExtrudeBuilder.() -> Unit = {},
|
action: Extruded.Builder.() -> Unit = {},
|
||||||
): Extruded = ExtrudeBuilder().apply(action).build().also { setChild(name, it) }
|
): Extruded = Extruded.Builder().apply(action).build().also { setChild(name, it) }
|
@ -15,7 +15,6 @@ import kotlin.math.sqrt
|
|||||||
@Serializable(Float32Euclidean2DSpace.VectorSerializer::class)
|
@Serializable(Float32Euclidean2DSpace.VectorSerializer::class)
|
||||||
public interface Float32Vector2D: Vector2D<Float>
|
public interface Float32Vector2D: Vector2D<Float>
|
||||||
|
|
||||||
|
|
||||||
public object Float32Euclidean2DSpace :
|
public object Float32Euclidean2DSpace :
|
||||||
GeometrySpace<Float32Vector2D>,
|
GeometrySpace<Float32Vector2D>,
|
||||||
ScaleOperations<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