feature/root #69
@ -16,7 +16,7 @@ allprojects {
|
|||||||
}
|
}
|
||||||
|
|
||||||
group = "space.kscience"
|
group = "space.kscience"
|
||||||
version = "0.2.0-dev-23"
|
version = "0.2.0-dev-24"
|
||||||
}
|
}
|
||||||
|
|
||||||
subprojects {
|
subprojects {
|
||||||
|
@ -15,7 +15,6 @@ public fun MetaProvider.doubleArray(
|
|||||||
it?.doubleArray ?: doubleArrayOf(*default)
|
it?.doubleArray ?: doubleArrayOf(*default)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public class DObjectCache(private val cache: List<Meta>, public val refStack: List<Int> = emptyList()) {
|
public class DObjectCache(private val cache: List<Meta>, public val refStack: List<Int> = emptyList()) {
|
||||||
public operator fun get(index: Int): Meta = cache[index]
|
public operator fun get(index: Int): Meta = cache[index]
|
||||||
|
|
||||||
@ -25,28 +24,6 @@ public class DObjectCache(private val cache: List<Meta>, public val refStack: Li
|
|||||||
public val empty: DObjectCache = DObjectCache(emptyList(), emptyList())
|
public val empty: DObjectCache = DObjectCache(emptyList(), emptyList())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//
|
|
||||||
//public interface ObjectRef<T : DObject> {
|
|
||||||
// public fun resolve(): T?
|
|
||||||
//}
|
|
||||||
|
|
||||||
//public class ChildObjectRef<T : DObject>(
|
|
||||||
// public val builder: (Meta, DObjectCache) -> T,
|
|
||||||
// public val refCache: DObjectCache,
|
|
||||||
// public val metaProvider: () -> Meta?
|
|
||||||
//) : ObjectRef<T> {
|
|
||||||
// override fun resolve(): T? {
|
|
||||||
// val meta = metaProvider() ?: return null
|
|
||||||
// meta["\$ref"]?.int?.let { refId ->
|
|
||||||
// if (refCache.refStack.contains(refId)) {
|
|
||||||
// println("Circular reference $refId in stack ${refCache.refStack}")
|
|
||||||
// return null
|
|
||||||
// }
|
|
||||||
// return builder(refCache[refId], refCache.stack(refId))
|
|
||||||
// }
|
|
||||||
// return builder(meta, refCache)
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
public open class DObject(public val meta: Meta, private val refCache: DObjectCache) {
|
public open class DObject(public val meta: Meta, private val refCache: DObjectCache) {
|
||||||
|
|
||||||
|
@ -4,6 +4,7 @@ import space.kscience.dataforge.meta.*
|
|||||||
import space.kscience.dataforge.names.Name
|
import space.kscience.dataforge.names.Name
|
||||||
import space.kscience.dataforge.names.plus
|
import space.kscience.dataforge.names.plus
|
||||||
import space.kscience.dataforge.values.doubleArray
|
import space.kscience.dataforge.values.doubleArray
|
||||||
|
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.*
|
||||||
@ -16,7 +17,16 @@ private operator fun Number.times(f: Float) = toFloat() * f
|
|||||||
|
|
||||||
private fun degToRad(d: Double) = d * PI / 180.0
|
private fun degToRad(d: Double) = d * PI / 180.0
|
||||||
|
|
||||||
private class RootToSolidContext(val prototypeHolder: PrototypeHolder)
|
private class RootToSolidContext(val prototypeHolder: PrototypeHolder, val maxLayer: Int = 3) {
|
||||||
|
val layers: MutableList<Int> = mutableListOf(0)
|
||||||
|
|
||||||
|
val layerLimits = listOf(10_000, 25_000, 50_000, 100_000, 200_000, 400_000, 600_000)
|
||||||
|
|
||||||
|
val bottomLayer: Int get() = layers.size - 1
|
||||||
|
fun addLayer() {
|
||||||
|
layers.add(0)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
|
// converting to XYZ to Tait–Bryan angles according to https://en.wikipedia.org/wiki/Euler_angles#Rotation_matrix
|
||||||
private fun Solid.rotate(rot: DoubleArray) {
|
private fun Solid.rotate(rot: DoubleArray) {
|
||||||
@ -67,157 +77,164 @@ private fun Solid.useMatrix(matrix: DGeoMatrix?) {
|
|||||||
private fun SolidGroup.addShape(
|
private fun SolidGroup.addShape(
|
||||||
shape: DGeoShape,
|
shape: DGeoShape,
|
||||||
context: RootToSolidContext,
|
context: RootToSolidContext,
|
||||||
name: String? = shape.fName.ifEmpty { null }
|
name: String? = shape.fName.ifEmpty { null },
|
||||||
): Solid? = when (shape.typename) {
|
block: Solid.() -> Unit = {}
|
||||||
"TGeoCompositeShape" -> {
|
) {
|
||||||
val fNode: DGeoBoolNode? by shape.dObject(::DGeoBoolNode)
|
when (shape.typename) {
|
||||||
val node = fNode ?: error("Composite shape node not resolved")
|
"TGeoCompositeShape" -> {
|
||||||
val compositeType = when (node.typename) {
|
val fNode: DGeoBoolNode? by shape.dObject(::DGeoBoolNode)
|
||||||
"TGeoIntersection" -> CompositeType.INTERSECT
|
val node = fNode ?: error("Composite shape node not resolved")
|
||||||
"TGeoSubtraction" -> CompositeType.SUBTRACT
|
val compositeType = when (node.typename) {
|
||||||
"TGeoUnion" -> CompositeType.GROUP
|
"TGeoIntersection" -> CompositeType.INTERSECT
|
||||||
else -> error("Unknown bool node type ${node.typename}")
|
"TGeoSubtraction" -> CompositeType.SUBTRACT
|
||||||
}
|
"TGeoUnion" -> CompositeType.GROUP
|
||||||
smartComposite(compositeType, name = name) {
|
else -> error("Unknown bool node type ${node.typename}")
|
||||||
addShape(node.fLeft!!, context, null).also {
|
|
||||||
if (it == null) TODO()
|
|
||||||
it.useMatrix(node.fLeftMat)
|
|
||||||
}
|
}
|
||||||
addShape(node.fRight!!, context, null).also {
|
smartComposite(compositeType, name = name) {
|
||||||
if (it == null) TODO()
|
addShape(node.fLeft!!, context, null) {
|
||||||
it.useMatrix(node.fRightMat)
|
this.useMatrix(node.fLeftMat)
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
"TGeoXtru" -> {
|
|
||||||
val fNvert by shape.meta.int(0)
|
|
||||||
val fX by shape.meta.doubleArray()
|
|
||||||
val fY by shape.meta.doubleArray()
|
|
||||||
val fNz by shape.meta.int(0)
|
|
||||||
val fZ by shape.meta.doubleArray()
|
|
||||||
val fX0 by shape.meta.doubleArray()
|
|
||||||
val fY0 by shape.meta.doubleArray()
|
|
||||||
val fScale by shape.meta.doubleArray()
|
|
||||||
|
|
||||||
extruded(name = name) {
|
|
||||||
(0 until fNvert).forEach { index ->
|
|
||||||
shape {
|
|
||||||
point(fX[index], fY[index])
|
|
||||||
}
|
}
|
||||||
}
|
addShape(node.fRight!!, context, null) {
|
||||||
|
this.useMatrix(node.fRightMat)
|
||||||
(0 until fNz).forEach { index ->
|
}
|
||||||
layer(
|
}.apply(block)
|
||||||
fZ[index],
|
|
||||||
fX0[index],
|
|
||||||
fY0[index],
|
|
||||||
fScale[index]
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
"TGeoXtru" -> {
|
||||||
"TGeoTube" -> {
|
val fNvert by shape.meta.int(0)
|
||||||
val fRmax by shape.meta.double(0.0)
|
val fX by shape.meta.doubleArray()
|
||||||
val fDz by shape.meta.double(0.0)
|
val fY by shape.meta.doubleArray()
|
||||||
val fRmin by shape.meta.double(0.0)
|
val fNz by shape.meta.int(0)
|
||||||
|
val fZ by shape.meta.doubleArray()
|
||||||
|
val fX0 by shape.meta.doubleArray()
|
||||||
|
val fY0 by shape.meta.doubleArray()
|
||||||
|
val fScale by shape.meta.doubleArray()
|
||||||
|
|
||||||
tube(
|
extruded(name = name) {
|
||||||
radius = fRmax,
|
(0 until fNvert).forEach { index ->
|
||||||
height = fDz * 2,
|
shape {
|
||||||
innerRadius = fRmin,
|
point(fX[index], fY[index])
|
||||||
name = name
|
}
|
||||||
)
|
}
|
||||||
}
|
|
||||||
"TGeoTubeSeg" -> {
|
|
||||||
val fRmax by shape.meta.double(0.0)
|
|
||||||
val fDz by shape.meta.double(0.0)
|
|
||||||
val fRmin by shape.meta.double(0.0)
|
|
||||||
val fPhi1 by shape.meta.double(0.0)
|
|
||||||
val fPhi2 by shape.meta.double(0.0)
|
|
||||||
|
|
||||||
tube(
|
(0 until fNz).forEach { index ->
|
||||||
radius = fRmax,
|
layer(
|
||||||
height = fDz * 2,
|
fZ[index],
|
||||||
innerRadius = fRmin,
|
fX0[index],
|
||||||
startAngle = degToRad(fPhi1),
|
fY0[index],
|
||||||
angle = degToRad(fPhi2 - fPhi1),
|
fScale[index]
|
||||||
name = name
|
)
|
||||||
)
|
}
|
||||||
}
|
}.apply(block)
|
||||||
"TGeoPcon" -> {
|
}
|
||||||
val fDphi by shape.meta.double(0.0)
|
"TGeoTube" -> {
|
||||||
val fNz by shape.meta.int(2)
|
val fRmax by shape.meta.double(0.0)
|
||||||
val fPhi1 by shape.meta.double(360.0)
|
val fDz by shape.meta.double(0.0)
|
||||||
val fRmax by shape.meta.doubleArray()
|
val fRmin by shape.meta.double(0.0)
|
||||||
val fRmin by shape.meta.doubleArray()
|
|
||||||
val fZ by shape.meta.doubleArray()
|
tube(
|
||||||
if (fNz == 2) {
|
radius = fRmax,
|
||||||
coneSurface(
|
height = fDz * 2,
|
||||||
bottomOuterRadius = fRmax[0],
|
innerRadius = fRmin,
|
||||||
bottomInnerRadius = fRmin[0],
|
name = name,
|
||||||
height = fZ[1] - fZ[0],
|
block = block
|
||||||
topOuterRadius = fRmax[1],
|
)
|
||||||
topInnerRadius = fRmin[1],
|
}
|
||||||
|
"TGeoTubeSeg" -> {
|
||||||
|
val fRmax by shape.meta.double(0.0)
|
||||||
|
val fDz by shape.meta.double(0.0)
|
||||||
|
val fRmin by shape.meta.double(0.0)
|
||||||
|
val fPhi1 by shape.meta.double(0.0)
|
||||||
|
val fPhi2 by shape.meta.double(0.0)
|
||||||
|
|
||||||
|
tube(
|
||||||
|
radius = fRmax,
|
||||||
|
height = fDz * 2,
|
||||||
|
innerRadius = fRmin,
|
||||||
startAngle = degToRad(fPhi1),
|
startAngle = degToRad(fPhi1),
|
||||||
angle = degToRad(fDphi),
|
angle = degToRad(fPhi2 - fPhi1),
|
||||||
name = name
|
name = name,
|
||||||
) {
|
block = block
|
||||||
z = (fZ[1] + fZ[0]) / 2
|
)
|
||||||
}
|
|
||||||
} else {
|
|
||||||
TODO()
|
|
||||||
}
|
}
|
||||||
}
|
"TGeoPcon" -> {
|
||||||
"TGeoPgon" -> {
|
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)
|
val fRmax by shape.meta.doubleArray()
|
||||||
val fRmax by shape.meta.doubleArray()
|
val fRmin by shape.meta.doubleArray()
|
||||||
val fRmin by shape.meta.doubleArray()
|
val fZ by shape.meta.doubleArray()
|
||||||
val fZ by shape.meta.doubleArray()
|
if (fNz == 2) {
|
||||||
|
coneSurface(
|
||||||
|
bottomOuterRadius = fRmax[0],
|
||||||
|
bottomInnerRadius = fRmin[0],
|
||||||
|
height = fZ[1] - fZ[0],
|
||||||
|
topOuterRadius = fRmax[1],
|
||||||
|
topInnerRadius = fRmin[1],
|
||||||
|
startAngle = degToRad(fPhi1),
|
||||||
|
angle = degToRad(fDphi),
|
||||||
|
name = name,
|
||||||
|
) {
|
||||||
|
z = (fZ[1] + fZ[0]) / 2
|
||||||
|
|
||||||
val fNedges by shape.meta.int(1)
|
}.apply(block)
|
||||||
|
} else {
|
||||||
|
TODO()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
"TGeoPgon" -> {
|
||||||
|
val fDphi by shape.meta.double(0.0)
|
||||||
|
val fNz by shape.meta.int(2)
|
||||||
|
val fPhi1 by shape.meta.double(360.0)
|
||||||
|
val fRmax by shape.meta.doubleArray()
|
||||||
|
val fRmin by shape.meta.doubleArray()
|
||||||
|
val fZ by shape.meta.doubleArray()
|
||||||
|
|
||||||
val startphi = degToRad(fPhi1)
|
val fNedges by shape.meta.int(1)
|
||||||
val deltaphi = degToRad(fDphi)
|
|
||||||
|
|
||||||
extruded(name) {
|
val startphi = degToRad(fPhi1)
|
||||||
//getting the radius of first
|
val deltaphi = degToRad(fDphi)
|
||||||
require(fNz > 1) { "The polyhedron geometry requires at least two planes" }
|
|
||||||
val baseRadius = fRmax[0]
|
extruded(name) {
|
||||||
shape {
|
//getting the radius of first
|
||||||
(0..fNedges).forEach {
|
require(fNz > 1) { "The polyhedron geometry requires at least two planes" }
|
||||||
val phi = deltaphi * fNedges * it + startphi
|
val baseRadius = fRmax[0]
|
||||||
(baseRadius * cos(phi) to baseRadius * sin(phi))
|
shape {
|
||||||
|
(0..fNedges).forEach {
|
||||||
|
val phi = deltaphi * fNedges * it + startphi
|
||||||
|
(baseRadius * cos(phi) to baseRadius * sin(phi))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
(0 until fNz).forEach { index ->
|
||||||
(0 until fNz).forEach { index ->
|
//scaling all radii relative to first layer radius
|
||||||
//scaling all radii relative to first layer radius
|
layer(fZ[index], scale = fRmax[index] / baseRadius)
|
||||||
layer(fZ[index], scale = fRmax[index] / baseRadius)
|
}
|
||||||
|
}.apply(block)
|
||||||
|
}
|
||||||
|
"TGeoShapeAssembly" -> {
|
||||||
|
val fVolume by shape.dObject(::DGeoVolume)
|
||||||
|
fVolume?.let { volume ->
|
||||||
|
addRootVolume(volume, context, block = block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
"TGeoBBox" -> {
|
||||||
"TGeoShapeAssembly" -> {
|
box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name, block = block)
|
||||||
val fVolume by shape.dObject(::DGeoVolume)
|
}
|
||||||
fVolume?.let { volume ->
|
else -> {
|
||||||
addRootVolume(volume, context)
|
TODO("A shape with type ${shape.typename} not implemented")
|
||||||
}
|
}
|
||||||
}
|
|
||||||
"TGeoBBox" -> {
|
|
||||||
box(shape.fDX * 2, shape.fDY * 2, shape.fDZ * 2, name = name)
|
|
||||||
}
|
|
||||||
else -> {
|
|
||||||
TODO("A shape with type ${shape.typename} not implemented")
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) {
|
private fun SolidGroup.addRootNode(obj: DGeoNode, context: RootToSolidContext) {
|
||||||
val volume = obj.fVolume ?: return
|
val volume = obj.fVolume ?: return
|
||||||
addRootVolume(volume, context, obj.fName).apply {
|
addRootVolume(volume, context, obj.fName) {
|
||||||
|
if (context.bottomLayer > 0) {
|
||||||
|
this.layer = context.bottomLayer
|
||||||
|
}
|
||||||
when (obj.typename) {
|
when (obj.typename) {
|
||||||
"TGeoNodeMatrix" -> {
|
"TGeoNodeMatrix" -> {
|
||||||
val fMatrix by obj.dObject(::DGeoMatrix)
|
val fMatrix by obj.dObject(::DGeoMatrix)
|
||||||
useMatrix(fMatrix)
|
this.useMatrix(fMatrix)
|
||||||
}
|
}
|
||||||
"TGeoNodeOffset" -> {
|
"TGeoNodeOffset" -> {
|
||||||
val fOffset by obj.meta.double(0.0)
|
val fOffset by obj.meta.double(0.0)
|
||||||
@ -227,19 +244,29 @@ 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 {
|
||||||
if(volume.fNodes.isEmpty()) {
|
val nodesNum = volume.fNodes.size
|
||||||
|
if (nodesNum == 0) {
|
||||||
//TODO add smart filter
|
//TODO add smart filter
|
||||||
volume.fShape?.let { shape ->
|
volume.fShape?.let { shape ->
|
||||||
addShape(shape, context)
|
addShape(shape, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
val expectedLayerSize = context.layers.last() + nodesNum
|
||||||
|
//If expected number exceeds layer limit, move everything else to the bottom layer.
|
||||||
|
if (expectedLayerSize >= context.layerLimits[context.bottomLayer]) {
|
||||||
|
context.addLayer()
|
||||||
|
println("Adding new layer. Sizes after add: ${context.layers}")
|
||||||
|
}
|
||||||
|
context.layers[context.bottomLayer] += nodesNum
|
||||||
volume.fNodes.forEach { node ->
|
volume.fNodes.forEach { node ->
|
||||||
addRootNode(node, context)
|
addRootNode(node, context)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return if (group.children.size == 1 && group.meta.isEmpty()) {
|
return if (group.isEmpty()) {
|
||||||
|
null
|
||||||
|
} else if (group.children.size == 1 && group.meta.isEmpty()) {
|
||||||
(group.children.values.first() as Solid).apply { parent = null }
|
(group.children.values.first() as Solid).apply { parent = null }
|
||||||
} else {
|
} else {
|
||||||
group
|
group
|
||||||
@ -252,8 +279,15 @@ private fun SolidGroup.addRootVolume(
|
|||||||
volume: DGeoVolume,
|
volume: DGeoVolume,
|
||||||
context: RootToSolidContext,
|
context: RootToSolidContext,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
cache: Boolean = true
|
cache: Boolean = true,
|
||||||
): Solid {
|
block: Solid.() -> Unit = {}
|
||||||
|
) {
|
||||||
|
//skip if maximum layer number is reached
|
||||||
|
if (context.bottomLayer > context.maxLayer){
|
||||||
|
println("Maximum layer depth reached. Skipping ${volume.fName}")
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
val combinedName = if (volume.fName.isEmpty()) {
|
val combinedName = if (volume.fName.isEmpty()) {
|
||||||
name
|
name
|
||||||
} else if (name == null) {
|
} else if (name == null) {
|
||||||
@ -262,23 +296,29 @@ private fun SolidGroup.addRootVolume(
|
|||||||
"${name}_${volume.fName}"
|
"${name}_${volume.fName}"
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (!cache) {
|
if (!cache) {
|
||||||
val group = buildVolume(volume, context)
|
val group = buildVolume(volume, context)?.apply {
|
||||||
|
volume.fFillColor?.let {
|
||||||
|
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
||||||
|
}
|
||||||
|
block()
|
||||||
|
}
|
||||||
set(combinedName?.let { Name.parse(it) }, group)
|
set(combinedName?.let { Name.parse(it) }, group)
|
||||||
group
|
|
||||||
} else {
|
} else {
|
||||||
val templateName = volumesName + volume.name
|
val templateName = volumesName + volume.name
|
||||||
val existing = getPrototype(templateName)
|
val existing = getPrototype(templateName)
|
||||||
if (existing == null) {
|
if (existing == null) {
|
||||||
context.prototypeHolder.prototypes {
|
context.prototypeHolder.prototypes {
|
||||||
set(templateName, buildVolume(volume, context))
|
val group = buildVolume(volume, context)
|
||||||
|
set(templateName, group)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ref(templateName, name)
|
ref(templateName, name).apply {
|
||||||
}.apply {
|
volume.fFillColor?.let {
|
||||||
volume.fFillColor?.let {
|
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
||||||
meta[MATERIAL_COLOR_KEY] = RootColors[it]
|
}
|
||||||
|
block()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -65,12 +65,6 @@ application {
|
|||||||
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
mainClass.set("ru.mipt.npm.muon.monitor.server.MMServerKt")
|
||||||
}
|
}
|
||||||
|
|
||||||
tasks.withType<org.jetbrains.kotlin.gradle.dsl.KotlinJsCompile>() {
|
|
||||||
kotlinOptions {
|
|
||||||
freeCompilerArgs = freeCompilerArgs + "-Xir-property-lazy-initialization"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
//distributions {
|
//distributions {
|
||||||
// main {
|
// main {
|
||||||
// contents {
|
// contents {
|
||||||
|
@ -9,6 +9,8 @@ import space.kscience.dataforge.meta.get
|
|||||||
import space.kscience.dataforge.meta.isLeaf
|
import space.kscience.dataforge.meta.isLeaf
|
||||||
import space.kscience.dataforge.values.string
|
import space.kscience.dataforge.values.string
|
||||||
import space.kscience.visionforge.solid.Solids
|
import space.kscience.visionforge.solid.Solids
|
||||||
|
import java.nio.file.Paths
|
||||||
|
import kotlin.io.path.writeText
|
||||||
|
|
||||||
|
|
||||||
private fun Meta.countTypes(): Sequence<String> = sequence {
|
private fun Meta.countTypes(): Sequence<String> = sequence {
|
||||||
@ -37,12 +39,18 @@ fun main() {
|
|||||||
|
|
||||||
val solid = geo.toSolid()
|
val solid = geo.toSolid()
|
||||||
|
|
||||||
//Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid))
|
Paths.get("BM@N.vf.json").writeText(Solids.encodeToString(solid))
|
||||||
//println(Solids.encodeToString(solid))
|
//println(Solids.encodeToString(solid))
|
||||||
|
|
||||||
context.makeVisionFile {
|
context.makeVisionFile {
|
||||||
vision("canvas") {
|
vision("canvas") {
|
||||||
solid
|
solid
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* SolidGroup {
|
/* SolidGroup {
|
||||||
set(
|
set(
|
||||||
"Coil",
|
"Coil",
|
||||||
@ -99,6 +107,3 @@ fun main() {
|
|||||||
}
|
}
|
||||||
}*//*
|
}*//*
|
||||||
}*/
|
}*/
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -2,7 +2,7 @@ kotlin.code.style=official
|
|||||||
kotlin.mpp.stability.nowarn=true
|
kotlin.mpp.stability.nowarn=true
|
||||||
|
|
||||||
#kotlin.jupyter.add.scanner=false
|
#kotlin.jupyter.add.scanner=false
|
||||||
kotlin.incremental.js.klib=false
|
#kotlin.incremental.js.klib=false
|
||||||
|
|
||||||
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
|
org.gradle.jvmargs=-XX:MaxMetaspaceSize=1G
|
||||||
org.gradle.parallel=true
|
org.gradle.parallel=true
|
@ -83,7 +83,7 @@ private fun RBuilder.visionTree(props: ObjectTreeProps): Unit {
|
|||||||
}
|
}
|
||||||
obj.children.entries
|
obj.children.entries
|
||||||
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
|
.filter { !it.key.toString().startsWith("@") } // ignore statics and other hidden children
|
||||||
.sortedBy { (it.value as? VisionGroup)?.isEmpty ?: true } // ignore empty groups
|
.sortedBy { (it.value as? VisionGroup)?.isEmpty() ?: true } // ignore empty groups
|
||||||
.forEach { (childToken, child) ->
|
.forEach { (childToken, child) ->
|
||||||
styledDiv {
|
styledDiv {
|
||||||
css {
|
css {
|
||||||
|
@ -63,7 +63,7 @@ public interface VisionGroup : Provider, Vision, VisionContainer<Vision> {
|
|||||||
*/
|
*/
|
||||||
public operator fun VisionGroup.iterator(): Iterator<Vision> = children.values.iterator()
|
public operator fun VisionGroup.iterator(): Iterator<Vision> = children.values.iterator()
|
||||||
|
|
||||||
public val VisionGroup.isEmpty: Boolean get() = this.children.isEmpty()
|
public fun VisionGroup.isEmpty(): Boolean = this.children.isEmpty()
|
||||||
|
|
||||||
public interface VisionContainerBuilder<in V : Vision> {
|
public interface VisionContainerBuilder<in V : Vision> {
|
||||||
//TODO add documentation
|
//TODO add documentation
|
||||||
|
@ -67,8 +67,8 @@ internal fun checkOrStoreFile(htmlPath: Path, filePath: Path, resource: String):
|
|||||||
if (!skip) {
|
if (!skip) {
|
||||||
logger.debug("File $fullPath does not exist or wrong checksum. Writing file")
|
logger.debug("File $fullPath does not exist or wrong checksum. Writing file")
|
||||||
Files.createDirectories(fullPath.parent)
|
Files.createDirectories(fullPath.parent)
|
||||||
Files.write(fullPath, bytes, StandardOpenOption.CREATE, StandardOpenOption.WRITE)
|
Files.write(fullPath, bytes, StandardOpenOption.CREATE,StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)
|
||||||
Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.WRITE)
|
Files.write(md5File, checksum.encodeToByteArray(), StandardOpenOption.CREATE, StandardOpenOption.TRUNCATE_EXISTING, StandardOpenOption.WRITE)
|
||||||
}
|
}
|
||||||
|
|
||||||
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
return if (htmlPath.isAbsolute && fullPath.startsWith(htmlPath.parent)) {
|
||||||
|
@ -57,8 +57,8 @@ public inline fun VisionContainerBuilder<Solid>.box(
|
|||||||
ySize: Number,
|
ySize: Number,
|
||||||
zSize: Number,
|
zSize: Number,
|
||||||
name: String? = null,
|
name: String? = null,
|
||||||
action: Box.() -> Unit = {},
|
block: Box.() -> Unit = {},
|
||||||
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(action).also { set(name, it) }
|
): Box = Box(xSize.toFloat(), ySize.toFloat(), zSize.toFloat()).apply(block).also { set(name, it) }
|
||||||
|
|
||||||
@Serializable
|
@Serializable
|
||||||
@SerialName("solid.hexagon")
|
@SerialName("solid.hexagon")
|
||||||
|
Loading…
Reference in New Issue
Block a user