Fix meshline

This commit is contained in:
Alexander Nozik 2025-02-10 11:56:48 +03:00
parent 82538ad70c
commit 674ade5a59
22 changed files with 79 additions and 53 deletions
CHANGELOG.md
demo
js-playground/src/jsMain/kotlin
playground
sat-demo/src/jvmMain/kotlin/ru/mipt/npm/sat
solid-showcase/src/commonMain/kotlin/space/kscience/visionforge/solid/demo
plotly/examples
visionforge-solid/src/commonMain/kotlin/space/kscience/visionforge/solid
visionforge-tables
visionforge-threejs

@ -3,10 +3,12 @@
## Unreleased
### Added
- Plotly refactored on top of visionforge/server
### Changed
- Simplified Vision and VisionGroup logic. Observation logic moved out.
- Use `Name` for child designation and `Path` for tree access
- Default intensity for AmbientLight is 2.0
### Deprecated

@ -2,7 +2,7 @@ import org.jetbrains.compose.web.css.*
import org.jetbrains.compose.web.dom.Div
import org.jetbrains.compose.web.renderComposable
import space.kscience.dataforge.context.Context
import space.kscience.plotly.PlotlyPlugin
import space.kscience.plotly.PlotlyJSPlugin
import space.kscience.plotly.models.Trace
import space.kscience.plotly.models.scatter
import space.kscience.visionforge.Colors
@ -25,7 +25,7 @@ fun Trace.appendXYLatest(x: Number, y: Number, history: Int = 400, xErr: Number?
public fun main() {
val playgroundContext = Context {
plugin(ThreePlugin)
plugin(PlotlyPlugin)
plugin(PlotlyJSPlugin)
plugin(MarkupPlugin)
}
startApplication { document ->

@ -1,8 +1,8 @@
plugins {
kotlin("multiplatform")
kotlin("jupyter.api")
id("com.github.johnrengelman.shadow") version "7.1.2"
// application
id("com.gradleup.shadow") version "8.3.6"
}
repositories {
@ -15,13 +15,15 @@ kotlin {
jvmToolchain(17)
js(IR) {
browser {
commonWebpackConfig {
cssSupport {
enabled = true
}
scssSupport {
enabled = true
}
}
webpackTask {
cssSupport{
enabled = true
}
scssSupport{
enabled = true
}
mainOutputFileName.set("js/visionforge-playground.js")
}
}
@ -43,9 +45,9 @@ kotlin {
val commonMain by getting {
dependencies {
implementation(projects.visionforgeSolid)
// implementation(projects.visionforgePlotly)
implementation(projects.plotly.plotlyktCore)
implementation(projects.visionforgeMarkdown)
// implementation(projects.visionforgeTables)
implementation(projects.visionforgeTables)
implementation(projects.cernRootLoader)
api(projects.visionforgeJupyter.visionforgeJupyterCommon)
}
@ -60,7 +62,7 @@ kotlin {
val jvmMain by getting {
dependencies {
implementation("io.ktor:ktor-server-cio:${spclibs.versions.ktor.get()}")
implementation("io.ktor:ktor-server-cio")
implementation(projects.visionforgeGdml)
implementation(projects.visionforgeServer)
implementation(spclibs.logback.classic)
@ -77,9 +79,7 @@ val jsBrowserDistribution = tasks.getByName("jsBrowserDistribution")
tasks.getByName<ProcessResources>("jvmProcessResources") {
dependsOn(jsBrowserDistribution)
from(jsBrowserDistribution) {
exclude("**/*.js.map")
}
from(jsBrowserDistribution)
}
val processJupyterApiResources by tasks.getting(org.jetbrains.kotlinx.jupyter.api.plugin.tasks.JupyterApiResourcesTask::class) {

@ -1,5 +1,5 @@
import space.kscience.dataforge.misc.DFExperimental
import space.kscience.plotly.PlotlyPlugin
import space.kscience.plotly.PlotlyJSPlugin
import space.kscience.visionforge.html.runVisionClient
import space.kscience.visionforge.jupyter.VFNotebookClient
import space.kscience.visionforge.markup.MarkupPlugin
@ -9,7 +9,7 @@ import space.kscience.visionforge.tables.TableVisionJsPlugin
@DFExperimental
fun main() = runVisionClient {
plugin(ThreePlugin)
plugin(PlotlyPlugin)
plugin(PlotlyJSPlugin)
plugin(MarkupPlugin)
plugin(TableVisionJsPlugin)
plugin(VFNotebookClient)

@ -2,6 +2,7 @@ package space.kscience.visionforge.examples
import kotlinx.html.h2
import space.kscience.dataforge.meta.ValueType
import space.kscience.plotly.PlotlyPlugin
import space.kscience.plotly.layout
import space.kscience.plotly.models.ScatterMode
import space.kscience.plotly.models.TextPosition
@ -43,6 +44,7 @@ fun main() = makeVisionFile(
h2 { +"Interactive plots with Plotly" }
vision("plot") {
requirePlugin(PlotlyPlugin)
plotly {
scatter {
x(1, 2, 3, 4)

@ -19,7 +19,11 @@ import kotlin.math.PI
import kotlin.math.cos
import kotlin.math.sin
suspend fun main() = serve {
suspend fun main() = serve(
routeConfiguration = {
updateInterval = 100
}
) {
// val azimuth = 60.degrees
// val inclination = 15.degrees
@ -45,6 +49,7 @@ suspend fun main() = serve {
//axes(200)
ambientLight {
color(Colors.white)
intensity = 3.0
}
val platform = solidGroup("platform") {
cylinder(50, 5, name = "base")
@ -87,7 +92,7 @@ suspend fun main() = serve {
var time: Long = 0L
while (isActive) {
with(QuaternionAlgebra) {
delay(200)
delay(100)
platform.quaternion = Quaternion.fromRotation(
15.degrees * sin(time.toDouble() * 2 * PI / xPeriod),
Float64Space3D.xAxis
@ -100,7 +105,7 @@ suspend fun main() = serve {
antenna.quaternion = qi.conjugate * incRot.conjugate * target
time += 200
time += 100
//antenna.quaternion = Quaternion.fromRotation(5.degrees, Euclidean3DSpace.zAxis) * antenna.quaternion
}
}

@ -27,7 +27,7 @@ fun main() = makeVisionFile(Path.of("curves.html"), resourceLocation = ResourceL
val cathodeTeflonDiskThickness = 5
val cathodeCopperSupportOuterRadius = 45
val cathodeCopperSupportInnerRadius = 8.5
val cathodeCopperSupportThickness = 1
val cathodeCopperSupportThickness = 1.0
// mylar cathode
val mylarCathodeThickness = 0.004
// patern

@ -9,6 +9,7 @@ import space.kscience.dataforge.context.Global
import space.kscience.plotly.PlotlyPlugin
import space.kscience.visionforge.html.*
import space.kscience.visionforge.markup.MarkupPlugin
import space.kscience.visionforge.server.VisionRoute
import space.kscience.visionforge.server.close
import space.kscience.visionforge.server.openInBrowser
import space.kscience.visionforge.server.visionPage
@ -42,6 +43,7 @@ public fun makeVisionFile(
public suspend fun serve(
title: String = "VisionForge page",
show: Boolean = true,
routeConfiguration: VisionRoute.() -> Unit = {},
content: HtmlVisionFragment,
) {
val context = Context("playground") {
@ -62,6 +64,7 @@ public suspend fun serve(
defer = true
},
VisionPage.title(title),
routeConfiguration = routeConfiguration,
visionFragment = content
)
}.start(false)

@ -36,6 +36,7 @@ suspend fun main() {
val sat = solids.visionOfSatellite(ySegments = 3).apply {
ambientLight {
color(Colors.white)
intensity = 3.0
}
}
val server = embeddedServer(CIO, port = 7777) {

@ -25,7 +25,6 @@ fun VisionLayout<Solid>.demo(name: String, title: String = name, block: SolidGro
block()
ambientLight {
color(Colors.white)
intensity = 0.5
}
pointLight(0, 0, 1000) {
color(Colors.white)

@ -11,7 +11,7 @@ dependencies {
implementation(projects.plotly.plotlyktServer)
implementation(projects.plotly.plotlyktScript)
implementation(kotlin("script-runtime"))
implementation("org.jetbrains.kotlinx:dataframe:0.13.1")
implementation("org.jetbrains.kotlinx:dataframe:0.15.0")
}
kotlin{

@ -16,7 +16,7 @@ dependencies {
javafx{
modules("javafx.web")
version = "11"
version = "17"
}
application {
@ -24,6 +24,6 @@ application {
}
kotlin{
jvmToolchain(11)
jvmToolchain(17)
}

@ -1,11 +1,14 @@
@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

@ -17,7 +17,7 @@ public abstract class LightSource : MiscSolid() {
override val descriptor: MetaDescriptor get() = LightSource.descriptor
public val color: ColorAccessor by colorProperty(SolidMaterial.COLOR_KEY)
public var intensity: Number by properties.number(INTENSITY_KEY) { 1.0 }
public var intensity: Number by properties.number(INTENSITY_KEY) { 2.0 }
public companion object {
public val INTENSITY_KEY: Name = "intensity".asName()

@ -1,6 +1,9 @@
@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

@ -10,6 +10,9 @@ kscience {
binaries.library()
browser {
webpackTask{
cssSupport {
enabled = true
}
scssSupport {
enabled = true
}
@ -23,8 +26,8 @@ kscience {
api("space.kscience:tables-kt:${tablesVersion}")
}
jsMain {
api(npm("tabulator-tables", "5.5.2"))
api(npm("@types/tabulator-tables", "5.5.3"))
api(npm("tabulator-tables", "6.3.1"))
api(npm("@types/tabulator-tables", "6.2.3"))
}
}

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

@ -8,8 +8,13 @@ import org.w3c.dom.Node
import org.w3c.dom.events.MouseEvent
import space.kscience.dataforge.context.info
import space.kscience.dataforge.context.logger
import space.kscience.dataforge.meta.*
import space.kscience.dataforge.names.*
import space.kscience.dataforge.meta.get
import space.kscience.dataforge.meta.isEmpty
import space.kscience.dataforge.meta.string
import space.kscience.dataforge.meta.useProperty
import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName
import space.kscience.dataforge.names.plus
import space.kscience.visionforge.Colors
import space.kscience.visionforge.solid.Solid
import space.kscience.visionforge.solid.specifications.*
@ -21,7 +26,10 @@ import three.external.controls.OrbitControls
import three.external.controls.TrackballControls
import three.geometries.EdgesGeometry
import three.materials.Material
import three.math.*
import three.math.Box3
import three.math.Plane
import three.math.Vector2
import three.math.Vector3
import three.meshline.MeshLine
import three.meshline.MeshLineMaterial
import three.meshline.isMeshLineMaterial
@ -104,10 +112,6 @@ public class ThreeCanvas(
camera.updateProjectionMatrix()
}
/**
* Attach canvas to given [HTMLElement]
*/
init {
check(element.getElementsByClassName("three-canvas").length == 0) {
"Three canvas already created in this element"
@ -311,13 +315,13 @@ public class ThreeCanvas(
public companion object {
public val SELECTED_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply {
color.set(Colors.ivory)
thickness = 2f
lineWidth = 2f
cached = true
}
public val HIGHLIGHT_MATERIAL: MeshLineMaterial = MeshLineMaterial().apply {
color.set(Colors.blue)
thickness = 1f
lineWidth = 1f
cached = true
}
//

@ -23,7 +23,7 @@ public object ThreeMeshLineFactory : ThreeFactory<PolyLine> {
)
val material = MeshLineMaterial().apply {
thickness = vision.thickness.toFloat()
lineWidth = vision.thickness.toFloat()
color = vision.color.string?.let { Color(it) } ?: ThreeMaterials.DEFAULT_LINE_COLOR
}

@ -11,7 +11,7 @@ public object ThreeSmartLineFactory : ThreeFactory<PolyLine> {
three: ThreePlugin,
vision: PolyLine,
observe: Boolean,
): Object3D = if (vision.thickness == 1.0) {
): Object3D = if (vision.thickness == PolyLine.DEFAULT_THICKNESS) {
ThreeLineFactory.build(three, vision, observe)
} else {
ThreeMeshLineFactory.build(three, vision, observe)

@ -1,4 +1,4 @@
@file:JsModule("three.meshline")
@file:JsModule("meshline")
package three.meshline
@ -6,6 +6,7 @@ package three.meshline
import three.core.BufferGeometry
import three.materials.ShaderMaterial
import three.math.Color
import three.math.Vector2
import three.math.Vector3
import three.textures.Texture
@ -13,25 +14,25 @@ import three.textures.Texture
* https://github.com/spite/THREE.MeshLine
*/
public external class MeshLine : BufferGeometry {
public fun setGeometry(geometry: BufferGeometry)
public external class MeshLineGeometry : BufferGeometry {
// public fun setGeometry(geometry: BufferGeometry)
public fun setPoints(points: Array<Vector3>)
}
public external class MeshLineMaterial : ShaderMaterial {
@JsName("lineWidth")
public var thickness: Float
public var lineWidth: Float
public var color: Color
public var map: Texture?
public var useMap: Boolean
public var useMap: Float
public var alphaMap: Texture?
public var useAlphaMap: Boolean
public var useAlphaMap: Float
public var gradient: Array<Color>
public var repeat: dynamic // - THREE.Vector2 to define the texture tiling (applies to map and alphaMap - MIGHT CHANGE IN THE FUTURE)
public var dashArray: dynamic //- the length and space between dashes. (0 - no dash)
public var repeat: Vector2 // - THREE.Vector2 to define the texture tiling (applies to map and alphaMap - MIGHT CHANGE IN THE FUTURE)
public var dashArray: Float //- the length and space between dashes. (0 - no dash)
public var dashOffset: dynamic // - defines the location where the dash will begin. Ideal to animate the line.
public var dashRatio: dynamic // - defines the ratio between that is visible or not (0 - more visible, 1 - more invisible).
public var resolution: dynamic // - THREE.Vector2 specifying the canvas size (REQUIRED)
public var resolution: Vector2 // - THREE.Vector2 specifying the canvas size (REQUIRED)
public var sizeAttenuation: Int // - makes the line width constant regardless distance (1 unit is 1px on screen) (0 - attenuate, 1 - don't attenuate)
}

@ -4,8 +4,8 @@ import three.core.BufferGeometry
import three.materials.Material
import three.math.Vector3
public fun MeshLine(geometry: BufferGeometry): MeshLine = MeshLine().apply { setGeometry(geometry) }
public fun MeshLine(geometry: BufferGeometry): MeshLineGeometry = MeshLineGeometry().apply { copy(geometry) }
public fun MeshLine(points: Array<Vector3>): MeshLine = MeshLine().apply { setPoints(points) }
public fun MeshLine(points: Array<Vector3>): MeshLineGeometry = MeshLineGeometry().apply { setPoints(points) }
internal fun isMeshLineMaterial(material: Material): Boolean = material.asDynamic().isMeshLineMaterial == true