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.gdml.GdmlShowCase
import space.kscience.visionforge.gdml.toVision
import space.kscience.visionforge.html.ResourceLocation
import space.kscience.visionforge.solid.Solids
fun main() {
@ -11,7 +10,7 @@ fun main() {
plugin(Solids)
}
context.makeVisionFile(resourceLocation = ResourceLocation.EMBED) {
context.makeVisionFile{
vision("canvas") {
GdmlShowCase.babyIaxo().toVision()
}

View File

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

View File

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

View File

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

View File

@ -47,40 +47,40 @@ public class ConeSurface(
//creating shape in x-y plane with z = 0
val bottomOuterPoints = shape(bottomRadius, -height / 2)
val upperOuterPoints = shape(topRadius, height / 2)
val topOuterPoints = shape(topRadius, height / 2)
//outer face
(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) {
face4(bottomOuterPoints.last(), bottomOuterPoints[0], upperOuterPoints[0], upperOuterPoints.last())
face4(bottomOuterPoints.last(), bottomOuterPoints[0], topOuterPoints[0], topOuterPoints.last())
}
if (bottomInnerRadius == 0f) {
val zeroBottom = Point3D(0f, 0f, 0f)
val zeroTop = Point3D(0f, 0f, height)
(1 until segments).forEach {
face(bottomOuterPoints[it - 1], zeroBottom, bottomOuterPoints[it])
face(upperOuterPoints[it - 1], upperOuterPoints[it], zeroTop)
face(topOuterPoints[it - 1], topOuterPoints[it], zeroTop)
}
if (angle == PI2) {
face(bottomOuterPoints.last(), zeroBottom, bottomOuterPoints[0])
face(upperOuterPoints.last(), upperOuterPoints[0], zeroTop)
face(topOuterPoints.last(), topOuterPoints[0], zeroTop)
} else {
face4(zeroTop, zeroBottom, bottomOuterPoints[0], upperOuterPoints[0])
face4(zeroTop, zeroBottom, bottomOuterPoints.last(), upperOuterPoints.last())
face4(zeroTop, zeroBottom, bottomOuterPoints[0], topOuterPoints[0])
face4(zeroTop, zeroBottom, bottomOuterPoints.last(), topOuterPoints.last())
}
} else {
val bottomInnerPoints = shape(bottomInnerRadius, -height / 2)
val upperInnerPoints = shape(topInnerRadius, height / 2)
val topInnerPoints = shape(topInnerRadius, height / 2)
//outer face
(1 until segments).forEach {
// inner surface
face4(
bottomInnerPoints[it],
bottomInnerPoints[it - 1],
upperInnerPoints[it - 1],
upperInnerPoints[it]
topInnerPoints[it - 1],
topInnerPoints[it]
)
//bottom cup
face4(
@ -91,28 +91,28 @@ public class ConeSurface(
)
//upper cup
face4(
upperInnerPoints[it],
upperInnerPoints[it - 1],
upperOuterPoints[it - 1],
upperOuterPoints[it]
topInnerPoints[it],
topInnerPoints[it - 1],
topOuterPoints[it - 1],
topOuterPoints[it]
)
}
if (angle == PI2) {
face4(bottomInnerPoints[0], bottomInnerPoints.last(), upperInnerPoints.last(), upperInnerPoints[0])
face4(bottomInnerPoints[0], bottomInnerPoints.last(), topInnerPoints.last(), topInnerPoints[0])
face4(
bottomInnerPoints.last(),
bottomInnerPoints[0],
bottomOuterPoints[0],
bottomOuterPoints.last()
)
face4(upperInnerPoints[0], upperInnerPoints.last(), upperOuterPoints.last(), upperOuterPoints[0])
face4(topInnerPoints[0], topInnerPoints.last(), topOuterPoints.last(), topOuterPoints[0])
} else {
face4(bottomInnerPoints[0], bottomOuterPoints[0], upperOuterPoints[0], upperInnerPoints[0])
face4(bottomInnerPoints[0], bottomOuterPoints[0], topOuterPoints[0], topInnerPoints[0])
face4(
bottomOuterPoints.last(),
bottomInnerPoints.last(),
upperInnerPoints.last(),
upperOuterPoints.last()
topInnerPoints.last(),
topOuterPoints.last()
)
}
}
@ -123,7 +123,7 @@ public class ConeSurface(
@VisionBuilder
public inline fun VisionContainerBuilder<Solid>.tube(
r: Number,
radius: Number,
height: Number,
innerRadius: Number,
startAngle: Number = 0f,
@ -131,10 +131,10 @@ public inline fun VisionContainerBuilder<Solid>.tube(
name: String? = null,
block: ConeSurface.() -> Unit = {},
): ConeSurface = ConeSurface(
bottomRadius = r.toFloat(),
bottomRadius = radius.toFloat(),
bottomInnerRadius = innerRadius.toFloat(),
height = height.toFloat(),
topRadius = r.toFloat(),
topRadius = radius.toFloat(),
topInnerRadius = innerRadius.toFloat(),
startAngle = startAngle.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.geometries.CylinderBufferGeometry
import space.kscience.visionforge.solid.ConeSurface
import space.kscience.visionforge.solid.ConeSegment
import space.kscience.visionforge.solid.detail
import kotlin.math.PI
import kotlin.math.pow
public object ThreeCylinderFactory : MeshThreeFactory<ConeSurface>(ConeSurface::class) {
override fun buildGeometry(obj: ConeSurface): BufferGeometry {
public object ThreeConeFactory : MeshThreeFactory<ConeSegment>(ConeSegment::class) {
override fun buildGeometry(obj: ConeSegment): BufferGeometry {
val cylinder = obj.detail?.let {
val segments = it.toDouble().pow(0.5).toInt()
CylinderBufferGeometry(

View File

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