UNPKG

gs-json

Version:

gs-JSON is a domain agnostic unifying 3D file format for geometric and semantic modelling (hence the 'gs').

250 lines 10.1 kB
import * as three from "three"; import * as arr from "../libs/arr/arr"; import * as threex from "../libs/threex/threex"; import * as math_conics from "../libs/conics/circles"; import { triangulate2D } from "../libs/triangulate/triangulate"; /** * Get the points for the obj */ export function getPointsFromObjs(objs) { const points_set = new Set(); for (const obj of objs) { for (const point of obj.getPointsSet()) { points_set.add(point); } } const points = Array.from(points_set); // create xyzs arr.Array const xyzs = points.map((v) => v.getPosition()); // create map from point IDs to index number const id_map = new Map(); points.forEach((point, i) => id_map.set(point.getID(), i)); // create a map from index to face path return { xyzs, id_map }; } // FACES ==================================================================================================== /** * Get mesh data from multiple objs. */ export function getDataFromAllFaces(objs) { // filter const objs_filtered = objs.filter((obj) => obj.getObjType() === 200 /* polymesh */); // get the points const points = getPointsFromObjs(objs_filtered); // create a map from index to face path const reverse_map = new Map(); // get the faces const faces = arr.Arr.flatten(objs_filtered.map((obj) => obj.getFaces())); // create triangles data const traingles = []; let tri_count = 0; for (const face of faces) { const verts = face.getVertices(); const verts_indexes = verts.map((v) => points.id_map.get(v.getPoint().getID())); if (verts.length === 3) { traingles.push(verts_indexes); reverse_map.set(tri_count, face.getTopoPath()); tri_count++; } else if (verts.length > 3) { const verts_tri = triangulate2D(verts, verts_indexes); traingles.push(verts_tri); for (let i = 0; i < verts_tri.length - 2; i = i + 3) { reverse_map.set(tri_count, face.getTopoPath()); tri_count++; } } } return { xyzs_flat: arr.Arr.flatten(points.xyzs), indexes: arr.Arr.flatten(traingles), reverse_map: reverse_map }; } // WIRES ==================================================================================================== /** * Get line segments data from wires. */ export function getDataFromAllWires(objs) { // filter const objs_filtered = objs.filter((obj) => obj.getObjType() === 200 /* polymesh */ || obj.getObjType() === 100 /* polyline */); // get the wires const wires = arr.Arr.flatten(objs_filtered.map((obj) => obj.getWires())); if (wires.length === 0) { return null; } const points = getPointsFromObjs(objs_filtered); // create a map from index to wire path const reverse_map = new Map(); // create line segments const indexes = []; let seg_count = 0; for (const wire of wires) { const path = wire.getTopoPath(); for (const edge of wire.getEdges()) { const verts = edge.getVertices(); const verts_indexes = verts.map((v) => points.id_map.get(v.getPoint().getID())); indexes.push(verts_indexes); reverse_map.set(seg_count, path); seg_count++; } } return { xyzs_flat: arr.Arr.flatten(points.xyzs), indexes: arr.Arr.flatten(indexes), reverse_map: reverse_map }; } // EDGES ==================================================================================================== /** * Get line segment data from edges. */ export function getDataFromAllEdges(objs) { // filter const objs_filtered = objs.filter((obj) => obj.getObjType() === 200 /* polymesh */ || obj.getObjType() === 100 /* polyline */); // get the points const edges = arr.Arr.flatten(objs_filtered.map((obj) => obj.getEdges())); if (edges.length === 0) { return null; } const points = getPointsFromObjs(objs_filtered); // create a map from index to edge path const reverse_map = new Map(); // create line segments const indexes = []; for (const [i, edge] of edges.entries()) { const verts = edge.getVertices(); const verts_indexes = verts.map((v) => points.id_map.get(v.getPoint().getID())); indexes.push(verts_indexes); reverse_map.set(i, edge.getTopoPath()); } return { xyzs_flat: arr.Arr.flatten(points.xyzs), indexes: arr.Arr.flatten(indexes), reverse_map: reverse_map }; } // VERTICES ==================================================================================================== /** * Get vertex data. */ export function getDataFromAllVertices(objs) { // filter, no need // get the points const vertices = arr.Arr.flatten(objs.map((obj) => obj.getVertices())); if (vertices.length === 0) { return null; } const points = getPointsFromObjs(objs); // create a map from index to vertex path const reverse_map = new Map(); // create points const indexes = []; for (const [i, vertex] of vertices.entries()) { const vert_index = points.id_map.get(vertex.getPoint().getID()); indexes.push(vert_index); reverse_map.set(i, vertex.getTopoPath()); } // return the data return { xyzs_flat: arr.Arr.flatten(points.xyzs), indexes: indexes, reverse_map: reverse_map }; } // OTHERS ==================================================================================================== /** * Get vertex data. */ export function getDataAllOtherLines(objs) { // filter //const objs_filtered: Array<gs.IRay|gs.IPlane|gs.ICircle> = objs.filter((obj) => const objs_filtered = objs.filter((obj) => obj.getObjType() === 1 /* ray */ || obj.getObjType() === 2 /* plane */ || obj.getObjType() === 3 /* circle */); // create points const indexes = []; const xyzs = []; let index_counter = 0; for (const [i, obj] of objs_filtered.entries()) { switch (obj.getObjType()) { case 1 /* ray */: const ray = obj; const ray_line = _renderRay(ray); xyzs.push(ray_line); indexes.push(index_counter); index_counter++; indexes.push(index_counter); index_counter++; break; case 2 /* plane */: const plane = obj; const p_faces = _renderPlane(plane); for (const face of p_faces) { xyzs.push(face); for (let j = 0; j < face.length - 1; j++) { indexes.push(index_counter); indexes.push(++index_counter); } index_counter++; } break; case 3 /* circle */: const obj_render_xyzs = math_conics.getRenderXYZs(obj, 1); xyzs.push(obj_render_xyzs); for (let j = 0; j < obj_render_xyzs.length - 1; j++) { indexes.push(index_counter); indexes.push(++index_counter); } index_counter++; break; default: // code... break; } } // return the data const xyzs_flat = arr.Arr.flatten(xyzs); return { xyzs_flat, indexes, reverse_map: null }; } function _renderRay(ray) { const r_origin = ray.getOrigin().getPosition(); const r_origin_vec = new three.Vector3(...r_origin); const r_dir = ray.getVector(); const r_dir_vec = new three.Vector3(...r_dir); r_dir_vec.setLength(100); const r_end = threex.addVectors(r_origin_vec, r_dir_vec).toArray(); return [r_origin, r_end]; } function _renderPlane(plane) { const p_origin = plane.getOrigin().getPosition(); const p_origin_vec = new three.Vector3(...p_origin); const p_axes = plane.getAxes(); const x_axis = new three.Vector3(...p_axes[0]); x_axis.setLength(10); const y_axis = new three.Vector3(...p_axes[1]); y_axis.setLength(10); const f1_1 = threex.addVectors(p_origin_vec, x_axis); const f1_2 = threex.addVectors(f1_1, y_axis); const f1_3 = threex.addVectors(p_origin_vec, y_axis); const f1 = [p_origin_vec, f1_1, f1_2, f1_3].map((v) => v.toArray()); const f2_1 = threex.addVectors(p_origin_vec, y_axis); const f2_2 = threex.subVectors(f2_1, x_axis); const f2_3 = threex.subVectors(p_origin_vec, x_axis); const f2 = [p_origin_vec, f2_1, f2_2, f2_3].map((v) => v.toArray()); const f3_1 = threex.subVectors(p_origin_vec, x_axis); const f3_2 = threex.subVectors(f3_1, y_axis); const f3_3 = threex.subVectors(p_origin_vec, y_axis); const f3 = [p_origin_vec, f3_1, f3_2, f3_3].map((v) => v.toArray()); const f4_1 = threex.subVectors(p_origin_vec, y_axis); const f4_2 = threex.addVectors(f4_1, x_axis); const f4_3 = threex.addVectors(p_origin_vec, x_axis); const f4 = [p_origin_vec, f4_1, f4_2, f4_3].map((v) => v.toArray()); const p_faces = [f1, f2, f3, f4]; return p_faces; } // POINTS ==================================================================================================== /** * Get point data. */ export function getDataFromAllPoints(points) { // create a map from index to vertex path const reverse_map = new Map(); // create points const indexes = []; const xyzs = []; for (const [i, point] of points.entries()) { xyzs.push(point.getPosition()); indexes.push(i); reverse_map.set(i, point.getID()); } // return the data return { xyzs_flat: arr.Arr.flatten(xyzs), indexes: indexes, reverse_map: reverse_map }; } //# sourceMappingURL=three_geom.js.map