Skip to content

Commit

Permalink
Minor adjustments:
Browse files Browse the repository at this point in the history
- Uses default Json instance now and moves custom serializer to Texture class.
- All getters for cached content are synchronized.
- Renamed classes to be consistent.
  • Loading branch information
Ralph Gasser committed Aug 28, 2024
1 parent 52e7df5 commit 9d75452
Show file tree
Hide file tree
Showing 17 changed files with 61 additions and 119 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ import org.vitrivr.engine.core.model.mesh.texturemodel.Model3d
* @author Rahel Arnold
* @version 1.0.0
*/
interface Model3DContent : ContentElement<Model3d> {
/** The [ContentType] of a [Model3DContent] is always [ContentType.MESH]. */
interface Model3dContent : ContentElement<Model3d> {
/** The [ContentType] of a [Model3dContent] is always [ContentType.MESH]. */

override val type: ContentType
get() = ContentType.MESH
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,9 +114,9 @@ class CachedContentFactory : ContentFactoriesFactory {
return content
}

override fun newMeshContent(model3d: Model3d): Model3DContent {
override fun newMeshContent(model3d: Model3d): Model3dContent {
check(!this.closed) { "CachedContentFactory has been closed." }
val content = CachedMeshContent(this.nextPath(), model3d)
val content = CachedModel3dContent(this.nextPath(), model3d)
this.refSet.add(CachedItem(content, this.referenceQueue))
return content
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ package org.vitrivr.engine.core.model.content.factory

import org.vitrivr.engine.core.model.content.element.AudioContent
import org.vitrivr.engine.core.model.content.element.ImageContent
import org.vitrivr.engine.core.model.content.element.Model3DContent
import org.vitrivr.engine.core.model.content.element.Model3dContent
import org.vitrivr.engine.core.model.content.element.TextContent
import org.vitrivr.engine.core.model.mesh.texturemodel.Model3d
import java.awt.image.BufferedImage
Expand All @@ -15,5 +15,5 @@ interface ContentFactory {

fun newTextContent(text: String): TextContent

fun newMeshContent(model3d: Model3d): Model3DContent
fun newMeshContent(model3d: Model3d): Model3dContent
}
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,11 @@ package org.vitrivr.engine.core.model.content.factory

import org.vitrivr.engine.core.context.Context
import org.vitrivr.engine.core.model.content.element.ContentElement
import org.vitrivr.engine.core.model.content.element.Model3DContent
import org.vitrivr.engine.core.model.content.element.Model3dContent
import org.vitrivr.engine.core.model.content.element.TextContent
import org.vitrivr.engine.core.model.content.impl.memory.InMemoryAudioContent
import org.vitrivr.engine.core.model.content.impl.memory.InMemoryImageContent
import org.vitrivr.engine.core.model.content.impl.memory.InMemoryMeshContent
import org.vitrivr.engine.core.model.content.impl.memory.InMemoryModel3dContent
import org.vitrivr.engine.core.model.content.impl.memory.InMemoryTextContent
import org.vitrivr.engine.core.model.mesh.texturemodel.Model3d
import org.vitrivr.engine.core.model.metamodel.Schema
Expand All @@ -21,10 +21,10 @@ import java.nio.ShortBuffer
*/
class InMemoryContentFactory : ContentFactoriesFactory {
override fun newContentFactory(schema: Schema, context: Context): ContentFactory = Instance()
private class Instance() : ContentFactory {
private class Instance : ContentFactory {
override fun newImageContent(bufferedImage: BufferedImage) = InMemoryImageContent(bufferedImage)
override fun newAudioContent(channels: Short, sampleRate: Int, audio: ShortBuffer) = InMemoryAudioContent(channels, sampleRate, audio)
override fun newTextContent(text: String): TextContent = InMemoryTextContent(text)
override fun newMeshContent(model3d: Model3d): Model3DContent = InMemoryMeshContent(model3d)
override fun newMeshContent(model3d: Model3d): Model3dContent = InMemoryModel3dContent(model3d)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import java.nio.ShortBuffer
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import java.util.*

/**
* A [AudioContent] implementation that is backed by a cache file.
Expand All @@ -29,6 +28,7 @@ class CachedAudioContent(override val path: Path, override val channels: Short,

/** The audio samples contained in this [CachedAudioContent]. */
override val content: ShortBuffer
@Synchronized
get() {
var buffer = this.reference.get()
if (buffer == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import java.lang.ref.SoftReference
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import java.util.*
import javax.imageio.ImageIO

/**
Expand All @@ -29,6 +28,7 @@ class CachedImageContent(override val path: Path, image: BufferedImage, override

/** The [BufferedImage] contained in this [CachedImageContent]. */
override val content: BufferedImage
@Synchronized
get() {
var image = this.reference.get()
if (image == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,35 +2,32 @@ package org.vitrivr.engine.core.model.content.impl.cache

import kotlinx.serialization.encodeToString
import kotlinx.serialization.json.Json
import kotlinx.serialization.modules.SerializersModule
import kotlinx.serialization.modules.contextual
import org.vitrivr.engine.core.model.content.element.ContentId
import org.vitrivr.engine.core.model.content.element.Model3DContent
import org.vitrivr.engine.core.model.content.element.Model3dContent
import org.vitrivr.engine.core.model.mesh.texturemodel.Model3d
import org.vitrivr.engine.core.model.mesh.texturemodel.util.BufferedImageSerializer
import java.lang.ref.SoftReference
import java.nio.charset.StandardCharsets
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption

/**
* A [Model3DContent] implementation that is backed by a cache file.
* A [Model3dContent] implementation that is backed by a cache file.
*
* This class caches a 3D model to disk in JSON format and uses a [SoftReference] to hold it in memory,
* reloading from JSON if necessary.
*
* @author Rahel Arnold
* @version 1.0.0
*/
class CachedMeshContent(override val path: Path, model: Model3d, override val id: ContentId = ContentId.randomUUID()) :
Model3DContent, CachedContent {
class CachedModel3dContent(override val path: Path, model: Model3d, override val id: ContentId = ContentId.randomUUID()) : Model3dContent, CachedContent {

/** The [SoftReference] of the [Model3d] used for caching. */
private var reference: SoftReference<Model3d> = SoftReference(model)

/** The [Model3d] contained in this [CachedMeshContent]. */
/** The [Model3d] contained in this [CachedModel3dContent]. */
override val content: Model3d
@Synchronized
get() {
var cachedModel = reference.get()
if (cachedModel == null) {
Expand All @@ -40,24 +37,10 @@ class CachedMeshContent(override val path: Path, model: Model3d, override val id
return cachedModel
}

/** JSON format configuration for serialization. */
private val jsonFormat = Json { prettyPrint = true }

init {
// Serialize the Model3d to JSON and write it to the cache file during initialization.
val jsonFormat = Json {
prettyPrint = true
serializersModule = SerializersModule {
contextual(BufferedImageSerializer) // Register the custom BufferedImage serializer
}
}
Files.newBufferedWriter(
this.path,
StandardCharsets.UTF_8,
StandardOpenOption.CREATE_NEW,
StandardOpenOption.WRITE
).use { writer ->
writer.write(jsonFormat.encodeToString(model))
/* Serialize the Model3d to JSON and write it to the cache file during initialization. */
Files.newBufferedWriter(this.path, StandardCharsets.UTF_8, StandardOpenOption.CREATE_NEW, StandardOpenOption.WRITE).use { writer ->
writer.write(Json.encodeToString(model))
}
}

Expand All @@ -68,7 +51,7 @@ class CachedMeshContent(override val path: Path, model: Model3d, override val id
*/
private fun reload(): Model3d {
return Files.newBufferedReader(this.path, StandardCharsets.UTF_8).use { reader ->
jsonFormat.decodeFromString(reader.readText())
Json.decodeFromString(reader.readText())
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import java.lang.ref.SoftReference
import java.nio.file.Files
import java.nio.file.Path
import java.nio.file.StandardOpenOption
import java.util.*

/**
* A [TextContent] implementation that is backed by a cache file.
Expand All @@ -24,6 +23,7 @@ class CachedTextContent(override val path: Path, text: String, override val id:

/** The [String] contained in this [CachedTextContent]. */
override val content: String
@Synchronized
get() {
var image = this.reference.get()
if (image == null) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,15 @@ package org.vitrivr.engine.core.model.content.impl.memory

import org.vitrivr.engine.core.model.content.element.ContentId
import org.vitrivr.engine.core.model.content.element.ImageContent
import org.vitrivr.engine.core.model.content.element.Model3DContent
import org.vitrivr.engine.core.model.content.element.Model3dContent
import org.vitrivr.engine.core.model.mesh.texturemodel.Model3d

/**
* A naive in-memory implementation of the [ImageContent] interface.
*
* Warning: Usage of [InMemoryMeshContent] may lead to out-of-memory situations in large extraction pipelines.
* Warning: Usage of [InMemoryModel3dContent] may lead to out-of-memory situations in large extraction pipelines.
*
* @author Luca Rossetto.
* @version 1.0.0
*/
data class InMemoryMeshContent(override val content: Model3d, override val id: ContentId = ContentId.randomUUID()) : Model3DContent
data class InMemoryModel3dContent(override val content: Model3d, override val id: ContentId = ContentId.randomUUID()) : Model3dContent
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
package org.vitrivr.engine.core.model.mesh.texturemodel

import kotlinx.serialization.Contextual
import kotlinx.serialization.Serializable
import org.vitrivr.engine.core.model.serializer.BufferedImageSerializer
import java.awt.image.BufferedImage
import java.io.*
import java.io.Serializable as JavaSerializable
import javax.imageio.ImageIO
import java.io.Serializable as JavaSerializable

/**
* This class represents a texture.
Expand All @@ -14,7 +14,8 @@ import javax.imageio.ImageIO
@Serializable
data class Texture(
var texturePath: String? = null,
@Contextual

@Serializable(with = BufferedImageSerializer::class)
var textureImage: BufferedImage? = null
) : JavaSerializable {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,44 +1,17 @@
package org.vitrivr.engine.core.model.mesh.texturemodel.util.types

import kotlinx.serialization.Serializable
import kotlin.math.cos
import kotlin.math.sin
import kotlin.math.sqrt
import kotlinx.serialization.Serializable

/**
* Represents a quaternion, which is a complex number used to represent rotations in 3D space.
*/
@Serializable
class Quaternionf {
var x: Float = 0f
var y: Float = 0f
var z: Float = 0f
var w: Float = 0f

/**
* Default constructor - initializes the quaternion as an identity quaternion (no rotation).
*/
constructor() {
identity()
}

/**
* Constructor with specified components.
*
* @param x The x-component of the quaternion.
* @param y The y-component of the quaternion.
* @param z The z-component of the quaternion.
* @param w The w-component of the quaternion.
*/
constructor(x: Float, y: Float, z: Float, w: Float) {
this.x = x
this.y = y
this.z = z
this.w = w
}

data class Quaternionf(var x: Float = 0f, var y: Float = 0f, var z: Float = 0f, var w: Float = 0f,) {
/**
* Sets the quaternion to the identity quaternion.
* The identity quaternion represents no rotation.
* Sets the quaternion to the identity quaternion. The identity quaternion represents no rotation.
*
* @return This quaternion after being set to the identity quaternion.
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
package org.vitrivr.engine.core.model.mesh.texturemodel.util.types

import kotlinx.serialization.Serializable
import kotlin.math.sqrt
import java.io.Serializable as JavaSerializable
import kotlinx.serialization.Serializable

/**
* Represents a 3D vector with floating-point coordinates.
* This class provides basic vector operations such as addition, subtraction, scaling, and normalization.
*/
@Serializable
class Vec3f
data class Vec3f
@JvmOverloads constructor(var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f) : JavaSerializable {

/**
Expand Down Expand Up @@ -177,30 +178,6 @@ class Vec3f
return "Vec3f($x, $y, $z)"
}

/**
* Compares this vector to another object for equality.
*
* @param obj The object to compare to.
* @return True if the object is a Vec3f with the same x, y, and z components, false otherwise.
*/
override fun equals(obj: Any?): Boolean {
if (this === obj) return true
if (obj == null || javaClass != obj.javaClass) return false
val vector = obj as Vec3f
return java.lang.Float.compare(vector.x, x) == 0 && java.lang.Float.compare(
vector.y, y
) == 0 && java.lang.Float.compare(vector.z, z) == 0
}

/**
* Computes a hash code for this vector.
*
* @return A hash code value for the vector.
*/
override fun hashCode(): Int {
return java.lang.Float.hashCode(x) xor java.lang.Float.hashCode(y) xor java.lang.Float.hashCode(z)
}

/**
* Computes the squared distance between this vector and another vector.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ import java.io.Serializable as JavaSerializable
* @property w The w component of the vector.
*/
@Serializable
class Vec4f(
data class Vec4f(
var x: Float = 0.0f, var y: Float = 0.0f, var z: Float = 0.0f, var w: Float = 0.0f
) : JavaSerializable {

Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package org.vitrivr.engine.core.model.mesh.texturemodel.util
package org.vitrivr.engine.core.model.serializer

import kotlinx.serialization.KSerializer
import kotlinx.serialization.descriptors.PrimitiveKind
Expand All @@ -9,9 +9,17 @@ import kotlinx.serialization.encoding.Encoder
import java.awt.image.BufferedImage
import java.io.ByteArrayInputStream
import java.io.ByteArrayOutputStream
import javax.imageio.ImageIO
import java.util.*
import javax.imageio.ImageIO

/**
* A custom [KSerializer] for [BufferedImage] objects.
*
* This serializer encodes a [BufferedImage] as a Base64 encoded PNG image.
*
* @author Rahel Arnold
* @version 1.0.0
*/
object BufferedImageSerializer : KSerializer<BufferedImage> {

override val descriptor: SerialDescriptor = PrimitiveSerialDescriptor("BufferedImage", PrimitiveKind.STRING)
Expand Down
Loading

0 comments on commit 9d75452

Please sign in to comment.