Skip to content

Commit 48a59b8

Browse files
committed
Fix free vs boundary halfedges
1 parent 9f9608c commit 48a59b8

File tree

7 files changed

+57
-25
lines changed

7 files changed

+57
-25
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
"csg",
99
"halfedge"
1010
],
11-
"version": "1.0.1",
11+
"version": "1.0.2",
1212
"author": {
1313
"name": "Axel Antoine",
1414
"email": "ax.antoine@gmail.com",

src/core/Halfedge.ts

Lines changed: 11 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,20 @@ export class Halfedge {
4747
}
4848

4949
/**
50-
* Indicates whether the halfedge is a boundary (i.e. it has no twin)
50+
* Indicates whether the halfedge is free (i.e. no connected face)
5151
*
5252
* @type {boolean}
5353
*/
54-
get isBoundary() {
55-
return this.face !== null;
54+
isFree() {
55+
return this.face === null;
56+
}
57+
58+
/**
59+
* Indicated wetcher the halfedge is a boundary (i.e. no connected face but
60+
* twin has a face)
61+
*/
62+
isBoundary() {
63+
return this.face === null && this.twin.face !== null;
5664
}
5765

5866
/**

src/core/Vertex.test.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -117,14 +117,14 @@ test('Vertex loop CCW', () => {
117117

118118
test('Boundary in halfedges loop', () => {
119119

120-
let array = generatorToArray(v1.boundaryHalfedgesInLoop());
120+
let array = generatorToArray(v1.freeHalfedgesInLoop());
121121
expect(array).toHaveLength(0);
122122

123123
const v1v2 = addEdge(struct, v1, v2);
124124
const v1v3 = addEdge(struct, v1, v3);
125125
const v1v4 = addEdge(struct, v1, v4);
126126

127-
array = generatorToArray(v1.boundaryHalfedgesInLoop());
127+
array = generatorToArray(v1.freeHalfedgesInLoop());
128128
expect(array).toHaveLength(3);
129129
expect(array).toContain(v1v2.twin);
130130
expect(array).toContain(v1v3.twin);
@@ -133,7 +133,7 @@ test('Boundary in halfedges loop', () => {
133133
// Close 1-2-3 triangles
134134
const v2v3 = addEdge(struct, v2, v3);
135135
addFace(struct, [v1v2, v2v3, v1v3.twin]);
136-
array = generatorToArray(v1.boundaryHalfedgesInLoop());
136+
array = generatorToArray(v1.freeHalfedgesInLoop());
137137
expect(array).toHaveLength(2);
138138
expect(array).toContain(v1v2.twin);
139139
expect(array).toContain(v1v4.twin);
@@ -145,20 +145,20 @@ test('Boundary in halfedges loop', () => {
145145
const v4v2 = addEdge(struct, v4, v2);
146146
addFace(struct, [v4v2, v1v2.twin, v1v4]);
147147

148-
array = generatorToArray(v1.boundaryHalfedgesInLoop());
148+
array = generatorToArray(v1.freeHalfedgesInLoop());
149149
expect(array).toHaveLength(0);
150150
});
151151

152152
test('Boundary out halfedges loop', () => {
153153

154-
let array = generatorToArray(v1.boundaryHalfedgesOutLoop());
154+
let array = generatorToArray(v1.freeHalfedgesOutLoop());
155155
expect(array).toHaveLength(0);
156156

157157
const v1v2 = addEdge(struct, v1, v2);
158158
const v1v3 = addEdge(struct, v1, v3);
159159
const v1v4 = addEdge(struct, v1, v4);
160160

161-
array = generatorToArray(v1.boundaryHalfedgesOutLoop());
161+
array = generatorToArray(v1.freeHalfedgesOutLoop());
162162
expect(array).toHaveLength(3);
163163
expect(array).toContain(v1v2);
164164
expect(array).toContain(v1v3);
@@ -167,7 +167,7 @@ test('Boundary out halfedges loop', () => {
167167
// Close 1-2-3 triangles
168168
const v2v3 = addEdge(struct, v2, v3);
169169
addFace(struct, [v1v2, v2v3, v1v3.twin]);
170-
array = generatorToArray(v1.boundaryHalfedgesOutLoop());
170+
array = generatorToArray(v1.freeHalfedgesOutLoop());
171171
expect(array).toHaveLength(2);
172172
expect(array).toContain(v1v3);
173173
expect(array).toContain(v1v4);
@@ -179,7 +179,7 @@ test('Boundary out halfedges loop', () => {
179179
const v4v2 = addEdge(struct, v4, v2);
180180
addFace(struct, [v4v2, v1v2.twin, v1v4]);
181181

182-
array = generatorToArray(v1.boundaryHalfedgesOutLoop());
182+
array = generatorToArray(v1.freeHalfedgesOutLoop());
183183
expect(array).toHaveLength(0);
184184
});
185185

src/core/Vertex.ts

Lines changed: 32 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -41,27 +41,51 @@ export class Vertex {
4141
}
4242

4343
/**
44-
* Returns a generator of free halfedges (i.e. without face) starting from this
45-
* vertex.
44+
* Returns a generator of free halfedges starting from this vertex.
4645
* @param start The halfedge to start, default is vertex halfedge
4746
*/
48-
*boundaryHalfedgesOutLoop(start = this.halfedge) {
47+
*freeHalfedgesOutLoop(start = this.halfedge) {
4948
for (const halfedge of this.loopCW(start)) {
50-
if (halfedge.face === null) {
49+
if (halfedge.isFree()) {
5150
yield halfedge;
5251
}
5352
}
5453
return null;
5554
}
5655

5756
/**
58-
* Returns a generator of free halfedges (i.e. without face) arriving to this
59-
* vertex.
57+
* Returns a generator of free halfedges arriving to this vertex.
58+
* @param start The halfedge to start, default is vertex halfedge
59+
*/
60+
*freeHalfedgesInLoop(start = this.halfedge) {
61+
for (const halfedge of this.loopCW(start)) {
62+
if (halfedge.twin.isFree()) {
63+
yield halfedge.twin;
64+
}
65+
}
66+
return null;
67+
}
68+
69+
/**
70+
* Returns a generator of boundary halfedges starting from this vertex.
71+
* @param start The halfedge to start, default is vertex halfedge
72+
*/
73+
*boundaryHalfedgesOutLoop(start = this.halfedge) {
74+
for (const halfedge of this.loopCW(start)) {
75+
if (halfedge.isBoundary()) {
76+
yield halfedge;
77+
}
78+
}
79+
return null;
80+
}
81+
82+
/**
83+
* Returns a generator of boundary halfedges arriving to this vertex.
6084
* @param start The halfedge to start, default is vertex halfedge
6185
*/
6286
*boundaryHalfedgesInLoop(start = this.halfedge) {
6387
for (const halfedge of this.loopCW(start)) {
64-
if (halfedge.twin.face === null) {
88+
if (halfedge.twin.isBoundary()) {
6589
yield halfedge.twin;
6690
}
6791
}
@@ -81,7 +105,7 @@ export class Vertex {
81105
return true;
82106
}
83107
for (const halfEdge of this.loopCW()) {
84-
if (halfEdge.face === null) {
108+
if (halfEdge.isFree()) {
85109
return true;
86110
}
87111
}

src/operations/addEdge.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ export function addEdge(
7474

7575

7676
// Update refs around v1 if not isolated
77-
const in1 = v1.boundaryHalfedgesInLoop().next().value;
77+
const in1 = v1.freeHalfedgesInLoop().next().value;
7878
if (in1) {
7979
const out1 = in1.next;
8080
h1.prev = in1;
@@ -87,7 +87,7 @@ export function addEdge(
8787
}
8888

8989
// Update refs around v2 if not isolated
90-
const in2 = v2.boundaryHalfedgesInLoop().next().value;
90+
const in2 = v2.freeHalfedgesInLoop().next().value;
9191
if (in2) {
9292

9393
const out2 = in2.next;

src/operations/addFace.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ function makeHalfedgesAdjacent(
8282

8383
// Find a boundary halfedge different from out.twin and in
8484
let g: Halfedge | null = null;
85-
const loop = halfOut.vertex.boundaryHalfedgesInLoop(halfOut);
85+
const loop = halfOut.vertex.freeHalfedgesInLoop(halfOut);
8686
let he = loop.next();
8787
while (!g && !he.done) {
8888
if (he.value !== halfIn) {

src/operations/cutFace.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ export function cutFace(
101101
h2.prev = h1;
102102

103103
// If v1 is not part of face, get any outgoing halfedge
104-
out1 = out1 ?? v1.boundaryHalfedgesOutLoop().next().value;
104+
out1 = out1 ?? v1.freeHalfedgesOutLoop().next().value;
105105

106106
// Update refs around v1 if not isolated
107107
if (out1) {
@@ -116,7 +116,7 @@ export function cutFace(
116116
}
117117

118118
// If v2 is not part of face, get any outgoing halfedge
119-
out2 = out2 ?? v2.boundaryHalfedgesOutLoop().next().value;
119+
out2 = out2 ?? v2.freeHalfedgesOutLoop().next().value;
120120

121121
// Update refs around v2 if not isolated
122122
if (out2) {

0 commit comments

Comments
 (0)