Fix tube rendering

This commit is contained in:
Alexander Nozik 2021-05-07 18:54:52 +03:00
parent e644b1b20a
commit 03b666017b
7 changed files with 56 additions and 57 deletions

View File

@ -3,7 +3,6 @@ package space.kscience.visionforge.examples
import space.kscience.dataforge.context.Context import space.kscience.dataforge.context.Context
import space.kscience.gdml.GdmlShowCase import space.kscience.gdml.GdmlShowCase
import space.kscience.visionforge.gdml.toVision import space.kscience.visionforge.gdml.toVision
import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.solid.Solids import space.kscience.visionforge.solid.Solids
fun main() { fun main() {
@ -11,7 +10,7 @@ fun main() {
plugin(Solids) plugin(Solids)
} }
context.makeVisionFile(resourceLocation = ResourceLocation.EMBED) { context.makeVisionFile{
vision("canvas") { vision("canvas") {
GdmlShowCase.babyIaxo().toVision() GdmlShowCase.babyIaxo().toVision()
} }

View File

@ -218,7 +218,7 @@ public fun runVisionClient(contextBuilder: ContextBuilder.() -> Unit) {
console.info("Starting VisionForge context") console.info("Starting VisionForge context")
val context = Context("VisionForge"){ val context = Context("VisionForge"){
contextBuilder() contextBuilder()
plugin(VisionClient) //plugin(VisionClient)
} }
val visionClient = context.fetch(VisionClient) val visionClient = context.fetch(VisionClient)
window.asDynamic()["renderAllVisionsById"] = visionClient::renderAllVisionsById window.asDynamic()["renderAllVisionsById"] = visionClient::renderAllVisionsById

View File

@ -180,34 +180,34 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
return when (solid) { return when (solid) {
is GdmlBox -> box(solid.x * lScale, solid.y * lScale, solid.z * lScale, name) is GdmlBox -> box(solid.x * lScale, solid.y * lScale, solid.z * lScale, name)
is GdmlTube -> tube( is GdmlTube -> tube(
solid.rmax * lScale, radius = solid.rmax * lScale,
solid.z * lScale, height = solid.z * lScale,
solid.rmin * lScale, innerRadius = solid.rmin * lScale,
solid.startphi * aScale, startAngle = solid.startphi * aScale,
solid.deltaphi * aScale, angle = solid.deltaphi * aScale,
name name = name
) )
is GdmlCone -> if (solid.rmin1.toDouble() == 0.0 && solid.rmin2.toDouble() == 0.0) { is GdmlCone -> if (solid.rmin1.toDouble() == 0.0 && solid.rmin2.toDouble() == 0.0) {
cone( cone(
bottomRadius = solid.rmax1, bottomRadius = solid.rmax1 * lScale,
height = solid.z, height = solid.z * lScale,
upperRadius = solid.rmax2, upperRadius = solid.rmax2 * lScale,
name = name name = name
) { ) {
startAngle = solid.startphi.toFloat() startAngle = solid.startphi * aScale
angle = solid.deltaphi.toFloat() angle = solid.deltaphi * aScale
} }
} else { } else {
coneSurface( coneSurface(
bottomOuterRadius = solid.rmax1, bottomOuterRadius = solid.rmax1 * lScale,
bottomInnerRadius = solid.rmin1, bottomInnerRadius = solid.rmin1 * lScale,
height = solid.z, height = solid.z * lScale,
topOuterRadius = solid.rmax2, topOuterRadius = solid.rmax2 * lScale,
topInnerRadius = solid.rmin2, topInnerRadius = solid.rmin2 * lScale,
name = name name = name
) { ) {
startAngle = solid.startphi.toFloat() startAngle = solid.startphi * aScale
angle = solid.deltaphi.toFloat() angle = solid.deltaphi * aScale
} }
} }
is GdmlXtru -> extrude(name) { is GdmlXtru -> extrude(name) {
@ -283,11 +283,11 @@ private class GdmlTransformer(val settings: GdmlTransformerSettings) {
} }
} }
is GdmlTrapezoid -> { is GdmlTrapezoid -> {
val dxBottom = solid.x1.toDouble() val dxBottom = solid.x1.toDouble() / 2
val dxTop = solid.x2.toDouble() val dxTop = solid.x2.toDouble() / 2
val dyBottom = solid.y1.toDouble() val dyBottom = solid.y1.toDouble() / 2
val dyTop = solid.y2.toDouble() val dyTop = solid.y2.toDouble() / 2
val dz = solid.z.toDouble() val dz = solid.z.toDouble() / 2
val node1 = Point3D(-dxBottom, -dyBottom, -dz) val node1 = Point3D(-dxBottom, -dyBottom, -dz)
val node2 = Point3D(dxBottom, -dyBottom, -dz) val node2 = Point3D(dxBottom, -dyBottom, -dz)
val node3 = Point3D(dxBottom, dyBottom, -dz) val node3 = Point3D(dxBottom, dyBottom, -dz)

View File

@ -14,9 +14,9 @@ import kotlin.math.sin
@Serializable @Serializable
@SerialName("solid.cone") @SerialName("solid.cone")
public class ConeSegment( public class ConeSegment(
public var radius: Float, public var bottomRadius: Float,
public var height: Float, public var height: Float,
public var upperRadius: Float, public var topRadius: Float,
public var startAngle: Float = 0f, public var startAngle: Float = 0f,
public var angle: Float = PI2 public var angle: Float = PI2
) : SolidBase(), GeometrySolid { ) : SolidBase(), GeometrySolid {
@ -35,8 +35,8 @@ public class ConeSegment(
geometryBuilder.apply { geometryBuilder.apply {
//creating shape in x-y plane with z = 0 //creating shape in x-y plane with z = 0
val bottomOuterPoints = shape(upperRadius, -height / 2) val bottomOuterPoints = shape(topRadius, -height / 2)
val upperOuterPoints = shape(radius, height / 2) val upperOuterPoints = shape(bottomRadius, height / 2)
//outer face //outer face
(1 until segments).forEach { (1 until segments).forEach {
face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1])
@ -87,5 +87,5 @@ public inline fun VisionContainerBuilder<Solid>.cone(
): ConeSegment = ConeSegment( ): ConeSegment = ConeSegment(
bottomRadius.toFloat(), bottomRadius.toFloat(),
height.toFloat(), height.toFloat(),
upperRadius = upperRadius.toFloat() topRadius = upperRadius.toFloat()
).apply(block).also { set(name, it) } ).apply(block).also { set(name, it) }

View File

@ -47,40 +47,40 @@ public class ConeSurface(
//creating shape in x-y plane with z = 0 //creating shape in x-y plane with z = 0
val bottomOuterPoints = shape(bottomRadius, -height / 2) val bottomOuterPoints = shape(bottomRadius, -height / 2)
val upperOuterPoints = shape(topRadius, height / 2) val topOuterPoints = shape(topRadius, height / 2)
//outer face //outer face
(1 until segments).forEach { (1 until segments).forEach {
face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], upperOuterPoints[it], upperOuterPoints[it - 1]) face4(bottomOuterPoints[it - 1], bottomOuterPoints[it], topOuterPoints[it], topOuterPoints[it - 1])
} }
if (angle == PI2) { if (angle == PI2) {
face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last()) face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last())
} }
if (bottomInnerRadius == 0f) { if (bottomInnerRadius == 0f) {
val zeroBottom = Point3D(0f, 0f, 0f) val zeroBottom = Point3D(0f, 0f, 0f)
val zeroTop = Point3D(0f, 0f, height) val zeroTop = Point3D(0f, 0f, height)
(1 until segments).forEach { (1 until segments).forEach {
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it]) face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop) face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop)
} }
if (angle == PI2) { if (angle == PI2) {
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0]) face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop) face(topOuterPoints.last(), topOuterPoints[0], zeroTop)
} else { } else {
face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0]) face4(zeroTop, zeroBottom, bottomOuterPoints[0], topOuterPoints[0])
face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last()) face4(zeroTop, zeroBottom, bottomOuterPoints.last(), topOuterPoints.last())
} }
} else { } else {
val bottomInnerPoints = shape(bottomInnerRadius, -height / 2) val bottomInnerPoints = shape(bottomInnerRadius, -height / 2)
val upperInnerPoints = shape(topInnerRadius, height / 2) val topInnerPoints = shape(topInnerRadius, height / 2)
//outer face //outer face
(1 until segments).forEach { (1 until segments).forEach {
// inner surface // inner surface
face4( face4(
bottomInnerPoints[it], bottomInnerPoints[it],
bottomInnerPoints[it - 1], bottomInnerPoints[it - 1],
upperInnerPoints[it - 1], topInnerPoints[it - 1],
upperInnerPoints[it] topInnerPoints[it]
) )
//bottom cup //bottom cup
face4( face4(
@ -91,28 +91,28 @@ public class ConeSurface(
) )
//upper cup //upper cup
face4( face4(
upperInnerPoints[it], topInnerPoints[it],
upperInnerPoints[it - 1], topInnerPoints[it - 1],
upperOuterPoints[it - 1], topOuterPoints[it - 1],
upperOuterPoints[it] topOuterPoints[it]
) )
} }
if (angle == PI2) { if (angle == PI2) {
face4(bottomInnerPoints[0], bottomInnerPoints.last(), upperInnerPoints.last(), upperInnerPoints[0]) face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0])
face4( face4(
bottomInnerPoints.last(), bottomInnerPoints.last(),
bottomInnerPoints[0], bottomInnerPoints[0],
bottomOuterPoints[0], bottomOuterPoints[0],
bottomOuterPoints.last() bottomOuterPoints.last()
) )
face4(upperInnerPoints[0], upperInnerPoints.last(), upperOuterPoints.last(), upperOuterPoints[0]) face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0])
} else { } else {
face4(bottomInnerPoints[0], bottomOuterPoints[0], upperOuterPoints[0], upperInnerPoints[0]) face4(bottomInnerPoints[0], bottomOuterPoints[0], topOuterPoints[0], topInnerPoints[0])
face4( face4(
bottomOuterPoints.last(), bottomOuterPoints.last(),
bottomInnerPoints.last(), bottomInnerPoints.last(),
upperInnerPoints.last(), topInnerPoints.last(),
upperOuterPoints.last() topOuterPoints.last()
) )
} }
} }
@ -123,7 +123,7 @@ public class ConeSurface(
@VisionBuilder @VisionBuilder
public inline fun VisionContainerBuilder<Solid>.tube( public inline fun VisionContainerBuilder<Solid>.tube(
r: Number, radius: Number,
height: Number, height: Number,
innerRadius: Number, innerRadius: Number,
startAngle: Number = 0f, startAngle: Number = 0f,
@ -131,10 +131,10 @@ public inline fun VisionContainerBuilder<Solid>.tube(
name: String? = null, name: String? = null,
block: ConeSurface.() -> Unit = {}, block: ConeSurface.() -> Unit = {},
): ConeSurface = ConeSurface( ): ConeSurface = ConeSurface(
bottomRadius = r.toFloat(), bottomRadius = radius.toFloat(),
bottomInnerRadius = innerRadius.toFloat(), bottomInnerRadius = innerRadius.toFloat(),
height = height.toFloat(), height = height.toFloat(),
topRadius = r.toFloat(), topRadius = radius.toFloat(),
topInnerRadius = innerRadius.toFloat(), topInnerRadius = innerRadius.toFloat(),
startAngle = startAngle.toFloat(), startAngle = startAngle.toFloat(),
angle = angle.toFloat() angle = angle.toFloat()

View File

@ -2,13 +2,13 @@ package space.kscience.visionforge.solid.three
import info.laht.threekt.core.BufferGeometry import info.laht.threekt.core.BufferGeometry
import info.laht.threekt.geometries.CylinderBufferGeometry import info.laht.threekt.geometries.CylinderBufferGeometry
import space.kscience.visionforge.solid.ConeSurface import space.kscience.visionforge.solid.ConeSegment
import space.kscience.visionforge.solid.detail import space.kscience.visionforge.solid.detail
import kotlin.math.PI import kotlin.math.PI
import kotlin.math.pow import kotlin.math.pow
public object ThreeCylinderFactory : MeshThreeFactory<ConeSurface>(ConeSurface::class) { public object ThreeConeFactory : MeshThreeFactory<ConeSegment>(ConeSegment::class) {
override fun buildGeometry(obj: ConeSurface): BufferGeometry { override 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()
CylinderBufferGeometry( CylinderBufferGeometry(

View File

@ -35,7 +35,7 @@ public class ThreePlugin : AbstractPlugin(), ElementVisionRenderer {
objectFactories[Box::class] = ThreeBoxFactory objectFactories[Box::class] = ThreeBoxFactory
objectFactories[Convex::class] = ThreeConvexFactory objectFactories[Convex::class] = ThreeConvexFactory
objectFactories[Sphere::class] = ThreeSphereFactory objectFactories[Sphere::class] = ThreeSphereFactory
objectFactories[ConeSurface::class] = ThreeCylinderFactory objectFactories[ConeSegment::class] = ThreeConeFactory
objectFactories[PolyLine::class] = ThreeLineFactory objectFactories[PolyLine::class] = ThreeLineFactory
objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory objectFactories[SolidLabel::class] = ThreeCanvasLabelFactory
} }