Fix serialization and tables

This commit is contained in:
2025-02-13 10:13:28 +03:00
parent 5a847141d0
commit 97b5973894
24 changed files with 2627 additions and 2404 deletions

View File

@ -13,9 +13,11 @@ repositories {
kotlin {
jvmToolchain(17)
js(IR) {
js {
useEsModules()
browser {
commonWebpackConfig {
outputFileName = "js/visionforge-playground.js"
cssSupport {
enabled = true
}
@ -23,9 +25,6 @@ kotlin {
enabled = true
}
}
webpackTask {
mainOutputFileName.set("js/visionforge-playground.js")
}
}
binaries.executable()
}
@ -66,16 +65,22 @@ kotlin {
implementation(projects.visionforgeGdml)
implementation(projects.visionforgeServer)
implementation(spclibs.logback.classic)
implementation("com.github.Ricky12Awesome:json-schema-serialization:0.6.6")
}
}
all {
languageSettings.optIn("space.kscience.dataforge.misc.DFExperimental")
}
}
}
val jsBrowserDistribution = tasks.getByName("jsBrowserDistribution")
val debug = false
val jsBrowserDistribution = if(debug) {
tasks.getByName("jsBrowserDevelopmentExecutableDistribution")
} else {
tasks.getByName("jsBrowserDistribution")
}
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(jsBrowserDistribution)

View File

@ -1,24 +0,0 @@
package space.kscience.visionforge.examples
import com.github.ricky12awesome.jss.encodeToSchema
import kotlinx.serialization.ExperimentalSerializationApi
import kotlinx.serialization.json.Json
import space.kscience.visionforge.solid.SolidGroup
import space.kscience.visionforge.solid.Solids
@OptIn(ExperimentalSerializationApi::class)
private val json = Json {
serializersModule = Solids.serializersModuleForSolids
prettyPrintIndent = " "
prettyPrint = true
ignoreUnknownKeys = true
isLenient = true
coerceInputValues = true
encodeDefaults = true
}
@ExperimentalSerializationApi
fun main() {
val schema = json.encodeToSchema(SolidGroup.serializer(), generateDefinitions = false)
println(schema)
}

View File

