Convert orx-shader-phrases and orx-noise to MPP

This commit is contained in:
Edwin Jakobs
2021-06-24 13:31:27 +02:00
parent 6a45db4491
commit 1cf5c825d6
69 changed files with 813 additions and 741 deletions

View File

@@ -0,0 +1,187 @@
package org.openrndr.boofcv.binding
import boofcv.struct.image.GrayF32
import boofcv.struct.image.GrayF64
import boofcv.struct.image.GrayU8
import boofcv.struct.image.Planar
import org.openrndr.color.ColorRGBa
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.ColorFormat
import org.openrndr.draw.ColorType
import org.openrndr.draw.colorBuffer
import kotlin.experimental.and
fun ColorBuffer.toGrayF32() : GrayF32 {
val p = GrayF32(width, height)
shadow.download()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val c = shadow.read(x, y)
p.data[offset] = (c.r * 255).toFloat()
offset++
}
}
return p
}
fun ColorBuffer.toGrayF64() : GrayF64 {
val p = GrayF64(width, height)
shadow.download()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val c = shadow.read(x, y)
p.data[offset] = (c.r * 255)
offset++
}
}
return p
}
fun ColorBuffer.toPlanarF32() : Planar<GrayF32> {
val p = Planar<GrayF32>(GrayF32::class.java, width, height, format.componentCount)
shadow.download()
val bands = p.bands
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val c = shadow.read(x, y)
bands[0].data[offset] = (c.r * 255).toFloat()
bands[1].data[offset] = (c.g * 255).toFloat()
bands[2].data[offset] = (c.b * 255).toFloat()
offset++
}
}
return p
}
fun ColorBuffer.toPlanarU8() : Planar<GrayU8> {
val p = Planar<GrayU8>(GrayU8::class.java, width, height, format.componentCount)
shadow.download()
val bands = p.bands
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val c = shadow.read(x, y)
bands[0].data[offset] = (c.r * 255).toInt().toByte()
bands[1].data[offset] = (c.g * 255).toInt().toByte()
bands[2].data[offset] = (c.b * 255).toInt().toByte()
offset++
}
}
return p
}
fun ColorBuffer.toGrayU8() : GrayU8 {
val p = GrayU8(width, height)
shadow.download()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val c = shadow.read(x, y)
p.data[offset] = (c.r * 255).toInt().coerceIn(0, 255).toByte()
offset++
}
}
return p
}
fun GrayU8.toColorBuffer() : ColorBuffer {
val cb = colorBuffer(width, height, 1.0, ColorFormat.RGB, ColorType.UINT8)
val shadow = cb.shadow
shadow.buffer.rewind()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val r = (data[offset].toInt() and 0xff).toDouble() / 255.0
offset++
shadow.write(x, y, ColorRGBa(r, r, r, 1.0))
}
}
shadow.upload()
return cb
}
fun GrayF32.toColorBuffer() : ColorBuffer {
val cb = colorBuffer(width, height, 1.0, ColorFormat.RGB, ColorType.FLOAT32)
val shadow = cb.shadow
shadow.buffer.rewind()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val r = data[offset].toDouble() / 255.0
offset++
shadow.write(x, y, ColorRGBa(r, r, r))
}
}
shadow.upload()
return cb
}
fun Planar<GrayU8>.toColorBuffer() : ColorBuffer {
val bandCount = bands.size
val format = when (bandCount) {
1 -> ColorFormat.R
2 -> ColorFormat.RG
3 -> ColorFormat.RGB
4 -> ColorFormat.RGBa
else -> throw IllegalArgumentException("only 1 to 4 bands supported")
}
val bands = bands
val cb = colorBuffer(width, height, 1.0, format, ColorType.UINT8)
val shadow = cb.shadow
shadow.buffer.rewind()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val r = (bands[0].data[offset].toInt() and 0xff).toDouble() / 255.0
val g = if (bandCount >= 2) (bands[1].data[offset].toInt() and 0xff).toDouble() / 255.0 else 0.0
val b = if (bandCount >= 3) (bands[2].data[offset].toInt() and 0xff).toDouble() / 255.0 else 0.0
val a = if (bandCount >= 4) (bands[2].data[offset].toInt() and 0xff).toDouble() / 255.0 else 1.0
offset++
shadow.write(x, y, ColorRGBa(r, g, b, a))
}
}
shadow.upload()
return cb
}
@JvmName("grayF32ToColorBuffer")
fun Planar<GrayF32>.toColorBuffer() : ColorBuffer {
val bandCount = bands.size
val format = when (bandCount) {
1 -> ColorFormat.R
2 -> ColorFormat.RG
3 -> ColorFormat.RGB
4 -> ColorFormat.RGBa
else -> throw IllegalArgumentException("only 1 to 4 bands supported")
}
val bands = bands
val cb = colorBuffer(width, height, 1.0, format, ColorType.UINT8)
val shadow = cb.shadow
shadow.buffer.rewind()
var offset = 0
for (y in 0 until height) {
for (x in 0 until width) {
val r = bands[0].data[offset] / 255.0
val g = if (bandCount >= 2) bands[1].data[offset] / 255.0 else 0.0
val b = if (bandCount >= 3) bands[2].data[offset] / 255.0 else 0.0
val a = if (bandCount >= 4) bands[3].data[offset] / 255.0 else 1.0
offset++
shadow.write(x, y, ColorRGBa(r, g, b, a))
}
}
shadow.upload()
return cb
}

