From 3b1ba45a883f45d746c236bce1750b2e198bc3e6 Mon Sep 17 00:00:00 2001 From: Val Erastov Date: Wed, 23 Nov 2016 19:22:23 -0800 Subject: [PATCH] mesh utils --- web/app/3d/mesh.js | 82 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 82 insertions(+) create mode 100644 web/app/3d/mesh.js diff --git a/web/app/3d/mesh.js b/web/app/3d/mesh.js new file mode 100644 index 00000000..4d153379 --- /dev/null +++ b/web/app/3d/mesh.js @@ -0,0 +1,82 @@ +import Vector from '../math/vector' +import * as cad_utils from './cad-utils' +import * as math from '../math/math' +import {Matrix3, AXIS, ORIGIN} from '../math/l3space' +import {HashTable} from '../utils/hashmap' + +export function MeshFace() { + this.polygons = []; +} + +export function MeshPolygon(id, normal, w, points) { + this.id = id; + this.normal = normal; + this.w = w; + this.points = points; + this.neighbors = []; +} + +export function Mesh(edges) { + this.edges = edges; + this.faces = []; + this.getEdgeInfo = function(point1, point2) { + return edges.get(arguments) + } +} + +Mesh.fromPolygons = function(polygons, smoothAngle) { + const edges = HashTable.forEdge(); + + let counter = 0; + const allPolygons = []; + function index(polygon) { + if (polygon.length < 3) { + console.warn('invalid polygon ' + polygon); + return; + } + const normal = cad_utils.normalOfCCWSeq(polygon); + const w = normal.dot(polygon[0]); + + const polygonInfo = new MeshPolygon(counter++, normal, w, polygon); + + allPolygons.push(polygonInfo); + + for (let p = polygon.length - 1, q = 0; q < polygon.length; p = q ++) { + var edgeKey = [polygon[p], polygon[q]]; + let edgeInfo = edges.get(edgeKey); + if (edgeInfo == null) { + edges.put(edgeKey, [polygonInfo]) + } else { + let other = edgeInfo[0]; + other.neighbors.push(polygonInfo); + polygonInfo.neighbors.push(other); + edgeInfo.push(polygonInfo); + } + } + } + + const visited = {}; + function mergePolygons(tr, meshFace) { + if (visited[tr.id]) { + return; + } + visited[tr.id] = true; + meshFace.polygons.push(tr); + for (let nb of tr.neighbors) { + if (Math.acos(nb.normal.dot(tr.normal)) < smoothAngle) { + mergePolygons(nb, meshFace) + } + } + } + polygons.forEach(p => index(p)); + const mesh = new Mesh(edges); + for (let tr of allPolygons) { + const meshFace = new MeshFace(); + mergePolygons(tr, meshFace); + if (meshFace.polygons.length != 0) { + mesh.faces.push(meshFace); + } + } + return mesh; +}; +