forked from kscience/visionforge
Suspended renderers and property change listeners
This commit is contained in:
parent
8204eb63c3
commit
2b70afdb86
@ -8,7 +8,7 @@ kscience{
|
|||||||
|
|
||||||
kotlin{
|
kotlin{
|
||||||
explicitApi = null
|
explicitApi = null
|
||||||
js(IR){
|
js{
|
||||||
useCommonJs()
|
useCommonJs()
|
||||||
browser {
|
browser {
|
||||||
binaries.executable()
|
binaries.executable()
|
||||||
|
@ -1,14 +1,14 @@
|
|||||||
plugins {
|
plugins {
|
||||||
id("space.kscience.gradle.mpp")
|
id("space.kscience.gradle.mpp")
|
||||||
application
|
// application
|
||||||
}
|
}
|
||||||
|
|
||||||
kscience {
|
kscience {
|
||||||
useCoroutines()
|
useCoroutines()
|
||||||
jvm {
|
jvm()
|
||||||
withJava()
|
js{
|
||||||
|
binaries.executable()
|
||||||
}
|
}
|
||||||
js()
|
|
||||||
dependencies {
|
dependencies {
|
||||||
implementation(projects.visionforgeSolid)
|
implementation(projects.visionforgeSolid)
|
||||||
implementation(projects.visionforgeGdml)
|
implementation(projects.visionforgeGdml)
|
||||||
@ -21,6 +21,6 @@ kscience {
|
|||||||
|
|
||||||
kotlin.explicitApi = null
|
kotlin.explicitApi = null
|
||||||
|
|
||||||
application {
|
//application {
|
||||||
mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
|
// mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
|
||||||
}
|
//}
|
@ -150,6 +150,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() {
|
||||||
|
@ -67,7 +67,7 @@ public var Vision.visible: Boolean?
|
|||||||
*/
|
*/
|
||||||
public fun Vision.onPropertyChange(
|
public fun Vision.onPropertyChange(
|
||||||
scope: CoroutineScope? = manager?.context,
|
scope: CoroutineScope? = manager?.context,
|
||||||
callback: (Name) -> Unit
|
callback: suspend (Name) -> Unit
|
||||||
): Job = properties.changes.onEach {
|
): Job = properties.changes.onEach {
|
||||||
callback(it)
|
callback(it)
|
||||||
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
}.launchIn(scope ?: error("Orphan Vision can't observe properties"))
|
@ -0,0 +1,25 @@
|
|||||||
|
package space.kscience.visionforge.solid
|
||||||
|
|
||||||
|
import kotlinx.serialization.SerialName
|
||||||
|
import kotlinx.serialization.Serializable
|
||||||
|
import space.kscience.visionforge.MutableVisionContainer
|
||||||
|
import space.kscience.visionforge.VisionBuilder
|
||||||
|
import space.kscience.visionforge.setChild
|
||||||
|
|
||||||
|
|
||||||
|
public sealed class StlVision: SolidBase<StlVision>()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("solid.stl.url")
|
||||||
|
public class StlUrlVision(public val url: String) : StlVision()
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
@SerialName("solid.stl.binary")
|
||||||
|
public class StlBinaryVision(public val data: ByteArray) : StlVision()
|
||||||
|
|
||||||
|
@VisionBuilder
|
||||||
|
public inline fun MutableVisionContainer<Solid>.stl(
|
||||||
|
url: String,
|
||||||
|
name: String? = null,
|
||||||
|
action: StlVision.() -> Unit = {},
|
||||||
|
): StlVision = StlUrlVision(url).apply(action).also { setChild(name, it) }
|
@ -5,7 +5,7 @@ import space.kscience.visionforge.solid.detail
|
|||||||
import three.geometries.BoxGeometry
|
import three.geometries.BoxGeometry
|
||||||
|
|
||||||
public object ThreeBoxFactory : ThreeMeshFactory<Box>(Box::class) {
|
public object ThreeBoxFactory : ThreeMeshFactory<Box>(Box::class) {
|
||||||
override fun buildGeometry(obj: Box): BoxGeometry =
|
override suspend fun buildGeometry(obj: Box): BoxGeometry =
|
||||||
obj.detail?.let { detail ->
|
obj.detail?.let { detail ->
|
||||||
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
BoxGeometry(obj.xSize, obj.ySize, obj.zSize, detail, detail, detail)
|
||||||
} ?: BoxGeometry(obj.xSize, obj.ySize, obj.zSize)
|
} ?: BoxGeometry(obj.xSize, obj.ySize, obj.zSize)
|
||||||
|
@ -8,7 +8,7 @@ import kotlin.math.PI
|
|||||||
import kotlin.math.pow
|
import kotlin.math.pow
|
||||||
|
|
||||||
public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::class) {
|
public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::class) {
|
||||||
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
override suspend fun buildGeometry(obj: ConeSegment): BufferGeometry {
|
||||||
val cylinder = obj.detail?.let {
|
val cylinder = obj.detail?.let {
|
||||||
val segments = it.toDouble().pow(0.5).toInt()
|
val segments = it.toDouble().pow(0.5).toInt()
|
||||||
CylinderGeometry(
|
CylinderGeometry(
|
||||||
|
@ -4,7 +4,7 @@ import space.kscience.visionforge.solid.Convex
|
|||||||
import three.external.geometries.ConvexBufferGeometry
|
import three.external.geometries.ConvexBufferGeometry
|
||||||
|
|
||||||
public object ThreeConvexFactory : ThreeMeshFactory<Convex>(Convex::class) {
|
public object ThreeConvexFactory : ThreeMeshFactory<Convex>(Convex::class) {
|
||||||
override fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
override suspend fun buildGeometry(obj: Convex): ConvexBufferGeometry {
|
||||||
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
val vectors = obj.points.map { it.toVector() }.toTypedArray()
|
||||||
return ConvexBufferGeometry(vectors)
|
return ConvexBufferGeometry(vectors)
|
||||||
}
|
}
|
||||||
|
@ -84,7 +84,7 @@ public fun Object3D.updateProperty(source: Vision, propertyName: Name) {
|
|||||||
* Generic factory for elements which provide inside geometry builder
|
* Generic factory for elements which provide inside geometry builder
|
||||||
*/
|
*/
|
||||||
public object ThreeShapeFactory : ThreeMeshFactory<GeometrySolid>(GeometrySolid::class) {
|
public object ThreeShapeFactory : ThreeMeshFactory<GeometrySolid>(GeometrySolid::class) {
|
||||||
override fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
override suspend fun buildGeometry(obj: GeometrySolid): BufferGeometry = ThreeGeometryBuilder().apply {
|
||||||
obj.toGeometry(this)
|
obj.toGeometry(this)
|
||||||
}.build()
|
}.build()
|
||||||
}
|
}
|
@ -1,6 +1,5 @@
|
|||||||
package space.kscience.visionforge.solid.three
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
import org.w3c.dom.url.URL
|
|
||||||
import space.kscience.visionforge.solid.SolidBase
|
import space.kscience.visionforge.solid.SolidBase
|
||||||
import three.core.Object3D
|
import three.core.Object3D
|
||||||
|
|
||||||
@ -10,15 +9,3 @@ import three.core.Object3D
|
|||||||
public abstract class ThreeJsVision : SolidBase<ThreeJsVision>() {
|
public abstract class ThreeJsVision : SolidBase<ThreeJsVision>() {
|
||||||
public abstract suspend fun render(three: ThreePlugin): Object3D
|
public abstract suspend fun render(three: ThreePlugin): Object3D
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ThreeStlVision(val url: URL): ThreeJsVision(){
|
|
||||||
override suspend fun render(three: ThreePlugin): Object3D {
|
|
||||||
// suspendCoroutine {
|
|
||||||
//
|
|
||||||
// }
|
|
||||||
// STLLoader()
|
|
||||||
|
|
||||||
TODO()
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
@ -21,10 +21,11 @@ import kotlin.reflect.KClass
|
|||||||
public abstract class ThreeMeshFactory<in T : Solid>(
|
public abstract class ThreeMeshFactory<in T : Solid>(
|
||||||
override val type: KClass<in T>,
|
override val type: KClass<in T>,
|
||||||
) : ThreeFactory<T> {
|
) : ThreeFactory<T> {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build a geometry for an object
|
* Build a geometry for an object
|
||||||
*/
|
*/
|
||||||
public abstract fun buildGeometry(obj: T): BufferGeometry
|
public abstract suspend fun buildGeometry(obj: T): BufferGeometry
|
||||||
|
|
||||||
override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh {
|
override suspend fun build(three: ThreePlugin, vision: T, observe: Boolean): Mesh {
|
||||||
val geometry = buildGeometry(vision)
|
val geometry = buildGeometry(vision)
|
||||||
|
@ -37,6 +37,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
|
|||||||
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
|
||||||
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
objectFactories[AmbientLightSource::class] = ThreeAmbientLightFactory
|
||||||
objectFactories[PointLightSource::class] = ThreePointLightFactory
|
objectFactories[PointLightSource::class] = ThreePointLightFactory
|
||||||
|
objectFactories[StlVision::class] = ThreeStlFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
|
@ -6,7 +6,7 @@ import three.core.BufferGeometry
|
|||||||
import three.geometries.SphereGeometry
|
import three.geometries.SphereGeometry
|
||||||
|
|
||||||
public object ThreeSphereFactory : ThreeMeshFactory<Sphere>(Sphere::class) {
|
public object ThreeSphereFactory : ThreeMeshFactory<Sphere>(Sphere::class) {
|
||||||
override fun buildGeometry(obj: Sphere): BufferGeometry {
|
override suspend fun buildGeometry(obj: Sphere): BufferGeometry {
|
||||||
return obj.detail?.let { detail ->
|
return obj.detail?.let { detail ->
|
||||||
SphereGeometry(
|
SphereGeometry(
|
||||||
radius = obj.radius,
|
radius = obj.radius,
|
||||||
|
@ -0,0 +1,38 @@
|
|||||||
|
package space.kscience.visionforge.solid.three
|
||||||
|
|
||||||
|
import org.khronos.webgl.ArrayBuffer
|
||||||
|
import org.khronos.webgl.Int8Array
|
||||||
|
import space.kscience.visionforge.solid.StlBinaryVision
|
||||||
|
import space.kscience.visionforge.solid.StlUrlVision
|
||||||
|
import space.kscience.visionforge.solid.StlVision
|
||||||
|
import three.core.BufferGeometry
|
||||||
|
import three.external.loaders.STLLoader
|
||||||
|
import kotlin.coroutines.resume
|
||||||
|
import kotlin.coroutines.resumeWithException
|
||||||
|
import kotlin.coroutines.suspendCoroutine
|
||||||
|
|
||||||
|
fun ArrayBuffer.toByteArray(): ByteArray = Int8Array(this).unsafeCast<ByteArray>()
|
||||||
|
|
||||||
|
public object ThreeStlFactory : ThreeMeshFactory<StlVision>(StlVision::class) {
|
||||||
|
|
||||||
|
private val loader = STLLoader().apply {
|
||||||
|
requestHeader = listOf("Access-Control-Allow-Origin: *")
|
||||||
|
}
|
||||||
|
|
||||||
|
override suspend fun buildGeometry(obj: StlVision): BufferGeometry = when (obj) {
|
||||||
|
is StlBinaryVision -> loader.parse(obj.data)
|
||||||
|
is StlUrlVision -> suspendCoroutine { continuation ->
|
||||||
|
loader.load(
|
||||||
|
url = obj.url,
|
||||||
|
onLoad = {
|
||||||
|
continuation.resume(it)
|
||||||
|
},
|
||||||
|
onError = {
|
||||||
|
continuation.resumeWithException(RuntimeException("Failed to load STL object from ${obj.url}"))
|
||||||
|
}
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
@ -22,17 +22,19 @@
|
|||||||
* THE SOFTWARE.
|
* THE SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
@file:JsModule("three")
|
@file:JsModule("three/examples/jsm/loaders/STLLoader.js")
|
||||||
@file:JsNonModule
|
@file:JsNonModule
|
||||||
|
|
||||||
package three.external.loaders
|
package three.external.loaders
|
||||||
|
|
||||||
|
import org.khronos.webgl.ArrayBuffer
|
||||||
import org.w3c.xhr.XMLHttpRequest
|
import org.w3c.xhr.XMLHttpRequest
|
||||||
import three.core.BufferGeometry
|
import three.core.BufferGeometry
|
||||||
import three.core.Object3D
|
|
||||||
|
|
||||||
external class STLLoader {
|
external class STLLoader {
|
||||||
|
|
||||||
|
var requestHeader: List<String>
|
||||||
|
|
||||||
fun load(
|
fun load(
|
||||||
url: String,
|
url: String,
|
||||||
onLoad: (BufferGeometry) -> Unit,
|
onLoad: (BufferGeometry) -> Unit,
|
||||||
@ -40,7 +42,10 @@ external class STLLoader {
|
|||||||
onError: () -> Unit = definedExternally
|
onError: () -> Unit = definedExternally
|
||||||
)
|
)
|
||||||
|
|
||||||
fun parse(data: String): Object3D
|
fun parse(data: String): BufferGeometry
|
||||||
fun parse(data: ByteArray): Object3D
|
|
||||||
|
fun parse(data: ByteArray): BufferGeometry
|
||||||
|
|
||||||
|
fun parse(data: ArrayBuffer): BufferGeometry
|
||||||
|
|
||||||
}
|
}
|
Loading…
Reference in New Issue
Block a user