mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-07 17:04:58 +01:00
prepare for brep tesselation
This commit is contained in:
parent
811a633167
commit
557ea09807
5 changed files with 163 additions and 25 deletions
|
|
@ -76,7 +76,7 @@ function addGlobalDebugActions(app) {
|
|||
AddVolume: (shell, color) => {
|
||||
color = color || 0xffffff;
|
||||
const geometry = new THREE.Geometry();
|
||||
triangulateToThree(shell, geometry);
|
||||
triangulateToThree(shell.faces, geometry);
|
||||
const mesh = new THREE.Mesh(geometry, createSolidMaterial({
|
||||
color,
|
||||
transparent: true,
|
||||
|
|
|
|||
|
|
@ -137,8 +137,8 @@ App.prototype.test2 = function() {
|
|||
// this.addShellOnScene(s1);
|
||||
// this.addShellOnScene(s2);
|
||||
|
||||
let result = this.TPI.brep.bool.intersect(s1, s2);
|
||||
|
||||
// let result = this.TPI.brep.bool.intersect(s1, s2);
|
||||
let result = s1;
|
||||
this.addShellOnScene(result);
|
||||
};
|
||||
|
||||
|
|
@ -149,10 +149,10 @@ App.prototype.test3 = function() {
|
|||
|
||||
const box3 = app.TPI.brep.primitives.box(150, 600, 350, new Matrix3().translate(25, 25, -250));
|
||||
// let result = app.TPI.brep.bool.union(box1, box2);
|
||||
let result = app.TPI.brep.bool.subtract(box1, box2);
|
||||
result = app.TPI.brep.bool.subtract(result, box3);
|
||||
// app.addShellOnScene(box1);
|
||||
app.addShellOnScene(result);
|
||||
// let result = app.TPI.brep.bool.subtract(box1, box2);
|
||||
// result = app.TPI.brep.bool.subtract(result, box3);
|
||||
app.addShellOnScene(box1);
|
||||
// app.addShellOnScene(result);
|
||||
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -2,8 +2,8 @@ import Vector from '../../math/vector'
|
|||
import {EDGE_AUX, FACE_CHUNK} from '../../brep/stitching'
|
||||
import {normalOfCCWSeq} from '../cad-utils'
|
||||
import {TriangulateFace} from '../tess/triangulation'
|
||||
import {SceneSolid, SceneFace, WIREFRAME_MATERIAL} from './scene-object'
|
||||
import brepTess from '../tess/brep-tess'
|
||||
import {SceneSolid, SceneFace, WIREFRAME_MATERIAL, createSolidMaterial} from './scene-object'
|
||||
import brepTess, {isMirrored} from '../tess/brep-tess'
|
||||
|
||||
const SMOOTH_RENDERING = false //true;
|
||||
|
||||
|
|
@ -16,9 +16,7 @@ export class BREPSceneSolid extends SceneSolid {
|
|||
}
|
||||
|
||||
createGeometry() {
|
||||
const geometry = new THREE.Geometry();
|
||||
geometry.dynamic = true;
|
||||
this.mesh = new THREE.Mesh(geometry, this.material);
|
||||
this.mesh = new THREE.Object3D();
|
||||
this.cadGroup.add(this.mesh);
|
||||
this.createFaces();
|
||||
this.createEdges();
|
||||
|
|
@ -26,16 +24,82 @@ export class BREPSceneSolid extends SceneSolid {
|
|||
}
|
||||
|
||||
createFaces() {
|
||||
const geom = this.mesh.geometry;
|
||||
const groups = triangulateToThree(this.shell, geom);
|
||||
for (let g of groups) {
|
||||
const sceneFace = new BREPSceneFace(g.brepFace, this);
|
||||
|
||||
for (let brepFace of this.shell.faces) {
|
||||
const sceneFace = new BREPSceneFace(brepFace, this);
|
||||
this.sceneFaces.push(sceneFace);
|
||||
for (let i = g.groupStart; i < g.groupEnd; i++) {
|
||||
const face = geom.faces[i];
|
||||
sceneFace.registerMeshFace(face);
|
||||
const geom = new THREE.Geometry();
|
||||
geom.dynamic = true;
|
||||
geom.faceVertexUvs[0] = [];
|
||||
|
||||
function tess(nurbs) {
|
||||
// __DEBUG__.AddNormal(nurbs.point(0.5,0.5), nurbs.normalInMiddle());
|
||||
const tess = nurbs.verb.tessellate({maxDepth: 3});
|
||||
const trs = tess.faces.map(faceIndices => {
|
||||
return faceIndices.map(i => tess.points[i]).map(p => new Vector().set3(p));
|
||||
});
|
||||
trs.forEach(tr => tr.reverse());
|
||||
if (isMirrored(nurbs)) {
|
||||
|
||||
}
|
||||
return trs;
|
||||
}
|
||||
|
||||
|
||||
const polygons = tess(brepFace.surface);
|
||||
const stitchedSurface = brepFace.data[FACE_CHUNK];
|
||||
const nurbs = stitchedSurface ? stitchedSurface.origin : undefined;
|
||||
|
||||
for (let p = 0; p < polygons.length; ++p) {
|
||||
const off = geom.vertices.length;
|
||||
const poly = polygons[p];
|
||||
const vLength = poly.length;
|
||||
if (vLength < 3) continue;
|
||||
const firstVertex = poly[0];
|
||||
geom.vertices.push(firstVertex.three());
|
||||
geom.vertices.push(poly[1].three());
|
||||
for (let i = 2; i < vLength; i++) {
|
||||
geom.vertices.push(poly[i].three());
|
||||
const a = off;
|
||||
const b = i - 1 + off;
|
||||
const c = i + off;
|
||||
let points = [firstVertex, poly[i - 1], poly[i]];
|
||||
|
||||
let normalOrNormals;
|
||||
if (nurbs && SMOOTH_RENDERING) {
|
||||
function normal(v) {
|
||||
const uv = nurbs.closestParam(v.data());
|
||||
const vec = new THREE.Vector3();
|
||||
vec.set.apply(vec, nurbs.normal(uv[0], uv[1]));
|
||||
vec.normalize();
|
||||
return vec;
|
||||
}
|
||||
|
||||
normalOrNormals = points.map(v => normal(v));
|
||||
} else {
|
||||
normalOrNormals = threeV(brepFace.surface.normal(firstVertex));
|
||||
}
|
||||
const face = new THREE.Face3(a, b, c);
|
||||
|
||||
geom.faceVertexUvs[0].push( points.map(p => new THREE.Vector2().fromArray(brepFace.surface.verb.closestParam(p.data()))));
|
||||
// face.materialIndex = gIdx++;
|
||||
geom.faces.push(face);
|
||||
}
|
||||
geom.computeFaceNormals();
|
||||
let texture = createTexture(brepFace);
|
||||
let material = createSolidMaterial(Object.assign({}, this.skin, {
|
||||
map: texture,
|
||||
transparent: true,
|
||||
color: '0xffffff'
|
||||
|
||||
}));
|
||||
this.mesh.add(new THREE.Mesh(geom, material))
|
||||
//view.setFaceColor(sceneFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
//geom.mergeVertices();
|
||||
}
|
||||
|
||||
|
|
@ -90,7 +154,62 @@ class BREPSceneFace extends SceneFace {
|
|||
}
|
||||
}
|
||||
|
||||
export function triangulateToThree(shell, geom) {
|
||||
function createTexture(brepFace) {
|
||||
const w = 200;
|
||||
const h = 200;
|
||||
function getCanvas() {
|
||||
if (brepFace.data.__canvas === undefined) {
|
||||
let canvas = brepFace.data.__canvas = document.createElement("canvas");
|
||||
canvas.width = 200;
|
||||
canvas.height = 200;
|
||||
}
|
||||
return brepFace.data.__canvas;
|
||||
}
|
||||
let canvas = getCanvas();
|
||||
let ctx = canvas.getContext("2d");
|
||||
|
||||
|
||||
|
||||
// ctx.fillStyle = '0xB0C4DE'
|
||||
// ctx.fillRect(0,0, 400,400)
|
||||
|
||||
// ctx.fillStyle = 'transparent'
|
||||
// ctx.beginPath();
|
||||
// ctx.moveTo(25, 25);
|
||||
// ctx.lineTo(105, 25);
|
||||
// ctx.lineTo(25, 105);
|
||||
// ctx.fill();
|
||||
ctx.scale(w,h);
|
||||
ctx.fillStyle = 'red';
|
||||
ctx.beginPath();
|
||||
|
||||
for (let loop of brepFace.loops) {
|
||||
for (let he of loop.halfEdges) {
|
||||
const uvs = he.edge.curve.verb.tessellate().map(p => brepFace.verb.closestParam(p));
|
||||
if (he.inverted) {
|
||||
uvs.reverse();
|
||||
}
|
||||
let uv = uvs[0];
|
||||
ctx.moveTo(uv[0], uv[1]);
|
||||
for (let i = 1; i < uv.length; ++i) {
|
||||
uv = uvs[i];
|
||||
ctx.lineTo(uv[0], uv[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
ctx.moveTo(55, 55);
|
||||
|
||||
ctx.lineTo(75, 175);
|
||||
ctx.fill();
|
||||
|
||||
let texture = new THREE.Texture(canvas);
|
||||
texture.needsUpdate = true;
|
||||
return texture;
|
||||
}
|
||||
|
||||
export function triangulateToThree(faces, geom) {
|
||||
const result = [];
|
||||
let gIdx = 0;
|
||||
|
||||
|
|
@ -99,7 +218,7 @@ export function triangulateToThree(shell, geom) {
|
|||
geom.faces.push(face);
|
||||
}
|
||||
|
||||
for (let brepFace of shell.faces) {
|
||||
for (let brepFace of faces) {
|
||||
const groupStart = geom.faces.length;
|
||||
const polygons = brepTess(brepFace);
|
||||
const stitchedSurface = brepFace.data[FACE_CHUNK];
|
||||
|
|
@ -131,6 +250,7 @@ export function triangulateToThree(shell, geom) {
|
|||
normalOrNormals = [firstVertex, poly[i - 1], poly[i]].map(v => normal(v));
|
||||
}
|
||||
const face = new THREE.Face3(a, b, c, normalOrNormals);
|
||||
createTexture(brepFace);
|
||||
addFace(face);
|
||||
}
|
||||
//view.setFaceColor(sceneFace, utils.isSmoothPiece(group.shared) ? 0xFF0000 : null);
|
||||
|
|
@ -161,3 +281,5 @@ class FaceGroup {
|
|||
function threeV(v) {
|
||||
return new THREE.Vector3(v.x, v.y, v.z)
|
||||
}
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ export class SceneSolid {
|
|||
this.cadGroup.add(this.wireframeGroup);
|
||||
this.mergeable = true;
|
||||
this.sceneFaces = [];
|
||||
|
||||
this.material = createSolidMaterial(skin);
|
||||
this.skin = skin;
|
||||
}
|
||||
|
||||
addLineToScene(a, b) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
import libtess from 'libtess'
|
||||
import Vector from "../../math/vector";
|
||||
import {Face} from "../../brep/topo/face";
|
||||
import BrepBuilder from "../../brep/brep-builder";
|
||||
|
||||
export default function(face) {
|
||||
export default function A(face) {
|
||||
function asUV(p) {
|
||||
let uv = face.surface.verb.closestParam(p);
|
||||
uv.push(0);
|
||||
|
|
@ -88,9 +90,24 @@ function analyzeCurvature(nurbs, triangles) {
|
|||
|
||||
}
|
||||
|
||||
function isMirrored(surface) {
|
||||
export function isMirrored(surface) {
|
||||
let a = surface.point(0, 0);
|
||||
let b = surface.point(1, 0);
|
||||
let c = surface.point(1, 1);
|
||||
return b.minus(a).cross(c.minus(a))._normalize().dot(surface.normalUV(0, 0)) < 0;
|
||||
}
|
||||
|
||||
|
||||
function test() {
|
||||
|
||||
let bb = new BrepBuilder();
|
||||
let shell = bb.face()
|
||||
.loop([bb.vertex(0,0,0), bb.vertex(100,0,0), bb.vertex(100,100,0), bb.vertex(0,100,0)])
|
||||
.loop([bb.vertex(-100,30,0), bb.vertex(200,30,0), bb.vertex(300,60,0), bb.vertex(-100,60,0)]).build();
|
||||
|
||||
let trs = A(shell.faces[0]);
|
||||
console.log(trs);
|
||||
|
||||
}
|
||||
|
||||
test();
|
||||
Loading…
Reference in a new issue