Multiple fixes

This commit is contained in:
Alexander Nozik 2023-05-29 21:38:30 +03:00
parent c48e5aac25
commit 33778801b6
28 changed files with 207 additions and 79 deletions

View File

@ -118,7 +118,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 +136,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 +149,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 +163,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 {

View File

@ -7,6 +7,7 @@ kscience {
js { js {
useCommonJs() useCommonJs()
browser { browser {
binaries.executable()
commonWebpackConfig { commonWebpackConfig {
cssSupport { cssSupport {
enabled.set(false) enabled.set(false)
@ -27,7 +28,6 @@ kscience {
implementation(projects.visionforgeThreejs) implementation(projects.visionforgeThreejs)
implementation(npm("react-file-drop", "3.0.6")) implementation(npm("react-file-drop", "3.0.6"))
} }
application()
} }
//kotlin { //kotlin {

View File

@ -4,13 +4,13 @@ plugins {
kscience{ kscience{
useCoroutines() useCoroutines()
application()
} }
kotlin{ kotlin{
js(IR){ js(IR){
useCommonJs() useCommonJs()
browser { browser {
binaries.executable()
commonWebpackConfig { commonWebpackConfig {
cssSupport{ cssSupport{
enabled.set(false) enabled.set(false)

View File

@ -38,7 +38,6 @@ kscience {
implementation(project(":visionforge-threejs")) implementation(project(":visionforge-threejs"))
//implementation(devNpm("webpack-bundle-analyzer", "4.4.0")) //implementation(devNpm("webpack-bundle-analyzer", "4.4.0"))
} }
application()
} }
application { application {

View File

@ -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 {
@ -29,6 +30,7 @@ kotlin {
} }
jvm { jvm {
// withJava()
compilations.all { compilations.all {
kotlinOptions { kotlinOptions {
jvmTarget = "11" jvmTarget = "11"
@ -89,3 +91,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")
//}

View File

@ -2,37 +2,73 @@
"cells": [ "cells": [
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 1,
"metadata": { "metadata": {
"tags": [], "tags": [],
"pycharm": { "pycharm": {
"is_executing": true "is_executing": true
},
"ExecuteTime": {
"end_time": "2023-05-29T15:22:37.933397300Z",
"start_time": "2023-05-29T15:22:37.913872100Z"
} }
}, },
"outputs": [], "outputs": [],
"source": [ "source": []
"@file:DependsOn(\"../build/libs/playground-0.3.0-dev-4-all.jar\")"
]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 3,
"metadata": {}, "metadata": {
"outputs": [], "ExecuteTime": {
"end_time": "2023-05-29T15:22:50.486483300Z",
"start_time": "2023-05-29T15:22:50.457485500Z"
}
},
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Line_2.jupyter.kts (1:1 - 3) Unresolved reference: vf"
]
}
],
"source": [ "source": [
"vf.startServer()" "vf.startServer()"
] ]
}, },
{ {
"cell_type": "code", "cell_type": "code",
"execution_count": null, "execution_count": 4,
"metadata": { "metadata": {
"collapsed": false, "collapsed": false,
"jupyter": { "jupyter": {
"outputs_hidden": false "outputs_hidden": false
},
"ExecuteTime": {
"end_time": "2023-05-29T15:22:51.410680600Z",
"start_time": "2023-05-29T15:22:51.250779400Z"
} }
}, },
"outputs": [], "outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"Line_3.jupyter.kts (1:16 - 26) Unresolved reference: coroutines\n",
"Line_3.jupyter.kts (4:1 - 7) Unresolved reference: Plotly\n",
"Line_3.jupyter.kts (5:5 - 12) Unresolved reference: scatter\n",
"Line_3.jupyter.kts (6:9 - 10) Unresolved reference: x\n",
"Line_3.jupyter.kts (7:9 - 10) Unresolved reference: y\n",
"Line_3.jupyter.kts (8:12 - 14) Unresolved reference: vf\n",
"Line_3.jupyter.kts (9:13 - 15) Unresolved reference: vf\n",
"Line_3.jupyter.kts (10:23 - 31) Unresolved reference: isActive\n",
"Line_3.jupyter.kts (11:21 - 26) Unresolved reference: delay\n",
"Line_3.jupyter.kts (12:21 - 22) Unresolved reference: y"
]
}
],
"source": [ "source": [
"import kotlinx.coroutines.*\n", "import kotlinx.coroutines.*\n",
"import kotlin.random.Random\n", "import kotlin.random.Random\n",
@ -84,6 +120,9 @@
"nbconvert_exporter": "", "nbconvert_exporter": "",
"pygments_lexer": "kotlin", "pygments_lexer": "kotlin",
"version": "1.8.0-dev-3517" "version": "1.8.0-dev-3517"
},
"ktnbPluginMetadata": {
"isAddProjectLibrariesToClasspath": false
} }
}, },
"nbformat": 4, "nbformat": 4,

View File

@ -0,0 +1,39 @@
package space.kscience.visionforge.examples
import kotlin.math.PI
import space.kscience.visionforge.Colors
import space.kscience.visionforge.solid.*
fun main() = makeVisionFile{
vision("canvas") {
solid {
ambientLight()
box(100.0, 100.0, 100.0) {
z = -110.0
color.set("teal")
}
sphere(50.0) {
x = 110
detail = 16
color.set("red")
}
tube(50, height = 10, innerRadius = 25, angle = PI) {
y = 110
detail = 16
rotationX = PI / 4
color.set("blue")
}
sphereLayer(50, 40, theta = PI / 2) {
rotationX = -PI * 3 / 4
z = 110
color.set(Colors.pink)
}
tube(30,20, 20){
detail = 31
y = - 220
}
}
}
}

View File

@ -8,7 +8,6 @@ kscience {
// useSerialization { // useSerialization {
// json() // json()
// } // }
application()
dependencies{ dependencies{
implementation(projects.visionforgeThreejs.visionforgeThreejsServer) implementation(projects.visionforgeThreejs.visionforgeThreejsServer)
implementation("ch.qos.logback:logback-classic:1.4.5") implementation("ch.qos.logback:logback-classic:1.4.5")

View File

@ -3,8 +3,7 @@ package ru.mipt.npm.sat
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.resources import io.ktor.server.http.content.staticResources
import io.ktor.server.http.content.static
import io.ktor.server.routing.routing import io.ktor.server.routing.routing
import kotlinx.coroutines.* import kotlinx.coroutines.*
import kotlinx.html.div import kotlinx.html.div
@ -41,9 +40,7 @@ fun main() {
val server = embeddedServer(CIO, connector.port, connector.host) { val server = embeddedServer(CIO, connector.port, connector.host) {
routing { routing {
static { staticResources("", null, null)
resources()
}
} }
visionPage( visionPage(

View File

@ -1,11 +1,11 @@
plugins { plugins {
id("space.kscience.gradle.mpp") id("space.kscience.gradle.mpp")
`maven-publish`
application application
} }
kscience { kscience {
useCoroutines() useCoroutines()
application()
jvm { jvm {
withJava() withJava()
} }
@ -23,3 +23,7 @@ kscience {
application { application {
mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt") mainClass.set("space.kscience.visionforge.solid.demo.FXDemoAppKt")
} }
kotlin{
explicitApi = null
}

View File

@ -5,8 +5,8 @@ import space.kscience.dataforge.names.Name
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.Solids
public interface VisionLayout<in V: Vision> { interface VisionLayout<in V: Vision> {
val solids: Solids val solids: Solids
public fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY) fun render(name: Name, vision: V, meta: Meta = Meta.EMPTY)
} }

View File

@ -6,5 +6,5 @@ kotlin.incremental.js.ir=true
org.gradle.parallel=true org.gradle.parallel=true
org.gradle.jvmargs=-Xmx4G org.gradle.jvmargs=-Xmx4G
toolsVersion=0.14.8-kotlin-1.8.20 toolsVersion=0.14.9-kotlin-1.8.20
org.jetbrains.compose.experimental.jscanvas.enabled=true org.jetbrains.compose.experimental.jscanvas.enabled=true

View File

@ -0,0 +1,11 @@
package space.kscience.visionforge.compose
import androidx.compose.material.Surface
import androidx.compose.runtime.Composable
@Composable
public fun ThreeJs(){
Surface {
}
}

View File

@ -4,26 +4,24 @@ plugins {
val dataforgeVersion: String by rootProject.extra val dataforgeVersion: String by rootProject.extra
kscience{ kscience {
jvm() jvm()
js() js()
native() native()
useCoroutines()
dependencies { dependencies {
api("space.kscience:dataforge-context:$dataforgeVersion") api("space.kscience:dataforge-context:$dataforgeVersion")
api(spclibs.kotlinx.html) api(spclibs.kotlinx.html)
// api("org.jetbrains.kotlin-wrappers:kotlin-css") // api("org.jetbrains.kotlin-wrappers:kotlin-css")
} }
testDependencies { jsMain {
implementation("org.jetbrains.kotlinx:kotlinx-coroutines-test:${space.kscience.gradle.KScienceVersions.coroutinesVersion}")
}
dependencies(jsMain){
api("org.jetbrains.kotlin-wrappers:kotlin-extensions") api("org.jetbrains.kotlin-wrappers:kotlin-extensions")
} }
useSerialization{ useSerialization {
json() json()
} }
} }
readme{ readme {
maturity = space.kscience.gradle.Maturity.DEVELOPMENT maturity = space.kscience.gradle.Maturity.DEVELOPMENT
} }

View File

@ -70,7 +70,7 @@ public class VisionManager(meta: Meta) : AbstractPlugin(meta), MutableVisionCont
private val defaultSerialModule: SerializersModule = SerializersModule { private val defaultSerialModule: SerializersModule = SerializersModule {
polymorphic(Vision::class) { polymorphic(Vision::class) {
default { SimpleVisionGroup.serializer() } defaultDeserializer { SimpleVisionGroup.serializer() }
subclass(NullVision.serializer()) subclass(NullVision.serializer())
subclass(SimpleVisionGroup.serializer()) subclass(SimpleVisionGroup.serializer())
subclass(VisionOfNumberField.serializer()) subclass(VisionOfNumberField.serializer())

View File

@ -94,7 +94,7 @@ internal class VisionPropertyTest {
} }
@Test @Test
fun testChildrenPropertyFlow() = runTest(dispatchTimeoutMs = 200) { fun testChildrenPropertyFlow() = runTest(timeout = 200.milliseconds) {
val group = Global.request(VisionManager).group { val group = Global.request(VisionManager).group {
properties { properties {

View File

@ -10,8 +10,9 @@ kscience {
binaries.library() binaries.library()
} }
dependencies { dependencies {
api(project(":visionforge-core")) api(projects.visionforgeCore)
api("org.jetbrains:markdown:$markdownVersion") api("org.jetbrains:markdown:$markdownVersion")
api("org.jetbrains:annotations:24.0.0")
} }
useSerialization() useSerialization()
} }

View File

@ -1,5 +1,8 @@
package space.kscience.visionforge.markup package space.kscience.visionforge.markup
import space.kscience.dataforge.context.PluginFactory
import space.kscience.visionforge.VisionPlugin import space.kscience.visionforge.VisionPlugin
public expect class MarkupPlugin: VisionPlugin public expect class MarkupPlugin: VisionPlugin{
public companion object : PluginFactory<MarkupPlugin>
}

View File

@ -10,6 +10,8 @@ import space.kscience.dataforge.names.Name
import space.kscience.dataforge.names.asName import space.kscience.dataforge.names.asName
import space.kscience.visionforge.AbstractVision import space.kscience.visionforge.AbstractVision
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionBuilder
import space.kscience.visionforge.html.VisionOutput
import space.kscience.visionforge.root import space.kscience.visionforge.root
@Serializable @Serializable
@ -39,3 +41,15 @@ internal val markupSerializersModule = SerializersModule {
subclass(VisionOfMarkup.serializer()) subclass(VisionOfMarkup.serializer())
} }
} }
/**
* Embed a dynamic markdown block in a vision
*/
@VisionBuilder
public inline fun VisionOutput.markdown(
format: String = VisionOfMarkup.COMMONMARK_FORMAT,
block: VisionOfMarkup.() -> Unit,
): VisionOfMarkup {
requirePlugin(MarkupPlugin)
return VisionOfMarkup(format).apply(block)
}

View File

@ -44,7 +44,7 @@ public actual class MarkupPlugin : VisionPlugin(), ElementVisionRenderer {
element.append(div) element.append(div)
} }
public companion object : PluginFactory<MarkupPlugin> { public actual companion object : PluginFactory<MarkupPlugin> {
override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP) override val tag: PluginTag = PluginTag("vision.markup", PluginTag.DATAFORGE_GROUP)
override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin()

View File

@ -1,6 +1,7 @@
package space.kscience.visionforge.markup package space.kscience.visionforge.markup
import kotlinx.serialization.modules.SerializersModule import kotlinx.serialization.modules.SerializersModule
import org.intellij.lang.annotations.Language
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.dataforge.context.PluginFactory import space.kscience.dataforge.context.PluginFactory
import space.kscience.dataforge.context.PluginTag import space.kscience.dataforge.context.PluginTag
@ -12,10 +13,14 @@ public actual class MarkupPlugin : VisionPlugin() {
override val tag: PluginTag get() = Companion.tag override val tag: PluginTag get() = Companion.tag
public companion object : PluginFactory<MarkupPlugin> { public actual companion object : PluginFactory<MarkupPlugin> {
override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP) override val tag: PluginTag = PluginTag("vision.plotly", PluginTag.DATAFORGE_GROUP)
override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin() override fun build(context: Context, meta: Meta): MarkupPlugin = MarkupPlugin()
} }
} }
public fun VisionOfMarkup.content(@Language("markdown") text: String) {
content = text
}

View File

@ -16,6 +16,7 @@ import space.kscience.plotly.Plot
import space.kscience.plotly.Plotly import space.kscience.plotly.Plotly
import space.kscience.visionforge.MutableVisionProperties import space.kscience.visionforge.MutableVisionProperties
import space.kscience.visionforge.Vision import space.kscience.visionforge.Vision
import space.kscience.visionforge.VisionBuilder
import space.kscience.visionforge.html.VisionOutput import space.kscience.visionforge.html.VisionOutput
@Serializable @Serializable
@ -82,7 +83,10 @@ public class VisionOfPlotly private constructor(
public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this) public fun Plot.asVision(): VisionOfPlotly = VisionOfPlotly(this)
@DFExperimental /**
* Embed a dynamic plotly plot in a vision
*/
@VisionBuilder
public inline fun VisionOutput.plotly( public inline fun VisionOutput.plotly(
block: Plot.() -> Unit, block: Plot.() -> Unit,
): VisionOfPlotly { ): VisionOfPlotly {

View File

@ -9,12 +9,10 @@ kscience {
useSerialization { useSerialization {
json() json()
} }
useCoroutines()
dependencies { dependencies {
api(projects.visionforgeCore) api(projects.visionforgeCore)
} }
testDependencies {
implementation(spclibs.kotlinx.coroutines.test)
}
dependencies(jvmTest) { dependencies(jvmTest) {
implementation(spclibs.logback.classic) implementation(spclibs.logback.classic)
} }

View File

@ -18,42 +18,54 @@ public class ConeSegment(
public val bottomRadius: Float, public val bottomRadius: Float,
public val height: Float, public val height: Float,
public val topRadius: Float, public val topRadius: Float,
public val startAngle: Float = 0f, public val phiStart: Float = 0f,
public val angle: Float = PI2 public val phi: Float = PI2,
) : SolidBase<ConeSegment>(), GeometrySolid { ) : SolidBase<ConeSegment>(), GeometrySolid {
init {
require(bottomRadius > 0) { "Bottom radius must be positive" }
require(topRadius > 0) { "Top radius must be positive" }
}
override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) { override fun <T : Any> toGeometry(geometryBuilder: GeometryBuilder<T>) {
val segments = detail ?: 32
val segments: Int = detail ?: 32
require(segments >= 4) { "The number of segments in cone segment is too small" } require(segments >= 4) { "The number of segments in cone segment is too small" }
val angleStep = angle / (segments - 1)
fun shape(r: Float, z: Float): List<Point3D> { val angleStep = phi / (segments - 1)
return (0 until segments).map { i ->
Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) /**
} * Top and bottom shape
*/
fun shape(r: Float, z: Float): List<Point3D> = (0 until segments).map { i ->
Point3D(r * cos(phiStart + angleStep * i), r * sin(phiStart + angleStep * i), z)
} }
geometryBuilder.apply { with(geometryBuilder) {
// top and bottom faces
val bottomOuterPoints: List<Point3D> = shape(topRadius, -height / 2)
val upperOuterPoints: List<Point3D> = shape(bottomRadius, height / 2)
//creating shape in x-y plane with z = 0
val bottomOuterPoints = shape(topRadius, -height / 2)
val upperOuterPoints = shape(bottomRadius, height / 2)
//outer face //outer face
(1 until segments).forEach { for (it in 1 until segments) {
face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1])
} }
if (angle == PI2) { //if the cone is closed
if (phi == PI2) {
face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last())
} }
val zeroBottom = Point3D(0f, 0f, 0f) //top and bottom cups
val zeroTop = Point3D(0f, 0f, height) val zeroBottom = Point3D(0f, 0f, -height / 2)
(1 until segments).forEach { val zeroTop = Point3D(0f, 0f, height / 2)
for (it in 1 until segments) {
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop)
} }
if (angle == PI2) { // closed surface
if (phi == PI2) {
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop)
} else { } else {
@ -71,7 +83,7 @@ public inline fun MutableVisionContainer<Solid>.cylinder(
r: Number, r: Number,
height: Number, height: Number,
name: String? = null, name: String? = null,
block: ConeSegment.() -> Unit = {} block: ConeSegment.() -> Unit = {},
): ConeSegment = ConeSegment( ): ConeSegment = ConeSegment(
r.toFloat(), r.toFloat(),
height.toFloat(), height.toFloat(),
@ -86,11 +98,11 @@ public inline fun MutableVisionContainer<Solid>.cone(
startAngle: Number = 0f, startAngle: Number = 0f,
angle: Number = PI2, angle: Number = PI2,
name: String? = null, name: String? = null,
block: ConeSegment.() -> Unit = {} block: ConeSegment.() -> Unit = {},
): ConeSegment = ConeSegment( ): ConeSegment = ConeSegment(
bottomRadius.toFloat(), bottomRadius.toFloat(),
height.toFloat(), height.toFloat(),
topRadius = upperRadius.toFloat(), topRadius = upperRadius.toFloat(),
startAngle = startAngle.toFloat(), phiStart = startAngle.toFloat(),
angle = angle.toFloat() phi = angle.toFloat()
).apply(block).also { setChild(name, it) } ).apply(block).also { setChild(name, it) }

View File

@ -38,11 +38,9 @@ public class ConeSurface(
require(segments >= 4) { "The number of segments in tube is too small" } require(segments >= 4) { "The number of segments in tube is too small" }
val angleStep = angle / (segments - 1) val angleStep = angle / (segments - 1)
fun shape(r: Float, z: Float): List<Point3D> { fun shape(r: Float, z: Float): List<Point3D> = (0 until segments).map { i ->
return (0 until segments).map { i ->
Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z) Point3D(r * cos(startAngle + angleStep * i), r * sin(startAngle + angleStep * i), z)
} }
}
geometryBuilder.apply { geometryBuilder.apply {
@ -50,7 +48,7 @@ public class ConeSurface(
val bottomOuterPoints = shape(bottomRadius, -height / 2) val bottomOuterPoints = shape(bottomRadius, -height / 2)
val topOuterPoints = shape(topRadius, height / 2) val topOuterPoints = shape(topRadius, height / 2)
//outer face //outer face
(1 until segments).forEach { for (it in 1 until segments) {
face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1]) face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1])
} }

View File

@ -44,6 +44,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
subclass(PolyLine.serializer()) subclass(PolyLine.serializer())
subclass(SolidLabel.serializer()) subclass(SolidLabel.serializer())
subclass(Sphere.serializer()) subclass(Sphere.serializer())
subclass(SphereLayer.serializer())
subclass(AmbientLightSource.serializer()) subclass(AmbientLightSource.serializer())
subclass(PointLightSource.serializer()) subclass(PointLightSource.serializer())
@ -56,7 +57,7 @@ public class Solids(meta: Meta) : VisionPlugin(meta), MutableVisionContainer<Sol
} }
polymorphic(Solid::class) { polymorphic(Solid::class) {
default { SolidBase.serializer(serializer<Solid>()) } defaultDeserializer { SolidBase.serializer(serializer<Solid>()) }
solids() solids()
} }
} }

View File

@ -18,16 +18,16 @@ public object ThreeConeFactory : ThreeMeshFactory<ConeSegment>(ConeSegment::clas
radialSegments = segments, radialSegments = segments,
heightSegments = segments, heightSegments = segments,
openEnded = false, openEnded = false,
thetaStart = obj.startAngle, thetaStart = obj.phiStart,
thetaLength = obj.angle thetaLength = obj.phi
) )
} ?: CylinderGeometry( } ?: CylinderGeometry(
radiusTop = obj.topRadius, radiusTop = obj.topRadius,
radiusBottom = obj.bottomRadius, radiusBottom = obj.bottomRadius,
height = obj.height, height = obj.height,
openEnded = false, openEnded = false,
thetaStart = obj.startAngle, thetaStart = obj.phiStart,
thetaLength = obj.angle thetaLength = obj.phi
) )
return cylinder.rotateX(PI/2) return cylinder.rotateX(PI/2)
} }

View File

@ -111,7 +111,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
is Composite -> compositeFactory.build(this, vision, observe) is Composite -> compositeFactory.build(this, vision, observe)
else -> { else -> {
//find specialized factory for this type if it is present //find a specialized factory for this type if it is present
val factory: ThreeFactory<Solid>? = findObjectFactory(vision::class) val factory: ThreeFactory<Solid>? = findObjectFactory(vision::class)
when { when {
factory != null -> factory.build(this, vision, observe) factory != null -> factory.build(this, vision, observe)