Skip to content

Instantly share code, notes, and snippets.

@juliendargelos
Last active December 18, 2019 13:52
Show Gist options
  • Save juliendargelos/efa54269f81439cbfe11a49f94de6f0a to your computer and use it in GitHub Desktop.
Save juliendargelos/efa54269f81439cbfe11a49f94de6f0a to your computer and use it in GitHub Desktop.
Utils for computing three geometries volume
export function computeVolume(geometry) {
return isBufferGeometry(geometry)
? computeBufferGeometryVolume(geometry)
: computeGeometryVolume(geometry)
}
export function computeBufferGeometryVolume(geometry) {
return geometry.index
? computeIndexedBufferGeometryVolume(geometry)
: computeNotIndexedBufferGeometryVolume(geometry)
}
export function computeGeometryVolume(geometry) {
return geometry.faces.length
? computeIndexedGeometryVolume(geometry)
: computeNotIndexedGeometryVolume(geometry)
}
export function computeIndexedGeometryVolume(geometry) {
const vertices = geometry.vertices
let p1, p2, p3
return Math.abs(geometry.faces.reduce((sum, { a, b, c }) => {
p1 = vertices[a]
p2 = vertices[b]
p3 = vertices[c]
return sum + computeTriangleSignedVolume(
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z,
p3.x, p3.y, p3.z
)
}, 0))
}
export function computeNotIndexedGeometryVolume(geometry) {
const vertices = geometry.vertices
const length = vertices.length
let sum = 0
let p1, p2, p3
for (var i = 0; i < length; i += 3) {
p1 = vertices[i]
p2 = vertices[i + 1]
p3 = vertices[i + 2]
sum += computeTriangleSignedVolume(
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z,
p3.x, p3.y, p3.z
)
}
return Math.abs(sum)
}
export function computeIndexedBufferGeometryVolume(geometry) {
const vertices = geometry.attributes.position.array
const indices = geometry.index.array
const length = indices.length
let sum = 0
let a, b, c
for (var i = 0; i < length; i += 3) {
a = indices[i] * 3
b = indices[i + 1] * 3
c = indices[i + 2] * 3
sum += computeTriangleSignedVolume(
vertices[a], vertices[a + 1], vertices[a + 2],
vertices[b], vertices[b + 1], vertices[b + 2],
vertices[c], vertices[c + 1], vertices[c + 2]
)
}
return Math.abs(sum)
}
export function computeNotIndexedBufferGeometryVolume(geometry) {
const vertices = geometry.attributes.position.array
const length = vertices.length
let sum = 0
for (var index = 0; index < length; index += 9) {
sum += computeTriangleSignedVolume(
vertices[index ], vertices[index + 1], vertices[index + 3],
vertices[index + 4], vertices[index + 5], vertices[index + 6],
vertices[index + 7], vertices[index + 8], vertices[index + 9]
)
}
return Math.abs(sum)
}
export function isBufferGeometry(geometry) {
return geometry.isBufferGeometry
}
function computeTriangleSignedVolume(x1, y1, z1, x2, y2, z2, x3, y3, z3) {
const v321 = x3 * y2 * z1
const v231 = x2 * y3 * z1
const v312 = x3 * y1 * z2
const v132 = x1 * y3 * z2
const v213 = x2 * y1 * z3
const v123 = x1 * y2 * z3
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6
}
import { Geometry, BufferGeometry, Vector3 } from 'three'
export function computeVolume(geometry: Geometry | BufferGeometry): number {
return isBufferGeometry(geometry)
? computeBufferGeometryVolume(geometry)
: computeGeometryVolume(geometry)
}
export function computeBufferGeometryVolume(geometry: BufferGeometry): number {
return geometry.index
? computeIndexedBufferGeometryVolume(geometry)
: computeNotIndexedBufferGeometryVolume(geometry)
}
export function computeGeometryVolume(geometry: Geometry): number {
return geometry.faces.length
? computeIndexedGeometryVolume(geometry)
: computeNotIndexedGeometryVolume(geometry)
}
export function computeIndexedGeometryVolume(geometry: Geometry): number {
const vertices = geometry.vertices
let p1: Vector3
let p2: Vector3
let p3: Vector3
return Math.abs(geometry.faces.reduce((sum, { a, b, c }) => {
p1 = vertices[a]
p2 = vertices[b]
p3 = vertices[c]
return sum + computeTriangleSignedVolume(
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z,
p3.x, p3.y, p3.z
)
}, 0))
}
export function computeNotIndexedGeometryVolume(geometry: Geometry): number {
const vertices = geometry.vertices
const length = vertices.length
let sum = 0
let p1: Vector3
let p2: Vector3
let p3: Vector3
for (var i = 0; i < length; i += 3) {
p1 = vertices[i]
p2 = vertices[i + 1]
p3 = vertices[i + 2]
sum += computeTriangleSignedVolume(
p1.x, p1.y, p1.z,
p2.x, p2.y, p2.z,
p3.x, p3.y, p3.z
)
}
return Math.abs(sum)
}
export function computeIndexedBufferGeometryVolume(
geometry: BufferGeometry
): number {
const vertices = geometry.attributes.position.array
const indices = geometry.index.array
const length = indices.length
let sum = 0
let a: number
let b: number
let c: number
for (var i = 0; i < length; i += 3) {
a = indices[i] * 3
b = indices[i + 1] * 3
c = indices[i + 2] * 3
sum += computeTriangleSignedVolume(
vertices[a], vertices[a + 1], vertices[a + 2],
vertices[b], vertices[b + 1], vertices[b + 2],
vertices[c], vertices[c + 1], vertices[c + 2]
)
}
return Math.abs(sum)
}
export function computeNotIndexedBufferGeometryVolume(
geometry: BufferGeometry
): number {
const vertices = geometry.attributes.position.array
const length = vertices.length
let sum = 0
for (var index = 0; index < length; index += 9) {
sum += computeTriangleSignedVolume(
vertices[index ], vertices[index + 1], vertices[index + 3],
vertices[index + 4], vertices[index + 5], vertices[index + 6],
vertices[index + 7], vertices[index + 8], vertices[index + 9],
)
}
return Math.abs(sum)
}
export function isBufferGeometry(
geometry: Geometry | BufferGeometry
): geometry is BufferGeometry {
return (geometry as BufferGeometry).isBufferGeometry
}
function computeTriangleSignedVolume(
x1: number, y1: number, z1: number,
x2: number, y2: number, z2: number,
x3: number, y3: number, z3: number
): number {
const v321 = x3 * y2 * z1
const v231 = x2 * y3 * z1
const v312 = x3 * y1 * z2
const v132 = x1 * y3 * z2
const v213 = x2 * y1 * z3
const v123 = x1 * y2 * z3
return (-v321 + v231 + v312 - v132 - v213 + v123) / 6
}
@juliendargelos
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment