Skip to content
Snippets Groups Projects
Commit 91385af0 authored by Alexander Rose's avatar Alexander Rose
Browse files

renamed Sureface to Mesh, wip MeshBuilder

parent 134df300
Branches
Tags
No related merge requests found
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
import { Run } from 'mol-task' import { Run } from 'mol-task'
import { compute } from 'mol-geo/util/marching-cubes/algorithm' import { compute } from 'mol-geo/util/marching-cubes/algorithm'
import { Surface } from 'mol-geo/shape/surface' import { Mesh } from 'mol-geo/shape/mesh'
import { Tensor, Mat4, Vec3 } from 'mol-math/linear-algebra' import { Tensor, Mat4, Vec3 } from 'mol-math/linear-algebra'
function fillField(tensor: Tensor, f: (x: number, y: number, z: number) => number, min: number[], max: number[]): Tensor { function fillField(tensor: Tensor, f: (x: number, y: number, z: number) => number, min: number[], max: number[]): Tensor {
...@@ -27,7 +27,7 @@ function fillField(tensor: Tensor, f: (x: number, y: number, z: number) => numbe ...@@ -27,7 +27,7 @@ function fillField(tensor: Tensor, f: (x: number, y: number, z: number) => numbe
return tensor return tensor
} }
export default async function computeSurface(f: (x: number, y: number, z: number) => number, data?: { field: Tensor, surface: Surface }) { export default async function computeSurface(f: (x: number, y: number, z: number) => number, data?: { field: Tensor, surface: Mesh }) {
let field: Tensor; let field: Tensor;
if (data) field = data.field; if (data) field = data.field;
else { else {
...@@ -51,7 +51,7 @@ export default async function computeSurface(f: (x: number, y: number, z: number ...@@ -51,7 +51,7 @@ export default async function computeSurface(f: (x: number, y: number, z: number
const scale = Mat4.fromScaling(Mat4.zero(), Vec3.create(size[0] / (grid[0] - 1), size[1] / (grid[1] - 1), size[2] / (grid[2] - 1))); const scale = Mat4.fromScaling(Mat4.zero(), Vec3.create(size[0] / (grid[0] - 1), size[1] / (grid[1] - 1), size[2] / (grid[2] - 1)));
const transform = Mat4.mul(Mat4.zero(), translation, scale); const transform = Mat4.mul(Mat4.zero(), translation, scale);
Surface.transformImmediate(surface, transform); Mesh.transformImmediate(surface, transform);
Surface.computeNormalsImmediate(surface); Mesh.computeNormalsImmediate(surface);
return { surface, field }; return { surface, field };
} }
\ No newline at end of file
/**
* Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { ValueCell } from 'mol-util/value-cell'
import { Vec3, Mat4 } from 'mol-math/linear-algebra';
import { ChunkedArray } from 'mol-data/util';
import Box, { BoxProps } from '../primitive/box';
import { Mesh } from './mesh';
type ElementId = { id: number }
export interface MeshBuilder {
add(t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array): number
addBox(t: Mat4, props?: BoxProps & ElementId): number
getMesh(): Mesh
}
const tmpV = Vec3.zero()
export namespace MeshBuilder {
export function create(initialCount = 2048, chunkSize = 1024): MeshBuilder {
const vertices = ChunkedArray.create(Float32Array, 3, chunkSize, initialCount);
const normals = ChunkedArray.create(Float32Array, 3, chunkSize, initialCount);
const indices = ChunkedArray.create(Uint32Array, 3, chunkSize * 3, initialCount * 3);
// const offsets = ChunkedArray.create<number>(n => new Uint32Array(n), 1, 1000);
// const elementIds = ChunkedArray.create(Uint32Array, 1, chunkSize, initialCount);
ChunkedArray.compact(indices, true)
const add = (t: Mat4, _vertices: Float32Array, _normals: Float32Array, _indices?: Uint32Array) => {
const offset = vertices.elementCount * vertices.elementSize
for (let i = 0, il = _vertices.length; i < il; i += 3) {
Vec3.fromArray(tmpV, _vertices, i)
Vec3.transformMat4(tmpV, tmpV, t)
// Vec3.transformDirection(tmpV, tmpV, n) // TODO
ChunkedArray.add3(vertices, tmpV[0], tmpV[1], tmpV[2]);
}
// ChunkedArray.add(vertices, _vertices[i])
return offset
}
return {
add,
addBox: (t: Mat4, props?: BoxProps & ElementId) => {
const box = Box(props)
return add(t, box.vertices, box.normals, box.indices)
},
getMesh: () => {
return {
vertexCount: vertices.elementCount,
triangleCount: indices.elementCount,
vertexBuffer: ValueCell.create(ChunkedArray.compact(vertices, true) as Float32Array),
indexBuffer: ValueCell.create(ChunkedArray.compact(indices, true) as Uint32Array),
normalBuffer: ValueCell.create(ChunkedArray.compact(normals, true) as Float32Array),
normalsComputed: true,
}
}
}
}
}
\ No newline at end of file
...@@ -7,8 +7,10 @@ ...@@ -7,8 +7,10 @@
import { Task } from 'mol-task' import { Task } from 'mol-task'
import { ValueCell } from 'mol-util' import { ValueCell } from 'mol-util'
import { Vec3, Mat4 } from 'mol-math/linear-algebra' import { Vec3, Mat4 } from 'mol-math/linear-algebra'
import Sphere from 'mol-math/geometry/sphere'
import { transformPositionArray } from '../util';
export interface Surface { export interface Mesh {
vertexCount: number, vertexCount: number,
triangleCount: number, triangleCount: number,
vertexBuffer: ValueCell<Float32Array>, vertexBuffer: ValueCell<Float32Array>,
...@@ -17,11 +19,11 @@ export interface Surface { ...@@ -17,11 +19,11 @@ export interface Surface {
normalsComputed: boolean, normalsComputed: boolean,
vertexAnnotation?: ValueCell<ArrayLike<number>> vertexAnnotation?: ValueCell<ArrayLike<number>>
//boundingSphere?: { center: Geometry.LinearAlgebra.Vector3, radius: number }; boundingSphere?: Sphere
} }
export namespace Surface { export namespace Mesh {
export function computeNormalsImmediate(surface: Surface) { export function computeNormalsImmediate(surface: Mesh) {
if (surface.normalsComputed) return; if (surface.normalsComputed) return;
const normals = surface.normalBuffer.ref.value && surface.normalBuffer.ref.value!.length >= surface.vertexCount * 3 const normals = surface.normalBuffer.ref.value && surface.normalBuffer.ref.value!.length >= surface.vertexCount * 3
...@@ -58,8 +60,8 @@ export namespace Surface { ...@@ -58,8 +60,8 @@ export namespace Surface {
surface.normalsComputed = true; surface.normalsComputed = true;
} }
export function computeNormals(surface: Surface): Task<Surface> { export function computeNormals(surface: Mesh): Task<Mesh> {
return Task.create<Surface>('Surface (Compute Normals)', async ctx => { return Task.create<Mesh>('Surface (Compute Normals)', async ctx => {
if (surface.normalsComputed) return surface; if (surface.normalsComputed) return surface;
await ctx.update('Computing normals...'); await ctx.update('Computing normals...');
...@@ -68,20 +70,15 @@ export namespace Surface { ...@@ -68,20 +70,15 @@ export namespace Surface {
}); });
} }
export function transformImmediate(surface: Surface, t: Mat4) { export function transformImmediate(mesh: Mesh, t: Mat4) {
const p = Vec3.zero(); transformRangeImmediate(mesh, t, 0, mesh.vertexCount)
const vertices = surface.vertexBuffer.ref.value; }
for (let i = 0, _c = surface.vertexCount * 3; i < _c; i += 3) {
p[0] = vertices[i]; export function transformRangeImmediate(mesh: Mesh, t: Mat4, offset: number, count: number) {
p[1] = vertices[i + 1]; transformPositionArray(t, mesh.vertexBuffer.ref.value, offset, count)
p[2] = vertices[i + 2]; // transformDirectionArray(n, mesh.normalBuffer.ref.value, offset, count) // TODO
Vec3.transformMat4(p, p, t); mesh.normalsComputed = false;
vertices[i] = p[0]; // mesh.boundingSphere = void 0;
vertices[i + 1] = p[1];
vertices[i + 2] = p[2];
}
surface.normalsComputed = false;
//surface.boundingSphere = void 0;
} }
} }
...@@ -168,38 +165,37 @@ export namespace Surface { ...@@ -168,38 +165,37 @@ export namespace Surface {
// return computation(async ctx => await laplacianSmoothComputation(ctx, surface, iterCount, (1.1 * vertexWeight) / 1.1)); // return computation(async ctx => await laplacianSmoothComputation(ctx, surface, iterCount, (1.1 * vertexWeight) / 1.1));
// } // }
// export function computeBoundingSphere(surface: Surface): Computation<Surface> { export function computeBoundingSphere(mesh: Mesh): Task<Mesh> {
// return computation<Surface>(async ctx => { return Task.create<Mesh>('Mesh (Compute Bounding Sphere)', async ctx => {
// if (surface.boundingSphere) { if (mesh.boundingSphere) {
// return surface; return mesh;
// } }
// await ctx.updateProgress('Computing bounding sphere...'); await ctx.update('Computing bounding sphere...');
// const vertices = surface.vertices; const vertices = mesh.vertexBuffer.ref.value;
// let x = 0, y = 0, z = 0; let x = 0, y = 0, z = 0;
// for (let i = 0, _c = surface.vertices.length; i < _c; i += 3) { for (let i = 0, _c = vertices.length; i < _c; i += 3) {
// x += vertices[i]; x += vertices[i];
// y += vertices[i + 1]; y += vertices[i + 1];
// z += vertices[i + 2]; z += vertices[i + 2];
// } }
// x /= surface.vertexCount; x /= mesh.vertexCount;
// y /= surface.vertexCount; y /= mesh.vertexCount;
// z /= surface.vertexCount; z /= mesh.vertexCount;
// let r = 0; let r = 0;
// for (let i = 0, _c = vertices.length; i < _c; i += 3) { for (let i = 0, _c = vertices.length; i < _c; i += 3) {
// const dx = x - vertices[i]; const dx = x - vertices[i];
// const dy = y - vertices[i + 1]; const dy = y - vertices[i + 1];
// const dz = z - vertices[i + 2]; const dz = z - vertices[i + 2];
// r = Math.max(r, dx * dx + dy * dy + dz * dz); r = Math.max(r, dx * dx + dy * dy + dz * dz);
// } }
// surface.boundingSphere = { mesh.boundingSphere = {
// center: LinearAlgebra.Vector3.fromValues(x, y, z), center: Vec3.create(x, y, z),
// radius: Math.sqrt(r) radius: Math.sqrt(r)
// } }
// return surface; return mesh;
// }); });
// } }
// export function transform(surface: Surface, t: number[]): Computation<Surface> { // export function transform(surface: Surface, t: number[]): Computation<Surface> {
// return computation<Surface>(async ctx => { // return computation<Surface>(async ctx => {
......
...@@ -4,9 +4,9 @@ ...@@ -4,9 +4,9 @@
* @author Alexander Rose <alexander.rose@weirdbyte.de> * @author Alexander Rose <alexander.rose@weirdbyte.de>
*/ */
import { Vec3 } from 'mol-math/linear-algebra' import { Vec3, Mat4, Mat3 } from 'mol-math/linear-algebra'
export function normalizeVec3array<T extends Helpers.NumberArray> (a: T) { export function normalizeVec3Array<T extends Helpers.NumberArray> (a: T) {
const n = a.length const n = a.length
for (let i = 0; i < n; i += 3) { for (let i = 0; i < n; i += 3) {
const x = a[ i ] const x = a[ i ]
...@@ -19,12 +19,26 @@ export function normalizeVec3array<T extends Helpers.NumberArray> (a: T) { ...@@ -19,12 +19,26 @@ export function normalizeVec3array<T extends Helpers.NumberArray> (a: T) {
} }
} }
const tmpV = Vec3.zero()
export function transformPositionArray (t: Mat4, array: Helpers.NumberArray, offset: number, count: number) {
for (let i = 0, il = count * 3; i < il; i += 3) {
Vec3.fromArray(tmpV, array, offset + i)
Vec3.transformMat4(tmpV, tmpV, t)
Vec3.toArray(tmpV, array, offset + i)
}
}
export function transformDirectionArray (t: Mat3, array: Helpers.NumberArray, offset: number, count: number) {
// TODO
}
export function setArrayZero(array: Helpers.NumberArray) { export function setArrayZero(array: Helpers.NumberArray) {
const n = array.length const n = array.length
for (let i = 0; i < n; ++i) array[i] = 0 for (let i = 0; i < n; ++i) array[i] = 0
} }
// iterate over the entire buffer and apply the radius to each vertex /** iterate over the entire buffer and apply the radius to each vertex */
export function appplyRadius(vertices: Helpers.NumberArray, radius: number) { export function appplyRadius(vertices: Helpers.NumberArray, radius: number) {
const v = Vec3.zero() const v = Vec3.zero()
const n = vertices.length const n = vertices.length
...@@ -36,8 +50,10 @@ export function appplyRadius(vertices: Helpers.NumberArray, radius: number) { ...@@ -36,8 +50,10 @@ export function appplyRadius(vertices: Helpers.NumberArray, radius: number) {
} }
} }
// indexed vertex normals weighted by triangle areas http://www.iquilezles.org/www/articles/normals/normals.htm /**
// normal array must contain only zeros * indexed vertex normals weighted by triangle areas http://www.iquilezles.org/www/articles/normals/normals.htm
* normal array must contain only zeros
*/
export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, indices: Helpers.NumberArray, normals: T) { export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, indices: Helpers.NumberArray, normals: T) {
const a = Vec3.zero() const a = Vec3.zero()
const b = Vec3.zero() const b = Vec3.zero()
...@@ -71,12 +87,11 @@ export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vert ...@@ -71,12 +87,11 @@ export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vert
normals[ ci + 2 ] += cb[ 2 ] normals[ ci + 2 ] += cb[ 2 ]
} }
normalizeVec3array(normals) normalizeVec3Array(normals)
return normals return normals
} }
// vertex normals for unindexed triangle soup /** vertex normals for unindexed triangle soup, normal array must contain only zeros */
// normal array must contain only zeros
export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, normals: T) { export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, normals: T) {
setArrayZero(normals) setArrayZero(normals)
...@@ -108,6 +123,6 @@ export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: H ...@@ -108,6 +123,6 @@ export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: H
normals[ i + 8 ] = cb[ 2 ] normals[ i + 8 ] = cb[ 2 ]
} }
normalizeVec3array(normals) normalizeVec3Array(normals)
return normals return normals
} }
\ No newline at end of file
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
import { Task, RuntimeContext } from 'mol-task' import { Task, RuntimeContext } from 'mol-task'
import { ChunkedArray } from 'mol-data/util' import { ChunkedArray } from 'mol-data/util'
import { Tensor } from 'mol-math/linear-algebra' import { Tensor } from 'mol-math/linear-algebra'
import { Surface } from '../../shape/surface' import { Mesh } from '../../shape/mesh'
import { Index, EdgeIdInfo, CubeEdges, EdgeTable, TriTable } from './tables' import { Index, EdgeIdInfo, CubeEdges, EdgeTable, TriTable } from './tables'
import { ValueCell } from 'mol-util' import { ValueCell } from 'mol-util'
...@@ -23,7 +23,7 @@ export interface MarchingCubesParameters { ...@@ -23,7 +23,7 @@ export interface MarchingCubesParameters {
annotationField?: Tensor, annotationField?: Tensor,
oldSurface?: Surface oldSurface?: Mesh
} }
export function compute(parameters: MarchingCubesParameters) { export function compute(parameters: MarchingCubesParameters) {
...@@ -71,7 +71,7 @@ class MarchingCubesComputation { ...@@ -71,7 +71,7 @@ class MarchingCubesComputation {
this.state.vertexBuffer = <any>void 0; this.state.vertexBuffer = <any>void 0;
this.state.verticesOnEdges = <any>void 0; this.state.verticesOnEdges = <any>void 0;
let ret: Surface = { let ret: Mesh = {
vertexCount: this.state.vertexCount, vertexCount: this.state.vertexCount,
triangleCount: this.state.triangleCount, triangleCount: this.state.triangleCount,
vertexBuffer: this.parameters.oldSurface ? ValueCell.update(this.parameters.oldSurface.vertexBuffer, vb) : ValueCell.create(vb), vertexBuffer: this.parameters.oldSurface ? ValueCell.update(this.parameters.oldSurface.vertexBuffer, vb) : ValueCell.create(vb),
......
// TODO: rebranded vec4 /**
\ No newline at end of file * Copyright (c) 2018 mol* contributors, licensed under MIT, See LICENSE file for more info.
*
* @author Alexander Rose <alexander.rose@weirdbyte.de>
*/
import { Vec3 } from '../linear-algebra'
export interface Sphere {
center: Vec3
radius: number
}
export namespace Sphere {
export function create(center: Vec3, radius: number): Sphere {
return { center, radius }
}
}
export default Sphere
\ No newline at end of file
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment