Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixed the sample method. #759

Merged
merged 6 commits into from
Aug 7, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
49 changes: 30 additions & 19 deletions src/main/kotlin/graphics/scenery/volumes/Colormap.kt
Original file line number Diff line number Diff line change
Expand Up @@ -26,31 +26,42 @@ class Colormap(val buffer: ByteBuffer, val width: Int, val height: Int) {
@Suppress("unused")
private constructor() : this(ByteBuffer.allocate(0), 0, 0)

private fun ByteArray.toRGBAColor() = Vector4f(
this[0].toUByte().toFloat() / 255f,
this[1].toUByte().toFloat() / 255f,
this[2].toUByte().toFloat() / 255f,
this[3].toUByte().toFloat() / 255f
)

/**
* Returns the value of the colormap, sampled at [position].
* Returns the value of the color map sampled at the normalized position.
*
* position: A floating point value between 0 and 1.
*/
@OptIn(ExperimentalUnsignedTypes::class)
fun sample(position: Float): Vector4f {
val bufferPosition: Float = position.coerceIn(0.0f, 1.0f) * width
val previous = floor(bufferPosition).roundToInt()
val next = ceil(bufferPosition).roundToInt()

val globalOffset = width * 4 * height / 2
val previousColor = globalOffset + previous * 4
val nextColor = globalOffset + next * 4
val bufferPosition: Float = position.coerceIn(0.0f, 1.0f) * (width - 1)
val previous = bufferPosition.toInt()

val b = buffer.duplicate()
val color = ByteArray(8)
@Suppress("USELESS_CAST")
(b.position(previousColor) as? ByteBuffer)?.get(color, 0, 4)
@Suppress("USELESS_CAST")
(b.position(nextColor) as? ByteBuffer)?.get(color, 4, 4)
val ub = color.toUByteArray()
val band = height/2

val c1 = Vector4f(ub[0].toFloat() / 255.0f, ub[1].toFloat() / 255.0f, ub[2].toFloat() / 255.0f, ub[3].toFloat() / 255.0f)
val c2 = Vector4f(ub[4].toFloat() / 255.0f, ub[5].toFloat() / 255.0f, ub[6].toFloat() / 255.0f, ub[7].toFloat() / 255.0f)
// The number of bytes per pixel are fixed at 4.
val globalOffset = width * band * 4

return c1.lerp(c2, bufferPosition - previous.toFloat())
val b = buffer.duplicate()
b.position(globalOffset + previous * 4)
val color = ByteArray(4)
b.get(color)
// Add to "Image" utility class?
skalarproduktraum marked this conversation as resolved.
Show resolved Hide resolved
val c1 = color.toRGBAColor()

if(bufferPosition > previous) {
//interpolate fraction part.
b.get(color)
val c2 = color.toRGBAColor()
return c1.lerp(c2, bufferPosition - previous.toFloat())
} else {
return c1
}
}

companion object {
Expand Down
27 changes: 13 additions & 14 deletions src/main/kotlin/graphics/scenery/volumes/ColormapPanel.kt
Original file line number Diff line number Diff line change
Expand Up @@ -208,7 +208,8 @@ class ColormapPanel(val target:Volume?): JPanel() {
private var hoveredOver: ColorPoint? = null
private var dragging: ColorPoint? = null
private var dragged = false

private var markerSpace = 10

init {
this.layout = MigLayout()
this.preferredSize = Dimension(1000, 40)
Expand Down Expand Up @@ -298,21 +299,18 @@ class ColormapPanel(val target:Volume?): JPanel() {
repaint()

if(width > 0 && height > 0) {
target?.colormap = Colormap.fromBuffer(toBuffer(), width, height)
val bi = toImage()
target?.colormap = Colormap.fromBuffer(Image.bufferedImageToRGBABuffer(bi), bi.width, bi.height)
}
}

internal fun toImage(): BufferedImage {
val rec: Rectangle = this.bounds
val bufferedImage = BufferedImage(rec.width, rec.height, BufferedImage.TYPE_INT_ARGB)
paintBackgroundGradient(colorPoints.sortedBy { it.position }, bufferedImage.graphics as Graphics2D)
val bufferedImage = BufferedImage(rec.width, rec.height - markerSpace, BufferedImage.TYPE_INT_ARGB)
paintBackgroundGradient(colorPoints.sortedBy { it.position }, bufferedImage.createGraphics())
return bufferedImage
}

private fun toBuffer(): ByteBuffer {
return Image.bufferedImageToRGBABuffer(toImage())
}

private fun pointAtMouse(e: MouseEvent) =
colorPoints.firstOrNull { (e.x - (width * it.position)).absoluteValue < height / 2 }

Expand All @@ -325,7 +323,8 @@ class ColormapPanel(val target:Volume?): JPanel() {
val pointList = colorPoints.sortedBy { it.position }

// background Gradient
paintBackgroundGradient(pointList, g2d)
val img = toImage()
g2d.drawImage(img, 0, 0, this)

// color point markers
val relativeSize = 0.25f //relative to height
Expand All @@ -350,10 +349,10 @@ class ColormapPanel(val target:Volume?): JPanel() {
// This draws a triangle below the gradient bar to indicate control points
g2d.paint = outlineColor
g2d.drawPolygon(intArrayOf(p1x.toInt(), (p1x - innerSize).toInt(), (p1x + innerSize).toInt()),
intArrayOf(h-10, h-1, h-1), 3)
intArrayOf(h - markerSpace, h - 1, h - 1), 3)
g2d.paint = it.color
g2d.fillPolygon(intArrayOf(p1x.toInt(), (p1x - innerSize-1).toInt(), (p1x + innerSize+1).toInt()),
intArrayOf(h-10-1, h, h), 3)
g2d.fillPolygon(intArrayOf(p1x.toInt(), (p1x - innerSize - 1).toInt(), (p1x + innerSize + 1).toInt()),
intArrayOf(h - markerSpace - 1, h, h), 3)
}
}

Expand All @@ -362,7 +361,7 @@ class ColormapPanel(val target:Volume?): JPanel() {
g2d: Graphics2D
) {
val w = width
val h = height
val h = height - markerSpace
for (i in 0 until pointList.size - 1) {
val p1 = pointList[i]
val p2 = pointList[i + 1]
Expand All @@ -371,7 +370,7 @@ class ColormapPanel(val target:Volume?): JPanel() {
val gp = GradientPaint(p1x, 0f, p1.color, p2x, 0f, p2.color)

g2d.paint = gp
g2d.fillRect(p1x.toInt(), 0, p2x.toInt(), h-10)
g2d.fillRect(p1x.toInt(), 0, p2x.toInt(), h)
}
}

Expand Down
Loading