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
No related branches found
No related tags found
No related merge requests found
......@@ -6,7 +6,7 @@
import { Run } from 'mol-task'
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'
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
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;
if (data) field = data.field;
else {
......@@ -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 transform = Mat4.mul(Mat4.zero(), translation, scale);
Surface.transformImmediate(surface, transform);
Surface.computeNormalsImmediate(surface);
Mesh.transformImmediate(surface, transform);
Mesh.computeNormalsImmediate(surface);
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 @@
import { Task } from 'mol-task'
import { ValueCell } from 'mol-util'
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,
triangleCount: number,
vertexBuffer: ValueCell<Float32Array>,
......@@ -17,11 +19,11 @@ export interface Surface {
normalsComputed: boolean,
vertexAnnotation?: ValueCell<ArrayLike<number>>
//boundingSphere?: { center: Geometry.LinearAlgebra.Vector3, radius: number };
boundingSphere?: Sphere
}
export namespace Surface {
export function computeNormalsImmediate(surface: Surface) {
export namespace Mesh {
export function computeNormalsImmediate(surface: Mesh) {
if (surface.normalsComputed) return;
const normals = surface.normalBuffer.ref.value && surface.normalBuffer.ref.value!.length >= surface.vertexCount * 3
......@@ -58,8 +60,8 @@ export namespace Surface {
surface.normalsComputed = true;
}
export function computeNormals(surface: Surface): Task<Surface> {
return Task.create<Surface>('Surface (Compute Normals)', async ctx => {
export function computeNormals(surface: Mesh): Task<Mesh> {
return Task.create<Mesh>('Surface (Compute Normals)', async ctx => {
if (surface.normalsComputed) return surface;
await ctx.update('Computing normals...');
......@@ -68,20 +70,15 @@ export namespace Surface {
});
}
export function transformImmediate(surface: Surface, t: Mat4) {
const p = Vec3.zero();
const vertices = surface.vertexBuffer.ref.value;
for (let i = 0, _c = surface.vertexCount * 3; i < _c; i += 3) {
p[0] = vertices[i];
p[1] = vertices[i + 1];
p[2] = vertices[i + 2];
Vec3.transformMat4(p, p, t);
vertices[i] = p[0];
vertices[i + 1] = p[1];
vertices[i + 2] = p[2];
export function transformImmediate(mesh: Mesh, t: Mat4) {
transformRangeImmediate(mesh, t, 0, mesh.vertexCount)
}
surface.normalsComputed = false;
//surface.boundingSphere = void 0;
export function transformRangeImmediate(mesh: Mesh, t: Mat4, offset: number, count: number) {
transformPositionArray(t, mesh.vertexBuffer.ref.value, offset, count)
// transformDirectionArray(n, mesh.normalBuffer.ref.value, offset, count) // TODO
mesh.normalsComputed = false;
// mesh.boundingSphere = void 0;
}
}
......@@ -168,38 +165,37 @@ export namespace Surface {
// return computation(async ctx => await laplacianSmoothComputation(ctx, surface, iterCount, (1.1 * vertexWeight) / 1.1));
// }
// export function computeBoundingSphere(surface: Surface): Computation<Surface> {
// return computation<Surface>(async ctx => {
// if (surface.boundingSphere) {
// return surface;
// }
// await ctx.updateProgress('Computing bounding sphere...');
// const vertices = surface.vertices;
// let x = 0, y = 0, z = 0;
// for (let i = 0, _c = surface.vertices.length; i < _c; i += 3) {
// x += vertices[i];
// y += vertices[i + 1];
// z += vertices[i + 2];
// }
// x /= surface.vertexCount;
// y /= surface.vertexCount;
// z /= surface.vertexCount;
// let r = 0;
// for (let i = 0, _c = vertices.length; i < _c; i += 3) {
// const dx = x - vertices[i];
// const dy = y - vertices[i + 1];
// const dz = z - vertices[i + 2];
// r = Math.max(r, dx * dx + dy * dy + dz * dz);
// }
// surface.boundingSphere = {
// center: LinearAlgebra.Vector3.fromValues(x, y, z),
// radius: Math.sqrt(r)
// }
// return surface;
// });
// }
export function computeBoundingSphere(mesh: Mesh): Task<Mesh> {
return Task.create<Mesh>('Mesh (Compute Bounding Sphere)', async ctx => {
if (mesh.boundingSphere) {
return mesh;
}
await ctx.update('Computing bounding sphere...');
const vertices = mesh.vertexBuffer.ref.value;
let x = 0, y = 0, z = 0;
for (let i = 0, _c = vertices.length; i < _c; i += 3) {
x += vertices[i];
y += vertices[i + 1];
z += vertices[i + 2];
}
x /= mesh.vertexCount;
y /= mesh.vertexCount;
z /= mesh.vertexCount;
let r = 0;
for (let i = 0, _c = vertices.length; i < _c; i += 3) {
const dx = x - vertices[i];
const dy = y - vertices[i + 1];
const dz = z - vertices[i + 2];
r = Math.max(r, dx * dx + dy * dy + dz * dz);
}
mesh.boundingSphere = {
center: Vec3.create(x, y, z),
radius: Math.sqrt(r)
}
return mesh;
});
}
// export function transform(surface: Surface, t: number[]): Computation<Surface> {
// return computation<Surface>(async ctx => {
......
......@@ -4,9 +4,9 @@
* @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
for (let i = 0; i < n; i += 3) {
const x = a[ i ]
......@@ -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) {
const n = array.length
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) {
const v = Vec3.zero()
const n = vertices.length
......@@ -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) {
const a = Vec3.zero()
const b = Vec3.zero()
......@@ -71,12 +87,11 @@ export function computeIndexedVertexNormals<T extends Helpers.NumberArray> (vert
normals[ ci + 2 ] += cb[ 2 ]
}
normalizeVec3array(normals)
normalizeVec3Array(normals)
return normals
}
// vertex normals for unindexed triangle soup
// normal array must contain only zeros
/** vertex normals for unindexed triangle soup, normal array must contain only zeros */
export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: Helpers.NumberArray, normals: T) {
setArrayZero(normals)
......@@ -108,6 +123,6 @@ export function computeVertexNormals<T extends Helpers.NumberArray> (vertices: H
normals[ i + 8 ] = cb[ 2 ]
}
normalizeVec3array(normals)
normalizeVec3Array(normals)
return normals
}
\ No newline at end of file
......@@ -7,7 +7,7 @@
import { Task, RuntimeContext } from 'mol-task'
import { ChunkedArray } from 'mol-data/util'
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 { ValueCell } from 'mol-util'
......@@ -23,7 +23,7 @@ export interface MarchingCubesParameters {
annotationField?: Tensor,
oldSurface?: Surface
oldSurface?: Mesh
}
export function compute(parameters: MarchingCubesParameters) {
......@@ -71,7 +71,7 @@ class MarchingCubesComputation {
this.state.vertexBuffer = <any>void 0;
this.state.verticesOnEdges = <any>void 0;
let ret: Surface = {
let ret: Mesh = {
vertexCount: this.state.vertexCount,
triangleCount: this.state.triangleCount,
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