View File

@@ -0,0 +1,51 @@
package org.openrndr.boofcv.binding
import boofcv.alg.filter.binary.Contour
import org.openrndr.shape.Shape
import org.openrndr.shape.ShapeContour
fun Contour.toShape(closed: Boolean = false, getInternal: Boolean, getExternal: Boolean): Shape {
val contours = mutableListOf<ShapeContour>()
if (getExternal) {
val externalPoints = external.toVector2s()
contours.addAll(listOf(ShapeContour.fromPoints(externalPoints, closed)))
}
if (getInternal) {
val internalCurves = internal.filter { it.size >= 3 }.map { it.toVector2s() }
contours.addAll(internalCurves.map { internalCurve ->
ShapeContour.fromPoints(internalCurve, closed)
})
}
return Shape(contours)
}
fun List<Contour>.toShapes(closed: Boolean = false,
internal: Boolean = true,
external: Boolean = true): List<Shape> {
return this.filter { it.external.size >= 3 }.map {
it.toShape(closed, internal, external)
}
}
fun List<Contour>.toShapeContours(closed: Boolean = false,
internal: Boolean = true,
external: Boolean = true): List<ShapeContour> {
val contours = mutableListOf<ShapeContour>()
this.forEach { contour ->
if(contour.external.size >= 3) {
if (external) {
val externalPoints = contour.external.toVector2s()
contours.add(ShapeContour.fromPoints(externalPoints, closed))
}
if (internal) {
val internalCurves = contour.internal.filter { it.size >= 3 }
.map { it.toVector2s() }
internalCurves.forEach { internalContour ->
contours.add(ShapeContour.fromPoints(internalContour, closed))
}
}
}
}
return contours
}

View File

@@ -0,0 +1,70 @@
package org.openrndr.boofcv.binding
import boofcv.abst.distort.FDistort
import boofcv.struct.image.ImageBase
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.ColorType
import kotlin.math.roundToInt
fun <T : ImageBase<out ImageBase<*>>?> ImageBase<T>.resizeBy(scaleX: Double, scaleY: Double = scaleX): T {
val scaled = this.createNew((this.width * scaleX).toInt(), (this.height * scaleY).toInt())
FDistort(this, scaled).scaleExt().apply()
return scaled
}
fun <T : ImageBase<out ImageBase<*>>?> ImageBase<T>.resizeTo(newWidth: Int? = null, newHeight: Int? = null): T {
val ar = this.width / this.height.toDouble()
val scaled = (if (newWidth != null && newHeight != null) {
val w = newWidth
val h = newHeight
this.createNew(w, h)
} else if (newWidth != null && newHeight == null) {
val w = newWidth
val h = newWidth / ar
this.createNew(w, h.roundToInt())
} else if (newWidth == null && newHeight != null) {
val w = newHeight * ar
val h = newHeight
this.createNew(w.roundToInt(), h)
} else {
this.createNew(this.width, this.height)
})
FDistort(this, scaled).scaleExt().apply()
return scaled
}
fun ColorBuffer.resizeBy(scaleX: Double, scaleY: Double = scaleX, convertToGray: Boolean = false): ColorBuffer {
return if (convertToGray) {
when (this.type) {
ColorType.FLOAT32, ColorType.FLOAT16 -> this.toGrayF32().resizeBy(scaleX, scaleY).toColorBuffer()
else -> this.toGrayU8().resizeBy(scaleX, scaleY).toColorBuffer()
}
} else {
when (this.type) {
ColorType.FLOAT32, ColorType.FLOAT16 -> this.toPlanarF32().resizeBy(scaleX, scaleY).toColorBuffer()
else -> this.toPlanarU8().resizeBy(scaleX, scaleY).toColorBuffer()
}
}
}
fun ColorBuffer.resizeTo(newWidth: Int? = null, newHeight: Int? = null, convertToGray: Boolean = false): ColorBuffer {
return if (convertToGray) {
when (this.type) {
ColorType.FLOAT32, ColorType.FLOAT16 -> this.toGrayF32().resizeTo(newWidth, newHeight).toColorBuffer()
else -> this.toGrayU8().resizeTo(newWidth, newHeight).toColorBuffer()
}
} else {
when (this.type) {
ColorType.FLOAT32, ColorType.FLOAT16 -> this.toPlanarF32().resizeTo(newWidth, newHeight).toColorBuffer()
else -> this.toPlanarU8().resizeTo(newWidth, newHeight).toColorBuffer()
}
}
}