@ -36,7 +36,7 @@ public class ConeSegment(
require(segments >= 4) { "The number of segments in cone is too small" }
val angleStep = phi / (segments - 1)
fun shape(r: Float, z: Float): List<Float32Vector3D> = (0 until segments).map { i ->
fun shape(r: Float, z: Float): List<FloatVector3D> = (0 until segments).map { i ->
Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z)
}
@ -81,7 +81,7 @@ public inline fun MutableVisionContainer<Solid>.cylinder(
r.toFloat(),
height.toFloat(),
r.toFloat()
).apply(block).also {
).apply(block).also {
setVision(SolidGroup.inferNameFor(name, it), it)
}
@ -100,6 +100,6 @@ public inline fun MutableVisionContainer<Solid>.cone(
topRadius = upperRadius.toFloat(),
phiStart = startAngle.toFloat(),
phi = angle.toFloat()
).apply(block).also {
).apply(block).also {
setVision(SolidGroup.inferNameFor(name, it), it)
}

View File

@ -38,7 +38,7 @@ public class ConeSurface(
require(segments >= 4) { "The number of segments in tube is too small" }
val angleStep = phi / (segments - 1)
fun shape(r: Float, z: Float): List<Float32Vector3D> = (0 until segments).map { i ->
fun shape(r: Float, z: Float): List<FloatVector3D> = (0 until segments).map { i ->
Float32Vector3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z)
}
@ -137,7 +137,7 @@ public inline fun MutableVisionContainer<Solid>.tube(
topInnerRadius = innerRadius.toFloat(),
phiStart = startAngle.toFloat(),
phi = angle.toFloat()
).apply(block).also {
).apply(block).also {
setVision(SolidGroup.inferNameFor(name, it), it)
}
@ -160,6 +160,6 @@ public inline fun MutableVisionContainer<Solid>.coneSurface(
topInnerRadius = topInnerRadius.toFloat(),
phiStart = startAngle.toFloat(),
phi = angle.toFloat()
).apply(block).also {
).apply(block).also {
setVision(SolidGroup.inferNameFor(name, it), it)
}

View File

@ -3,7 +3,6 @@ package space.kscience.visionforge.solid
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import space.kscience.dataforge.names.NameToken
import space.kscience.kmath.geometry.euclidean3d.Float32Space3D
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
import space.kscience.visionforge.MutableVisionContainer
@ -13,18 +12,18 @@ import space.kscience.visionforge.MutableVisionContainer
@Serializable
@SerialName("solid.convex")
public class Convex(
public val points: List<@Serializable(Float32Space3D.VectorSerializer::class) Float32Vector3D>
public val points: List<FloatVector3D>
) : SolidBase<Convex>()
public inline fun MutableVisionContainer<Solid>.convex(
name: String? = null,
action: ConvexBuilder.() -> Unit = {},
): Convex = ConvexBuilder().apply(action).build().also {
): Convex = ConvexBuilder().apply(action).build().also {
setVision(name?.let(NameToken::parse) ?: SolidGroup.staticNameFor(it), it)
}
public class ConvexBuilder {
private val points = ArrayList<Float32Vector3D>()
private val points = ArrayList<FloatVector3D>()
public fun point(x: Number, y: Number, z: Number) {
points.add(Float32Vector3D(x, y, z))

View File

@ -25,8 +25,8 @@ public class CutTube(
public val height: Float,
public val phiStart: Float = 0f,
public val phi: Float = PI2,
public val nTop: Float32Vector3D,
public val nBottom: Float32Vector3D,
public val nTop: FloatVector3D,
public val nBottom: FloatVector3D,
) : SolidBase<CutTube>(), GeometrySolid {
init {
@ -45,7 +45,7 @@ public class CutTube(
require(segments >= 4) { "The number of segments in the tube is too small" }
val angleStep = phi / (segments - 1)
fun section(r: Float, z: Float, n: Float32Vector3D): List<Float32Vector3D> = (0 until segments).map { i ->
fun section(r: Float, z: Float, n: FloatVector3D): List<FloatVector3D> = (0 until segments).map { i ->
val x = r * cos(phiStart + angleStep * i)
val y = r * sin(phiStart + angleStep * i)
Float32Vector3D(x, y, (n.z * z - n.x * x - n.y * y) / n.z)
@ -153,8 +153,8 @@ public inline fun MutableVisionContainer<Solid>.cutTube(
height: Number,
startAngle: Number = 0f,
angle: Number = PI2,
topNormal: Float32Vector3D,
bottomNormal: Float32Vector3D,
topNormal: FloatVector3D,
bottomNormal: FloatVector3D,
name: String? = null,
block: CutTube.() -> Unit = {},
): CutTube = CutTube(
@ -165,6 +165,6 @@ public inline fun MutableVisionContainer<Solid>.cutTube(
phi = angle.toFloat(),
nTop = topNormal,
nBottom = bottomNormal
).apply(block).also {
).apply(block).also {
setVision(SolidGroup.inferNameFor(name, it), it)
}

View File

@ -1,15 +1,11 @@
@file:UseSerializers(Float32Space2D.VectorSerializer::class)
package space.kscience.visionforge.solid
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import space.kscience.dataforge.meta.MutableMeta
import space.kscience.dataforge.meta.update
import space.kscience.kmath.geometry.component1
import space.kscience.kmath.geometry.component2
import space.kscience.kmath.geometry.euclidean2d.Float32Space2D
import space.kscience.kmath.geometry.euclidean2d.Float32Vector2D
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
import space.kscience.visionforge.MutableVisionContainer
import space.kscience.visionforge.VisionBuilder
@ -41,7 +37,7 @@ public class Extruded(
/**
* Expand the shape for specific layers
*/
val layers: List<List<Float32Vector3D>> = layers.map { layer ->
val layers: List<List<FloatVector3D>> = layers.map { layer ->
shape.map { (x, y) ->
val newX = layer.x + x * layer.scale
val newY = layer.y + y * layer.scale
@ -52,7 +48,7 @@ public class Extruded(
if (layers.size < 2) error("Extruded shape requires more than one layer")
var lowerLayer = layers.first()
var upperLayer: List<Float32Vector3D>
var upperLayer: List<FloatVector3D>
geometryBuilder.cap(layers.first().reversed())
@ -82,7 +78,7 @@ public class Extruded(
}
public class Builder(
public var shape: List<Float32Vector2D> = emptyList(),
public var shape: List<FloatVector2D> = emptyList(),
public var layers: MutableList<Layer> = ArrayList(),
public val properties: MutableMeta = MutableMeta(),
) {

View File

@ -14,17 +14,23 @@ public interface GeometryBuilder<T : Any> {
* @param normal optional external normal to the face
* @param meta optional additional platform-specific parameters like color or texture index
*/
public fun face(vertex1: Float32Vector3D, vertex2: Float32Vector3D, vertex3: Float32Vector3D, normal: Float32Vector3D? = null, meta: Meta = Meta.EMPTY)
public fun face(
vertex1: FloatVector3D,
vertex2: FloatVector3D,
vertex3: FloatVector3D,
normal: FloatVector3D? = null,
meta: Meta = Meta.EMPTY
)
public fun build(): T
}
public fun GeometryBuilder<*>.face4(
vertex1: Float32Vector3D,
vertex2: Float32Vector3D,
vertex3: Float32Vector3D,
vertex4: Float32Vector3D,
normal: Float32Vector3D? = null,
vertex1: FloatVector3D,
vertex2: FloatVector3D,
vertex3: FloatVector3D,
vertex4: FloatVector3D,
normal: FloatVector3D? = null,
meta: Meta = Meta.EMPTY
) {
face(vertex1, vertex2, vertex3, normal, meta)
@ -38,7 +44,7 @@ public interface GeometrySolid : Solid {
public fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>)
}
public fun <T : Any> GeometryBuilder<T>.cap(shape: List<Float32Vector3D>, normal: Float32Vector3D? = null) {
public fun <T : Any> GeometryBuilder<T>.cap(shape: List<FloatVector3D>, normal: FloatVector3D? = null) {
//FIXME won't work for non-convex shapes
val center = Float32Vector3D(
shape.map { it.x }.average(),

View File

@ -1,23 +1,20 @@
@file:UseSerializers(Float32Space3D.VectorSerializer::class)
package space.kscience.visionforge.solid
import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import space.kscience.kmath.geometry.euclidean3d.Float32Space3D
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
import space.kscience.visionforge.MutableVisionContainer
import space.kscience.visionforge.VisionBuilder
public interface Hexagon : GeometrySolid {
public val node1: Float32Vector3D
public val node2: Float32Vector3D
public val node3: Float32Vector3D
public val node4: Float32Vector3D
public val node5: Float32Vector3D
public val node6: Float32Vector3D
public val node7: Float32Vector3D
public val node8: Float32Vector3D
public val node1: FloatVector3D
public val node2: FloatVector3D
public val node3: FloatVector3D
public val node4: FloatVector3D
public val node5: FloatVector3D
public val node6: FloatVector3D
public val node7: FloatVector3D
public val node8: FloatVector3D
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
geometryBuilder.face4(node1, node4, node3, node2)
@ -44,14 +41,14 @@ public class Box(
private inline val dy get() = ySize / 2
private inline val dz get() = zSize / 2
override val node1: Float32Vector3D get() = Float32Vector3D(-dx, -dy, -dz)
override val node2: Float32Vector3D get() = Float32Vector3D(dx, -dy, -dz)
override val node3: Float32Vector3D get() = Float32Vector3D(dx, dy, -dz)
override val node4: Float32Vector3D get() = Float32Vector3D(-dx, dy, -dz)
override val node5: Float32Vector3D get() = Float32Vector3D(-dx, -dy, dz)
override val node6: Float32Vector3D get() = Float32Vector3D(dx, -dy, dz)
override val node7: Float32Vector3D get() = Float32Vector3D(dx, dy, dz)
override val node8: Float32Vector3D get() = Float32Vector3D(-dx, dy, dz)
override val node1: FloatVector3D get() = Float32Vector3D(-dx, -dy, -dz)
override val node2: FloatVector3D get() = Float32Vector3D(dx, -dy, -dz)
override val node3: FloatVector3D get() = Float32Vector3D(dx, dy, -dz)
override val node4: FloatVector3D get() = Float32Vector3D(-dx, dy, -dz)
override val node5: FloatVector3D get() = Float32Vector3D(-dx, -dy, dz)
override val node6: FloatVector3D get() = Float32Vector3D(dx, -dy, dz)
override val node7: FloatVector3D get() = Float32Vector3D(dx, dy, dz)
override val node8: FloatVector3D get() = Float32Vector3D(-dx, dy, dz)
}
@VisionBuilder
@ -68,26 +65,26 @@ public inline fun MutableVisionContainer<Solid>.box(
@Serializable
@SerialName("solid.hexagon")
public class GenericHexagon(
override val node1: Float32Vector3D,
override val node2: Float32Vector3D,
override val node3: Float32Vector3D,
override val node4: Float32Vector3D,
override val node5: Float32Vector3D,
override val node6: Float32Vector3D,
override val node7: Float32Vector3D,
override val node8: Float32Vector3D,
override val node1: FloatVector3D,
override val node2: FloatVector3D,
override val node3: FloatVector3D,
override val node4: FloatVector3D,
override val node5: FloatVector3D,
override val node6: FloatVector3D,
override val node7: FloatVector3D,
override val node8: FloatVector3D,
) : SolidBase<GenericHexagon>(), Hexagon
@VisionBuilder
public inline fun MutableVisionContainer<Solid>.hexagon(
node1: Float32Vector3D,
node2: Float32Vector3D,
node3: Float32Vector3D,
node4: Float32Vector3D,
node5: Float32Vector3D,
node6: Float32Vector3D,
node7: Float32Vector3D,
node8: Float32Vector3D,
node1: FloatVector3D,
node2: FloatVector3D,
node3: FloatVector3D,
node4: FloatVector3D,
node5: FloatVector3D,
node6: FloatVector3D,
node7: FloatVector3D,
node8: FloatVector3D,
name: String? = null,
action: Hexagon.() -> Unit = {},
): Hexagon = GenericHexagon(node1, node2, node3, node4, node5, node6, node7, node8).apply(action).also {

View File

@ -4,13 +4,12 @@ import kotlinx.serialization.SerialName
import kotlinx.serialization.Serializable
import space.kscience.dataforge.meta.number
import space.kscience.dataforge.names.NameToken
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
import space.kscience.visionforge.MutableVisionContainer
import space.kscience.visionforge.VisionBuilder
@Serializable
@SerialName("solid.line")
public class PolyLine(public val points: List<Float32Vector3D>) : SolidBase<PolyLine>() {
public class PolyLine(public val points: List<FloatVector3D>) : SolidBase<PolyLine>() {
//var lineType by string()
public var thickness: Number by properties.number { DEFAULT_THICKNESS }
@ -22,9 +21,9 @@ public class PolyLine(public val points: List<Float32Vector3D>) : SolidBase<Poly
@VisionBuilder
public fun MutableVisionContainer<Solid>.polyline(
vararg points: Float32Vector3D,
vararg points: FloatVector3D,
name: String? = null,
action: PolyLine.() -> Unit = {},
): PolyLine = PolyLine(points.toList()).apply(action).also {
): PolyLine = PolyLine(points.toList()).apply(action).also {
setVision(name?.let(NameToken::parse) ?: SolidGroup.staticNameFor(it), it)
}

View File

@ -1,21 +1,18 @@
@file:UseSerializers(Float32Space2D.VectorSerializer::class)
package space.kscience.visionforge.solid
import kotlinx.serialization.Serializable
import kotlinx.serialization.UseSerializers
import space.kscience.kmath.geometry.euclidean2d.Float32Space2D
import space.kscience.kmath.geometry.euclidean2d.Float32Vector2D
import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
public typealias Shape2D = List<Float32Vector2D>
public typealias Shape2D = List<FloatVector2D>
/**
* A builder for 2D shapes
*/
@Serializable
public class Shape2DBuilder(private val points: ArrayList<Float32Vector2D> = ArrayList()) {
public class Shape2DBuilder(private val points: ArrayList<FloatVector2D> = ArrayList()) {
public fun point(x: Number, y: Number) {
points.add(Float32Vector2D(x, y))

View File

@ -170,19 +170,19 @@ internal fun float32(name: Name, default: Number): ReadWriteProperty<Solid, Numb
}
/**
* A [Float32Vector3D] solid property delegate
* A [FloatVector3D] solid property delegate
*/
internal fun float32Vector(
name: Name,
defaultX: Float,
defaultY: Float = defaultX,
defaultZ: Float = defaultX,
): ReadWriteProperty<Solid, Float32Vector3D?> =
object : ReadWriteProperty<Solid, Float32Vector3D?> {
override fun getValue(thisRef: Solid, property: KProperty<*>): Float32Vector3D? {
): ReadWriteProperty<Solid, FloatVector3D?> =
object : ReadWriteProperty<Solid, FloatVector3D?> {
override fun getValue(thisRef: Solid, property: KProperty<*>): FloatVector3D? {
val item = thisRef.properties[name] ?: return null
//using dynamic property accessor because values could change
return object : Float32Vector3D {
return object : FloatVector3D {
override val x: Float get() = item[X_KEY]?.float ?: defaultX
override val y: Float get() = item[Y_KEY]?.float ?: defaultY
override val z: Float get() = item[Z_KEY]?.float ?: defaultZ
@ -191,7 +191,7 @@ internal fun float32Vector(
}
}
override fun setValue(thisRef: Solid, property: KProperty<*>, value: Float32Vector3D?) {
override fun setValue(thisRef: Solid, property: KProperty<*>, value: FloatVector3D?) {
if (value == null) {
thisRef.properties[name] = null
} else {
@ -202,9 +202,9 @@ internal fun float32Vector(
}
}
public var Solid.position: Float32Vector3D? by float32Vector(POSITION_KEY, 0f)
public var Solid.rotation: Float32Vector3D? by float32Vector(ROTATION_KEY, 0f)
public var Solid.scale: Float32Vector3D? by float32Vector(SCALE_KEY, 1f)
public var Solid.position: FloatVector3D? by float32Vector(POSITION_KEY, 0f)
public var Solid.rotation: FloatVector3D? by float32Vector(ROTATION_KEY, 0f)
public var Solid.scale: FloatVector3D? by float32Vector(SCALE_KEY, 1f)
public fun Solid.scale(scaleFactor: Number) {
scale = Float32Vector3D(scaleFactor, scaleFactor, scaleFactor)

View File

@ -12,8 +12,6 @@ import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.names.NameToken
import space.kscience.kmath.geometry.euclidean3d.Float32Space3D
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
import space.kscience.visionforge.*
import space.kscience.visionforge.html.VisionOutput
import space.kscience.visionforge.solid.specifications.Canvas3DOptions
@ -67,11 +65,6 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
defaultDeserializer { SolidBase.serializer(serializer<Solid>()) }
solids()
}
polymorphic(Float32Vector3D::class, Float32Space3D.VectorSerializer)
// polymorphic(Float64Vector3D::class, Float64Space3D.VectorSerializer)
}
internal val jsonForSolids: Json = Json(VisionManager.defaultJson) {

View File

@ -21,7 +21,7 @@ public class Sphere(
) : SolidBase<Sphere>(), GeometrySolid {
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D {
fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): FloatVector3D {
// This transformation matches three.js sphere implementation
val y = r * cos(theta)
val z = r * sin(theta) * sin(phi)
@ -59,6 +59,6 @@ public inline fun MutableVisionContainer<Solid>.sphere(
action: Sphere.() -> Unit = {},
): Sphere = Sphere(
radius.toFloat(),
).apply(action).also {
).apply(action).also {
setVision(name?.let(NameToken::parse) ?: SolidGroup.staticNameFor(it), it)
}

View File

@ -28,7 +28,7 @@ public class SphereLayer(
require(outerRadius > 0) { "Outer radius must be positive" }
require(innerRadius >= 0) { "inner radius must be non-negative" }
fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): Float32Vector3D {
fun point3dFromSphCoord(r: Float, theta: Float, phi: Float): FloatVector3D {
// This transformation matches three.js sphere implementation
val y = r * cos(theta)
val z = r * sin(theta) * sin(phi)
@ -86,6 +86,6 @@ public inline fun MutableVisionContainer<Solid>.sphereLayer(
phi.toFloat(),
thetaStart.toFloat(),
theta.toFloat()
).apply(action).also {
).apply(action).also {
setVision(name?.let(NameToken::parse) ?: SolidGroup.staticNameFor(it), it)
}

View File

@ -37,11 +37,11 @@ public class Surface(
require(inner == null || inner.size == outer.size) { "Outer shape size is ${outer.size}, but inner is ${inner?.size}" }
}
public fun outerPoints(): List<Float32Vector3D> = outer.map { (x, y) -> Float32Vector3D(x, y, z) }
public fun outerPoints(): List<FloatVector3D> = outer.map { (x, y) -> Float32Vector3D(x, y, z) }
public fun innerPoints(): List<Float32Vector3D>? = inner?.map { (x, y) -> Float32Vector3D(x, y, z) }
public fun innerPoints(): List<FloatVector3D>? = inner?.map { (x, y) -> Float32Vector3D(x, y, z) }
public val center: Float32Vector3D by lazy {
public val center: FloatVector3D by lazy {
Float32Vector3D(
outer.sumOf { it.x } / size,
outer.sumOf { it.y } / size,

View File

@ -1,9 +1,11 @@
package space.kscience.visionforge.solid
import kotlinx.serialization.Serializable
import space.kscience.dataforge.meta.Meta
import space.kscience.dataforge.meta.MetaProvider
import space.kscience.dataforge.meta.float
import space.kscience.dataforge.meta.get
import space.kscience.kmath.geometry.euclidean2d.Float32Space2D
import space.kscience.kmath.geometry.euclidean2d.Float32Vector2D
import space.kscience.kmath.geometry.euclidean3d.Float32Space3D
import space.kscience.kmath.geometry.euclidean3d.Float32Vector3D
@ -12,19 +14,22 @@ import space.kscience.visionforge.solid.Solid.Companion.Y_KEY
import space.kscience.visionforge.solid.Solid.Companion.Z_KEY
import kotlin.math.PI
public typealias FloatVector2D = @Serializable(with = Float32Space2D.VectorSerializer::class) Float32Vector2D
public typealias FloatVector3D = @Serializable(with = Float32Space3D.VectorSerializer::class) Float32Vector3D
public const val PI2: Float = 2 * PI.toFloat()
public fun Float32Vector2D.toMeta(): Meta = Meta {
public fun FloatVector2D.toMeta(): Meta = Meta {
X_KEY put x
Y_KEY put y
}
internal fun Meta.toVector2D(): Float32Vector2D =
internal fun Meta.toVector2D(): FloatVector2D =
Float32Vector2D(this["x"].float ?: 0f, this["y"].float ?: 0f)
//@Suppress("SERIALIZER_TYPE_INCOMPATIBLE")
//@Serializable(Point3DSerializer::class)
//public interface MutablePoint3D : Float32Vector3D {
//public interface MutablePoint3D : Vector3D {
// override var x: Float
// override var y: Float
// override var z: Float
@ -45,7 +50,7 @@ internal fun MetaProvider.point3D(default: Float = 0f) = Float32Space3D.vector(
)
public fun Float32Vector3D.toMeta(): Meta = Meta {
public fun FloatVector3D.toMeta(): Meta = Meta {
X_KEY put x
Y_KEY put y
Z_KEY put z

View File

@ -9,7 +9,7 @@ kscience {
js {
binaries.library()
browser {
webpackTask{
webpackTask {
cssSupport {
enabled = true
}
@ -26,8 +26,9 @@ kscience {
api("space.kscience:tables-kt:${tablesVersion}")
}
jsMain {
api(npm("tabulator-tables", "6.3.1"))
api(npm("@types/tabulator-tables", "6.2.3"))
api("org.jetbrains.kotlin-wrappers:kotlin-js")
implementation(npm("tabulator-tables", "6.3.1"))
// api(npm("@types/tabulator-tables", "6.2.3"))
}
}

View File

@ -1,6 +1,5 @@
package space.kscience.visionforge.tables
import js.import.importAsync
import js.objects.jso
import org.w3c.dom.Element
import org.w3c.dom.HTMLElement
@ -15,8 +14,9 @@ import space.kscience.dataforge.names.asName
import space.kscience.visionforge.Vision
import space.kscience.visionforge.html.ElementVisionRenderer
import space.kscience.visionforge.html.JsVisionClient
import tabulator.Tabulator
import tabulator.Options
import tabulator.TabulatorFull
import tabulator.TabulatorSimpleCss
public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer {
public val visionClient: JsVisionClient by require(JsVisionClient)
@ -26,8 +26,8 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer {
override fun attach(context: Context) {
super.attach(context)
importAsync<Any>("tabulator-tables/dist/css/tabulator.min.css")
importAsync<Any>("tabulator-tables/src/js/modules/ResizeColumns/ResizeColumns.js")
//TODO add dynamic CSS loading
@Suppress("UnusedVariable") val css = TabulatorSimpleCss
}
override fun rateVision(vision: Vision): Int = when (vision) {
@ -39,15 +39,7 @@ public class TableVisionJsPlugin : AbstractPlugin(), ElementVisionRenderer {
val table: VisionOfTable = (vision as? VisionOfTable)
?: error("VisionOfTable expected but ${vision::class} found")
val tableOptions = jso<Tabulator.Options> {
columns = table.headers.map { header ->
jso<Tabulator.ColumnDefinition> {
field = header.name
title = header.properties.title ?: header.name
resizable = true
}
}.toTypedArray()
val tableOptions = jso<Options> {
columns = Array(table.headers.size + 1) {
if (it == 0) {
jso {

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,28 @@
package tabulator
@JsModule("tabulator-tables/dist/css/tabulator_bootstrap5.min.css")
internal external object TabulatorBootstrapCss
@JsModule("tabulator-tables/dist/css/tabulator_bulma.min.css")
internal external object TabulatorBulmaCss
@JsModule("tabulator-tables/dist/css/tabulator_materialize.min.css")
internal external object TabulatorMaterializeCss
@JsModule("tabulator-tables/dist/css/tabulator_midnight.min.css")
internal external object TabulatorMidnightCss
@JsModule("tabulator-tables/dist/css/tabulator_modern.min.css")
internal external object TabulatorModernCss
@JsModule("tabulator-tables/dist/css/tabulator_semanticui.min.css")
internal external object TabulatorSemanticCss
@JsModule("tabulator-tables/dist/css/tabulator_simple.min.css")
internal external object TabulatorSimpleCss
@JsModule("tabulator-tables/dist/css/tabulator_site.min.css")
internal external object TabulatorSiteCss
@JsModule("tabulator-tables/dist/css/tabulator_site_dark.min.css")
internal external object TabulatorSiteDarkCss

View File

@ -2,44 +2,38 @@
package tabulator
import js.objects.Record
import org.w3c.dom.events.UIEvent
@Suppress("UNUSED_TYPEALIAS_PARAMETER")
internal typealias Pick<T, K> = Any
@Suppress("UNUSED_TYPEALIAS_PARAMETER")
internal typealias Record<K, T> = Any
typealias ValueStringCallback = (value: Any) -> String
internal typealias FilterFunction = (field: String, type: String /* "=" | "!=" | "like" | "<" | ">" | "<=" | ">=" | "in" | "regex" | "starts" | "ends" */, value: Any, filterParams: Tabulator.FilterParams) -> Unit
typealias ValueBooleanCallback = (value: Any) -> Boolean
internal typealias GroupValuesArg = Array<Array<Any>>
typealias ValueVoidCallback = (value: Any) -> Unit
internal typealias CustomMutator = (value: Any, data: Any, type: String /* "data" | "edit" */, mutatorParams: Any, cell: Tabulator.CellComponent) -> Any
typealias EmptyCallback = (callback: () -> Unit) -> Unit
internal typealias CustomAccessor = (value: Any, data: Any, type: String /* "data" | "download" | "clipboard" */, AccessorParams: Any, column: Tabulator.ColumnComponent, row: Tabulator.RowComponent) -> Any
typealias CellEventCallback = (e: UIEvent, cell: CellComponent) -> Unit
internal typealias ColumnCalcParams = (values: Any, data: Any) -> Any
typealias CellEditEventCallback = (cell: CellComponent) -> Unit
internal typealias ValueStringCallback = (value: Any) -> String
typealias ColumnEventCallback = (e: UIEvent, column: ColumnComponent) -> Unit
internal typealias ValueBooleanCallback = (value: Any) -> Boolean
typealias RowEventCallback = (e: UIEvent, row: RowComponent) -> Unit
internal typealias ValueVoidCallback = (value: Any) -> Unit
typealias RowChangedCallback = (row: RowComponent) -> Unit
internal typealias EmptyCallback = (callback: () -> Unit) -> Unit
typealias GroupEventCallback = (e: UIEvent, group: GroupComponent) -> Unit
internal typealias CellEventCallback = (e: UIEvent, cell: Tabulator.CellComponent) -> Unit
typealias JSONRecord = Record<String, dynamic /* String | Number | Boolean */>
internal typealias CellEditEventCallback = (cell: Tabulator.CellComponent) -> Unit
typealias FilterFunction = (field: String, type: String /* "=" | "!=" | "like" | "<" | ">" | "<=" | ">=" | "in" | "regex" | "starts" | "ends" */, value: Any, filterParams: FilterParams) -> Unit
internal typealias ColumnEventCallback = (e: UIEvent, column: Tabulator.ColumnComponent) -> Unit
typealias GroupValuesArg = Array<Array<Any>>
internal typealias RowEventCallback = (e: UIEvent, row: Tabulator.RowComponent) -> Unit
typealias CustomMutator = (value: Any, data: Any, type: String /* "data" | "edit" */, mutatorParams: Any, cell: CellComponent) -> Any
internal typealias RowChangedCallback = (row: Tabulator.RowComponent) -> Unit
typealias CustomAccessor = (value: Any, data: Any, type: String /* "data" | "download" | "clipboard" */, AccessorParams: Any, column: ColumnComponent, row: RowComponent) -> Any
internal typealias GroupEventCallback = (e: UIEvent, group: Tabulator.GroupComponent) -> Unit
internal typealias JSONRecord = Record<String, dynamic /* String | Number | Boolean */>
internal typealias ColumnSorterParamLookupFunction = (column: Tabulator.ColumnComponent, dir: String /* "asc" | "desc" */) -> Any
typealias ColumnSorterParamLookupFunction = (column: ColumnComponent, dir: String /* "asc" | "desc" */) -> Any

View File

@ -24,6 +24,7 @@ kscience {
// api(npm("file-saver", "2.0.5"))
// api(npm("@types/file-saver", "2.0.7"))
implementation(npm("three", "0.173.0"))
implementation(npm("@types/three", "0.173.0"))
implementation(npm("three-csg-ts", "3.2.0"))
implementation(npm("meshline", "3.3.1"))
}