Merge pull request #76 from SciProgCentre/dev
0.3.0-dev-17
This commit is contained in:
commit
8e5503f0d8
8
.github/workflows/build.yml
vendored
8
.github/workflows/build.yml
vendored
@ -8,15 +8,15 @@ on:
|
|||||||
jobs:
|
jobs:
|
||||||
build:
|
build:
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
timeout-minutes: 40
|
timeout-minutes: 30
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v2
|
- uses: actions/checkout@v3.5.3
|
||||||
- name: Set up JDK 11
|
- name: Set up JDK 11
|
||||||
uses: actions/setup-java@v2.5.0
|
uses: actions/setup-java@v3.12.0
|
||||||
with:
|
with:
|
||||||
java-version: 11
|
java-version: 11
|
||||||
distribution: liberica
|
distribution: liberica
|
||||||
- name: execute build
|
- name: execute build
|
||||||
uses: gradle/gradle-build-action@v2
|
uses: gradle/gradle-build-action@v2.7.1
|
||||||
with:
|
with:
|
||||||
arguments: build
|
arguments: build
|
||||||
|
2
.gitignore
vendored
2
.gitignore
vendored
@ -7,3 +7,5 @@ build/
|
|||||||
data/
|
data/
|
||||||
|
|
||||||
!gradle-wrapper.jar
|
!gradle-wrapper.jar
|
||||||
|
|
||||||
|
/kotlin-js-store/yarn.lock
|
||||||
|
13
CHANGELOG.md
13
CHANGELOG.md
@ -2,14 +2,27 @@
|
|||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
|
- Context receivers flag
|
||||||
|
- MeshLine for thick lines
|
||||||
|
- Custom client-side events and thier processing in VisionServer
|
||||||
|
|
||||||
### Changed
|
### 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
|
### Deprecated
|
||||||
|
|
||||||
### Removed
|
### Removed
|
||||||
|
|
||||||
### Fixed
|
### Fixed
|
||||||
|
- Jupyter integration for IDEA and Jupyter lab.
|
||||||
|
|
||||||
### Security
|
### Security
|
||||||
|
|
||||||
|
@ -1,29 +1,50 @@
|
|||||||
|
import org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile
|
||||||
|
import space.kscience.gradle.useApache2Licence
|
||||||
|
import space.kscience.gradle.useSPCTeam
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.project")
|
id("space.kscience.gradle.project")
|
||||||
id("org.jetbrains.kotlinx.kover") version "0.5.0-RC"
|
// 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")
|
val fxVersion by extra("11")
|
||||||
|
|
||||||
allprojects{
|
allprojects {
|
||||||
group = "space.kscience"
|
group = "space.kscience"
|
||||||
version = "0.2.0"
|
version = "0.3.0-dev-17"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
if (name.startsWith("visionforge")) apply<MavenPublishPlugin>()
|
if (name.startsWith("visionforge")) apply<MavenPublishPlugin>()
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
|
mavenLocal()
|
||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
maven("https://maven.jzy3d.org/releases")
|
maven("https://maven.jzy3d.org/releases")
|
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<org.jetbrains.kotlin.gradle.tasks.KotlinCompile> {
|
||||||
|
kotlinOptions {
|
||||||
|
freeCompilerArgs = freeCompilerArgs + "-Xcontext-receivers"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
tasks.withType<KotlinJsCompile>{
|
||||||
|
kotlinOptions{
|
||||||
|
useEsClasses = true
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ksciencePublish {
|
ksciencePublish {
|
||||||
github("visionforge")
|
pom("https://github.com/SciProgCentre/visionforge") {
|
||||||
space()
|
useApache2Licence()
|
||||||
|
useSPCTeam()
|
||||||
|
}
|
||||||
|
repository("spc","https://maven.sciprog.center/kscience")
|
||||||
sonatype()
|
sonatype()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,19 +1,14 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience{
|
kscience{
|
||||||
|
jvm()
|
||||||
|
js()
|
||||||
|
dependencies {
|
||||||
|
api(projects.visionforgeSolid)
|
||||||
|
}
|
||||||
useSerialization {
|
useSerialization {
|
||||||
json()
|
json()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin {
|
|
||||||
sourceSets {
|
|
||||||
val commonMain by getting {
|
|
||||||
dependencies {
|
|
||||||
api(project(":visionforge-solid"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,6 @@ import space.kscience.dataforge.meta.*
|
|||||||
import space.kscience.dataforge.misc.Named
|
import space.kscience.dataforge.misc.Named
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.values.doubleArray
|
|
||||||
import kotlin.properties.ReadOnlyProperty
|
import kotlin.properties.ReadOnlyProperty
|
||||||
|
|
||||||
public fun MetaProvider.doubleArray(
|
public fun MetaProvider.doubleArray(
|
||||||
@ -43,7 +42,7 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac
|
|||||||
}
|
}
|
||||||
|
|
||||||
internal fun <T : DObject> tObjectArray(
|
internal fun <T : DObject> tObjectArray(
|
||||||
builder: (Meta, DObjectCache) -> T
|
builder: (Meta, DObjectCache) -> T,
|
||||||
): ReadOnlyProperty<Any?, List<T>> = ReadOnlyProperty { _, property ->
|
): ReadOnlyProperty<Any?, List<T>> = ReadOnlyProperty { _, property ->
|
||||||
meta.getIndexed(Name.of(property.name, "arr")).values.mapNotNull {
|
meta.getIndexed(Name.of(property.name, "arr")).values.mapNotNull {
|
||||||
resolve(builder, it)
|
resolve(builder, it)
|
||||||
@ -52,9 +51,9 @@ public open class DObject(public val meta: Meta, public val refCache: DObjectCac
|
|||||||
|
|
||||||
internal fun <T : DObject> dObject(
|
internal fun <T : DObject> dObject(
|
||||||
builder: (Meta, DObjectCache) -> T,
|
builder: (Meta, DObjectCache) -> T,
|
||||||
key: Name? = null
|
key: Name? = null,
|
||||||
): ReadOnlyProperty<Any?, T?> = ReadOnlyProperty { _, property ->
|
): ReadOnlyProperty<Any?, T?> = 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 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 class DGeoMedium(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) {
|
||||||
public val fMaterial: DGeoMaterial? by dObject(::DGeoMaterial)
|
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 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 fScale: DoubleArray by meta.doubleArray(1.0, 1.0, 1.0)
|
||||||
public val x: Double get() = fScale[0]
|
public val x: Double get() = fScale[0]
|
||||||
public val y: Double get() = fScale[1]
|
public val y: Double get() = fScale[1]
|
||||||
public val z: Double get() = fScale[2]
|
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 class DGeoBoolNode(meta: Meta, refCache: DObjectCache) : DObject(meta, refCache) {
|
||||||
public val fLeft: DGeoShape? by dObject(::DGeoShape)
|
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 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 class DGeoManager(meta: Meta, refCache: DObjectCache) : DNamed(meta, refCache) {
|
||||||
public val fMatrices: List<DGeoMatrix> by tObjectArray(::DGeoMatrix)
|
public val fMatrices: List<DGeoMatrix> by tObjectArray(::dGeoMatrix)
|
||||||
|
|
||||||
public val fShapes: List<DGeoShape> by tObjectArray(::DGeoShape)
|
public val fShapes: List<DGeoShape> by tObjectArray(::DGeoShape)
|
||||||
|
|
||||||
|
@ -1,13 +1,23 @@
|
|||||||
package ru.mipt.npm.root
|
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.Name
|
||||||
|
import space.kscience.dataforge.names.parseAsName
|
||||||
import space.kscience.dataforge.names.plus
|
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.isEmpty
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.SolidMaterial.Companion.MATERIAL_COLOR_KEY
|
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()
|
private val volumesName = Name.EMPTY //"volumes".asName()
|
||||||
|
|
||||||
@ -20,51 +30,48 @@ private fun degToRad(d: Double) = d * PI / 180.0
|
|||||||
private data class RootToSolidContext(
|
private data class RootToSolidContext(
|
||||||
val prototypeHolder: PrototypeHolder,
|
val prototypeHolder: PrototypeHolder,
|
||||||
val currentLayer: Int = 0,
|
val currentLayer: Int = 0,
|
||||||
val maxLayer: Int = 5
|
val maxLayer: Int = 5,
|
||||||
|
val ignoreRootColors: Boolean = false,
|
||||||
|
val colorCache: MutableMap<Meta, String> = 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) {
|
private fun Solid.rotate(rot: DoubleArray) {
|
||||||
val xAngle = atan2(-rot[5], rot[8])
|
val matrix = VirtualMatrix(3, 3) { i, j -> rot[i * 3 + j] }
|
||||||
val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2)))
|
quaternion = Quaternion.fromRotationMatrix(matrix)
|
||||||
val zAngle = atan2(-rot[1], rot[0])
|
|
||||||
rotation = Point3D(xAngle, yAngle, zAngle)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Solid.translate(trans: DoubleArray) {
|
private fun Solid.translate(trans: DoubleArray) {
|
||||||
val (x, y, z) = trans
|
val (x, y, z) = trans
|
||||||
position = Point3D(x, y, z)
|
position = Float32Vector3D(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Solid.useMatrix(matrix: DGeoMatrix?) {
|
private fun Solid.scale(s: DoubleArray) {
|
||||||
if (matrix == null) return
|
scale = Float32Vector3D(s[0], s[1], s[2])
|
||||||
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()
|
|
||||||
|
|
||||||
translate(fTranslation)
|
private fun Solid.useMatrix(matrix: DGeoMatrix?): Unit {
|
||||||
matrix.meta["fRotation.fRotationMatrix"]?.value?.let {
|
when (matrix) {
|
||||||
rotate(it.doubleArray)
|
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()
|
is DGeoCombiTrans -> {
|
||||||
val fRotationMatrix by matrix.meta.doubleArray()
|
translate(matrix.fTranslation)
|
||||||
val fScale by matrix.meta.doubleArray()
|
matrix.fRotation?.fRotationMatrix?.let { rotate(it) }
|
||||||
translate(fTranslation)
|
}
|
||||||
rotate(fRotationMatrix)
|
|
||||||
scale = Point3D(fScale[0], fScale[1], fScale[2])
|
is DGeoHMatrix -> {
|
||||||
|
translate(matrix.fTranslation)
|
||||||
|
matrix.fRotation?.fRotationMatrix?.let { rotate(it) }
|
||||||
|
scale(matrix.fScale)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -73,7 +80,7 @@ private fun SolidGroup.addShape(
|
|||||||
shape: DGeoShape,
|
shape: DGeoShape,
|
||||||
context: RootToSolidContext,
|
context: RootToSolidContext,
|
||||||
name: String? = shape.fName.ifEmpty { null },
|
name: String? = shape.fName.ifEmpty { null },
|
||||||
block: Solid.() -> Unit = {}
|
block: Solid.() -> Unit = {},
|
||||||
) {
|
) {
|
||||||
when (shape.typename) {
|
when (shape.typename) {
|
||||||
"TGeoCompositeShape" -> {
|
"TGeoCompositeShape" -> {
|
||||||
@ -87,13 +94,14 @@ private fun SolidGroup.addShape(
|
|||||||
}
|
}
|
||||||
smartComposite(compositeType, name = name) {
|
smartComposite(compositeType, name = name) {
|
||||||
addShape(node.fLeft!!, context, null) {
|
addShape(node.fLeft!!, context, null) {
|
||||||
this.useMatrix(node.fLeftMat)
|
useMatrix(node.fLeftMat)
|
||||||
}
|
}
|
||||||
addShape(node.fRight!!, context, null) {
|
addShape(node.fRight!!, context, null) {
|
||||||
this.useMatrix(node.fRightMat)
|
useMatrix(node.fRightMat)
|
||||||
}
|
}
|
||||||
}.apply(block)
|
}.apply(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoXtru" -> {
|
"TGeoXtru" -> {
|
||||||
val fNvert by shape.meta.int(0)
|
val fNvert by shape.meta.int(0)
|
||||||
val fX by shape.meta.doubleArray()
|
val fX by shape.meta.doubleArray()
|
||||||
@ -105,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])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -121,6 +129,7 @@ private fun SolidGroup.addShape(
|
|||||||
}
|
}
|
||||||
}.apply(block)
|
}.apply(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoTube" -> {
|
"TGeoTube" -> {
|
||||||
val fRmax by shape.meta.double(0.0)
|
val fRmax by shape.meta.double(0.0)
|
||||||
val fDz by shape.meta.double(0.0)
|
val fDz by shape.meta.double(0.0)
|
||||||
@ -134,6 +143,7 @@ private fun SolidGroup.addShape(
|
|||||||
block = block
|
block = block
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoTubeSeg" -> {
|
"TGeoTubeSeg" -> {
|
||||||
val fRmax by shape.meta.double(0.0)
|
val fRmax by shape.meta.double(0.0)
|
||||||
val fDz by shape.meta.double(0.0)
|
val fDz by shape.meta.double(0.0)
|
||||||
@ -151,6 +161,7 @@ private fun SolidGroup.addShape(
|
|||||||
block = block
|
block = block
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoPcon" -> {
|
"TGeoPcon" -> {
|
||||||
val fDphi by shape.meta.double(0.0)
|
val fDphi by shape.meta.double(0.0)
|
||||||
val fNz by shape.meta.int(2)
|
val fNz by shape.meta.int(2)
|
||||||
@ -170,14 +181,14 @@ 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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoPgon" -> {
|
"TGeoPgon" -> {
|
||||||
//TODO add a inner polygone layer
|
|
||||||
val fDphi by shape.meta.double(0.0)
|
val fDphi by shape.meta.double(0.0)
|
||||||
val fNz by shape.meta.int(2)
|
val fNz by shape.meta.int(2)
|
||||||
val fPhi1 by shape.meta.double(360.0)
|
val fPhi1 by shape.meta.double(360.0)
|
||||||
@ -190,31 +201,41 @@ private fun SolidGroup.addShape(
|
|||||||
val startphi = degToRad(fPhi1)
|
val startphi = degToRad(fPhi1)
|
||||||
val deltaphi = degToRad(fDphi)
|
val deltaphi = degToRad(fDphi)
|
||||||
|
|
||||||
extruded(name) {
|
fun Shape2DBuilder.pGon(radius: Double){
|
||||||
|
(0..<fNedges).forEach {
|
||||||
|
val phi = deltaphi / fNedges * it + startphi
|
||||||
|
point(radius * cos(phi), radius * sin(phi))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
surface(name) {
|
||||||
//getting the radius of first
|
//getting the radius of first
|
||||||
require(fNz > 1) { "The polyhedron geometry requires at least two planes" }
|
require(fNz > 1) { "The polyhedron geometry requires at least two planes" }
|
||||||
val baseRadius = fRmax[0]
|
for (index in 0 until fNz){
|
||||||
shape {
|
layer(
|
||||||
(0..fNedges).forEach {
|
fZ[index],
|
||||||
val phi = deltaphi * fNedges * it + startphi
|
innerBuilder = {
|
||||||
(baseRadius * cos(phi) to baseRadius * sin(phi))
|
pGon(fRmin[index])
|
||||||
}
|
},
|
||||||
}
|
outerBuilder = {
|
||||||
(0 until fNz).forEach { index ->
|
pGon(fRmax[index])
|
||||||
//scaling all radii relative to first layer radius
|
}
|
||||||
layer(fZ[index], scale = fRmax[index] / baseRadius)
|
)
|
||||||
}
|
}
|
||||||
}.apply(block)
|
}.apply(block)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoShapeAssembly" -> {
|
"TGeoShapeAssembly" -> {
|
||||||
val fVolume by shape.dObject(::DGeoVolume)
|
val fVolume by shape.dObject(::DGeoVolume)
|
||||||
fVolume?.let { volume ->
|
fVolume?.let { volume ->
|
||||||
addRootVolume(volume, context, block = block)
|
addRootVolume(volume, context, name = volume.fName.ifEmpty { null }, block = block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoBBox" -> {
|
"TGeoBBox" -> {
|
||||||
box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name, block = block)
|
box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name, block = block)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoTrap" -> {
|
"TGeoTrap" -> {
|
||||||
val fTheta by shape.meta.double(0.0)
|
val fTheta by shape.meta.double(0.0)
|
||||||
val fPhi 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)
|
val fDz by shape.meta.double(0.0)
|
||||||
//TODO check proper node order
|
//TODO check proper node order
|
||||||
val node1 = Point3D(-fBl1, -fH1, -fDz)
|
val node1 = Float32Vector3D(-fBl1, -fH1, -fDz)
|
||||||
val node2 = Point3D(fBl1, -fH1, -fDz)
|
val node2 = Float32Vector3D(fBl1, -fH1, -fDz)
|
||||||
val node3 = Point3D(fTl1, fH1, -fDz)
|
val node3 = Float32Vector3D(fTl1, fH1, -fDz)
|
||||||
val node4 = Point3D(-fTl1, fH1, -fDz)
|
val node4 = Float32Vector3D(-fTl1, fH1, -fDz)
|
||||||
val node5 = Point3D(-fBl2, -fH2, fDz)
|
val node5 = Float32Vector3D(-fBl2, -fH2, fDz)
|
||||||
val node6 = Point3D(fBl2, -fH2, fDz)
|
val node6 = Float32Vector3D(fBl2, -fH2, fDz)
|
||||||
val node7 = Point3D(fTl2, fH2, fDz)
|
val node7 = Float32Vector3D(fTl2, fH2, fDz)
|
||||||
val node8 = Point3D(-fTl2, fH2, fDz)
|
val node8 = Float32Vector3D(-fTl2, fH2, fDz)
|
||||||
hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name)
|
hexagon(node1, node2, node3, node4, node5, node6, node7, node8, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoScaledShape" -> {
|
"TGeoScaledShape" -> {
|
||||||
val fShape by shape.dObject(::DGeoShape)
|
val fShape by shape.dObject(::DGeoShape)
|
||||||
val fScale by shape.dObject(::DGeoScale)
|
val fScale by shape.dObject(::DGeoScale)
|
||||||
fShape?.let { scaledShape ->
|
fShape?.let { scaledShape ->
|
||||||
group(name?.let { Name.parse(it) }) {
|
solidGroup(name?.let { Name.parse(it) }) {
|
||||||
scale = Point3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0)
|
scale = Float32Vector3D(fScale?.x ?: 1.0, fScale?.y ?: 1.0, fScale?.z ?: 1.0)
|
||||||
addShape(scaledShape, context)
|
addShape(scaledShape, context)
|
||||||
apply(block)
|
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 -> {
|
else -> {
|
||||||
TODO("A shape with type ${shape.typename} not implemented")
|
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) {
|
addRootVolume(volume, context, obj.fName) {
|
||||||
when (obj.typename) {
|
when (obj.typename) {
|
||||||
"TGeoNodeMatrix" -> {
|
"TGeoNodeMatrix" -> {
|
||||||
val fMatrix by obj.dObject(::DGeoMatrix)
|
val fMatrix by obj.dObject(::dGeoMatrix)
|
||||||
this.useMatrix(fMatrix)
|
this.useMatrix(fMatrix)
|
||||||
}
|
}
|
||||||
|
|
||||||
"TGeoNodeOffset" -> {
|
"TGeoNodeOffset" -> {
|
||||||
val fOffset by obj.meta.double(0.0)
|
val fOffset by obj.meta.double(0.0)
|
||||||
x = fOffset
|
x = fOffset
|
||||||
@ -276,12 +338,12 @@ private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? {
|
private fun buildVolume(volume: DGeoVolume, context: RootToSolidContext): Solid? {
|
||||||
val group = SolidGroup {
|
val group = SolidGroup().apply {
|
||||||
//set current layer
|
//set current layer
|
||||||
layer = context.currentLayer
|
layer = context.currentLayer
|
||||||
val nodes = volume.fNodes
|
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
|
//TODO add smart filter
|
||||||
volume.fShape?.let { shape ->
|
volume.fShape?.let { shape ->
|
||||||
addShape(shape, context)
|
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
|
null
|
||||||
} else if (group.children.size == 1 && group.meta.isEmpty()) {
|
} else if (group.items.size == 1 && group.properties.own == null) {
|
||||||
(group.children.values.first() as Solid).apply { parent = null }
|
group.items.values.first().apply { parent = null }
|
||||||
} else {
|
} else {
|
||||||
group
|
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,
|
context: RootToSolidContext,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
cache: Boolean = true,
|
cache: Boolean = true,
|
||||||
block: Solid.() -> Unit = {}
|
block: Solid.() -> Unit = {},
|
||||||
) {
|
) {
|
||||||
val combinedName = if (volume.fName.isEmpty()) {
|
val combinedName = name?.parseAsName()?.let {
|
||||||
name
|
// this fix is required to work around malformed root files with duplicated node names
|
||||||
} else if (name == null) {
|
if (get(it) != null) {
|
||||||
volume.fName
|
it.withIndex(volume.hashCode().toString(16))
|
||||||
} else {
|
} else {
|
||||||
"${name}_${volume.fName}"
|
it
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cache) {
|
if (!cache) {
|
||||||
val group = buildVolume(volume, context)?.apply {
|
val group = buildVolume(volume, context)?.apply(block) ?: return
|
||||||
volume.fFillColor?.let {
|
setChild(combinedName, group)
|
||||||
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
|
||||||
}
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
set(combinedName?.let { Name.parse(it) }, group)
|
|
||||||
} else {
|
} else {
|
||||||
val templateName = volumesName + volume.name
|
val templateName = volumesName + volume.name
|
||||||
val existing = getPrototype(templateName)
|
val existing = context.prototypeHolder.getPrototype(templateName)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
context.prototypeHolder.prototypes {
|
context.prototypeHolder.prototypes {
|
||||||
val group = buildVolume(volume, context)
|
val group = buildVolume(volume, context) ?: return@prototypes
|
||||||
set(templateName, group)
|
setChild(templateName, group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref(templateName, name).apply {
|
ref(templateName, combinedName).apply(block)
|
||||||
volume.fFillColor?.let {
|
|
||||||
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
|
||||||
}
|
|
||||||
block()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public fun DGeoManager.toSolid(): SolidGroup = SolidGroup {
|
public fun MutableVisionContainer<Solid>.rootGeo(
|
||||||
val context = RootToSolidContext(this)
|
dGeoManager: DGeoManager,
|
||||||
fNodes.forEach { node ->
|
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)
|
addRootNode(node, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -1,7 +1,7 @@
|
|||||||
package ru.mipt.npm.root
|
package ru.mipt.npm.root
|
||||||
|
|
||||||
public object RootColors {
|
public object RootColors {
|
||||||
private val colorMap = Array<String>(924) { "white" }
|
private val colorMap = MutableList(924) { "white" }
|
||||||
|
|
||||||
//colorMap[110] = "white"
|
//colorMap[110] = "white"
|
||||||
|
|
||||||
|
@ -12,9 +12,10 @@ import kotlinx.serialization.modules.polymorphic
|
|||||||
import kotlinx.serialization.modules.subclass
|
import kotlinx.serialization.modules.subclass
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("UNUSED_PARAMETER")
|
||||||
private fun <T> jsonRootDeserializer(
|
private fun <T> jsonRootDeserializer(
|
||||||
tSerializer: KSerializer<T>,
|
tSerializer: KSerializer<T>,
|
||||||
builder: (JsonElement) -> T
|
builder: (JsonElement) -> T,
|
||||||
): DeserializationStrategy<T> = object :
|
): DeserializationStrategy<T> = object :
|
||||||
DeserializationStrategy<T> {
|
DeserializationStrategy<T> {
|
||||||
private val jsonElementSerializer = JsonElement.serializer()
|
private val jsonElementSerializer = JsonElement.serializer()
|
||||||
@ -46,6 +47,7 @@ private object RootDecoder {
|
|||||||
private val refCache: List<RefEntry>,
|
private val refCache: List<RefEntry>,
|
||||||
) : KSerializer<T> by tSerializer {
|
) : KSerializer<T> by tSerializer {
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
override fun deserialize(decoder: Decoder): T {
|
override fun deserialize(decoder: Decoder): T {
|
||||||
val input = decoder as JsonDecoder
|
val input = decoder as JsonDecoder
|
||||||
@ -82,7 +84,7 @@ private object RootDecoder {
|
|||||||
|
|
||||||
return ref.getOrPutValue {
|
return ref.getOrPutValue {
|
||||||
// println("Decoding $it")
|
// println("Decoding $it")
|
||||||
val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content
|
// val actualTypeName = it.jsonObject["_typename"]?.jsonPrimitive?.content
|
||||||
input.json.decodeFromJsonElement(tSerializer, it)
|
input.json.decodeFromJsonElement(tSerializer, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -90,9 +92,8 @@ private object RootDecoder {
|
|||||||
|
|
||||||
private fun <T> KSerializer<T>.unref(refCache: List<RefEntry>): KSerializer<T> = RootUnrefSerializer(this, refCache)
|
private fun <T> KSerializer<T>.unref(refCache: List<RefEntry>): KSerializer<T> = RootUnrefSerializer(this, refCache)
|
||||||
|
|
||||||
@OptIn(ExperimentalSerializationApi::class)
|
|
||||||
fun unrefSerializersModule(
|
fun unrefSerializersModule(
|
||||||
refCache: List<RefEntry>
|
refCache: List<RefEntry>,
|
||||||
): SerializersModule = SerializersModule {
|
): SerializersModule = SerializersModule {
|
||||||
|
|
||||||
contextual(TObjArray::class) {
|
contextual(TObjArray::class) {
|
||||||
@ -118,7 +119,7 @@ private object RootDecoder {
|
|||||||
subclass(TGeoCompositeShape.serializer().unref(refCache))
|
subclass(TGeoCompositeShape.serializer().unref(refCache))
|
||||||
subclass(TGeoShapeAssembly.serializer().unref(refCache))
|
subclass(TGeoShapeAssembly.serializer().unref(refCache))
|
||||||
|
|
||||||
default {
|
defaultDeserializer {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
TGeoShape.serializer().unref(refCache)
|
TGeoShape.serializer().unref(refCache)
|
||||||
} else {
|
} else {
|
||||||
@ -136,7 +137,7 @@ private object RootDecoder {
|
|||||||
|
|
||||||
|
|
||||||
val unrefed = TGeoMatrix.serializer().unref(refCache)
|
val unrefed = TGeoMatrix.serializer().unref(refCache)
|
||||||
default {
|
defaultDeserializer {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
unrefed
|
unrefed
|
||||||
} else {
|
} else {
|
||||||
@ -149,7 +150,7 @@ private object RootDecoder {
|
|||||||
subclass(TGeoVolumeAssembly.serializer().unref(refCache))
|
subclass(TGeoVolumeAssembly.serializer().unref(refCache))
|
||||||
|
|
||||||
val unrefed = TGeoVolume.serializer().unref(refCache)
|
val unrefed = TGeoVolume.serializer().unref(refCache)
|
||||||
default {
|
defaultDeserializer {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
unrefed
|
unrefed
|
||||||
} else {
|
} else {
|
||||||
@ -163,7 +164,7 @@ private object RootDecoder {
|
|||||||
subclass(TGeoNodeOffset.serializer().unref(refCache))
|
subclass(TGeoNodeOffset.serializer().unref(refCache))
|
||||||
|
|
||||||
val unrefed = TGeoNode.serializer().unref(refCache)
|
val unrefed = TGeoNode.serializer().unref(refCache)
|
||||||
default {
|
defaultDeserializer {
|
||||||
if (it == null) {
|
if (it == null) {
|
||||||
unrefed
|
unrefed
|
||||||
} else {
|
} else {
|
||||||
@ -197,11 +198,13 @@ private object RootDecoder {
|
|||||||
fillCache(it)
|
fillCache(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
is JsonArray -> {
|
is JsonArray -> {
|
||||||
element.forEach {
|
element.forEach {
|
||||||
fillCache(it)
|
fillCache(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
else -> {
|
else -> {
|
||||||
//ignore primitives
|
//ignore primitives
|
||||||
}
|
}
|
||||||
@ -216,6 +219,7 @@ private object RootDecoder {
|
|||||||
|
|
||||||
var value: Any? = null
|
var value: Any? = null
|
||||||
|
|
||||||
|
@Suppress("UNCHECKED_CAST")
|
||||||
fun <T> getOrPutValue(builder: (JsonElement) -> T): T {
|
fun <T> getOrPutValue(builder: (JsonElement) -> T): T {
|
||||||
if (value == null) {
|
if (value == null) {
|
||||||
value = builder(element)
|
value = builder(element)
|
||||||
|
@ -3,6 +3,7 @@ package ru.mipt.npm.root.serialization
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
import kotlin.math.atan2
|
import kotlin.math.atan2
|
||||||
@ -24,12 +25,12 @@ private fun Solid.rotate(rot: DoubleArray) {
|
|||||||
val xAngle = atan2(-rot[5], rot[8])
|
val xAngle = atan2(-rot[5], rot[8])
|
||||||
val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2)))
|
val yAngle = atan2(rot[2], sqrt(1.0 - rot[2].pow(2)))
|
||||||
val zAngle = atan2(-rot[1], rot[0])
|
val zAngle = atan2(-rot[1], rot[0])
|
||||||
rotation = Point3D(xAngle, yAngle, zAngle)
|
rotation = Float32Vector3D(xAngle, yAngle, zAngle)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Solid.translate(trans: DoubleArray) {
|
private fun Solid.translate(trans: DoubleArray) {
|
||||||
val (x, y, z) = trans
|
val (x, y, z) = trans
|
||||||
position = Point3D(x, y, z)
|
position = Float32Vector3D(x, y, z)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun Solid.useMatrix(matrix: TGeoMatrix?) {
|
private fun Solid.useMatrix(matrix: TGeoMatrix?) {
|
||||||
@ -51,7 +52,7 @@ private fun Solid.useMatrix(matrix: TGeoMatrix?) {
|
|||||||
translate(matrix.fTranslation)
|
translate(matrix.fTranslation)
|
||||||
rotate(matrix.fRotationMatrix)
|
rotate(matrix.fRotationMatrix)
|
||||||
val (xScale, yScale, zScale) = matrix.fScale
|
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) {
|
return if (volume is TGeoVolumeAssemblyRef) {
|
||||||
buildGroup(volume.value)
|
buildGroup(volume.value)
|
||||||
} else {
|
} else {
|
||||||
SolidGroup {
|
SolidGroup().apply {
|
||||||
volume.fShape?.let { addShape(it) }
|
volume.fShape?.let { addShape(it) }
|
||||||
volume.fNodes?.let {
|
volume.fNodes?.let {
|
||||||
it.arr.forEach { obj ->
|
it.arr.forEach { obj ->
|
||||||
@ -160,7 +161,7 @@ private fun SolidGroup.volume(volume: TGeoVolume, name: String? = null, cache: B
|
|||||||
name = combinedName,
|
name = combinedName,
|
||||||
obj = group,
|
obj = group,
|
||||||
prototypeHolder = rootPrototypes,
|
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 {
|
public fun MutableVisionContainer<Solid>.rootGeo(tGeoManager: TGeoManager): SolidGroup = solidGroup {
|
||||||
fNodes.arr.forEach {
|
tGeoManager.fNodes.arr.forEach {
|
||||||
node(it)
|
node(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
11
demo/build.gradle.kts
Normal file
11
demo/build.gradle.kts
Normal file
@ -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<KotlinPluginWrapper> {
|
||||||
|
configure<KotlinProjectExtension> {
|
||||||
|
explicitApi = ExplicitApiMode.Disabled
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,60 +1,68 @@
|
|||||||
import ru.mipt.npm.gradle.DependencyConfiguration
|
|
||||||
import ru.mipt.npm.gradle.FXModule
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
application
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
group = "demo"
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
val fxVersion: String by rootProject.extra
|
jvm()
|
||||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
|
||||||
application()
|
|
||||||
}
|
|
||||||
|
|
||||||
kotlin {
|
|
||||||
jvm {
|
|
||||||
withJava()
|
|
||||||
}
|
|
||||||
|
|
||||||
js {
|
js {
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
browser {
|
browser {
|
||||||
|
binaries.executable()
|
||||||
commonWebpackConfig {
|
commonWebpackConfig {
|
||||||
cssSupport.enabled = false
|
cssSupport {
|
||||||
|
enabled.set(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
dependencies {
|
||||||
sourceSets {
|
implementation(projects.visionforgeSolid)
|
||||||
commonMain {
|
implementation(projects.visionforgeGdml)
|
||||||
dependencies {
|
}
|
||||||
implementation(project(":visionforge-solid"))
|
jvmMain {
|
||||||
implementation(project(":visionforge-gdml"))
|
// implementation(project(":visionforge-fx"))
|
||||||
}
|
implementation(spclibs.logback.classic)
|
||||||
}
|
}
|
||||||
jvmMain {
|
jsMain {
|
||||||
dependencies {
|
implementation(projects.ui.ring)
|
||||||
implementation(project(":visionforge-fx"))
|
implementation(projects.visionforgeThreejs)
|
||||||
implementation("ch.qos.logback:logback-classic:1.2.5")
|
implementation(npm("react-file-drop", "3.0.6"))
|
||||||
}
|
|
||||||
}
|
|
||||||
jsMain {
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":ui:ring"))
|
|
||||||
implementation(project(":visionforge-threejs"))
|
|
||||||
implementation(npm("react-file-drop", "3.0.6"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
kotlin {
|
||||||
mainClass.set("space.kscience.visionforge.gdml.demo.GdmlFxDemoAppKt")
|
explicitApi = null
|
||||||
}
|
}
|
||||||
|
|
||||||
val convertGdmlToJson by tasks.creating(JavaExec::class) {
|
//kotlin {
|
||||||
group = "application"
|
//
|
||||||
classpath = sourceSets["main"].runtimeClasspath
|
// sourceSets {
|
||||||
mainClass.set("space.kscience.dataforge.vis.spatial.gdml.demo.SaveToJsonKt")
|
// 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")
|
||||||
|
//}
|
@ -1,13 +1,11 @@
|
|||||||
package space.kscience.visionforge.gdml
|
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.names.Name
|
||||||
import space.kscience.dataforge.values.asValue
|
|
||||||
import space.kscience.dataforge.values.string
|
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.computeProperties
|
import space.kscience.visionforge.getChild
|
||||||
import space.kscience.visionforge.get
|
|
||||||
import space.kscience.visionforge.setProperty
|
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import space.kscience.visionforge.solid.material
|
import space.kscience.visionforge.solid.material
|
||||||
@ -20,8 +18,8 @@ class GDMLVisionTest {
|
|||||||
|
|
||||||
@Test
|
@Test
|
||||||
fun testCubesStyles(){
|
fun testCubesStyles(){
|
||||||
val segment = cubes["composite-000.segment-0"] as Solid
|
val segment = cubes.children.getChild("composite-000.segment-0") as Solid
|
||||||
println(segment.computeProperties().getValue(Vision.STYLE_KEY))
|
println(segment.properties.getValue(Vision.STYLE_KEY))
|
||||||
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
// println(segment.computePropertyNode(SolidMaterial.MATERIAL_KEY))
|
||||||
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
// println(segment.computeProperty(SolidMaterial.MATERIAL_COLOR_KEY))
|
||||||
|
|
||||||
@ -35,7 +33,7 @@ class GDMLVisionTest {
|
|||||||
fun testPrototypeProperty() {
|
fun testPrototypeProperty() {
|
||||||
val child = cubes[Name.of("composite-000","segment-0")]
|
val child = cubes[Name.of("composite-000","segment-0")]
|
||||||
assertNotNull(child)
|
assertNotNull(child)
|
||||||
child.setProperty(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
child.properties.setValue(SolidMaterial.MATERIAL_COLOR_KEY, "red".asValue())
|
||||||
assertEquals("red", child.getPropertyValue(SolidMaterial.MATERIAL_COLOR_KEY)?.string)
|
assertEquals("red", child.properties[SolidMaterial.MATERIAL_COLOR_KEY].string)
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -9,30 +9,38 @@ import react.Component
|
|||||||
import react.Props
|
import react.Props
|
||||||
import react.State
|
import react.State
|
||||||
|
|
||||||
external enum class DropEffects {
|
sealed external class DropEffects {
|
||||||
copy,
|
@JsName("copy")
|
||||||
move,
|
object Copy : DropEffects
|
||||||
link,
|
|
||||||
none
|
@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 className: String?
|
||||||
var targetClassName: String?
|
var targetClassName: String?
|
||||||
var draggingOverFrameClassName: String?
|
var draggingOverFrameClassName: String?
|
||||||
var draggingOverTargetClassName: String?
|
var draggingOverTargetClassName: String?
|
||||||
|
|
||||||
// var frame?: Exclude<HTMLElementTagNameMap[keyof HTMLElementTagNameMap], HTMLElement> | HTMLDocument;
|
// var frame?: Exclude<HTMLElementTagNameMap[keyof HTMLElementTagNameMap], HTMLElement> | HTMLDocument;
|
||||||
var onFrameDragEnter: ((event: DragEvent) -> Unit)?
|
var onFrameDragEnter: ((event: DragEvent) -> Unit)?
|
||||||
var onFrameDragLeave: ((event: DragEvent) -> Unit)?
|
var onFrameDragLeave: ((event: DragEvent) -> Unit)?
|
||||||
var onFrameDrop: ((event: DragEvent) -> Unit)?
|
var onFrameDrop: ((event: DragEvent) -> Unit)?
|
||||||
// var onDragOver: ReactDragEventHandler<HTMLDivElement>?
|
|
||||||
|
// var onDragOver: ReactDragEventHandler<HTMLDivElement>?
|
||||||
// var onDragLeave: ReactDragEventHandler<HTMLDivElement>?
|
// var onDragLeave: ReactDragEventHandler<HTMLDivElement>?
|
||||||
var onDrop: ((files: FileList?, event: dynamic) -> Unit)?//event:DragEvent<HTMLDivElement>)
|
var onDrop: ((files: FileList?, event: dynamic) -> Unit)?//event:DragEvent<HTMLDivElement>)
|
||||||
var dropEffect: DropEffects?
|
var dropEffect: DropEffects?
|
||||||
}
|
}
|
||||||
|
|
||||||
external interface FileDropState: State {
|
external interface FileDropState : State {
|
||||||
var draggingOverFrame: Boolean
|
var draggingOverFrame: Boolean
|
||||||
var draggingOverTarget: Boolean
|
var draggingOverTarget: Boolean
|
||||||
}
|
}
|
||||||
|
@ -10,13 +10,11 @@ import org.w3c.files.get
|
|||||||
import react.Props
|
import react.Props
|
||||||
import react.dom.h2
|
import react.dom.h2
|
||||||
import react.fc
|
import react.fc
|
||||||
import react.useMemo
|
|
||||||
import react.useState
|
import react.useState
|
||||||
import space.kscience.dataforge.context.Context
|
|
||||||
import space.kscience.dataforge.context.fetch
|
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.gdml.Gdml
|
import space.kscience.gdml.Gdml
|
||||||
import space.kscience.gdml.decodeFromString
|
import space.kscience.gdml.decodeFromString
|
||||||
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.gdml.markLayers
|
import space.kscience.visionforge.gdml.markLayers
|
||||||
import space.kscience.visionforge.gdml.toVision
|
import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
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.setAsRoot
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
import space.kscience.visionforge.solid.ambientLight
|
||||||
|
import space.kscience.visionforge.solid.invoke
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
|
|
||||||
external interface GDMLAppProps : Props {
|
external interface GDMLAppProps : Props {
|
||||||
var context: Context
|
var solids: Solids
|
||||||
var vision: Solid?
|
var vision: Solid?
|
||||||
var selected: Name?
|
var selected: Name?
|
||||||
}
|
}
|
||||||
|
|
||||||
@JsExport
|
@JsExport
|
||||||
val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
||||||
val visionManager = useMemo(props.context) { props.context.fetch(Solids).visionManager }
|
|
||||||
var deferredVision: Deferred<Solid?> by useState {
|
var deferredVision: Deferred<Solid?> by useState {
|
||||||
CompletableDeferred(props.vision)
|
CompletableDeferred(props.vision)
|
||||||
}
|
}
|
||||||
@ -50,12 +49,15 @@ val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
name.endsWith(".gdml") || name.endsWith(".xml") -> {
|
||||||
val gdml = Gdml.decodeFromString(data)
|
val gdml = Gdml.decodeFromString(data)
|
||||||
gdml.toVision().apply {
|
gdml.toVision().apply {
|
||||||
setAsRoot(visionManager)
|
setAsRoot(props.solids.visionManager)
|
||||||
console.info("Marking layers for file $name")
|
console.info("Marking layers for file $name")
|
||||||
markLayers()
|
markLayers()
|
||||||
|
ambientLight {
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
name.endsWith(".json") -> visionManager.decodeFromString(data)
|
name.endsWith(".json") -> props.solids.visionManager.decodeFromString(data)
|
||||||
else -> {
|
else -> {
|
||||||
window.alert("File extension is not recognized: $name")
|
window.alert("File extension is not recognized: $name")
|
||||||
error("File extension is not recognized: $name")
|
error("File extension is not recognized: $name")
|
||||||
@ -76,7 +78,7 @@ val GDMLApp = fc<GDMLAppProps>("GDMLApp") { props ->
|
|||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
attrs {
|
attrs {
|
||||||
this.context = props.context
|
this.solids = props.solids
|
||||||
this.builderOfSolid = deferredVision
|
this.builderOfSolid = deferredVision
|
||||||
this.selected = props.selected
|
this.selected = props.selected
|
||||||
tab("Load") {
|
tab("Load") {
|
||||||
|
@ -1,12 +1,18 @@
|
|||||||
package space.kscience.visionforge.gdml.demo
|
package space.kscience.visionforge.gdml.demo
|
||||||
|
|
||||||
import kotlinx.browser.document
|
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import react.dom.render
|
import org.w3c.dom.Document
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.gdml.GdmlShowCase
|
import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.gdml.toVision
|
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.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
import styled.injectGlobal
|
import styled.injectGlobal
|
||||||
@ -14,7 +20,7 @@ import styled.injectGlobal
|
|||||||
|
|
||||||
private class GDMLDemoApp : Application {
|
private class GDMLDemoApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
val context = Context("gdml-demo"){
|
val context = Context("gdml-demo"){
|
||||||
plugin(ThreePlugin)
|
plugin(ThreePlugin)
|
||||||
}
|
}
|
||||||
@ -39,12 +45,16 @@ private class GDMLDemoApp : Application {
|
|||||||
|
|
||||||
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
|
val element = document.getElementById("application") ?: error("Element with id 'application' not found on page")
|
||||||
|
|
||||||
render(element) {
|
createRoot(element).render {
|
||||||
child(GDMLApp) {
|
child(GDMLApp) {
|
||||||
val vision = GdmlShowCase.cubes().toVision()
|
val vision = GdmlShowCase.cubes().toVision().apply {
|
||||||
|
ambientLight {
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
|
}
|
||||||
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
//println(context.plugins.fetch(VisionManager).encodeToString(vision))
|
||||||
attrs {
|
attrs {
|
||||||
this.context = context
|
this.solids = context.request(Solids)
|
||||||
this.vision = vision
|
this.vision = vision
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,7 +2,6 @@ package space.kscience.visionforge.gdml.demo
|
|||||||
|
|
||||||
import drop.FileDrop
|
import drop.FileDrop
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.css.properties.border
|
|
||||||
import org.w3c.files.FileList
|
import org.w3c.files.FileList
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
import styled.css
|
import styled.css
|
||||||
@ -13,7 +12,7 @@ import styled.styledDiv
|
|||||||
fun RBuilder.fileDrop(title: String, action: (files: FileList?) -> Unit) {
|
fun RBuilder.fileDrop(title: String, action: (files: FileList?) -> Unit) {
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
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
|
flexGrow = 0.0
|
||||||
alignContent = Align.center
|
alignContent = Align.center
|
||||||
}
|
}
|
||||||
|
@ -1,83 +1,83 @@
|
|||||||
package space.kscience.visionforge.gdml.demo
|
//package space.kscience.visionforge.gdml.demo
|
||||||
|
//
|
||||||
import javafx.geometry.Orientation
|
//import javafx.geometry.Orientation
|
||||||
import javafx.scene.Parent
|
//import javafx.scene.Parent
|
||||||
import javafx.stage.FileChooser
|
//import javafx.stage.FileChooser
|
||||||
import space.kscience.dataforge.context.Context
|
//import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.fetch
|
//import space.kscience.dataforge.context.fetch
|
||||||
import space.kscience.gdml.GdmlShowCase
|
//import space.kscience.gdml.GdmlShowCase
|
||||||
import space.kscience.visionforge.VisionManager
|
//import space.kscience.visionforge.VisionManager
|
||||||
import space.kscience.visionforge.editor.VisionEditorFragment
|
//import space.kscience.visionforge.editor.VisionEditorFragment
|
||||||
import space.kscience.visionforge.editor.VisionTreeFragment
|
//import space.kscience.visionforge.editor.VisionTreeFragment
|
||||||
import space.kscience.visionforge.gdml.toVision
|
//import space.kscience.visionforge.gdml.toVision
|
||||||
import space.kscience.visionforge.solid.FX3DPlugin
|
//import space.kscience.visionforge.solid.FX3DPlugin
|
||||||
import space.kscience.visionforge.solid.FXCanvas3D
|
//import space.kscience.visionforge.solid.FXCanvas3D
|
||||||
import space.kscience.visionforge.solid.Solid
|
//import space.kscience.visionforge.solid.Solid
|
||||||
import space.kscience.visionforge.solid.SolidMaterial
|
//import space.kscience.visionforge.solid.SolidMaterial
|
||||||
import tornadofx.*
|
//import tornadofx.*
|
||||||
|
//
|
||||||
class GDMLDemoApp : App(GDMLView::class)
|
//class GDMLDemoApp : App(GDMLView::class)
|
||||||
|
//
|
||||||
class GDMLView : View() {
|
//class GDMLView : View() {
|
||||||
private val context = Context {
|
// private val context = Context {
|
||||||
plugin(FX3DPlugin)
|
// plugin(FX3DPlugin)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private val fx3d = context.fetch(FX3DPlugin)
|
// private val fx3d = context.fetch(FX3DPlugin)
|
||||||
private val visionManager = context.fetch(VisionManager)
|
// private val visionManager = context.fetch(VisionManager)
|
||||||
private val canvas = FXCanvas3D(fx3d)
|
// private val canvas = FXCanvas3D(fx3d)
|
||||||
|
//
|
||||||
private val treeFragment = VisionTreeFragment().apply {
|
// private val treeFragment = VisionTreeFragment().apply {
|
||||||
this.itemProperty.bind(canvas.rootObjectProperty)
|
// this.itemProperty.bind(canvas.rootObjectProperty)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
private val propertyEditor = VisionEditorFragment().apply {
|
// private val propertyEditor = VisionEditorFragment().apply {
|
||||||
descriptorProperty.set(SolidMaterial.descriptor)
|
// descriptorProperty.set(SolidMaterial.descriptor)
|
||||||
visionProperty.bind(treeFragment.selectedProperty)
|
// visionProperty.bind(treeFragment.selectedProperty)
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
override val root: Parent = borderpane {
|
// override val root: Parent = borderpane {
|
||||||
top {
|
// top {
|
||||||
buttonbar {
|
// buttonbar {
|
||||||
button("Load GDML/json") {
|
// button("Load GDML/json") {
|
||||||
action {
|
// action {
|
||||||
val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull()
|
// val file = chooseFile("Select a GDML/json file", filters = fileNameFilter).firstOrNull()
|
||||||
if (file != null) {
|
// if (file != null) {
|
||||||
runAsync {
|
// runAsync {
|
||||||
visionManager.readFile(file) as Solid
|
// visionManager.readFile(file) as Solid
|
||||||
} ui {
|
// } ui {
|
||||||
canvas.render(it)
|
// canvas.render(it)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
center {
|
// center {
|
||||||
splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) {
|
// splitpane(Orientation.HORIZONTAL, treeFragment.root, canvas.root, propertyEditor.root) {
|
||||||
setDividerPositions(0.2, 0.6, 0.2)
|
// setDividerPositions(0.2, 0.6, 0.2)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
init {
|
// init {
|
||||||
runAsync {
|
// runAsync {
|
||||||
GdmlShowCase.cubes().toVision()
|
// GdmlShowCase.cubes().toVision()
|
||||||
} ui {
|
// } ui {
|
||||||
canvas.render(it)
|
// canvas.render(it)
|
||||||
}
|
// }
|
||||||
}
|
// }
|
||||||
|
//
|
||||||
companion object {
|
// companion object {
|
||||||
private val fileNameFilter = arrayOf(
|
// private val fileNameFilter = arrayOf(
|
||||||
FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"),
|
// FileChooser.ExtensionFilter("GDML", "*.gdml", "*.xml"),
|
||||||
FileChooser.ExtensionFilter("JSON", "*.json"),
|
// FileChooser.ExtensionFilter("JSON", "*.json"),
|
||||||
FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"),
|
// FileChooser.ExtensionFilter("JSON.ZIP", "*.json.zip"),
|
||||||
FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz")
|
// FileChooser.ExtensionFilter("JSON.GZ", "*.json.gz")
|
||||||
)
|
// )
|
||||||
}
|
// }
|
||||||
}
|
//}
|
||||||
|
//
|
||||||
fun main() {
|
//fun main() {
|
||||||
launch<GDMLDemoApp>()
|
// launch<GDMLDemoApp>()
|
||||||
}
|
//}
|
@ -1,28 +1,35 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.js")
|
id("space.kscience.gradle.mpp")
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience{
|
kscience {
|
||||||
useCoroutines()
|
useCoroutines()
|
||||||
application()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
kotlin{
|
kotlin {
|
||||||
js(IR){
|
explicitApi = null
|
||||||
|
js {
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
browser {
|
browser {
|
||||||
|
binaries.executable()
|
||||||
commonWebpackConfig {
|
commonWebpackConfig {
|
||||||
cssSupport.enabled = false
|
cssSupport {
|
||||||
|
enabled.set(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kscience {
|
||||||
|
|
||||||
dependencies{
|
dependencies {
|
||||||
implementation(projects.visionforge.visionforgeGdml)
|
implementation(projects.visionforge.visionforgeGdml)
|
||||||
implementation(projects.visionforge.visionforgePlotly)
|
implementation(projects.visionforge.visionforgePlotly)
|
||||||
implementation(projects.visionforge.visionforgeMarkdown)
|
implementation(projects.visionforge.visionforgeMarkdown)
|
||||||
implementation(projects.visionforge.visionforgeThreejs)
|
implementation(projects.visionforge.visionforgeThreejs)
|
||||||
implementation(projects.ui.ring)
|
}
|
||||||
|
jsMain {
|
||||||
|
implementation(projects.ui.ring)
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,15 +1,17 @@
|
|||||||
import kotlinx.browser.document
|
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import react.child
|
import org.w3c.dom.Document
|
||||||
import react.dom.render
|
|
||||||
import ringui.SmartTabs
|
import ringui.SmartTabs
|
||||||
import ringui.Tab
|
import ringui.Tab
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
|
import space.kscience.dataforge.context.request
|
||||||
import space.kscience.plotly.models.Trace
|
import space.kscience.plotly.models.Trace
|
||||||
import space.kscience.plotly.scatter
|
import space.kscience.plotly.scatter
|
||||||
import space.kscience.visionforge.Application
|
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.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.ThreeCanvasWithControls
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||||
import space.kscience.visionforge.ring.solid
|
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 {
|
private class JsPlaygroundApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
|
|
||||||
val playgroundContext = Context {
|
val playgroundContext = Context {
|
||||||
plugin(ThreeWithControlsPlugin)
|
plugin(ThreeWithControlsPlugin)
|
||||||
plugin(VisionClient)
|
plugin(JsVisionClient)
|
||||||
plugin(PlotlyPlugin)
|
plugin(PlotlyPlugin)
|
||||||
}
|
}
|
||||||
|
|
||||||
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
|
val element = document.getElementById("playground") ?: error("Element with id 'playground' not found on page")
|
||||||
|
|
||||||
render(element) {
|
createRoot(element).render {
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
padding(0.pt)
|
padding = Padding(0.pt)
|
||||||
margin(0.pt)
|
margin = Margin(0.pt)
|
||||||
height = 100.vh
|
height = 100.vh
|
||||||
width = 100.vw
|
width = 100.vw
|
||||||
}
|
}
|
||||||
SmartTabs("gravity") {
|
SmartTabs("gravity") {
|
||||||
Tab("gravity") {
|
Tab("gravity") {
|
||||||
GravityDemo{
|
GravityDemo {
|
||||||
attrs {
|
attrs {
|
||||||
this.context = playgroundContext
|
this.solids = playgroundContext.request(Solids)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -71,8 +73,11 @@ private class JsPlaygroundApp : Application {
|
|||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
val random = Random(112233)
|
val random = Random(112233)
|
||||||
attrs {
|
attrs {
|
||||||
context = playgroundContext
|
solids = playgroundContext.request(Solids)
|
||||||
solid {
|
solid {
|
||||||
|
ambientLight {
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
repeat(100) {
|
repeat(100) {
|
||||||
sphere(5, name = "sphere[$it]") {
|
sphere(5, name = "sphere[$it]") {
|
||||||
x = random.nextDouble(-300.0, 300.0)
|
x = random.nextDouble(-300.0, 300.0)
|
@ -4,9 +4,9 @@ import kotlinx.coroutines.launch
|
|||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import react.Props
|
import react.Props
|
||||||
import react.fc
|
import react.fc
|
||||||
import space.kscience.dataforge.context.Context
|
|
||||||
import space.kscience.plotly.layout
|
import space.kscience.plotly.layout
|
||||||
import space.kscience.plotly.models.Trace
|
import space.kscience.plotly.models.Trace
|
||||||
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.markup.VisionOfMarkup
|
import space.kscience.visionforge.markup.VisionOfMarkup
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||||
@ -17,14 +17,14 @@ import styled.styledDiv
|
|||||||
import kotlin.math.sqrt
|
import kotlin.math.sqrt
|
||||||
|
|
||||||
external interface DemoProps : Props {
|
external interface DemoProps : Props {
|
||||||
var context: Context
|
var solids: Solids
|
||||||
}
|
}
|
||||||
|
|
||||||
val GravityDemo = fc<DemoProps> { props ->
|
val GravityDemo = fc<DemoProps> { props ->
|
||||||
val velocityTrace = Trace{
|
val velocityTrace = Trace {
|
||||||
name = "velocity"
|
name = "velocity"
|
||||||
}
|
}
|
||||||
val energyTrace = Trace{
|
val energyTrace = Trace {
|
||||||
name = "energy"
|
name = "energy"
|
||||||
}
|
}
|
||||||
val markup = VisionOfMarkup()
|
val markup = VisionOfMarkup()
|
||||||
@ -39,14 +39,19 @@ val GravityDemo = fc<DemoProps> { props ->
|
|||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
attrs {
|
attrs {
|
||||||
context = props.context
|
solids = props.solids
|
||||||
solid {
|
solid {
|
||||||
|
pointLight(200, 200, 200, name = "light"){
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
|
ambientLight()
|
||||||
|
|
||||||
sphere(5.0, "ball") {
|
sphere(5.0, "ball") {
|
||||||
detail = 16
|
detail = 16
|
||||||
color("red")
|
color("red")
|
||||||
val h = 100.0
|
val h = 100.0
|
||||||
y = h
|
y = h
|
||||||
context.launch {
|
solids.context.launch {
|
||||||
val g = 10.0
|
val g = 10.0
|
||||||
val dt = 0.1
|
val dt = 0.1
|
||||||
var time = 0.0
|
var time = 0.0
|
||||||
@ -91,7 +96,7 @@ val GravityDemo = fc<DemoProps> { props ->
|
|||||||
height = 50.vh - 50.pt
|
height = 50.vh - 50.pt
|
||||||
}
|
}
|
||||||
plotly {
|
plotly {
|
||||||
traces(velocityTrace,energyTrace)
|
traces(velocityTrace, energyTrace)
|
||||||
layout {
|
layout {
|
||||||
xaxis.title = "time"
|
xaxis.title = "time"
|
||||||
}
|
}
|
@ -1,5 +1,4 @@
|
|||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.css.properties.border
|
|
||||||
import kotlinx.dom.clear
|
import kotlinx.dom.clear
|
||||||
import kotlinx.html.dom.append
|
import kotlinx.html.dom.append
|
||||||
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
|
import org.intellij.markdown.flavours.commonmark.CommonMarkFlavourDescriptor
|
||||||
@ -45,10 +44,10 @@ val Markup = fc<MarkupProps>("Markup") { props ->
|
|||||||
css {
|
css {
|
||||||
width = 100.pct
|
width = 100.pct
|
||||||
height = 100.pct
|
height = 100.pct
|
||||||
border(2.pt, BorderStyle.solid, Color.blue)
|
border= Border(2.pt, BorderStyle.solid, Color.blue)
|
||||||
padding(left = 8.pt)
|
padding = Padding(left = 8.pt)
|
||||||
backgroundColor = Color.white
|
backgroundColor = Color.white
|
||||||
flex(1.0)
|
flex = Flex(1.0)
|
||||||
zIndex = 10000
|
zIndex = 10000
|
||||||
}
|
}
|
||||||
ref = elementRef
|
ref = elementRef
|
@ -1,5 +1,4 @@
|
|||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.css.properties.border
|
|
||||||
import org.w3c.dom.Element
|
import org.w3c.dom.Element
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
import react.*
|
import react.*
|
||||||
@ -20,9 +19,9 @@ val Plotly = fc<PlotlyProps>("Plotly") { props ->
|
|||||||
useEffect(props.plot, elementRef) {
|
useEffect(props.plot, elementRef) {
|
||||||
val element = elementRef.current as? HTMLElement ?: error("Plotly element not found")
|
val element = elementRef.current as? HTMLElement ?: error("Plotly element not found")
|
||||||
props.plot?.let {
|
props.plot?.let {
|
||||||
element.plot(it, PlotlyConfig {
|
element.plot(PlotlyConfig {
|
||||||
responsive = true
|
responsive = true
|
||||||
})
|
}, it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -30,8 +29,8 @@ val Plotly = fc<PlotlyProps>("Plotly") { props ->
|
|||||||
css {
|
css {
|
||||||
width = 100.pct
|
width = 100.pct
|
||||||
height = 100.pct
|
height = 100.pct
|
||||||
border(2.pt, BorderStyle.solid, Color.blue)
|
border = Border(2.pt, BorderStyle.solid, Color.blue)
|
||||||
flex(1.0)
|
flex = Flex(1.0)
|
||||||
}
|
}
|
||||||
ref = elementRef
|
ref = elementRef
|
||||||
}
|
}
|
@ -1,64 +1,47 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.mipt.npm"
|
group = "ru.mipt.npm"
|
||||||
|
|
||||||
val ktorVersion: String = npmlibs.versions.ktor.get()
|
val ktorVersion: String = spclibs.versions.ktor.get()
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
useCoroutines()
|
useCoroutines()
|
||||||
useSerialization()
|
useSerialization()
|
||||||
application()
|
useKtor()
|
||||||
}
|
fullStack(
|
||||||
|
"muon-monitor.js",
|
||||||
kotlin {
|
jvmConfig = { withJava() },
|
||||||
jvm {
|
jsConfig = { useCommonJs() }
|
||||||
withJava()
|
) {
|
||||||
}
|
commonWebpackConfig {
|
||||||
js {
|
cssSupport {
|
||||||
useCommonJs()
|
enabled.set(false)
|
||||||
browser {
|
|
||||||
commonWebpackConfig {
|
|
||||||
cssSupport.enabled = false
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
afterEvaluate {
|
commonMain {
|
||||||
val jsBrowserDistribution by tasks.getting
|
implementation(projects.visionforgeSolid)
|
||||||
|
|
||||||
tasks.getByName<ProcessResources>("jvmProcessResources") {
|
|
||||||
dependsOn(jsBrowserDistribution)
|
|
||||||
duplicatesStrategy = DuplicatesStrategy.EXCLUDE
|
|
||||||
from(jsBrowserDistribution)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
jvmMain {
|
||||||
sourceSets {
|
implementation("org.apache.commons:commons-math3:3.6.1")
|
||||||
commonMain {
|
implementation("io.ktor:ktor-server-cio:${ktorVersion}")
|
||||||
dependencies {
|
implementation("io.ktor:ktor-server-content-negotiation:${ktorVersion}")
|
||||||
implementation(project(":visionforge-solid"))
|
implementation("io.ktor:ktor-serialization-kotlinx-json:${ktorVersion}")
|
||||||
}
|
implementation("ch.qos.logback:logback-classic:1.2.11")
|
||||||
}
|
}
|
||||||
jvmMain {
|
jsMain {
|
||||||
dependencies {
|
implementation(projects.ui.ring)
|
||||||
implementation("org.apache.commons:commons-math3:3.6.1")
|
implementation(projects.visionforgeThreejs)
|
||||||
implementation(npmlibs.ktor.server.cio)
|
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
|
||||||
implementation(npmlibs.ktor.serialization)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jsMain {
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":ui:ring"))
|
|
||||||
implementation(project(":visionforge-threejs"))
|
|
||||||
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
kotlin.explicitApi = null
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
||||||
}
|
}
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package ru.mipt.npm.muon.monitor
|
package ru.mipt.npm.muon.monitor
|
||||||
|
|
||||||
import kotlinx.serialization.Serializable
|
import kotlinx.serialization.Serializable
|
||||||
import space.kscience.visionforge.solid.Point3D
|
import space.kscience.visionforge.solid.Float32Vector3D
|
||||||
|
|
||||||
typealias Track = List<Point3D>
|
typealias Track = List<Float32Vector3D>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -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.CENTRAL_LAYER_Z
|
||||||
import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z
|
import ru.mipt.npm.muon.monitor.Monitor.LOWER_LAYER_Z
|
||||||
import ru.mipt.npm.muon.monitor.Monitor.UPPER_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.VisionManager
|
||||||
import space.kscience.visionforge.removeAll
|
|
||||||
import space.kscience.visionforge.setAsRoot
|
import space.kscience.visionforge.setAsRoot
|
||||||
import space.kscience.visionforge.setProperty
|
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
|
import kotlin.collections.set
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
class Model(val manager: VisionManager) {
|
class Model(val manager: VisionManager) {
|
||||||
private val map = HashMap<String, SolidGroup>()
|
private val map = HashMap<String, SolidGroup>()
|
||||||
private val events = HashSet<Event>()
|
private val events = HashSet<Event>()
|
||||||
|
|
||||||
private fun SolidGroup.pixel(pixel: SC1) {
|
private fun MutableVisionContainer<Solid>.pixel(pixel: SC1) {
|
||||||
val group = group(pixel.name) {
|
val group = solidGroup(pixel.name) {
|
||||||
position = Point3D(pixel.center.x, pixel.center.y, pixel.center.z)
|
position = Float32Vector3D(pixel.center.x, pixel.center.y, pixel.center.z)
|
||||||
box(pixel.xSize, pixel.ySize, pixel.zSize)
|
box(pixel.xSize, pixel.ySize, pixel.zSize)
|
||||||
label(pixel.name) {
|
label(pixel.name) {
|
||||||
z = -Monitor.PIXEL_Z_SIZE / 2 - 5
|
z = -Monitor.PIXEL_Z_SIZE / 2 - 5
|
||||||
@ -27,52 +28,52 @@ class Model(val manager: VisionManager) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private fun SolidGroup.detector(detector: SC16) {
|
private fun SolidGroup.detector(detector: SC16) {
|
||||||
group(detector.name) {
|
solidGroup(detector.name) {
|
||||||
detector.pixels.forEach {
|
detector.pixels.forEach {
|
||||||
pixel(it)
|
pixel(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
var tracks: SolidGroup
|
val tracks: SolidGroup = SolidGroup()
|
||||||
|
|
||||||
val root: SolidGroup = SolidGroup().apply {
|
val root: SolidGroup = SolidGroup().apply {
|
||||||
setAsRoot(this@Model.manager)
|
setAsRoot(this@Model.manager)
|
||||||
material {
|
material {
|
||||||
wireframe
|
|
||||||
color("darkgreen")
|
color("darkgreen")
|
||||||
}
|
}
|
||||||
rotationX = PI / 2
|
rotationX = PI / 2
|
||||||
group("bottom") {
|
solidGroup("bottom") {
|
||||||
Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach {
|
Monitor.detectors.filter { it.center.z == LOWER_LAYER_Z }.forEach {
|
||||||
detector(it)
|
detector(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group("middle") {
|
solidGroup("middle") {
|
||||||
Monitor.detectors.filter { it.center.z == CENTRAL_LAYER_Z }.forEach {
|
Monitor.detectors.filter { it.center.z == CENTRAL_LAYER_Z }.forEach {
|
||||||
detector(it)
|
detector(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group("top") {
|
solidGroup("top") {
|
||||||
Monitor.detectors.filter { it.center.z == UPPER_LAYER_Z }.forEach {
|
Monitor.detectors.filter { it.center.z == UPPER_LAYER_Z }.forEach {
|
||||||
detector(it)
|
detector(it)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
tracks = group("tracks")
|
|
||||||
|
setChild("tracks".asName(), tracks)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun highlight(pixel: String) {
|
private fun highlight(pixel: String) {
|
||||||
println("highlight $pixel")
|
println("highlight $pixel")
|
||||||
map[pixel]?.color?.invoke("blue")
|
map[pixel]?.color("blue")
|
||||||
}
|
}
|
||||||
|
|
||||||
fun reset() {
|
fun reset() {
|
||||||
map.values.forEach {
|
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) {
|
fun displayEvent(event: Event) {
|
||||||
@ -83,7 +84,6 @@ class Model(val manager: VisionManager) {
|
|||||||
}
|
}
|
||||||
event.track?.let {
|
event.track?.let {
|
||||||
tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") {
|
tracks.polyline(*it.toTypedArray(), name = "track[${event.id}]") {
|
||||||
thickness = 4
|
|
||||||
color("red")
|
color("red")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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_XY_SIZE
|
||||||
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE
|
import ru.mipt.npm.muon.monitor.Monitor.PIXEL_Z_SIZE
|
||||||
import space.kscience.visionforge.solid.Point3D
|
import space.kscience.visionforge.solid.Float32Euclidean3DSpace
|
||||||
import space.kscience.visionforge.solid.plus
|
import space.kscience.visionforge.solid.Float32Vector3D
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A single pixel
|
* A single pixel
|
||||||
*/
|
*/
|
||||||
class SC1(
|
class SC1(
|
||||||
val name: String,
|
val name: String,
|
||||||
val center: Point3D,
|
val center: Float32Vector3D,
|
||||||
val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE
|
val xSize: Float = PIXEL_XY_SIZE, val ySize: Float = PIXEL_XY_SIZE, val zSize: Float = PIXEL_Z_SIZE,
|
||||||
)
|
)
|
||||||
|
|
||||||
class SC16(
|
class SC16(
|
||||||
val name: String,
|
val name: String,
|
||||||
val center: Point3D
|
val center: Float32Vector3D,
|
||||||
) {
|
) {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -28,77 +28,90 @@ class SC16(
|
|||||||
val y: Double
|
val y: Double
|
||||||
when (index) {
|
when (index) {
|
||||||
7 -> {
|
7 -> {
|
||||||
x = 1.5 * Monitor.PIXEL_XY_SPACING;
|
x = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 1.5 * Monitor.PIXEL_XY_SPACING;
|
y = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
4 -> {
|
4 -> {
|
||||||
x = 0.5 * Monitor.PIXEL_XY_SPACING;
|
x = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 1.5 * Monitor.PIXEL_XY_SPACING;
|
y = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
6 -> {
|
6 -> {
|
||||||
x = 1.5 * Monitor.PIXEL_XY_SPACING;
|
x = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 0.5 * Monitor.PIXEL_XY_SPACING;
|
y = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
5 -> {
|
5 -> {
|
||||||
x = 0.5 * Monitor.PIXEL_XY_SPACING;
|
x = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 0.5 * Monitor.PIXEL_XY_SPACING;
|
y = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
3 -> {
|
3 -> {
|
||||||
x = -1.5 * Monitor.PIXEL_XY_SPACING;
|
x = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 1.5 * Monitor.PIXEL_XY_SPACING;
|
y = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
0 -> {
|
0 -> {
|
||||||
x = -0.5 * Monitor.PIXEL_XY_SPACING;
|
x = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 1.5 * Monitor.PIXEL_XY_SPACING;
|
y = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
2 -> {
|
2 -> {
|
||||||
x = -1.5 * Monitor.PIXEL_XY_SPACING;
|
x = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 0.5 * Monitor.PIXEL_XY_SPACING;
|
y = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
1 -> {
|
1 -> {
|
||||||
x = -0.5 * Monitor.PIXEL_XY_SPACING;
|
x = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = 0.5 * Monitor.PIXEL_XY_SPACING;
|
y = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
11 -> {
|
11 -> {
|
||||||
x = -1.5 * Monitor.PIXEL_XY_SPACING;
|
x = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -1.5 * Monitor.PIXEL_XY_SPACING;
|
y = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
8 -> {
|
8 -> {
|
||||||
x = -0.5 * Monitor.PIXEL_XY_SPACING;
|
x = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -1.5 * Monitor.PIXEL_XY_SPACING;
|
y = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
10 -> {
|
10 -> {
|
||||||
x = -1.5 * Monitor.PIXEL_XY_SPACING;
|
x = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -0.5 * Monitor.PIXEL_XY_SPACING;
|
y = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
9 -> {
|
9 -> {
|
||||||
x = -0.5 * Monitor.PIXEL_XY_SPACING;
|
x = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -0.5 * Monitor.PIXEL_XY_SPACING;
|
y = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
15 -> {
|
15 -> {
|
||||||
x = 1.5 * Monitor.PIXEL_XY_SPACING;
|
x = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -1.5 * Monitor.PIXEL_XY_SPACING;
|
y = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
12 -> {
|
12 -> {
|
||||||
x = 0.5 * Monitor.PIXEL_XY_SPACING;
|
x = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -1.5 * Monitor.PIXEL_XY_SPACING;
|
y = -1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
14 -> {
|
14 -> {
|
||||||
x = 1.5 * Monitor.PIXEL_XY_SPACING;
|
x = 1.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -0.5 * Monitor.PIXEL_XY_SPACING;
|
y = -0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
}
|
}
|
||||||
|
|
||||||
13 -> {
|
13 -> {
|
||||||
x = 0.5 * Monitor.PIXEL_XY_SPACING;
|
x = 0.5 * Monitor.PIXEL_XY_SPACING
|
||||||
y = -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}"
|
val pixelName = "${name}_${index}"
|
||||||
SC1(pixelName, offset + center)
|
SC1(pixelName, with(Float32Euclidean3DSpace) { offset + center })
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,11 +150,11 @@ object Monitor {
|
|||||||
.mapNotNull { line ->
|
.mapNotNull { line ->
|
||||||
if (line.startsWith(" ")) {
|
if (line.startsWith(" ")) {
|
||||||
val split = line.trim().split("\\s+".toRegex())
|
val split = line.trim().split("\\s+".toRegex())
|
||||||
val detectorName = split[1];
|
val detectorName = split[1]
|
||||||
val x = split[4].toDouble() - 500
|
val x = split[4].toDouble() - 500
|
||||||
val y = split[5].toDouble() - 500
|
val y = split[5].toDouble() - 500
|
||||||
val z = 180 - split[6].toDouble()
|
val z = 180 - split[6].toDouble()
|
||||||
SC16(detectorName, Point3D(x, y, z))
|
SC16(detectorName, Float32Vector3D(x, y, z))
|
||||||
} else {
|
} else {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
|
@ -16,15 +16,18 @@ import react.dom.p
|
|||||||
import react.fc
|
import react.fc
|
||||||
import react.useMemo
|
import react.useMemo
|
||||||
import react.useState
|
import react.useState
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.meta.invoke
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
import space.kscience.visionforge.react.flexRow
|
import space.kscience.visionforge.react.flexRow
|
||||||
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
import space.kscience.visionforge.ring.ThreeCanvasWithControls
|
||||||
import space.kscience.visionforge.ring.tab
|
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.specifications.Canvas3DOptions
|
||||||
import space.kscience.visionforge.solid.three.edges
|
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
import styled.styledSpan
|
import styled.styledSpan
|
||||||
@ -32,7 +35,7 @@ import kotlin.math.PI
|
|||||||
|
|
||||||
external interface MMAppProps : Props {
|
external interface MMAppProps : Props {
|
||||||
var model: Model
|
var model: Model
|
||||||
var context: Context
|
var solids: Solids
|
||||||
var selected: Name?
|
var selected: Name?
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -42,17 +45,21 @@ val MMApp = fc<MMAppProps>("Muon monitor") { props ->
|
|||||||
|
|
||||||
val mmOptions = useMemo {
|
val mmOptions = useMemo {
|
||||||
Canvas3DOptions {
|
Canvas3DOptions {
|
||||||
camera = Camera {
|
camera {
|
||||||
distance = 2100.0
|
distance = 2100.0
|
||||||
latitude = PI / 6
|
latitude = PI / 6
|
||||||
azimuth = PI + PI / 6
|
azimuth = PI + PI / 6
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val root = useMemo(props.model) {
|
val root = useMemo(props.model) {
|
||||||
props.model.root.apply {
|
props.model.root.apply {
|
||||||
edges()
|
edges()
|
||||||
|
ambientLight{
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -64,7 +71,7 @@ val MMApp = fc<MMAppProps>("Muon monitor") { props ->
|
|||||||
}
|
}
|
||||||
child(ThreeCanvasWithControls) {
|
child(ThreeCanvasWithControls) {
|
||||||
attrs {
|
attrs {
|
||||||
this.context = props.context
|
this.solids = props.solids
|
||||||
this.builderOfSolid = CompletableDeferred(root)
|
this.builderOfSolid = CompletableDeferred(root)
|
||||||
this.selected = props.selected
|
this.selected = props.selected
|
||||||
this.options = mmOptions
|
this.options = mmOptions
|
||||||
@ -75,7 +82,7 @@ val MMApp = fc<MMAppProps>("Muon monitor") { props ->
|
|||||||
+"Next"
|
+"Next"
|
||||||
attrs {
|
attrs {
|
||||||
onClickFunction = {
|
onClickFunction = {
|
||||||
context.launch {
|
solids.context.launch {
|
||||||
val event = window.fetch(
|
val event = window.fetch(
|
||||||
"http://localhost:8080/event",
|
"http://localhost:8080/event",
|
||||||
RequestInit("GET")
|
RequestInit("GET")
|
||||||
|
@ -1,31 +1,34 @@
|
|||||||
package ru.mipt.npm.muon.monitor
|
package ru.mipt.npm.muon.monitor
|
||||||
|
|
||||||
import kotlinx.browser.document
|
import org.w3c.dom.Document
|
||||||
import react.dom.render
|
|
||||||
import space.kscience.dataforge.context.Context
|
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.Application
|
||||||
import space.kscience.visionforge.VisionManager
|
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.solid.three.ThreePlugin
|
||||||
import space.kscience.visionforge.startApplication
|
import space.kscience.visionforge.startApplication
|
||||||
|
|
||||||
private class MMDemoApp : Application {
|
private class MMDemoApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
|
|
||||||
val context = Context("MM-demo") {
|
val context = Context("MM-demo") {
|
||||||
plugin(ThreePlugin)
|
plugin(ThreePlugin)
|
||||||
}
|
}
|
||||||
val visionManager = context.fetch(VisionManager)
|
|
||||||
|
val visionManager = context.request(VisionManager)
|
||||||
|
|
||||||
val model = Model(visionManager)
|
val model = Model(visionManager)
|
||||||
|
|
||||||
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
val element = document.getElementById("app") ?: error("Element with id 'app' not found on page")
|
||||||
render(element) {
|
createRoot(element).render {
|
||||||
child(MMApp) {
|
child(MMApp) {
|
||||||
attrs {
|
attrs {
|
||||||
this.model = model
|
this.model = model
|
||||||
this.context = context
|
this.solids = context.request(Solids)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@
|
|||||||
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">-->
|
<!-- <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">-->
|
||||||
<title>Three js demo for particle physics</title>
|
<title>Three js demo for particle physics</title>
|
||||||
<script type="text/javascript" src="muon-monitor.js"></script>
|
<script type="text/javascript" src="muon-monitor.js"></script>
|
||||||
<link rel="stylesheet" href="css/custom-bootstrap.css">
|
|
||||||
</head>
|
</head>
|
||||||
<body class="application">
|
<body class="application">
|
||||||
<div class="container-fluid max-vh-100" id = "app"> </div>
|
<div class="container-fluid max-vh-100" id = "app"> </div>
|
||||||
|
@ -1,31 +1,28 @@
|
|||||||
package ru.mipt.npm.muon.monitor.server
|
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.ContentType
|
||||||
import io.ktor.http.HttpStatusCode
|
import io.ktor.http.HttpStatusCode
|
||||||
import io.ktor.http.content.resources
|
import io.ktor.serialization.kotlinx.json.json
|
||||||
import io.ktor.http.content.static
|
import io.ktor.server.application.Application
|
||||||
import io.ktor.response.respond
|
import io.ktor.server.application.call
|
||||||
import io.ktor.response.respondText
|
import io.ktor.server.application.install
|
||||||
import io.ktor.routing.Routing
|
import io.ktor.server.application.log
|
||||||
import io.ktor.routing.get
|
|
||||||
import io.ktor.serialization.json
|
|
||||||
import io.ktor.server.cio.CIO
|
import io.ktor.server.cio.CIO
|
||||||
import io.ktor.server.engine.embeddedServer
|
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 org.apache.commons.math3.random.JDKRandomGenerator
|
||||||
import ru.mipt.npm.muon.monitor.Model
|
import ru.mipt.npm.muon.monitor.Model
|
||||||
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
import ru.mipt.npm.muon.monitor.sim.Cos2TrackGenerator
|
||||||
import ru.mipt.npm.muon.monitor.sim.simulateOne
|
import ru.mipt.npm.muon.monitor.sim.simulateOne
|
||||||
import space.kscience.dataforge.context.Context
|
import space.kscience.dataforge.context.Context
|
||||||
import space.kscience.dataforge.context.Global
|
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.dataforge.misc.DFExperimental
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
import java.awt.Desktop
|
import java.awt.Desktop
|
||||||
@ -38,10 +35,8 @@ private val generator = Cos2TrackGenerator(JDKRandomGenerator(223))
|
|||||||
fun Application.module(context: Context = Global) {
|
fun Application.module(context: Context = Global) {
|
||||||
val currentDir = File(".").absoluteFile
|
val currentDir = File(".").absoluteFile
|
||||||
environment.log.info("Current directory: $currentDir")
|
environment.log.info("Current directory: $currentDir")
|
||||||
val solidManager = context.fetch(Solids)
|
val solidManager = context.request(Solids)
|
||||||
|
|
||||||
install(DefaultHeaders)
|
|
||||||
install(CallLogging)
|
|
||||||
install(ContentNegotiation) {
|
install(ContentNegotiation) {
|
||||||
json()
|
json()
|
||||||
}
|
}
|
||||||
@ -57,9 +52,7 @@ fun Application.module(context: Context = Global) {
|
|||||||
status = HttpStatusCode.OK
|
status = HttpStatusCode.OK
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
static("/") {
|
staticResources("/", null)
|
||||||
resources()
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
try {
|
try {
|
||||||
Desktop.getDesktop().browse(URI("http://localhost:8080/index.html"))
|
Desktop.getDesktop().browse(URI("http://localhost:8080/index.html"))
|
||||||
|
@ -5,7 +5,7 @@ import org.apache.commons.math3.geometry.euclidean.threed.Plane
|
|||||||
import org.apache.commons.math3.geometry.euclidean.threed.Vector3D
|
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.CENTRAL_LAYER_Z
|
||||||
import ru.mipt.npm.muon.monitor.Monitor.GEOMETRY_TOLERANCE
|
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.
|
* 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<Point3D> {
|
fun Line.toKMathVectors(): List<Float32Vector3D> {
|
||||||
val basePoint = basePlane.intersection(this)
|
val basePoint = basePlane.intersection(this)
|
||||||
val bottom = basePoint.subtract(2000.0, direction)
|
val bottom = basePoint.subtract(2000.0, direction)
|
||||||
val top = basePoint.add(2000.0, direction)
|
val top = basePoint.add(2000.0, direction)
|
||||||
return listOf(bottom.toPoint(), top.toPoint())
|
return listOf(bottom.toKMathVector(), top.toKMathVector())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -43,7 +43,7 @@ fun readEffs(): Map<String, Double> {
|
|||||||
|
|
||||||
|
|
||||||
fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection<SC1> = defaultHitResolver): Event {
|
fun buildEventByTrack(index: Int, track: Line, hitResolver: (Line) -> Collection<SC1> = 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<SC1> = { track: Line ->
|
val defaultHitResolver: (Line) -> Collection<SC1> = { track: Line ->
|
||||||
|
@ -2,6 +2,7 @@ plugins {
|
|||||||
kotlin("multiplatform")
|
kotlin("multiplatform")
|
||||||
kotlin("jupyter.api")
|
kotlin("jupyter.api")
|
||||||
id("com.github.johnrengelman.shadow") version "7.1.2"
|
id("com.github.johnrengelman.shadow") version "7.1.2"
|
||||||
|
// application
|
||||||
}
|
}
|
||||||
|
|
||||||
repositories {
|
repositories {
|
||||||
@ -16,23 +17,25 @@ kotlin {
|
|||||||
useCommonJs()
|
useCommonJs()
|
||||||
browser {
|
browser {
|
||||||
webpackTask {
|
webpackTask {
|
||||||
this.outputFileName = "js/visionforge-playground.js"
|
mainOutputFileName.set("js/visionforge-playground.js")
|
||||||
}
|
}
|
||||||
commonWebpackConfig {
|
commonWebpackConfig {
|
||||||
sourceMaps = true
|
sourceMaps = true
|
||||||
cssSupport.enabled = false
|
cssSupport{
|
||||||
|
enabled.set(false)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
}
|
}
|
||||||
|
|
||||||
jvm {
|
jvm {
|
||||||
withJava()
|
// withJava()
|
||||||
compilations.all {
|
compilations.all {
|
||||||
kotlinOptions {
|
kotlinOptions {
|
||||||
jvmTarget = "11"
|
jvmTarget = "11"
|
||||||
freeCompilerArgs =
|
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 {
|
testRuns["test"].executionTask.configure {
|
||||||
@ -44,12 +47,11 @@ kotlin {
|
|||||||
val commonMain by getting {
|
val commonMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.visionforgeSolid)
|
implementation(projects.visionforgeSolid)
|
||||||
implementation(projects.visionforgeGdml)
|
|
||||||
implementation(projects.visionforgePlotly)
|
implementation(projects.visionforgePlotly)
|
||||||
implementation(projects.visionforgeMarkdown)
|
implementation(projects.visionforgeMarkdown)
|
||||||
implementation(projects.visionforgeTables)
|
implementation(projects.visionforgeTables)
|
||||||
implementation(projects.cernRootLoader)
|
implementation(projects.cernRootLoader)
|
||||||
implementation(projects.jupyter)
|
api(projects.visionforgeJupyter.visionforgeJupyterCommon)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -63,8 +65,10 @@ kotlin {
|
|||||||
|
|
||||||
val jvmMain by getting {
|
val jvmMain by getting {
|
||||||
dependencies {
|
dependencies {
|
||||||
|
implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}")
|
||||||
|
implementation(projects.visionforgeGdml)
|
||||||
implementation(projects.visionforgeServer)
|
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")
|
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -88,3 +92,7 @@ val processJupyterApiResources by tasks.getting(org.jetbrains.kotlinx.jupyter.ap
|
|||||||
}
|
}
|
||||||
|
|
||||||
tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources)
|
tasks.findByName("shadowJar")?.dependsOn(processJupyterApiResources)
|
||||||
|
|
||||||
|
//application{
|
||||||
|
// mainClass.set("space.kscience.visionforge.examples.ShapesKt")
|
||||||
|
//}
|
98
demo/playground/notebooks/common-demo.ipynb
Normal file
98
demo/playground/notebooks/common-demo.ipynb
Normal file
@ -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
|
||||||
|
}
|
45
demo/playground/notebooks/controls.ipynb
Normal file
45
demo/playground/notebooks/controls.ipynb
Normal file
@ -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
|
||||||
|
}
|
89
demo/playground/notebooks/dynamic-demo.ipynb
Normal file
89
demo/playground/notebooks/dynamic-demo.ipynb
Normal file
@ -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
|
||||||
|
}
|
@ -1,4 +1,5 @@
|
|||||||
import space.kscience.dataforge.misc.DFExperimental
|
import space.kscience.dataforge.misc.DFExperimental
|
||||||
|
import space.kscience.visionforge.jupyter.VFNotebookClient
|
||||||
import space.kscience.visionforge.markup.MarkupPlugin
|
import space.kscience.visionforge.markup.MarkupPlugin
|
||||||
import space.kscience.visionforge.plotly.PlotlyPlugin
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
import space.kscience.visionforge.ring.ThreeWithControlsPlugin
|
||||||
@ -11,4 +12,5 @@ fun main() = runVisionClient {
|
|||||||
plugin(PlotlyPlugin)
|
plugin(PlotlyPlugin)
|
||||||
plugin(MarkupPlugin)
|
plugin(MarkupPlugin)
|
||||||
plugin(TableVisionJsPlugin)
|
plugin(TableVisionJsPlugin)
|
||||||
|
plugin(VFNotebookClient)
|
||||||
}
|
}
|
83
demo/playground/src/jvmMain/kotlin/BmnDemo.kt
Normal file
83
demo/playground/src/jvmMain/kotlin/BmnDemo.kt
Normal file
@ -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<String> = 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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -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<Gdml> { gdmlModel ->
|
|
||||||
handler.produceHtml {
|
|
||||||
vision { gdmlModel.toVision() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
render<Plot> { plot ->
|
|
||||||
handler.produceHtml {
|
|
||||||
vision { plot.asVision() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
@ -1,7 +1,8 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import kotlinx.html.h2
|
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.layout
|
||||||
import space.kscience.plotly.models.ScatterMode
|
import space.kscience.plotly.models.ScatterMode
|
||||||
import space.kscience.plotly.models.TextPosition
|
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.plotly.plotly
|
||||||
import space.kscience.visionforge.solid.box
|
import space.kscience.visionforge.solid.box
|
||||||
import space.kscience.visionforge.solid.solid
|
import space.kscience.visionforge.solid.solid
|
||||||
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import space.kscience.visionforge.solid.z
|
import space.kscience.visionforge.solid.z
|
||||||
import space.kscience.visionforge.tables.columnTable
|
import space.kscience.visionforge.tables.columnTable
|
||||||
import java.nio.file.Paths
|
import kotlin.io.path.Path
|
||||||
|
|
||||||
|
|
||||||
fun main() = makeVisionFile(
|
fun main() = makeVisionFile(
|
||||||
Paths.get("VisionForgeDemo.html"),
|
Path("VisionForgeDemo.html"),
|
||||||
resourceLocation = ResourceLocation.EMBED
|
resourceLocation = ResourceLocation.EMBED
|
||||||
) {
|
) {
|
||||||
markdown {
|
markdown {
|
||||||
@ -32,8 +34,15 @@ fun main() = makeVisionFile(
|
|||||||
|
|
||||||
h2 { +"3D visualization with Three-js" }
|
h2 { +"3D visualization with Three-js" }
|
||||||
vision("3D") {
|
vision("3D") {
|
||||||
solid {
|
solid(
|
||||||
box(100, 100, 100, name = "aBox"){
|
Canvas3DOptions {
|
||||||
|
axes {
|
||||||
|
size = 200.0
|
||||||
|
visible = true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
box(100, 100, 100, name = "aBox") {
|
||||||
z = 50.0
|
z = 50.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
102
demo/playground/src/jvmMain/kotlin/antenna.kt
Normal file
102
demo/playground/src/jvmMain/kotlin/antenna.kt
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
demo/playground/src/jvmMain/kotlin/axes.kt
Normal file
22
demo/playground/src/jvmMain/kotlin/axes.kt
Normal file
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
22
demo/playground/src/jvmMain/kotlin/extruded.kt
Normal file
22
demo/playground/src/jvmMain/kotlin/extruded.kt
Normal file
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,22 +1,42 @@
|
|||||||
package space.kscience.visionforge.examples
|
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 kotlinx.html.*
|
||||||
import space.kscience.dataforge.context.Global
|
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.VisionManager
|
||||||
import space.kscience.visionforge.html.Page
|
import space.kscience.visionforge.html.VisionOfHtmlForm
|
||||||
import space.kscience.visionforge.html.formFragment
|
import space.kscience.visionforge.html.VisionPage
|
||||||
|
import space.kscience.visionforge.html.bindForm
|
||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
import space.kscience.visionforge.server.close
|
import space.kscience.visionforge.server.close
|
||||||
import space.kscience.visionforge.server.openInBrowser
|
import space.kscience.visionforge.server.openInBrowser
|
||||||
import space.kscience.visionforge.server.serve
|
import space.kscience.visionforge.server.visionPage
|
||||||
|
|
||||||
|
@Suppress("ExtractKtorModule")
|
||||||
fun main() {
|
fun main() {
|
||||||
val visionManager = Global.fetch(VisionManager)
|
val visionManager = Global.request(VisionManager)
|
||||||
|
|
||||||
val server = visionManager.serve {
|
val server = embeddedServer(CIO) {
|
||||||
page(header = Page.scriptHeader("js/visionforge-playground.js")) {
|
|
||||||
val form = formFragment("form") {
|
routing {
|
||||||
|
staticResources("/", null)
|
||||||
|
}
|
||||||
|
|
||||||
|
val form = VisionOfHtmlForm("form").apply {
|
||||||
|
onPropertyChange(visionManager.context) {
|
||||||
|
println(values)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
visionPage(
|
||||||
|
visionManager,
|
||||||
|
VisionPage.scriptHeader("js/visionforge-playground.js"),
|
||||||
|
) {
|
||||||
|
bindForm(form) {
|
||||||
label {
|
label {
|
||||||
htmlFor = "fname"
|
htmlFor = "fname"
|
||||||
+"First name:"
|
+"First name:"
|
||||||
@ -47,17 +67,15 @@ fun main() {
|
|||||||
value = "Submit"
|
value = "Submit"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
println(form.values)
|
||||||
vision("form") { form }
|
vision(form)
|
||||||
form.onPropertyChange {
|
|
||||||
println(this)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}.start(false)
|
||||||
|
|
||||||
server.openInBrowser()
|
server.openInBrowser()
|
||||||
|
|
||||||
while (readln() != "exit") {
|
while (readlnOrNull() != "exit") {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,7 +5,7 @@ import space.kscience.visionforge.gdml.toVision
|
|||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
|
||||||
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM){
|
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
requirePlugin(Solids)
|
requirePlugin(Solids)
|
||||||
GdmlShowCase.cubes().toVision()
|
GdmlShowCase.cubes().toVision()
|
||||||
|
@ -223,7 +223,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}.toVision {
|
}.toVision {
|
||||||
configure { _, solid, _ ->
|
solids { _, solid, _ ->
|
||||||
//disable visibility for the world box
|
//disable visibility for the world box
|
||||||
if(solid.name == "world"){
|
if(solid.name == "world"){
|
||||||
visible = false
|
visible = false
|
||||||
|
@ -1,12 +1,15 @@
|
|||||||
package space.kscience.visionforge.examples
|
package space.kscience.visionforge.examples
|
||||||
|
|
||||||
import space.kscience.gdml.GdmlShowCase
|
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.Solids
|
||||||
|
import space.kscience.visionforge.solid.solid
|
||||||
|
|
||||||
fun main() = makeVisionFile {
|
fun main() = makeVisionFile {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
requirePlugin(Solids)
|
requirePlugin(Solids)
|
||||||
GdmlShowCase.babyIaxo().toVision()
|
solid {
|
||||||
|
gdml(GdmlShowCase.babyIaxo(), "D0")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -6,6 +6,7 @@ import kotlinx.serialization.json.Json
|
|||||||
import space.kscience.visionforge.solid.SolidGroup
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
|
||||||
|
@OptIn(ExperimentalSerializationApi::class)
|
||||||
private val json = Json {
|
private val json = Json {
|
||||||
serializersModule = Solids.serializersModuleForSolids
|
serializersModule = Solids.serializersModuleForSolids
|
||||||
prettyPrintIndent = " "
|
prettyPrintIndent = " "
|
||||||
|
@ -1,15 +1,92 @@
|
|||||||
package space.kscience.visionforge.examples
|
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.html.ResourceLocation
|
||||||
import space.kscience.visionforge.plotly.plotly
|
import space.kscience.visionforge.plotly.plotly
|
||||||
|
|
||||||
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
|
fun main() = makeVisionFile(resourceLocation = ResourceLocation.SYSTEM) {
|
||||||
vision {
|
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 {
|
plotly {
|
||||||
scatter {
|
traces(trace1, trace2)
|
||||||
x(1, 2, 3)
|
layout {
|
||||||
y(5, 8, 7)
|
width = 800
|
||||||
|
height = 800
|
||||||
|
title = "Advanced Violin Plot"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package space.kscience.visionforge.examples
|
|||||||
|
|
||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
import kotlinx.html.h1
|
import kotlinx.html.h1
|
||||||
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import java.nio.file.Paths
|
import java.nio.file.Paths
|
||||||
@ -17,6 +18,9 @@ fun main() = makeVisionFile(
|
|||||||
div {
|
div {
|
||||||
vision {
|
vision {
|
||||||
solid {
|
solid {
|
||||||
|
ambientLight {
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
repeat(100) {
|
repeat(100) {
|
||||||
sphere(5, name = "sphere[$it]") {
|
sphere(5, name = "sphere[$it]") {
|
||||||
x = random.nextDouble(-300.0, 300.0)
|
x = random.nextDouble(-300.0, 300.0)
|
||||||
|
@ -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<String> = 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)
|
|
||||||
}
|
|
||||||
}*//*
|
|
||||||
}*/
|
|
@ -1,14 +1,24 @@
|
|||||||
package space.kscience.visionforge.examples
|
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.dataforge.context.Global
|
||||||
import space.kscience.visionforge.html.HtmlVisionFragment
|
import space.kscience.visionforge.html.*
|
||||||
import space.kscience.visionforge.html.Page
|
import space.kscience.visionforge.markup.MarkupPlugin
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.plotly.PlotlyPlugin
|
||||||
import space.kscience.visionforge.html.importScriptHeader
|
import space.kscience.visionforge.server.close
|
||||||
import space.kscience.visionforge.makeFile
|
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.awt.Desktop
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
|
|
||||||
public fun makeVisionFile(
|
public fun makeVisionFile(
|
||||||
path: Path? = null,
|
path: Path? = null,
|
||||||
title: String = "VisionForge page",
|
title: String = "VisionForge page",
|
||||||
@ -16,15 +26,58 @@ public fun makeVisionFile(
|
|||||||
show: Boolean = true,
|
show: Boolean = true,
|
||||||
content: HtmlVisionFragment,
|
content: HtmlVisionFragment,
|
||||||
): Unit {
|
): Unit {
|
||||||
val actualPath = Page(Global, content = content).makeFile(path) { actualPath ->
|
val actualPath = VisionPage(Global.visionManager, content = content).makeFile(path) { actualPath ->
|
||||||
mapOf(
|
mapOf(
|
||||||
"title" to Page.title(title),
|
"title" to VisionPage.title(title),
|
||||||
"playground" to Page.importScriptHeader("js/visionforge-playground.js", resourceLocation, actualPath),
|
"playground" to VisionPage.importScriptHeader(
|
||||||
|
"js/visionforge-playground.js",
|
||||||
|
resourceLocation,
|
||||||
|
actualPath
|
||||||
|
),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
if (show) Desktop.getDesktop().browse(actualPath.toFile().toURI())
|
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
|
//@DFExperimental
|
||||||
//public fun Context.makeVisionFile(
|
//public fun Context.makeVisionFile(
|
||||||
// vision: Vision,
|
// vision: Vision,
|
||||||
|
40
demo/playground/src/jvmMain/kotlin/shapes.kt
Normal file
40
demo/playground/src/jvmMain/kotlin/shapes.kt
Normal file
@ -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
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
demo/playground/src/jvmMain/kotlin/surface.kt
Normal file
19
demo/playground/src/jvmMain/kotlin/surface.kt
Normal file
@ -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) })
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
package space.kscience.visionforge.examples
|
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.ColumnHeader
|
||||||
import space.kscience.tables.valueRow
|
import space.kscience.tables.valueRow
|
||||||
import space.kscience.visionforge.html.ResourceLocation
|
import space.kscience.visionforge.html.ResourceLocation
|
||||||
|
Binary file not shown.
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
Binary file not shown.
Binary file not shown.
@ -1,5 +1,5 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.jvm")
|
id("space.kscience.gradle.jvm")
|
||||||
application
|
application
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8,15 +8,15 @@ kscience {
|
|||||||
// useSerialization {
|
// useSerialization {
|
||||||
// json()
|
// json()
|
||||||
// }
|
// }
|
||||||
application()
|
useKtor()
|
||||||
|
dependencies{
|
||||||
|
implementation("io.ktor:ktor-server-cio")
|
||||||
|
implementation(projects.visionforgeThreejs.visionforgeThreejsServer)
|
||||||
|
implementation(spclibs.logback.classic)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
group = "ru.mipt.npm"
|
group = "center.sciprog"
|
||||||
|
|
||||||
dependencies{
|
|
||||||
implementation(project(":visionforge-threejs:visionforge-threejs-server"))
|
|
||||||
implementation("ch.qos.logback:logback-classic:1.2.3")
|
|
||||||
}
|
|
||||||
|
|
||||||
application {
|
application {
|
||||||
mainClass.set("ru.mipt.npm.sat.SatServerKt")
|
mainClass.set("ru.mipt.npm.sat.SatServerKt")
|
||||||
|
@ -6,7 +6,7 @@ import space.kscience.visionforge.style
|
|||||||
import space.kscience.visionforge.useStyle
|
import space.kscience.visionforge.useStyle
|
||||||
import kotlin.math.PI
|
import kotlin.math.PI
|
||||||
|
|
||||||
internal fun visionOfSatellite(
|
internal fun Solids.visionOfSatellite(
|
||||||
layers: Int = 10,
|
layers: Int = 10,
|
||||||
layerHeight: Number = 10,
|
layerHeight: Number = 10,
|
||||||
xSegments: Int = 3,
|
xSegments: Int = 3,
|
||||||
@ -14,7 +14,7 @@ internal fun visionOfSatellite(
|
|||||||
xSegmentSize: Number = 30,
|
xSegmentSize: Number = 30,
|
||||||
ySegmentSize: Number = xSegmentSize,
|
ySegmentSize: Number = xSegmentSize,
|
||||||
fiberDiameter: Number = 1.0,
|
fiberDiameter: Number = 1.0,
|
||||||
): SolidGroup = SolidGroup {
|
): SolidGroup = solidGroup {
|
||||||
color("darkgreen")
|
color("darkgreen")
|
||||||
val transparent by style {
|
val transparent by style {
|
||||||
this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3
|
this[SolidMaterial.MATERIAL_OPACITY_KEY] = 0.3
|
||||||
@ -31,7 +31,7 @@ internal fun visionOfSatellite(
|
|||||||
val totalXSize = xSegments * xSegmentSize.toDouble()
|
val totalXSize = xSegments * xSegmentSize.toDouble()
|
||||||
val totalYSize = ySegments * ySegmentSize.toDouble()
|
val totalYSize = ySegments * ySegmentSize.toDouble()
|
||||||
for (layer in 1..layers) {
|
for (layer in 1..layers) {
|
||||||
group("layer[$layer]") {
|
solidGroup("layer[$layer]") {
|
||||||
for (i in 1..xSegments) {
|
for (i in 1..xSegments) {
|
||||||
for (j in 1..ySegments) {
|
for (j in 1..ySegments) {
|
||||||
box(xSegmentSize, ySegmentSize, layerHeight, name = "segment[$i,$j]") {
|
box(xSegmentSize, ySegmentSize, layerHeight, name = "segment[$i,$j]") {
|
||||||
@ -42,7 +42,7 @@ internal fun visionOfSatellite(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
group("fibers") {
|
solidGroup("fibers") {
|
||||||
for (i in 1..xSegments) {
|
for (i in 1..xSegments) {
|
||||||
cylinder(fiberDiameter, totalYSize) {
|
cylinder(fiberDiameter, totalYSize) {
|
||||||
useStyle(red)
|
useStyle(red)
|
||||||
|
@ -1,38 +1,57 @@
|
|||||||
package ru.mipt.npm.sat
|
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.coroutines.*
|
||||||
import kotlinx.html.div
|
import kotlinx.html.div
|
||||||
import kotlinx.html.h1
|
import kotlinx.html.h1
|
||||||
import space.kscience.dataforge.context.Context
|
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.dataforge.names.Name
|
||||||
import space.kscience.visionforge.html.Page
|
import space.kscience.visionforge.Colors
|
||||||
import space.kscience.visionforge.html.plus
|
import space.kscience.visionforge.html.VisionPage
|
||||||
import space.kscience.visionforge.server.close
|
import space.kscience.visionforge.server.close
|
||||||
import space.kscience.visionforge.server.openInBrowser
|
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.solid.*
|
||||||
import space.kscience.visionforge.three.threeJsHeader
|
import space.kscience.visionforge.three.threeJsHeader
|
||||||
import space.kscience.visionforge.visionManager
|
|
||||||
import kotlin.random.Random
|
import kotlin.random.Random
|
||||||
|
|
||||||
|
|
||||||
|
@Suppress("ExtractKtorModule")
|
||||||
fun main() {
|
fun main() {
|
||||||
val satContext = Context("sat") {
|
val satContext = Context("sat") {
|
||||||
plugin(Solids)
|
plugin(Solids)
|
||||||
}
|
}
|
||||||
|
|
||||||
//Create a geometry
|
val solids = satContext.request(Solids)
|
||||||
val sat = visionOfSatellite(ySegments = 3)
|
|
||||||
|
|
||||||
val server = satContext.visionManager.serve {
|
//Create a geometry
|
||||||
page(header = Page.threeJsHeader + Page.styleSheetHeader("css/styles.css")) {
|
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") {
|
div("flex-column") {
|
||||||
h1 { +"Satellite detector demo" }
|
h1 { +"Satellite detector demo" }
|
||||||
vision { sat }
|
vision { sat }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
}.start(false)
|
||||||
|
|
||||||
server.openInBrowser()
|
server.openInBrowser()
|
||||||
|
|
||||||
@ -46,7 +65,8 @@ fun main() {
|
|||||||
val targetVision = sat[target] as Solid
|
val targetVision = sat[target] as Solid
|
||||||
targetVision.color("red")
|
targetVision.color("red")
|
||||||
delay(1000)
|
delay(1000)
|
||||||
targetVision.color.clear()
|
//use to ensure that color is cleared
|
||||||
|
targetVision.color.value = Null
|
||||||
delay(500)
|
delay(500)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
21
demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt
Normal file
21
demo/sat-demo/src/main/kotlin/ru/mipt/npm/sat/static.kt
Normal file
@ -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")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,44 +1,26 @@
|
|||||||
import ru.mipt.npm.gradle.DependencyConfiguration
|
|
||||||
import ru.mipt.npm.gradle.FXModule
|
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
application
|
// application
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
useCoroutines()
|
useCoroutines()
|
||||||
val fxVersion: String by rootProject.extra
|
jvm()
|
||||||
useFx(FXModule.CONTROLS, version = fxVersion, configuration = DependencyConfiguration.IMPLEMENTATION)
|
js{
|
||||||
application()
|
binaries.executable()
|
||||||
}
|
}
|
||||||
|
dependencies {
|
||||||
kotlin {
|
implementation(projects.visionforgeSolid)
|
||||||
|
implementation(projects.visionforgeGdml)
|
||||||
jvm {
|
|
||||||
withJava()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
sourceSets {
|
jsMain {
|
||||||
commonMain {
|
implementation(projects.visionforgeThreejs)
|
||||||
dependencies {
|
|
||||||
implementation(project(":visionforge-solid"))
|
|
||||||
// implementation(project(":visionforge-gdml"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jvmMain {
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":visionforge-fx"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
jsMain {
|
|
||||||
dependencies {
|
|
||||||
implementation(project(":visionforge-threejs"))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
application {
|
kotlin.explicitApi = null
|
||||||
mainClassName = "space.kscience.visionforge.solid.demo.FXDemoAppKt"
|
|
||||||
}
|
//application {
|
||||||
|
// mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
|
||||||
|
//}
|
@ -3,7 +3,10 @@ package space.kscience.visionforge.solid.demo
|
|||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
|
||||||
public interface VisionLayout<in V: Vision> {
|
interface VisionLayout<in V: Vision> {
|
||||||
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
val solids: Solids
|
||||||
|
|
||||||
|
fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
|
||||||
}
|
}
|
@ -4,6 +4,8 @@ import kotlinx.coroutines.*
|
|||||||
import space.kscience.dataforge.meta.Meta
|
import space.kscience.dataforge.meta.Meta
|
||||||
import space.kscience.dataforge.meta.invoke
|
import space.kscience.dataforge.meta.invoke
|
||||||
import space.kscience.dataforge.names.Name
|
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.Colors
|
||||||
import space.kscience.visionforge.solid.*
|
import space.kscience.visionforge.solid.*
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
@ -18,7 +20,12 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
|
|||||||
val meta = Meta {
|
val meta = Meta {
|
||||||
"title" put title
|
"title" put title
|
||||||
}
|
}
|
||||||
val vision = SolidGroup(block)
|
val vision = solids.solidGroup {
|
||||||
|
block()
|
||||||
|
ambientLight {
|
||||||
|
color(Colors.white)
|
||||||
|
}
|
||||||
|
}
|
||||||
render(Name.parse(name), vision, meta)
|
render(Name.parse(name), vision, meta)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -39,6 +46,7 @@ val canvasOptions = Canvas3DOptions {
|
|||||||
@OptIn(DelicateCoroutinesApi::class)
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
fun VisionLayout<Solid>.showcase() {
|
fun VisionLayout<Solid>.showcase() {
|
||||||
demo("shapes", "Basic shapes") {
|
demo("shapes", "Basic shapes") {
|
||||||
|
ambientLight()
|
||||||
box(100.0, 100.0, 100.0) {
|
box(100.0, 100.0, 100.0) {
|
||||||
z = -110.0
|
z = -110.0
|
||||||
color("teal")
|
color("teal")
|
||||||
@ -62,7 +70,7 @@ fun VisionLayout<Solid>.showcase() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
demo("dynamic", "Dynamic properties") {
|
demo("dynamic", "Dynamic properties") {
|
||||||
val group = group {
|
val group = solidGroup {
|
||||||
box(100, 100, 100) {
|
box(100, 100, 100) {
|
||||||
z = 110.0
|
z = 110.0
|
||||||
opacity = 0.5
|
opacity = 0.5
|
||||||
@ -94,11 +102,18 @@ fun VisionLayout<Solid>.showcase() {
|
|||||||
|
|
||||||
demo("rotation", "Rotations") {
|
demo("rotation", "Rotations") {
|
||||||
box(100, 100, 100)
|
box(100, 100, 100)
|
||||||
group {
|
solidGroup {
|
||||||
x = 200
|
x = 200
|
||||||
rotationY = PI / 4
|
rotationY = PI / 4
|
||||||
|
axes(200)
|
||||||
box(100, 100, 100) {
|
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)
|
color(Colors.red)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -124,7 +139,10 @@ fun VisionLayout<Solid>.showcase() {
|
|||||||
color(Colors.blue)
|
color(Colors.blue)
|
||||||
}
|
}
|
||||||
repeat(20) {
|
repeat(20) {
|
||||||
polyline(Point3D(100, 100, 100), Point3D(-100, -100, -100)) {
|
polyline(
|
||||||
|
Float32Vector3D(100, 100, 100),
|
||||||
|
Float32Vector3D(-100, -100, -100)
|
||||||
|
) {
|
||||||
thickness = 3.0
|
thickness = 3.0
|
||||||
rotationX = it * PI2 / 20
|
rotationX = it * PI2 / 20
|
||||||
color(Colors.green)
|
color(Colors.green)
|
||||||
@ -141,6 +159,10 @@ fun VisionLayout<Solid>.showcase() {
|
|||||||
z = 26
|
z = 26
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
demo("STL", "STL loaded from URL") {
|
||||||
|
stl("https://ozeki.hu/attachments/116/Menger_sponge_sample.stl")
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun VisionLayout<Solid>.showcaseCSG() {
|
fun VisionLayout<Solid>.showcaseCSG() {
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
package space.kscience.visionforge.solid.demo
|
package space.kscience.visionforge.solid.demo
|
||||||
|
|
||||||
import kotlinx.browser.document
|
|
||||||
import kotlinx.coroutines.delay
|
import kotlinx.coroutines.delay
|
||||||
import kotlinx.coroutines.isActive
|
import kotlinx.coroutines.isActive
|
||||||
import kotlinx.coroutines.launch
|
import kotlinx.coroutines.launch
|
||||||
|
import org.w3c.dom.Document
|
||||||
import space.kscience.visionforge.Application
|
import space.kscience.visionforge.Application
|
||||||
import space.kscience.visionforge.solid.x
|
import space.kscience.visionforge.solid.x
|
||||||
import space.kscience.visionforge.solid.y
|
import space.kscience.visionforge.solid.y
|
||||||
@ -12,7 +12,7 @@ import kotlin.random.Random
|
|||||||
|
|
||||||
private class ThreeDemoApp : Application {
|
private class ThreeDemoApp : Application {
|
||||||
|
|
||||||
override fun start(state: Map<String, Any>) {
|
override fun start(document: Document, state: Map<String, Any>) {
|
||||||
|
|
||||||
val element = document.getElementById("demo") ?: error("Element with id 'demo' not found on page")
|
val element = document.getElementById("demo") ?: error("Element with id 'demo' not found on page")
|
||||||
|
|
||||||
|
@ -10,12 +10,13 @@ import org.w3c.dom.Element
|
|||||||
import org.w3c.dom.HTMLDivElement
|
import org.w3c.dom.HTMLDivElement
|
||||||
import org.w3c.dom.HTMLElement
|
import org.w3c.dom.HTMLElement
|
||||||
import space.kscience.dataforge.context.Global
|
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.Meta
|
||||||
import space.kscience.dataforge.meta.get
|
import space.kscience.dataforge.meta.get
|
||||||
import space.kscience.dataforge.meta.string
|
import space.kscience.dataforge.meta.string
|
||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.visionforge.solid.Solid
|
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.ThreeCanvas
|
||||||
import space.kscience.visionforge.solid.three.ThreePlugin
|
import space.kscience.visionforge.solid.three.ThreePlugin
|
||||||
|
|
||||||
@ -25,7 +26,9 @@ class ThreeDemoGrid(element: Element) : VisionLayout<Solid> {
|
|||||||
|
|
||||||
private val outputs: MutableMap<Name, ThreeCanvas> = HashMap()
|
private val outputs: MutableMap<Name, ThreeCanvas> = HashMap()
|
||||||
|
|
||||||
private val three = Global.fetch(ThreePlugin)
|
private val three = Global.request(ThreePlugin)
|
||||||
|
|
||||||
|
override val solids: Solids get() = three.solids
|
||||||
|
|
||||||
init {
|
init {
|
||||||
element.clear()
|
element.clear()
|
||||||
|
@ -1,20 +1,19 @@
|
|||||||
package space.kscience.visionforge.solid.demo
|
package space.kscience.visionforge.solid.demo
|
||||||
|
|
||||||
import info.laht.threekt.core.Object3D
|
import space.kscience.dataforge.meta.asValue
|
||||||
import info.laht.threekt.geometries.BoxGeometry
|
|
||||||
import info.laht.threekt.objects.Mesh
|
|
||||||
import space.kscience.dataforge.meta.get
|
|
||||||
import space.kscience.dataforge.meta.int
|
import space.kscience.dataforge.meta.int
|
||||||
import space.kscience.dataforge.meta.number
|
import space.kscience.dataforge.meta.number
|
||||||
import space.kscience.dataforge.names.asName
|
import space.kscience.dataforge.names.asName
|
||||||
import space.kscience.dataforge.names.startsWith
|
import space.kscience.dataforge.names.startsWith
|
||||||
import space.kscience.dataforge.values.asValue
|
|
||||||
import space.kscience.visionforge.onPropertyChange
|
import space.kscience.visionforge.onPropertyChange
|
||||||
import space.kscience.visionforge.set
|
import space.kscience.visionforge.setChild
|
||||||
import space.kscience.visionforge.setProperty
|
|
||||||
import space.kscience.visionforge.solid.SolidGroup
|
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.layer
|
||||||
import space.kscience.visionforge.solid.three.*
|
import space.kscience.visionforge.solid.three.*
|
||||||
|
import three.core.Object3D
|
||||||
|
import three.geometries.BoxGeometry
|
||||||
|
import three.objects.Mesh
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
internal fun SolidGroup.varBox(
|
internal fun SolidGroup.varBox(
|
||||||
@ -22,11 +21,11 @@ internal fun SolidGroup.varBox(
|
|||||||
ySize: Number,
|
ySize: Number,
|
||||||
name: String = "",
|
name: String = "",
|
||||||
action: VariableBox.() -> Unit = {},
|
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() {
|
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 geometry = BoxGeometry(xSize, ySize, 1)
|
||||||
|
|
||||||
val material = ThreeMaterials.DEFAULT.clone()
|
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)
|
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
|
//add listener to object properties
|
||||||
onPropertyChange { name ->
|
onPropertyChange { name ->
|
||||||
when {
|
when {
|
||||||
name == VALUE -> {
|
name == VALUE -> {
|
||||||
val value = meta.get(VALUE).int ?: 0
|
val value = properties.getValue(VALUE)?.int ?: 0
|
||||||
val size = value.toFloat() / 255f * 20f
|
val size = value.toFloat() / 255f * 20f
|
||||||
mesh.scale.z = size.toDouble()
|
mesh.scale.z = size.toDouble()
|
||||||
mesh.position.z = size.toDouble() / 2
|
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)
|
material.color.setRGB(r.toFloat() / 256, g.toFloat() / 256, b.toFloat() / 256)
|
||||||
mesh.updateMatrix()
|
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)
|
else -> mesh.updateProperty(this@VariableBox, name)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -70,9 +70,9 @@ internal class VariableBox(val xSize: Number, val ySize: Number) : ThreeJsVision
|
|||||||
}
|
}
|
||||||
|
|
||||||
var value: Int
|
var value: Int
|
||||||
get() = meta[VALUE].int ?: 0
|
get() = properties.getValue(VALUE)?.int ?: 0
|
||||||
set(value) {
|
set(value) {
|
||||||
setProperty(VALUE, value.asValue())
|
properties.setValue(VALUE, value.asValue())
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
@ -10,9 +10,11 @@ import space.kscience.dataforge.names.Name
|
|||||||
import space.kscience.visionforge.solid.FX3DPlugin
|
import space.kscience.visionforge.solid.FX3DPlugin
|
||||||
import space.kscience.visionforge.solid.FXCanvas3D
|
import space.kscience.visionforge.solid.FXCanvas3D
|
||||||
import space.kscience.visionforge.solid.Solid
|
import space.kscience.visionforge.solid.Solid
|
||||||
|
import space.kscience.visionforge.solid.Solids
|
||||||
import tornadofx.*
|
import tornadofx.*
|
||||||
|
|
||||||
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
||||||
|
|
||||||
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
private val outputs = FXCollections.observableHashMap<Name, FXCanvas3D>()
|
||||||
|
|
||||||
override val root: Parent = borderpane {
|
override val root: Parent = borderpane {
|
||||||
@ -24,6 +26,9 @@ class FXDemoGrid : View(title = "DataForge-vis FX demo"), VisionLayout<Solid> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private val fx3d = Global.fetch(FX3DPlugin)
|
private val fx3d = Global.fetch(FX3DPlugin)
|
||||||
|
override val solids: Solids get() = fx3d.solids
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
override fun render(name: Name, vision: Solid, meta: Meta) {
|
override fun render(name: Name, vision: Solid, meta: Meta) {
|
||||||
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
outputs.getOrPut(name) { FXCanvas3D(fx3d, canvasOptions) }.render(vision)
|
@ -2,10 +2,10 @@ package space.kscience.visionforge.demo
|
|||||||
|
|
||||||
import javafx.geometry.Orientation
|
import javafx.geometry.Orientation
|
||||||
import space.kscience.dataforge.meta.MutableMeta
|
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.MetaDescriptor
|
||||||
import space.kscience.dataforge.meta.descriptors.node
|
import space.kscience.dataforge.meta.descriptors.node
|
||||||
import space.kscience.dataforge.meta.descriptors.value
|
import space.kscience.dataforge.meta.descriptors.value
|
||||||
import space.kscience.dataforge.values.ValueType
|
|
||||||
import space.kscience.visionforge.editor.FXMetaModel
|
import space.kscience.visionforge.editor.FXMetaModel
|
||||||
import space.kscience.visionforge.editor.MetaViewer
|
import space.kscience.visionforge.editor.MetaViewer
|
||||||
import space.kscience.visionforge.editor.MutableMetaEditor
|
import space.kscience.visionforge.editor.MutableMetaEditor
|
@ -3,7 +3,7 @@
|
|||||||
![](../docs/images/hierarchy.png)
|
![](../docs/images/hierarchy.png)
|
||||||
|
|
||||||
### Vision
|
### 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
|
* 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.
|
Sets the `item` property to the element with the `name` identification.
|
||||||
|
@ -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
|
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.
|
`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:
|
The order is this:
|
||||||
* own styles
|
* own styles
|
||||||
* prototypes
|
* prototypes
|
||||||
|
@ -59,7 +59,7 @@ box(10, 10, 10, name = "small box"){
|
|||||||
rotation = Point3D(0, 0, 0)
|
rotation = Point3D(0, 0, 0)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/small-box.png)
|
![](../images/small-box.png)
|
||||||
|
|
||||||
The `big box` will have properties with custom values.
|
The `big box` will have properties with custom values.
|
||||||
```kotlin
|
```kotlin
|
||||||
@ -72,7 +72,7 @@ box(40, 40, 40, name = "big box"){
|
|||||||
rotation = Point3D(60, 80, 0)
|
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.
|
If we compare these boxes, we will see all differences.
|
||||||
|
|
||||||
Here is the function `main` with both boxes.
|
Here is the function `main` with both boxes.
|
||||||
@ -111,8 +111,8 @@ fun main(){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/two-boxes-1.png)
|
![](../images/two-boxes-1.png)
|
||||||
![](../docs/images/two-boxes-2.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.***
|
***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)
|
![](../images/polyline-points.png)
|
||||||
![](../docs/images/polyline-points-2.png)
|
![](../images/polyline-points-2.png)
|
||||||
|
|
||||||
### 2) Box
|
### 2) Box
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ Let's create just usual `box` with equal ribs.
|
|||||||
color("pink")
|
color("pink")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/box.png)
|
![](../images/box.png)
|
||||||
|
|
||||||
Now, let's make `box` with bigger `y` value.
|
Now, let's make `box` with bigger `y` value.
|
||||||
```kotlin
|
```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.
|
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.
|
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.
|
Predictably, only the `x-axis` rib is bigger than other ribs.
|
||||||
|
|
||||||
![](../docs/images/wide-box.png)
|
![](../images/wide-box.png)
|
||||||
|
|
||||||
### 3) Sphere
|
### 3) Sphere
|
||||||
|
|
||||||
@ -206,7 +206,7 @@ As for `radius`, it has `Float` type, and, as you can guess, it sets the radius
|
|||||||
color("blue")
|
color("blue")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/sphere.png)
|
![](../images/sphere.png)
|
||||||
|
|
||||||
### 4) Hexagon
|
### 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`
|
5) Edge with vertices `node1`, `node5`, `node8`, `node4`
|
||||||
6) Edge with vertices `node8`, `node5`, `node6`, `node7`
|
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.
|
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")
|
color("green")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/classic-hexagon.png)
|
![](../images/classic-hexagon.png)
|
||||||
|
|
||||||
Now, let's make a custom hexagon.
|
Now, let's make a custom hexagon.
|
||||||
|
|
||||||
@ -258,7 +258,7 @@ hexagon(
|
|||||||
color("brown")
|
color("brown")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/custom-hexagon.png)
|
![](../images/custom-hexagon.png)
|
||||||
### 3) Cone
|
### 3) Cone
|
||||||
It takes in six values: `bottomRadius`, `height`, `upperRadius`, `startAngle`, `angle`, and `name`.
|
It takes in six values: `bottomRadius`, `height`, `upperRadius`, `startAngle`, `angle`, and `name`.
|
||||||
|
|
||||||
@ -274,8 +274,8 @@ Let's build a classic cone:
|
|||||||
color("beige")
|
color("beige")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/cone-1.png)
|
![](../images/cone-1.png)
|
||||||
![](../docs/images/cone-2.png)
|
![](../images/cone-2.png)
|
||||||
|
|
||||||
First of all, we have to try to build a frustum cone:
|
First of all, we have to try to build a frustum cone:
|
||||||
```kotlin
|
```kotlin
|
||||||
@ -283,7 +283,7 @@ cone(60, 80, name = "cone") {
|
|||||||
color(0u, 40u, 0u)
|
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:
|
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)
|
color(0u, 0u, 200u)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/cone-segment-1.png)
|
![](../images/cone-segment-1.png)
|
||||||
![](../docs/images/cone-segment-2.png)
|
![](../images/cone-segment-2.png)
|
||||||
|
|
||||||
Finally, the segment of frustum cone is left for a try:
|
Finally, the segment of frustum cone is left for a try:
|
||||||
```kotlin
|
```kotlin
|
||||||
@ -301,7 +301,7 @@ cone(60, 100, 20, PI*3/4, angle = PI/3, name = "cone") {
|
|||||||
color(190u, 0u, 0u)
|
color(190u, 0u, 0u)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/frustum-cone-segment.png)
|
![](../images/frustum-cone-segment.png)
|
||||||
|
|
||||||
### 4) Cone Surface
|
### 4) Cone Surface
|
||||||
This solid is set by seven values:`bottomOuterRadius`, `bottomInnerRadius`, `height`, `topOuterRadius`, `topInnerRadius`, `startAngle`, and `angle`.
|
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)
|
rotation = Point3D(2, 50, -9)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/cone-surface-1.png)
|
![](../images/cone-surface-1.png)
|
||||||
![](../docs/images/cone-surface-2.png)
|
![](../images/cone-surface-2.png)
|
||||||
|
|
||||||
Now, let's create a cone surface and set all it's properties:
|
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)
|
rotation = Point3D(2, 50, -9)
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/cone-surface-fragment.png)
|
![](../images/cone-surface-fragment.png)
|
||||||
![](../docs/images/cone-surface-fragment-2.png)
|
![](../images/cone-surface-fragment-2.png)
|
||||||
|
|
||||||
### 5) Cylinder
|
### 5) Cylinder
|
||||||
|
|
||||||
@ -344,8 +344,8 @@ cylinder(40, 100, "cylinder"){
|
|||||||
color("indigo")
|
color("indigo")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/cylinder-1.png)
|
![](../images/cylinder-1.png)
|
||||||
![](../docs/images/cylinder-2.png)
|
![](../images/cylinder-2.png)
|
||||||
### 6) Tube
|
### 6) Tube
|
||||||
|
|
||||||
`tube` takes in `radius`, `height`, `innerRadius`, `startAngle`, `angle`, and `name`. *All values are familiar from `cone`, and `coneSurface` solids.*
|
`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
|
opacity = 0.4
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/tube.png)
|
![](../images/tube.png)
|
||||||
|
|
||||||
This is an example of tube fragment:
|
This is an example of tube fragment:
|
||||||
|
|
||||||
@ -365,7 +365,7 @@ tube(50, 40, 20, 0f, PI, name = "fragmented tube"){
|
|||||||
color("white")
|
color("white")
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
![](../docs/images/tube-fragment.png)
|
![](../images/tube-fragment.png)
|
||||||
### 7) Extruded
|
### 7) Extruded
|
||||||
|
|
||||||
`extruded` is set by two values: `shape`, and `layer`.
|
`extruded` is set by two values: `shape`, and `layer`.
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
interface Vision{
|
interface Vision{
|
||||||
val parent: VisionGroup?
|
val parent: VisionGroup?
|
||||||
fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value?
|
fun getProperty(name,inherit,includeStyles,includeDefaults): Value?
|
||||||
}
|
}
|
||||||
|
|
||||||
interface Solid{
|
interface Solid{
|
||||||
@ -81,7 +81,7 @@ Solid <--- Composite
|
|||||||
|
|
||||||
interface SolidReference{
|
interface SolidReference{
|
||||||
val prototype: Solid
|
val prototype: Solid
|
||||||
fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value?
|
fun getProperty(name,inherit,includeStyles,includeDefaults): Value?
|
||||||
}
|
}
|
||||||
VisionGroup <---- SolidReference
|
VisionGroup <---- SolidReference
|
||||||
SolidReferenceGroup -- SolidReference
|
SolidReferenceGroup -- SolidReference
|
||||||
@ -91,7 +91,7 @@ class SolidReferenceGroup{
|
|||||||
var properties: MutableMeta?
|
var properties: MutableMeta?
|
||||||
val prototype: Solid
|
val prototype: Solid
|
||||||
val children: Map<NameToken, Vision>
|
val children: Map<NameToken, Vision>
|
||||||
fun getPropertyValue(name,inherit,includeStyles,includeDefaults): Value?
|
fun getProperty(name,inherit,includeStyles,includeDefaults): Value?
|
||||||
}
|
}
|
||||||
VisionBase <-- SolidReferenceGroup
|
VisionBase <-- SolidReferenceGroup
|
||||||
VisionGroup <-- SolidReferenceGroup
|
VisionGroup <-- SolidReferenceGroup
|
||||||
|
@ -1,12 +1,13 @@
|
|||||||
kotlin.code.style=official
|
kotlin.code.style=official
|
||||||
kotlin.mpp.stability.nowarn=true
|
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.parallel=true
|
||||||
|
org.gradle.jvmargs=-Xmx4G
|
||||||
|
|
||||||
publishing.github=false
|
org.jetbrains.compose.experimental.jscanvas.enabled=true
|
||||||
publishing.sonatype=false
|
|
||||||
|
|
||||||
toolsVersion=0.11.1-kotlin-1.6.10
|
toolsVersion=0.15.2-kotlin-1.9.21
|
||||||
|
#kotlin.experimental.tryK2=true
|
||||||
|
#kscience.wasm.disabled=true
|
||||||
|
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@ -1,5 +1,5 @@
|
|||||||
distributionBase=GRADLE_USER_HOME
|
distributionBase=GRADLE_USER_HOME
|
||||||
distributionPath=wrapper/dists
|
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
|
zipStoreBase=GRADLE_USER_HOME
|
||||||
zipStorePath=wrapper/dists
|
zipStorePath=wrapper/dists
|
||||||
|
@ -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
|
|
||||||
}
|
|
@ -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<HtmlFragment> { fragment ->
|
|
||||||
handler.produceHtml(fragment = fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
render<HtmlVisionFragment> { fragment ->
|
|
||||||
handler.produceHtml(fragment = fragment)
|
|
||||||
}
|
|
||||||
|
|
||||||
render<Vision> { vision ->
|
|
||||||
handler.produceHtml {
|
|
||||||
vision { vision }
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
render<Page> { page ->
|
|
||||||
HTML(page.render(createHTML()), true)
|
|
||||||
}
|
|
||||||
|
|
||||||
render<HtmlFormFragment> { 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()
|
|
||||||
}
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
@ -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")
|
|
||||||
}
|
|
||||||
```
|
|
@ -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<ProcessResources>("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
|
|
||||||
}
|
|
@ -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)
|
|
||||||
}
|
|
||||||
|
|
@ -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<Gdml> { gdmlModel ->
|
|
||||||
handler.produceHtml {
|
|
||||||
vision { gdmlModel.toVision() }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,3 +0,0 @@
|
|||||||
const ringConfig = require('@jetbrains/ring-ui/webpack.config').config;
|
|
||||||
|
|
||||||
config.module.rules.push(...ringConfig.module.rules)
|
|
@ -1,7 +1,6 @@
|
|||||||
rootProject.name = "visionforge"
|
rootProject.name = "visionforge"
|
||||||
|
|
||||||
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
enableFeaturePreview("TYPESAFE_PROJECT_ACCESSORS")
|
||||||
enableFeaturePreview("VERSION_CATALOGS")
|
|
||||||
|
|
||||||
pluginManagement {
|
pluginManagement {
|
||||||
|
|
||||||
@ -12,13 +11,14 @@ pluginManagement {
|
|||||||
maven("https://repo.kotlin.link")
|
maven("https://repo.kotlin.link")
|
||||||
mavenCentral()
|
mavenCentral()
|
||||||
gradlePluginPortal()
|
gradlePluginPortal()
|
||||||
|
maven("https://maven.pkg.jetbrains.space/public/p/compose/dev")
|
||||||
}
|
}
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
id("ru.mipt.npm.gradle.project") version toolsVersion
|
id("space.kscience.gradle.project") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.mpp") version toolsVersion
|
id("space.kscience.gradle.mpp") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.jvm") version toolsVersion
|
id("space.kscience.gradle.jvm") version toolsVersion
|
||||||
id("ru.mipt.npm.gradle.js") version toolsVersion
|
id("space.kscience.gradle.js") version toolsVersion
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,8 +33,8 @@ dependencyResolutionManagement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
versionCatalogs {
|
versionCatalogs {
|
||||||
create("npmlibs") {
|
create("spclibs") {
|
||||||
from("ru.mipt.npm:version-catalog:$toolsVersion")
|
from("space.kscience:version-catalog:$toolsVersion")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -45,9 +45,10 @@ include(
|
|||||||
":ui:ring",
|
":ui:ring",
|
||||||
// ":ui:material",
|
// ":ui:material",
|
||||||
":ui:bootstrap",
|
":ui:bootstrap",
|
||||||
|
":ui:compose",
|
||||||
":visionforge-core",
|
":visionforge-core",
|
||||||
":visionforge-solid",
|
":visionforge-solid",
|
||||||
":visionforge-fx",
|
// ":visionforge-fx",
|
||||||
":visionforge-threejs",
|
":visionforge-threejs",
|
||||||
":visionforge-threejs:visionforge-threejs-server",
|
":visionforge-threejs:visionforge-threejs-server",
|
||||||
":visionforge-gdml",
|
":visionforge-gdml",
|
||||||
@ -61,8 +62,8 @@ include(
|
|||||||
":demo:muon-monitor",
|
":demo:muon-monitor",
|
||||||
":demo:sat-demo",
|
":demo:sat-demo",
|
||||||
":demo:playground",
|
":demo:playground",
|
||||||
":demo:plotly-fx",
|
// ":demo:plotly-fx",
|
||||||
":demo:js-playground",
|
":demo:js-playground",
|
||||||
":jupyter",
|
":visionforge-jupyter",
|
||||||
":jupyter:visionforge-jupyter-gdml"
|
":visionforge-jupyter:visionforge-jupyter-common"
|
||||||
)
|
)
|
||||||
|
@ -1,15 +1,19 @@
|
|||||||
plugins {
|
plugins {
|
||||||
kotlin("js")
|
id("space.kscience.gradle.mpp")
|
||||||
id("ru.mipt.npm.gradle.js")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
val dataforgeVersion: String by rootProject.extra
|
val dataforgeVersion: String by rootProject.extra
|
||||||
|
|
||||||
dependencies {
|
kscience{
|
||||||
api(project(":visionforge-solid"))
|
js()
|
||||||
api(project(":ui:react"))
|
jsMain{
|
||||||
implementation(npm("file-saver", "2.0.2"))
|
dependencies {
|
||||||
implementation(npm("bootstrap","4.6.0"))
|
api(project(":visionforge-solid"))
|
||||||
implementation(npm("jquery","3.5.1"))
|
api(project(":ui:react"))
|
||||||
implementation(npm("popper.js","1.16.1"))
|
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"))
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
@ -1,8 +1,8 @@
|
|||||||
package space.kscience.visionforge.bootstrap
|
package space.kscience.visionforge.bootstrap
|
||||||
|
|
||||||
public fun useBootstrap(){
|
public fun useBootstrap(){
|
||||||
kotlinext.js.require("bootstrap/dist/css/bootstrap.min.css")
|
kotlinext.js.require<dynamic>("bootstrap/dist/css/bootstrap.min.css")
|
||||||
kotlinext.js.require("bootstrap")
|
kotlinext.js.require<dynamic>("bootstrap")
|
||||||
}
|
}
|
||||||
|
|
||||||
//public inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
//public inline fun TagConsumer<HTMLElement>.card(title: String, crossinline block: TagConsumer<HTMLElement>.() -> Unit) {
|
@ -1,10 +1,8 @@
|
|||||||
package space.kscience.visionforge.bootstrap
|
package space.kscience.visionforge.bootstrap
|
||||||
|
|
||||||
import kotlinx.css.BorderStyle
|
import kotlinx.coroutines.DelicateCoroutinesApi
|
||||||
import kotlinx.css.Color
|
import kotlinx.coroutines.GlobalScope
|
||||||
import kotlinx.css.padding
|
import kotlinx.css.*
|
||||||
import kotlinx.css.properties.border
|
|
||||||
import kotlinx.css.px
|
|
||||||
import kotlinx.html.js.onClickFunction
|
import kotlinx.html.js.onClickFunction
|
||||||
import org.w3c.dom.events.Event
|
import org.w3c.dom.events.Event
|
||||||
import org.w3c.files.Blob
|
import org.w3c.files.Blob
|
||||||
@ -15,7 +13,6 @@ import react.RBuilder
|
|||||||
import react.dom.attrs
|
import react.dom.attrs
|
||||||
import react.dom.button
|
import react.dom.button
|
||||||
import react.fc
|
import react.fc
|
||||||
import space.kscience.dataforge.meta.withDefault
|
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.encodeToString
|
import space.kscience.visionforge.encodeToString
|
||||||
import space.kscience.visionforge.react.flexColumn
|
import space.kscience.visionforge.react.flexColumn
|
||||||
@ -28,7 +25,7 @@ private fun saveData(event: Event, fileName: String, mimeType: String = "text/pl
|
|||||||
event.stopPropagation();
|
event.stopPropagation();
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
|
|
||||||
val fileSaver = kotlinext.js.require("file-saver")
|
val fileSaver = kotlinext.js.require<dynamic>("file-saver")
|
||||||
val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8"))
|
val blob = Blob(arrayOf(dataBuilder()), BlobPropertyBag("$mimeType;charset=utf-8"))
|
||||||
fileSaver.saveAs(blob, fileName)
|
fileSaver.saveAs(blob, fileName)
|
||||||
}
|
}
|
||||||
@ -47,12 +44,13 @@ public external interface CanvasControlsProps : Props {
|
|||||||
public var vision: Vision?
|
public var vision: Vision?
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public val CanvasControls: FC<CanvasControlsProps> = fc("CanvasControls") { props ->
|
public val CanvasControls: FC<CanvasControlsProps> = fc("CanvasControls") { props ->
|
||||||
flexColumn {
|
flexColumn {
|
||||||
flexRow {
|
flexRow {
|
||||||
css {
|
css {
|
||||||
border(1.px, BorderStyle.solid, Color.blue)
|
border = Border(1.px, BorderStyle.solid, Color.blue)
|
||||||
padding(4.px)
|
padding = Padding(4.px)
|
||||||
}
|
}
|
||||||
props.vision?.let { vision ->
|
props.vision?.let { vision ->
|
||||||
button {
|
button {
|
||||||
@ -68,9 +66,10 @@ public val CanvasControls: FC<CanvasControlsProps> = fc("CanvasControls") { prop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@OptIn(DelicateCoroutinesApi::class)
|
||||||
propertyEditor(
|
propertyEditor(
|
||||||
ownProperties = props.canvasOptions.meta,
|
scope = props.vision?.manager?.context ?: GlobalScope,
|
||||||
allProperties = props.canvasOptions.meta.withDefault(Canvas3DOptions.descriptor.defaultNode),
|
properties = props.canvasOptions.meta,
|
||||||
descriptor = Canvas3DOptions.descriptor,
|
descriptor = Canvas3DOptions.descriptor,
|
||||||
expanded = false
|
expanded = false
|
||||||
)
|
)
|
@ -30,7 +30,7 @@ public external interface TabPaneProps : PropsWithChildren {
|
|||||||
public val TabPane: FC<TabPaneProps> = fc("TabPane") { props ->
|
public val TabPane: FC<TabPaneProps> = fc("TabPane") { props ->
|
||||||
var activeTab: String? by useState(props.activeTab)
|
var activeTab: String? by useState(props.activeTab)
|
||||||
|
|
||||||
val children: Array<out ReactElement?> = Children.map(props.children) {
|
val children: Array<out ReactElement<*>?> = Children.map(props.children) {
|
||||||
it.asElementOrNull()
|
it.asElementOrNull()
|
||||||
} ?: emptyArray()
|
} ?: emptyArray()
|
||||||
|
|
@ -1,7 +1,6 @@
|
|||||||
package space.kscience.visionforge.bootstrap
|
package space.kscience.visionforge.bootstrap
|
||||||
|
|
||||||
import kotlinx.css.*
|
import kotlinx.css.*
|
||||||
import kotlinx.css.properties.border
|
|
||||||
import react.FC
|
import react.FC
|
||||||
import react.PropsWithChildren
|
import react.PropsWithChildren
|
||||||
import react.RBuilder
|
import react.RBuilder
|
||||||
@ -10,8 +9,8 @@ import react.fc
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.isEmpty
|
import space.kscience.dataforge.names.isEmpty
|
||||||
import space.kscience.visionforge.Vision
|
import space.kscience.visionforge.Vision
|
||||||
import space.kscience.visionforge.VisionGroup
|
|
||||||
import space.kscience.visionforge.react.visionTree
|
import space.kscience.visionforge.react.visionTree
|
||||||
|
import space.kscience.visionforge.solid.SolidGroup
|
||||||
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
|
||||||
import styled.css
|
import styled.css
|
||||||
import styled.styledDiv
|
import styled.styledDiv
|
||||||
@ -33,13 +32,13 @@ public val ThreeControls: FC<ThreeControlsProps> = fc { props ->
|
|||||||
}
|
}
|
||||||
tab("Tree") {
|
tab("Tree") {
|
||||||
css {
|
css {
|
||||||
border(1.px, BorderStyle.solid, Color.lightGray)
|
border = Border(1.px, BorderStyle.solid, Color.lightGray)
|
||||||
padding(10.px)
|
padding = Padding(10.px)
|
||||||
}
|
}
|
||||||
h2 { +"Object tree" }
|
h2 { +"Object tree" }
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
flex(1.0, 1.0, FlexBasis.inherit)
|
flex = Flex(1.0, 1.0, FlexBasis.inherit)
|
||||||
}
|
}
|
||||||
props.vision?.let {
|
props.vision?.let {
|
||||||
visionTree(it, props.selected, props.onSelect)
|
visionTree(it, props.selected, props.onSelect)
|
||||||
@ -51,7 +50,7 @@ public val ThreeControls: FC<ThreeControlsProps> = fc { props ->
|
|||||||
val selectedObject: Vision? = when {
|
val selectedObject: Vision? = when {
|
||||||
selected == null -> null
|
selected == null -> null
|
||||||
selected.isEmpty() -> props.vision
|
selected.isEmpty() -> props.vision
|
||||||
else -> (props.vision as? VisionGroup)?.get(selected)
|
else -> (props.vision as? SolidGroup)?.get(selected)
|
||||||
}
|
}
|
||||||
if (selectedObject != null) {
|
if (selectedObject != null) {
|
||||||
visionPropertyEditor(selectedObject, key = selected)
|
visionPropertyEditor(selectedObject, key = selected)
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user