View File

@@ -0,0 +1,83 @@
package org.openrndr.boofcv.binding
import georegression.struct.line.LineSegment2D_F32
import georegression.struct.line.LineSegment2D_F64
import georegression.struct.trig.Circle2D_F32
import georegression.struct.trig.Circle2D_F64
import org.openrndr.draw.Drawer
import org.openrndr.math.Vector2
import org.openrndr.shape.Circle
fun Drawer.lineSegment(segment: LineSegment2D_F32) {
lineSegment(
segment.a.x.toDouble(),
segment.a.y.toDouble(),
segment.b.x.toDouble(),
segment.b.y.toDouble()
)
}
@JvmName("lineSegments2D_F32")
fun Drawer.lineSegments(segments: List<LineSegment2D_F32>) {
lineSegments(
segments.flatMap { segment ->
listOf(
Vector2(segment.a.x.toDouble(), segment.a.y.toDouble()),
Vector2(segment.b.x.toDouble(), segment.b.y.toDouble())
)
}
)
}
fun Drawer.lineSegment(segment: LineSegment2D_F64) {
lineSegment(
segment.a.x,
segment.a.y,
segment.b.x,
segment.b.y
)
}
@JvmName("lineSegments2D_F64")
fun Drawer.lineSegments(segments: List<LineSegment2D_F64>) {
lineSegments(
segments.flatMap { segment ->
listOf(
Vector2(segment.a.x, segment.a.y),
Vector2(segment.b.x, segment.b.y)
)
}
)
}
fun Drawer.circle(circle: Circle2D_F32) {
circle(
circle.center.x.toDouble(), circle.center.y.toDouble(),
circle.radius.toDouble()
)
}
fun Drawer.circle(circle: Circle2D_F64) {
circle(
circle.center.x, circle.center.y,
circle.radius
)
}
@JvmName("circles2D_F32")
fun Drawer.circles(circles: List<Circle2D_F32>) {
circles(
circles.map {
Circle(it.center.x.toDouble(), it.center.y.toDouble(), it.radius.toDouble())
}
)
}
@JvmName("circles2D_F64")
fun Drawer.circles(circles: List<Circle2D_F64>) {
circles(
circles.map {
Circle(it.center.x.toDouble(), it.center.y.toDouble(), it.radius.toDouble())
}
)
}

View File

@@ -0,0 +1,33 @@
package org.openrndr.boofcv.binding
import boofcv.struct.flow.ImageFlow
import org.openrndr.draw.ColorBuffer
import org.openrndr.draw.ColorFormat
import org.openrndr.draw.ColorType
import org.openrndr.draw.colorBuffer
import java.nio.Buffer
import java.nio.ByteBuffer
import java.nio.ByteOrder
fun ImageFlow.toColorBuffer(): ColorBuffer {
val cb = colorBuffer(
width, height, format = ColorFormat.RG,
type = ColorType.FLOAT32
)
val bb = ByteBuffer.allocateDirect(width * height * 8)
bb.order(ByteOrder.nativeOrder())
for (y in 0 until height) {
for (x in 0 until width) {
val f = get(x, y)
bb.putFloat(f.x)
bb.putFloat(f.y)
}
}
(bb as Buffer).rewind()
cb.write(bb)
cb.flipV = true
return cb
}

View File

@@ -0,0 +1,19 @@
package org.openrndr.boofcv.binding
import georegression.struct.affine.Affine2D_F32
import georegression.struct.affine.Affine2D_F64
import org.openrndr.math.Matrix44
fun Affine2D_F32.toMatrix44() = Matrix44(
c0r0 = a11.toDouble(), c1r0 = a12.toDouble(), c3r0 = tx.toDouble(),
c0r1 = a21.toDouble(), c1r1 = a22.toDouble(), c3r1 = ty.toDouble(),
c2r2 = 1.0,
c3r3 = 1.0
)
fun Affine2D_F64.toMatrix44() = Matrix44(
c0r0 = a11, c1r0 = a12, c3r0 = tx,
c0r1 = a21, c1r1 = a22, c3r1 = ty,
c2r2 = 1.0,
c3r3 = 1.0
)

View File

@@ -0,0 +1,11 @@
package org.openrndr.boofcv.binding
import georegression.struct.point.Point2D_F32
import georegression.struct.point.Point2D_F64
import georegression.struct.point.Point2D_I32
import org.openrndr.math.Vector2
fun Point2D_I32.toVector2() = Vector2(x.toDouble(), y.toDouble())
fun Point2D_F32.toVector2() = Vector2(x.toDouble(), y.toDouble())
fun Point2D_F64.toVector2() = Vector2(x.toDouble(), y.toDouble())
fun List<Point2D_I32>.toVector2s() = this.map { it.toVector2() }