mirror of
https://github.com/xibyte/jsketcher
synced 2025-12-09 09:52:34 +01:00
fixing extrude when all edges are coincident
This commit is contained in:
parent
f5b6c20b97
commit
c1e7e134a4
2 changed files with 128 additions and 35 deletions
|
|
@ -178,19 +178,21 @@ function replaceMergedFaces(facesData, mergedFaces) {
|
|||
filterInPlace(facesData, ({face}) =>
|
||||
mergedFaces.find(({originFaces}) => originFaces.indexOf(face) > -1) === undefined
|
||||
);
|
||||
for (let {mergedLoops, referenceSurface, originFaces} of mergedFaces) {
|
||||
let fakeFace = new Face(referenceSurface);
|
||||
for (let mergedLoop of mergedLoops) {
|
||||
let actualHalfEdges = [];
|
||||
mergedLoop.halfEdges.forEach(he => addDecayed(he, actualHalfEdges));
|
||||
mergedLoop.halfEdges = actualHalfEdges;
|
||||
fakeFace.innerLoops.push(mergedLoop);
|
||||
mergedLoop.face = fakeFace;
|
||||
mergedLoop.link();
|
||||
}
|
||||
facesData.push(initSolveDataForFace(fakeFace));
|
||||
for (let originFace of originFaces) {
|
||||
originFace.data[MY].newEdges.forEach(e => addNewEdge(fakeFace, e));
|
||||
for (let {facePrototypes, originFaces} of mergedFaces) {
|
||||
for (let {loops, surface} of facePrototypes) {
|
||||
let fakeFace = new Face(surface);
|
||||
for (let loop of loops) {
|
||||
let actualHalfEdges = [];
|
||||
loop.halfEdges.forEach(he => addDecayed(he, actualHalfEdges));
|
||||
loop.halfEdges = actualHalfEdges;
|
||||
fakeFace.innerLoops.push(loop);
|
||||
loop.face = fakeFace;
|
||||
loop.link();
|
||||
}
|
||||
facesData.push(initSolveDataForFace(fakeFace));
|
||||
for (let originFace of originFaces) {
|
||||
originFace.data[MY].newEdges.forEach(e => addNewEdge(fakeFace, e));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -316,9 +318,6 @@ function mergeFaces(facesA, facesB, opType) {
|
|||
}
|
||||
}
|
||||
|
||||
let originFace = facesA[0];
|
||||
let referenceSurface = createBoundingNurbs(allPoints, originFace.surface.simpleSurface);
|
||||
|
||||
let valid = new Set();
|
||||
let invalid = new Set();
|
||||
|
||||
|
|
@ -346,6 +345,7 @@ function mergeFaces(facesA, facesB, opType) {
|
|||
|
||||
function checkCoincidentEdges(edgeA, edgeB) {
|
||||
if (isSameEdge(edgeA, edgeB)) {
|
||||
EdgeSolveData.markCollision(edgeA, edgeB);
|
||||
coincidentEdges.add(edgeA);
|
||||
coincidentEdges.add(edgeB);
|
||||
markEdgeTransferred(edgeA.edge);
|
||||
|
|
@ -407,29 +407,42 @@ function mergeFaces(facesA, facesB, opType) {
|
|||
}
|
||||
}
|
||||
|
||||
let graph = new EdgeGraph();
|
||||
let discardedEdges = new Set();
|
||||
for (let face of originFaces) {
|
||||
for (let edge of face.edges) {
|
||||
discardedEdges.add(edge);
|
||||
if (!invalid.has(edge)) {
|
||||
graph.add(edge);
|
||||
|
||||
|
||||
let facePrototypes = [];
|
||||
let leftovers = null;
|
||||
for (let referenceFace of originFaces) {
|
||||
|
||||
let graph = new EdgeGraph();
|
||||
for (let face of originFaces) {
|
||||
for (let edge of face.edges) {
|
||||
if (!invalid.has(edge) && (leftovers == null || leftovers.has(edge))) {
|
||||
graph.add(edge);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
leftovers = new Set(graph.graphEdges);
|
||||
let detectedLoops = detectLoops(referenceFace.surface, graph);
|
||||
|
||||
for (let loop of detectedLoops) {
|
||||
for (let edge of loop.halfEdges) {
|
||||
// EdgeSolveData.setPriority(edge, 1);
|
||||
leftovers.delete(edge);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (detectedLoops.length !== 0) {
|
||||
facePrototypes.push({
|
||||
loops: detectedLoops,
|
||||
surface: createBoundingNurbs(allPoints, referenceFace.surface.simpleSurface),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
let detectedLoops = detectLoops(originFace.surface, graph);
|
||||
// for (let loop of detectedLoops) {
|
||||
// for (let edge of loop.halfEdges) {
|
||||
// // EdgeSolveData.setPriority(edge, 1);
|
||||
// discardedEdges.delete(edge);
|
||||
// }
|
||||
// }
|
||||
|
||||
|
||||
return {
|
||||
mergedLoops: detectedLoops,
|
||||
referenceSurface,
|
||||
facePrototypes,
|
||||
originFaces
|
||||
};
|
||||
}
|
||||
|
|
@ -466,7 +479,8 @@ function filterFaces(faces) {
|
|||
|
||||
function doesFaceContainNewEdge(face) {
|
||||
for (let e of face.edges) {
|
||||
if (getPriority(e) > 0 || getPriority(e.twin()) > 0) {
|
||||
if (getPriority(e) > 0 || getPriority(e.twin()) > 0 ||
|
||||
EdgeSolveData.get(e).affected === true) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
@ -1056,6 +1070,21 @@ EdgeSolveData.setPriority = function(halfEdge, value) {
|
|||
EdgeSolveData.createIfEmpty(halfEdge).priority = value;
|
||||
};
|
||||
|
||||
EdgeSolveData.markAffected = function(halfEdge) {
|
||||
EdgeSolveData.createIfEmpty(halfEdge).affected = true;
|
||||
};
|
||||
|
||||
EdgeSolveData.markCollision = function(halfEdge1, halfEdge2) {
|
||||
|
||||
function markNeighborhoodAffected(edge) {
|
||||
EdgeSolveData.markAffected(edge);
|
||||
EdgeSolveData.markAffected(edge.next);
|
||||
EdgeSolveData.markAffected(edge.prev);
|
||||
}
|
||||
markNeighborhoodAffected(halfEdge1);
|
||||
markNeighborhoodAffected(halfEdge2);
|
||||
};
|
||||
|
||||
EdgeSolveData.addPriority = function(halfEdge, value) {
|
||||
EdgeSolveData.createIfEmpty(halfEdge).priority += value;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -66,6 +66,22 @@ export default defineTests([
|
|||
}
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'Adjacent2Edges2FaceExtrude',
|
||||
'state': {
|
||||
'sketches': {'0:3': {'Segment': [[[-21, 250], [250, 250]], [[250, 250], [250, -8]], [[250, -8], [-21, -8]], [[-21, -8], [-21, 250]]]}},
|
||||
'operations': [{'type': 'BOX', 'params': {'width': 500, 'height': 500, 'depth': 500}}, {
|
||||
'type': 'EXTRUDE',
|
||||
'params': {'value': 50, 'prism': 1, 'angle': 0, 'rotation': 0, 'face': '0:3'}
|
||||
}]
|
||||
},
|
||||
'expected': {
|
||||
'format': 'LOOPS',
|
||||
'vertices': [[-300, -8, -21], [-300, -8, 250], [-300, 250, -21], [-300, 250, 250], [-250, -250, -250], [-250, -250, 250], [-250, -8, -21], [-250, -8, 250], [-250, 250, -250], [-250, 250, -21], [-250, 250, 250], [250, -250, -250], [250, -250, 250], [250, 250, -250], [250, 250, 250]],
|
||||
'faces': [[[11, 12, 5, 4]], [[13, 14, 12, 11]], [[11, 4, 8, 13]], [[0, 6, 7, 1]], [[2, 9, 6, 0]], [[3, 2, 0, 1]], [[2, 3, 10, 14, 13, 8, 9]], [[7, 6, 9, 8, 4, 5]], [[3, 1, 7, 5, 12, 14, 10]]]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'VertexOnEdge',
|
||||
'state': {
|
||||
|
|
@ -181,6 +197,54 @@ export default defineTests([
|
|||
'vertices': [[-250, -250, -250], [-250, -250, 250], [-250, -8, 250], [-250, -8, 464], [-250, 250, -250], [-250, 250, -21], [-250, 426, -21], [-250, 426, 464], [250, -250, -250], [250, -250, 250], [250, -8, 250], [250, -8, 464], [250, 250, -250], [250, 250, -21], [250, 426, -21], [250, 426, 464]],
|
||||
'faces': [[[8, 9, 1, 0]], [[5, 13, 12, 4]], [[10, 2, 1, 9]], [[8, 0, 4, 12]], [[13, 5, 6, 14]], [[2, 10, 11, 3]], [[15, 7, 3, 11]], [[14, 6, 7, 15]], [[12, 13, 14, 15, 11, 10, 9, 8]], [[3, 7, 6, 5, 4, 0, 1, 2]]]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'StickingOut2FacesExtrude',
|
||||
'state': {
|
||||
'sketches': {'0:3': {'Segment': [[[-21, 426], [464, 426]], [[464, 426], [464, -8]], [[464, -8], [-21, -8]], [[-21, -8], [-21, 426]]]}},
|
||||
'operations': [{'type': 'BOX', 'params': {'width': 500, 'height': 500, 'depth': 500}}, {
|
||||
'type': 'EXTRUDE',
|
||||
'params': {'value': 50, 'prism': 1, 'angle': 0, 'rotation': 0, 'face': '0:3'}
|
||||
}]
|
||||
},
|
||||
'expected': {
|
||||
'format': 'LOOPS',
|
||||
'vertices': [[-300, -8, -21], [-300, -8, 464], [-300, 426, -21], [-300, 426, 464], [-250, -250, -250], [-250, -250, 250], [-250, -8, -21], [-250, -8, 250], [-250, -8, 464], [-250, 250, -250], [-250, 250, -21], [-250, 250, 250], [-250, 426, -21], [-250, 426, 464], [250, -250, -250], [250, -250, 250], [250, 250, -250], [250, 250, 250]],
|
||||
'faces': [[[14, 15, 5, 4]], [[16, 17, 15, 14]], [[10, 11, 17, 16, 9]], [[7, 5, 15, 17, 11]], [[14, 4, 9, 16]], [[3, 13, 12, 2]], [[1, 8, 13, 3]], [[0, 6, 7, 8, 1]], [[2, 12, 10, 6, 0]], [[3, 2, 0, 1]], [[7, 6, 10, 9, 4, 5]], [[7, 11, 10, 12, 13, 8]]]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'AllEdgesAdjacentExtrude',
|
||||
'state': {
|
||||
'sketches': {'0:3': {'Segment': [[[-250, 250], [250, 250]], [[250, 250], [250, -250]], [[250, -250], [-250, -250]], [[-250, -250], [-250, 250]]]}},
|
||||
'operations': [{'type': 'BOX', 'params': {'width': 500, 'height': 500, 'depth': 500}}, {
|
||||
'type': 'EXTRUDE',
|
||||
'params': {'value': 50, 'prism': 1, 'angle': 0, 'rotation': 0, 'face': '0:3'}
|
||||
}]
|
||||
},
|
||||
'expected': {
|
||||
'format': 'LOOPS',
|
||||
'vertices': [[-300, -250, -250], [-300, -250, 250], [-300, 250, -250], [-300, 250, 250], [-250, -250, -250], [-250, -250, 250], [-250, 250, -250], [-250, 250, 250], [250, -250, -250], [250, -250, 250], [250, 250, -250], [250, 250, 250]],
|
||||
'faces': [[[10, 11, 9, 8]], [[3, 2, 0, 1]], [[1, 0, 4, 8, 9, 5]], [[2, 3, 7, 11, 10, 6]], [[3, 1, 5, 9, 11, 7]], [[0, 2, 6, 10, 8, 4]]]
|
||||
}
|
||||
},
|
||||
|
||||
{
|
||||
'name': 'AllEdgesAdjacentCut',
|
||||
'state': {
|
||||
'sketches': {'0:3': {'Segment': [[[-250, 250], [250, 250]], [[250, 250], [250, -250]], [[250, -250], [-250, -250]], [[-250, -250], [-250, 250]]]}},
|
||||
'operations': [{'type': 'BOX', 'params': {'width': 500, 'height': 500, 'depth': 500}}, {
|
||||
'type': 'CUT',
|
||||
'params': {'value': 50, 'prism': 1, 'angle': 0, 'rotation': 0, 'face': '0:3'}
|
||||
}]
|
||||
},
|
||||
'expected': {
|
||||
'format': 'LOOPS',
|
||||
'vertices': [[-200, -250, -250], [-200, -250, 250], [-200, 250, -250], [-200, 250, 250], [250, -250, -250], [250, -250, 250], [250, 250, -250], [250, 250, 250]],
|
||||
'faces': [[[6, 7, 5, 4]], [[3, 2, 0, 1]], [[1, 0, 4, 5]], [[2, 3, 7, 6]], [[3, 1, 5, 7]], [[0, 2, 6, 4]]]
|
||||
}
|
||||
}
|
||||
|
||||
]);
|
||||
|
|
|
|||
Loading…
Reference in a new issue