Apply fixjsstyle to libtess.js

This commit is contained in:
Tom Payne
2013-09-03 11:29:03 +02:00
parent 31f3e92494
commit f8efa7c6a4
21 changed files with 604 additions and 410 deletions

View File

@@ -35,18 +35,21 @@
// require libtess // require libtess
/*global libtess */ /*global libtess */
// TODO(bckenny): better typing for DictKey? actually libtess.ActiveRegion // TODO(bckenny): better typing for DictKey? actually libtess.ActiveRegion
/** @typedef {Object} */ /** @typedef {Object} */
libtess.dictKey; libtess.dictKey;
// TODO(bckenny): better typing for all of this, really. no need not to eg use tess as frame directly // TODO(bckenny): better typing for all of this, really. no need not to eg use tess as frame directly
/** /**
* [Dict description] * [Dict description]
* *
* @constructor * @constructor
* @param {Object} frame [description] * @param {Object} frame [description].
* @param {function(Object, Object, Object): boolean} leq [description] * @param {function(Object, Object, Object): boolean} leq [description].
*/ */
libtess.Dict = function(frame, leq) { libtess.Dict = function(frame, leq) {
/** /**
@@ -72,6 +75,7 @@ libtess.Dict = function(frame, leq) {
this.leq_ = /** @type {function(Object, libtess.dictKey, libtess.dictKey): boolean} */(leq); this.leq_ = /** @type {function(Object, libtess.dictKey, libtess.dictKey): boolean} */(leq);
}; };
/** /**
* [deleteDict description] * [deleteDict description]
*/ */
@@ -85,11 +89,12 @@ libtess.Dict.prototype.deleteDict = function() {
// NOTE(bckenny): nulled at callsite (sweep.doneEdgeDict_) // NOTE(bckenny): nulled at callsite (sweep.doneEdgeDict_)
}; };
/** /**
* [insertBefore description] * [insertBefore description]
* @param {libtess.DictNode} node [description] * @param {libtess.DictNode} node [description].
* @param {Object} key [description] * @param {Object} key [description].
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.Dict.prototype.insertBefore = function(node, key) { libtess.Dict.prototype.insertBefore = function(node, key) {
do { do {
@@ -107,19 +112,21 @@ libtess.Dict.prototype.insertBefore = function(node, key) {
return newNode; return newNode;
}; };
/** /**
* [insert description] * [insert description]
* @param {Object} key [description] * @param {Object} key [description].
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.Dict.prototype.insert = function(key) { libtess.Dict.prototype.insert = function(key) {
// NOTE(bckenny): from a macro in dict.h/dict-list.h // NOTE(bckenny): from a macro in dict.h/dict-list.h
return this.insertBefore(this.head, key); return this.insertBefore(this.head, key);
}; };
/** /**
* [deleteNode description] * [deleteNode description]
* @param {libtess.DictNode} node [description] * @param {libtess.DictNode} node [description].
*/ */
libtess.Dict.prototype.deleteNode = function(node) { libtess.Dict.prototype.deleteNode = function(node) {
// NOTE(bckenny): nulled at callsite (sweep.deleteRegion_) // NOTE(bckenny): nulled at callsite (sweep.deleteRegion_)
@@ -128,13 +135,14 @@ libtess.Dict.prototype.deleteNode = function(node) {
// memFree( node ); TODO(bckenny) // memFree( node ); TODO(bckenny)
}; };
/** /**
* Search returns the node with the smallest key greater than or equal * Search returns the node with the smallest key greater than or equal
* to the given key. If there is no such key, returns a node whose * to the given key. If there is no such key, returns a node whose
* key is null. Similarly, max(d).getSucc() has a null key, etc. * key is null. Similarly, max(d).getSucc() has a null key, etc.
* *
* @param {Object} key [description] * @param {Object} key [description].
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.Dict.prototype.search = function(key) { libtess.Dict.prototype.search = function(key) {
var node = this.head; var node = this.head;
@@ -146,18 +154,20 @@ libtess.Dict.prototype.search = function(key) {
return node; return node;
}; };
/** /**
* [getMin description] * [getMin description]
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.Dict.prototype.getMin = function() { libtess.Dict.prototype.getMin = function() {
// NOTE(bckenny): from a macro in dict.h/dict-list.h // NOTE(bckenny): from a macro in dict.h/dict-list.h
return this.head.next; return this.head.next;
}; };
/** /**
* [getMax description] * [getMax description]
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.Dict.prototype.getMax = function() { libtess.Dict.prototype.getMax = function() {
// NOTE(bckenny): from a macro in dict.h/dict-list.h // NOTE(bckenny): from a macro in dict.h/dict-list.h

View File

@@ -38,6 +38,8 @@
// TODO(bckenny): better typing for DictKey? // TODO(bckenny): better typing for DictKey?
/** /**
* [DictNode description] * [DictNode description]
* @constructor * @constructor
@@ -63,26 +65,29 @@ libtess.DictNode = function() {
this.prev = null; this.prev = null;
}; };
/** /**
* [getKey description] * [getKey description]
* @return {libtess.dictKey} [description] * @return {libtess.dictKey} [description].
*/ */
libtess.DictNode.prototype.getKey = function() { libtess.DictNode.prototype.getKey = function() {
return this.key; return this.key;
}; };
/** /**
* [getSucc description] * [getSucc description]
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.DictNode.prototype.getSucc = function() { libtess.DictNode.prototype.getSucc = function() {
// TODO(bckenny): unabreviated naming? // TODO(bckenny): unabreviated naming?
return this.next; return this.next;
}; };
/** /**
* [getPred description] * [getPred description]
* @return {libtess.DictNode} [description] * @return {libtess.DictNode} [description].
*/ */
libtess.DictNode.prototype.getPred = function() { libtess.DictNode.prototype.getPred = function() {
// TODO(bckenny): unabreviated naming? // TODO(bckenny): unabreviated naming?

View File

@@ -45,28 +45,31 @@ libtess.geom = function() {
}; };
/** /**
* [vertEq description] * [vertEq description]
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.geom.vertEq = function(u, v) { libtess.geom.vertEq = function(u, v) {
return u.s === v.s && u.t === v.t; return u.s === v.s && u.t === v.t;
}; };
/** /**
* Returns true if u is lexicographically <= v. * Returns true if u is lexicographically <= v.
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @return {boolean} * @return {boolean}
*/ */
libtess.geom.vertLeq = function(u, v) { libtess.geom.vertLeq = function(u, v) {
return (u.s < v.s) || (u.s === v.s && u.t <= v.t); return (u.s < v.s) || (u.s === v.s && u.t <= v.t);
}; };
/** /**
* Given three vertices u,v,w such that geom.vertLeq(u,v) && geom.vertLeq(v,w), * Given three vertices u,v,w such that geom.vertLeq(u,v) && geom.vertLeq(v,w),
* evaluates the t-coord of the edge uw at the s-coord of the vertex v. * evaluates the t-coord of the edge uw at the s-coord of the vertex v.
@@ -78,10 +81,10 @@ libtess.geom.vertLeq = function(u, v) {
* let r be the negated result (this evaluates (uw)(v.s)), then * let r be the negated result (this evaluates (uw)(v.s)), then
* r is guaranteed to satisfy MIN(u.t,w.t) <= r <= MAX(u.t,w.t). * r is guaranteed to satisfy MIN(u.t,w.t) <= r <= MAX(u.t,w.t).
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @param {libtess.GluVertex} w [description] * @param {libtess.GluVertex} w [description].
* @return {number} double * @return {number} double.
*/ */
libtess.geom.edgeEval = function(u, v, w) { libtess.geom.edgeEval = function(u, v, w) {
var gapL, gapR; var gapL, gapR;
@@ -103,15 +106,16 @@ libtess.geom.edgeEval = function(u, v, w) {
return 0; return 0;
}; };
/** /**
* Returns a number whose sign matches geom.edgeEval(u,v,w) but which * Returns a number whose sign matches geom.edgeEval(u,v,w) but which
* is cheaper to evaluate. Returns > 0, == 0 , or < 0 * is cheaper to evaluate. Returns > 0, == 0 , or < 0
* as v is above, on, or below the edge uw. * as v is above, on, or below the edge uw.
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @param {libtess.GluVertex} w [description] * @param {libtess.GluVertex} w [description].
* @return {number} double * @return {number} double.
*/ */
libtess.geom.edgeSign = function(u, v, w) { libtess.geom.edgeSign = function(u, v, w) {
var gapL, gapR; var gapL, gapR;
@@ -129,18 +133,20 @@ libtess.geom.edgeSign = function(u, v, w) {
return 0; return 0;
}; };
/** /**
* Version of VertLeq with s and t transposed. * Version of VertLeq with s and t transposed.
* Returns true if u is lexicographically <= v. * Returns true if u is lexicographically <= v.
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @return {boolean} * @return {boolean}
*/ */
libtess.geom.transLeq = function(u, v) { libtess.geom.transLeq = function(u, v) {
return (u.t < v.t) || (u.t === v.t && u.s <= v.s); return (u.t < v.t) || (u.t === v.t && u.s <= v.s);
}; };
/** /**
* Version of geom.edgeEval with s and t transposed. * Version of geom.edgeEval with s and t transposed.
* Given three vertices u,v,w such that geom.transLeq(u,v) && geom.transLeq(v,w), * Given three vertices u,v,w such that geom.transLeq(u,v) && geom.transLeq(v,w),
@@ -153,10 +159,10 @@ libtess.geom.transLeq = function(u, v) {
* let r be the negated result (this evaluates (uw)(v.t)), then * let r be the negated result (this evaluates (uw)(v.t)), then
* r is guaranteed to satisfy MIN(u.s,w.s) <= r <= MAX(u.s,w.s). * r is guaranteed to satisfy MIN(u.s,w.s) <= r <= MAX(u.s,w.s).
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @param {libtess.GluVertex} w [description] * @param {libtess.GluVertex} w [description].
* @return {number} double * @return {number} double.
*/ */
libtess.geom.transEval = function(u, v, w) { libtess.geom.transEval = function(u, v, w) {
var gapL, gapR; var gapL, gapR;
@@ -178,16 +184,17 @@ libtess.geom.transEval = function(u, v, w) {
return 0; return 0;
}; };
/** /**
* Version of geom.edgeSign with s and t transposed. * Version of geom.edgeSign with s and t transposed.
* Returns a number whose sign matches geom.transEval(u,v,w) but which * Returns a number whose sign matches geom.transEval(u,v,w) but which
* is cheaper to evaluate. Returns > 0, == 0 , or < 0 * is cheaper to evaluate. Returns > 0, == 0 , or < 0
* as v is above, on, or below the edge uw. * as v is above, on, or below the edge uw.
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @param {libtess.GluVertex} w [description] * @param {libtess.GluVertex} w [description].
* @return {number} double * @return {number} double.
*/ */
libtess.geom.transSign = function(u, v, w) { libtess.geom.transSign = function(u, v, w) {
var gapL, gapR; var gapL, gapR;
@@ -205,37 +212,41 @@ libtess.geom.transSign = function(u, v, w) {
return 0; return 0;
}; };
/** /**
* [edgeGoesLeft description] * [edgeGoesLeft description]
* *
* @param {libtess.GluHalfEdge} e [description] * @param {libtess.GluHalfEdge} e [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.geom.edgeGoesLeft = function(e) { libtess.geom.edgeGoesLeft = function(e) {
return libtess.geom.vertLeq(e.dst(), e.org); return libtess.geom.vertLeq(e.dst(), e.org);
}; };
/** /**
* [edgeGoesRight description] * [edgeGoesRight description]
* *
* @param {libtess.GluHalfEdge} e [description] * @param {libtess.GluHalfEdge} e [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.geom.edgeGoesRight = function(e) { libtess.geom.edgeGoesRight = function(e) {
return libtess.geom.vertLeq(e.org, e.dst()); return libtess.geom.vertLeq(e.org, e.dst());
}; };
/** /**
* [vertL1dist description] * [vertL1dist description]
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @return {number} [description] * @return {number} [description].
*/ */
libtess.geom.vertL1dist = function(u, v) { libtess.geom.vertL1dist = function(u, v) {
return Math.abs(u.s - v.s) + Math.abs(u.t - v.t); return Math.abs(u.s - v.s) + Math.abs(u.t - v.t);
}; };
/** /**
* For almost-degenerate situations, the results are not reliable. * For almost-degenerate situations, the results are not reliable.
* Unless the floating-point arithmetic can be performed without * Unless the floating-point arithmetic can be performed without
@@ -243,15 +254,16 @@ libtess.geom.vertL1dist = function(u, v) {
* on some degenerate inputs, so the client must have some way to * on some degenerate inputs, so the client must have some way to
* handle this situation. * handle this situation.
* *
* @param {libtess.GluVertex} u [description] * @param {libtess.GluVertex} u [description].
* @param {libtess.GluVertex} v [description] * @param {libtess.GluVertex} v [description].
* @param {libtess.GluVertex} w [description] * @param {libtess.GluVertex} w [description].
* @return {boolean} * @return {boolean}
*/ */
libtess.geom.vertCCW = function(u, v, w) { libtess.geom.vertCCW = function(u, v, w) {
return (u.s * (v.t - w.t) + v.s * (w.t - u.t) + w.s * (u.t - v.t)) >= 0; return (u.s * (v.t - w.t) + v.s * (w.t - u.t) + w.s * (u.t - v.t)) >= 0;
}; };
/** /**
* Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b), * Given parameters a,x,b,y returns the value (b*x+a*y)/(a+b),
* or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces * or (x+y)/2 if a==b==0. It requires that a,b >= 0, and enforces
@@ -262,11 +274,11 @@ libtess.geom.vertCCW = function(u, v, w) {
* even when a and b differ greatly in magnitude. * even when a and b differ greatly in magnitude.
* *
* @private * @private
* @param {number} a [description] * @param {number} a [description].
* @param {number} x [description] * @param {number} x [description].
* @param {number} b [description] * @param {number} b [description].
* @param {number} y [description] * @param {number} y [description].
* @return {number} [description] * @return {number} [description].
*/ */
libtess.geom.interpolate_ = function(a, x, b, y) { libtess.geom.interpolate_ = function(a, x, b, y) {
//(a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b, ((a <= b) ? ((b == 0) ? ((x+y) / 2) : (x + (y-x) * (a/(a+b)))) : (y + (x-y) * (b/(a+b))))) //(a = (a < 0) ? 0 : a, b = (b < 0) ? 0 : b, ((a <= b) ? ((b == 0) ? ((x+y) / 2) : (x + (y-x) * (a/(a+b)))) : (y + (x-y) * (b/(a+b)))))
@@ -284,16 +296,17 @@ libtess.geom.interpolate_ = function(a, x, b, y) {
} }
}; };
/** /**
* Given edges (o1,d1) and (o2,d2), compute their point of intersection. * Given edges (o1,d1) and (o2,d2), compute their point of intersection.
* The computed point is guaranteed to lie in the intersection of the * The computed point is guaranteed to lie in the intersection of the
* bounding rectangles defined by each edge. * bounding rectangles defined by each edge.
* *
* @param {libtess.GluVertex} o1 [description] * @param {libtess.GluVertex} o1 [description].
* @param {libtess.GluVertex} d1 [description] * @param {libtess.GluVertex} d1 [description].
* @param {libtess.GluVertex} o2 [description] * @param {libtess.GluVertex} o2 [description].
* @param {libtess.GluVertex} d2 [description] * @param {libtess.GluVertex} d2 [description].
* @param {libtess.GluVertex} v output * @param {libtess.GluVertex} v output.
*/ */
libtess.geom.edgeIntersect = function(o1, d1, o2, d2, v) { libtess.geom.edgeIntersect = function(o1, d1, o2, d2, v) {
/* This is certainly not the most efficient way to find the intersection /* This is certainly not the most efficient way to find the intersection

View File

@@ -32,13 +32,15 @@
* @author Brendan Kenny * @author Brendan Kenny
*/ */
/** /**
* Base namespace. * Base namespace.
*/ */
var libtess = libtess || {}; var libtess = libtess || {};
/** /**
* @define {boolean} [DEBUG description] * @define {boolean} [DEBUG description].
*/ */
libtess.DEBUG = false; libtess.DEBUG = false;
@@ -55,6 +57,7 @@ libtess.assert = function(condition, opt_message) {
} }
}; };
/** /**
* [sweepDebugEvent description] * [sweepDebugEvent description]
* @param {libtess.GluTesselator} tess * @param {libtess.GluTesselator} tess
@@ -64,6 +67,7 @@ libtess.sweepDebugEvent = function(tess) {
// sweep event updated // sweep event updated
}; };
/** /**
* [GLU_TESS_MAX_COORD description] * [GLU_TESS_MAX_COORD description]
* @type {number} * @type {number}
@@ -72,6 +76,7 @@ libtess.sweepDebugEvent = function(tess) {
libtess.GLU_TESS_MAX_COORD = 1e150; libtess.GLU_TESS_MAX_COORD = 1e150;
// NOTE(bckenny): from glu.pl generator // NOTE(bckenny): from glu.pl generator
/** /**
* [TRUE_PROJECT description] * [TRUE_PROJECT description]
* TODO(bckenny): see alg-outline for description * TODO(bckenny): see alg-outline for description
@@ -80,6 +85,7 @@ libtess.GLU_TESS_MAX_COORD = 1e150;
*/ */
libtess.TRUE_PROJECT = false; libtess.TRUE_PROJECT = false;
/** /**
* We cache vertex data for single-contour polygons so that we can * We cache vertex data for single-contour polygons so that we can
* try a quick-and-dirty decomposition first. * try a quick-and-dirty decomposition first.
@@ -88,6 +94,7 @@ libtess.TRUE_PROJECT = false;
*/ */
libtess.TESS_MAX_CACHE = 100; libtess.TESS_MAX_CACHE = 100;
/** /**
* [GLU_TESS_DEFAULT_TOLERANCE description] * [GLU_TESS_DEFAULT_TOLERANCE description]
* @type {number} * @type {number}
@@ -95,6 +102,7 @@ libtess.TESS_MAX_CACHE = 100;
*/ */
libtess.GLU_TESS_DEFAULT_TOLERANCE = 0.0; libtess.GLU_TESS_DEFAULT_TOLERANCE = 0.0;
/** /**
* The begin/end calls must be properly nested. We keep track of * The begin/end calls must be properly nested. We keep track of
* the current state to enforce the ordering. * the current state to enforce the ordering.
@@ -108,6 +116,7 @@ libtess.tessState = {
T_IN_CONTOUR: 2 T_IN_CONTOUR: 2
}; };
/** /**
* The input contours parition the plane into regions. A winding * The input contours parition the plane into regions. A winding
* rule determines which of these regions are inside the polygon. * rule determines which of these regions are inside the polygon.
@@ -139,6 +148,7 @@ libtess.windingRule = {
GLU_TESS_WINDING_ABS_GEQ_TWO: 100134 GLU_TESS_WINDING_ABS_GEQ_TWO: 100134
}; };
/** /**
* The type of primitive return from a "begin" callback. GL_LINE_LOOP is only * The type of primitive return from a "begin" callback. GL_LINE_LOOP is only
* returned when GLU_TESS_BOUNDARY_ONLY is true. Values of enum match WebGL * returned when GLU_TESS_BOUNDARY_ONLY is true. Values of enum match WebGL
@@ -155,6 +165,7 @@ libtess.primitiveType = {
GL_TRIANGLE_FAN: 6 GL_TRIANGLE_FAN: 6
}; };
/** /**
* The types of errors provided to error callback. * The types of errors provided to error callback.
* @enum {number} * @enum {number}
@@ -170,6 +181,7 @@ libtess.errorType = {
GLU_TESS_NEED_COMBINE_CALLBACK: 100156 GLU_TESS_NEED_COMBINE_CALLBACK: 100156
}; };
/** /**
* GLU enums necessary for this project. * GLU enums necessary for this project.
* see enumglu.spec * see enumglu.spec
@@ -203,9 +215,11 @@ libtess.gluEnum = {
GLU_TESS_COMBINE_DATA: 100111 GLU_TESS_COMBINE_DATA: 100111
}; };
/** @typedef {number} */ /** @typedef {number} */
libtess.PQHandle; libtess.PQHandle;
// TODO(bckenny): better typing on key? // TODO(bckenny): better typing on key?
/** @typedef {Object} */ /** @typedef {Object} */
libtess.PQKey; libtess.PQKey;

View File

@@ -35,6 +35,8 @@
// require libtess // require libtess
/*global libtess */ /*global libtess */
/** /**
* Cached vertex data for single-countour polygons for quick-and-dirty * Cached vertex data for single-countour polygons for quick-and-dirty
* decomposition. * decomposition.

View File

@@ -47,6 +47,8 @@
// TODO(bckenny): create more javascript-y API, e.g. make gluTessEndPolygon async, // TODO(bckenny): create more javascript-y API, e.g. make gluTessEndPolygon async,
// don't require so many temp objects created // don't require so many temp objects created
/** /**
* [GluTesselator description] * [GluTesselator description]
* *
@@ -289,6 +291,7 @@ libtess.GluTesselator = function() {
} }
}; };
/** /**
* Destory the tesselator object. See README. * Destory the tesselator object. See README.
*/ */
@@ -298,10 +301,11 @@ libtess.GluTesselator.prototype.gluDeleteTess = function() {
// memFree(tess); TODO(bckenny) // memFree(tess); TODO(bckenny)
}; };
/** /**
* Set properties for control over tesselation. See README. * Set properties for control over tesselation. See README.
* @param {libtess.gluEnum} which [description] * @param {libtess.gluEnum} which [description].
* @param {number|boolean} value [description] * @param {number|boolean} value [description].
*/ */
libtess.GluTesselator.prototype.gluTessProperty = function(which, value) { libtess.GluTesselator.prototype.gluTessProperty = function(which, value) {
// TODO(bckenny): split into more setters? // TODO(bckenny): split into more setters?
@@ -342,10 +346,11 @@ libtess.GluTesselator.prototype.gluTessProperty = function(which, value) {
this.callErrorOrErrorData(libtess.gluEnum.GLU_INVALID_VALUE); this.callErrorOrErrorData(libtess.gluEnum.GLU_INVALID_VALUE);
}; };
/** /**
* Returns tessellator property * Returns tessellator property
* @param {libtess.gluEnum} which [description] * @param {libtess.gluEnum} which [description].
* @return {number|boolean} [description] * @return {number|boolean} [description].
*/ */
libtess.GluTesselator.prototype.gluGetTessProperty = function(which) { libtess.GluTesselator.prototype.gluGetTessProperty = function(which) {
// TODO(bckenny): as above, split into more getters? and improve on switch statement // TODO(bckenny): as above, split into more getters? and improve on switch statement
@@ -377,6 +382,7 @@ libtess.GluTesselator.prototype.gluGetTessProperty = function(which) {
return false; return false;
}; };
/** /**
* Lets the user supply the polygon normal, if known. All input data * Lets the user supply the polygon normal, if known. All input data
* is projected into a plane perpendicular to the normal before * is projected into a plane perpendicular to the normal before
@@ -386,9 +392,9 @@ libtess.GluTesselator.prototype.gluGetTessProperty = function(which) {
* you know that all polygons lie in the x-y plane, call * you know that all polygons lie in the x-y plane, call
* "tess.gluTessNormal(0.0, 0.0, 1.0)" before rendering any polygons. * "tess.gluTessNormal(0.0, 0.0, 1.0)" before rendering any polygons.
* *
* @param {number} x [description] * @param {number} x [description].
* @param {number} y [description] * @param {number} y [description].
* @param {number} z [description] * @param {number} z [description].
*/ */
libtess.GluTesselator.prototype.gluTessNormal = function(x, y, z) { libtess.GluTesselator.prototype.gluTessNormal = function(x, y, z) {
this.normal[0] = x; this.normal[0] = x;
@@ -396,11 +402,12 @@ libtess.GluTesselator.prototype.gluTessNormal = function(x, y, z) {
this.normal[2] = z; this.normal[2] = z;
}; };
/** /**
* Specify callbacks. See README. A null or undefined opt_fn removes current callback. * Specify callbacks. See README. A null or undefined opt_fn removes current callback.
* *
* @param {libtess.gluEnum} which [description] * @param {libtess.gluEnum} which [description].
* @param {?function()=} opt_fn [description] * @param {?function()=} opt_fn [description].
*/ */
libtess.GluTesselator.prototype.gluTessCallback = function(which, opt_fn) { libtess.GluTesselator.prototype.gluTessCallback = function(which, opt_fn) {
var fn = !opt_fn ? null : opt_fn; var fn = !opt_fn ? null : opt_fn;
@@ -473,12 +480,13 @@ libtess.GluTesselator.prototype.gluTessCallback = function(which, opt_fn) {
} }
}; };
/** /**
* Specify a vertex and associated data. Must be within calls to * Specify a vertex and associated data. Must be within calls to
* beginContour/endContour. See README. * beginContour/endContour. See README.
* *
* @param {Array.<number>} coords [description] * @param {Array.<number>} coords [description].
* @param {Object} data [description] * @param {Object} data [description].
*/ */
libtess.GluTesselator.prototype.gluTessVertex = function(coords, data) { libtess.GluTesselator.prototype.gluTessVertex = function(coords, data) {
var tooLarge = false; var tooLarge = false;
@@ -523,9 +531,10 @@ libtess.GluTesselator.prototype.gluTessVertex = function(coords, data) {
this.addVertex_(clamped, data); this.addVertex_(clamped, data);
}; };
/** /**
* [gluTessBeginPolygon description] * [gluTessBeginPolygon description]
* @param {Object} data Client data for current polygon * @param {Object} data Client data for current polygon.
*/ */
libtess.GluTesselator.prototype.gluTessBeginPolygon = function(data) { libtess.GluTesselator.prototype.gluTessBeginPolygon = function(data) {
this.requireState_(libtess.tessState.T_DORMANT); this.requireState_(libtess.tessState.T_DORMANT);
@@ -538,6 +547,7 @@ libtess.GluTesselator.prototype.gluTessBeginPolygon = function(data) {
this.polygonData_ = data; this.polygonData_ = data;
}; };
/** /**
* [gluTessBeginContour description] * [gluTessBeginContour description]
*/ */
@@ -555,6 +565,7 @@ libtess.GluTesselator.prototype.gluTessBeginContour = function() {
} }
}; };
/** /**
* [gluTessEndContour description] * [gluTessEndContour description]
*/ */
@@ -563,6 +574,7 @@ libtess.GluTesselator.prototype.gluTessEndContour = function() {
this.state = libtess.tessState.T_IN_POLYGON; this.state = libtess.tessState.T_IN_POLYGON;
}; };
/** /**
* [gluTessEndPolygon description] * [gluTessEndPolygon description]
*/ */
@@ -644,6 +656,7 @@ libtess.GluTesselator.prototype.gluTessEndPolygon = function() {
this.mesh = null; this.mesh = null;
}; };
/** /**
* Return the tessellator to its original dormant state. * Return the tessellator to its original dormant state.
* @private * @private
@@ -657,10 +670,11 @@ libtess.GluTesselator.prototype.makeDormant_ = function() {
this.mesh = null; this.mesh = null;
}; };
/** /**
* [requireState_ description] * [requireState_ description]
* @private * @private
* @param {libtess.tessState} state [description] * @param {libtess.tessState} state [description].
*/ */
libtess.GluTesselator.prototype.requireState_ = function(state) { libtess.GluTesselator.prototype.requireState_ = function(state) {
if (this.state !== state) { if (this.state !== state) {
@@ -668,10 +682,11 @@ libtess.GluTesselator.prototype.requireState_ = function(state) {
} }
}; };
/** /**
* [gotoState_ description] * [gotoState_ description]
* @private * @private
* @param {libtess.tessState} newState [description] * @param {libtess.tessState} newState [description].
*/ */
libtess.GluTesselator.prototype.gotoState_ = function(newState) { libtess.GluTesselator.prototype.gotoState_ = function(newState) {
while (this.state !== newState) { while (this.state !== newState) {
@@ -711,11 +726,12 @@ libtess.GluTesselator.prototype.gotoState_ = function(newState) {
} }
}; };
/** /**
* [addVertex_ description] * [addVertex_ description]
* @private * @private
* @param {Array.<number>} coords [description] * @param {Array.<number>} coords [description].
* @param {Object} data [description] * @param {Object} data [description].
*/ */
libtess.GluTesselator.prototype.addVertex_ = function(coords, data) { libtess.GluTesselator.prototype.addVertex_ = function(coords, data) {
var e = this.lastEdge_; var e = this.lastEdge_;
@@ -747,11 +763,12 @@ libtess.GluTesselator.prototype.addVertex_ = function(coords, data) {
this.lastEdge_ = e; this.lastEdge_ = e;
}; };
/** /**
* [cacheVertex_ description] * [cacheVertex_ description]
* @private * @private
* @param {Array.<number>} coords [description] * @param {Array.<number>} coords [description].
* @param {Object} data [description] * @param {Object} data [description].
*/ */
libtess.GluTesselator.prototype.cacheVertex_ = function(coords, data) { libtess.GluTesselator.prototype.cacheVertex_ = function(coords, data) {
var v = this.cache[this.cacheCount]; var v = this.cache[this.cacheCount];
@@ -763,6 +780,7 @@ libtess.GluTesselator.prototype.cacheVertex_ = function(coords, data) {
++this.cacheCount; ++this.cacheCount;
}; };
/** /**
* [emptyCache_ description] * [emptyCache_ description]
* @private * @private
@@ -780,13 +798,14 @@ libtess.GluTesselator.prototype.emptyCache_ = function() {
this.emptyCache = false; this.emptyCache = false;
}; };
// TODO(bckenny): all following conditional callbacks could be simplified // TODO(bckenny): all following conditional callbacks could be simplified
// TODO(bckenny): using null for now, but may rework // TODO(bckenny): using null for now, but may rework
// TODO(bckenny): should add documentation that references in callback are volatile (or make a copy) // TODO(bckenny): should add documentation that references in callback are volatile (or make a copy)
// see README callback descriptions // see README callback descriptions
/** /**
* [callBeginOrBeginData description] * [callBeginOrBeginData description]
* @param {libtess.primitiveType} type [description] * @param {libtess.primitiveType} type [description].
*/ */
libtess.GluTesselator.prototype.callBeginOrBeginData = function(type) { libtess.GluTesselator.prototype.callBeginOrBeginData = function(type) {
if (this.callBeginData_) { if (this.callBeginData_) {
@@ -797,9 +816,10 @@ libtess.GluTesselator.prototype.callBeginOrBeginData = function(type) {
} }
}; };
/** /**
* [callVertexOrVertexData description] * [callVertexOrVertexData description]
* @param {Object} data [description] * @param {Object} data [description].
*/ */
libtess.GluTesselator.prototype.callVertexOrVertexData = function(data) { libtess.GluTesselator.prototype.callVertexOrVertexData = function(data) {
if (this.callVertexData_) { if (this.callVertexData_) {
@@ -810,9 +830,10 @@ libtess.GluTesselator.prototype.callVertexOrVertexData = function(data) {
} }
}; };
/** /**
* [callEdgeFlagOrEdgeFlagData description] * [callEdgeFlagOrEdgeFlagData description]
* @param {boolean} flag [description] * @param {boolean} flag [description].
*/ */
libtess.GluTesselator.prototype.callEdgeFlagOrEdgeFlagData = function(flag) { libtess.GluTesselator.prototype.callEdgeFlagOrEdgeFlagData = function(flag) {
if (this.callEdgeFlagData_) { if (this.callEdgeFlagData_) {
@@ -823,6 +844,7 @@ libtess.GluTesselator.prototype.callEdgeFlagOrEdgeFlagData = function(flag) {
} }
}; };
/** /**
* [callEndOrEndData description] * [callEndOrEndData description]
*/ */
@@ -835,12 +857,13 @@ libtess.GluTesselator.prototype.callEndOrEndData = function() {
} }
}; };
/** /**
* [callCombineOrCombineData description] * [callCombineOrCombineData description]
* @param {Array.<number>} coords [description] * @param {Array.<number>} coords [description].
* @param {Array.<Object>} data [description] * @param {Array.<Object>} data [description].
* @param {Array.<number>} weight [description] * @param {Array.<number>} weight [description].
* @return {Object} Interpolated vertex * @return {Object} Interpolated vertex.
*/ */
libtess.GluTesselator.prototype.callCombineOrCombineData = libtess.GluTesselator.prototype.callCombineOrCombineData =
function(coords, data, weight) { function(coords, data, weight) {
@@ -860,10 +883,11 @@ libtess.GluTesselator.prototype.callCombineOrCombineData =
return interpData; return interpData;
}; };
// TODO(bckenny): combine the enums in libtess // TODO(bckenny): combine the enums in libtess
/** /**
* [callErrorOrErrorData description] * [callErrorOrErrorData description]
* @param {(libtess.errorType|libtess.gluEnum)} errno [description] * @param {(libtess.errorType|libtess.gluEnum)} errno [description].
*/ */
libtess.GluTesselator.prototype.callErrorOrErrorData = function(errno) { libtess.GluTesselator.prototype.callErrorOrErrorData = function(errno) {
if (this.callErrorData_) { if (this.callErrorData_) {

View File

@@ -48,12 +48,13 @@ libtess.mesh = function() {
/****************** Basic Edge Operations **********************/ /****************** Basic Edge Operations **********************/
/** /**
* makeEdge creates one edge, two vertices, and a loop (face). * makeEdge creates one edge, two vertices, and a loop (face).
* The loop consists of the two new half-edges. * The loop consists of the two new half-edges.
* *
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.mesh.makeEdge = function(mesh) { libtess.mesh.makeEdge = function(mesh) {
// TODO(bckenny): probably move to GluMesh, but needs Make* methods with it // TODO(bckenny): probably move to GluMesh, but needs Make* methods with it
@@ -68,6 +69,7 @@ libtess.mesh.makeEdge = function(mesh) {
return e; return e;
}; };
/** /**
* meshSplice(eOrg, eDst) is the basic operation for changing the * meshSplice(eOrg, eDst) is the basic operation for changing the
* mesh connectivity and topology. It changes the mesh so that * mesh connectivity and topology. It changes the mesh so that
@@ -92,8 +94,8 @@ libtess.mesh.makeEdge = function(mesh) {
* If eDst == eOrg.oNext, the new vertex will have a single edge. * If eDst == eOrg.oNext, the new vertex will have a single edge.
* If eDst == eOrg.oPrev(), the old vertex will have a single edge. * If eDst == eOrg.oPrev(), the old vertex will have a single edge.
* *
* @param {libtess.GluHalfEdge} eOrg [description] * @param {libtess.GluHalfEdge} eOrg [description].
* @param {libtess.GluHalfEdge} eDst [description] * @param {libtess.GluHalfEdge} eDst [description].
*/ */
libtess.mesh.meshSplice = function(eOrg, eDst) { libtess.mesh.meshSplice = function(eOrg, eDst) {
// TODO: more descriptive name? // TODO: more descriptive name?
@@ -135,6 +137,7 @@ libtess.mesh.meshSplice = function(eOrg, eDst) {
} }
}; };
/** /**
* deleteEdge(eDel) removes the edge eDel. There are several cases: * deleteEdge(eDel) removes the edge eDel. There are several cases:
* if (eDel.lFace != eDel.rFace()), we join two loops into one; the loop * if (eDel.lFace != eDel.rFace()), we join two loops into one; the loop
@@ -146,7 +149,7 @@ libtess.mesh.meshSplice = function(eOrg, eDst) {
* plus a few calls to memFree, but this would allocate and delete * plus a few calls to memFree, but this would allocate and delete
* unnecessary vertices and faces. * unnecessary vertices and faces.
* *
* @param {libtess.GluHalfEdge} eDel [description] * @param {libtess.GluHalfEdge} eDel [description].
*/ */
libtess.mesh.deleteEdge = function(eDel) { libtess.mesh.deleteEdge = function(eDel) {
var eDelSym = eDel.sym; var eDelSym = eDel.sym;
@@ -199,13 +202,14 @@ libtess.mesh.deleteEdge = function(eDel) {
* operations above. They are provided for convenience and efficiency. * operations above. They are provided for convenience and efficiency.
*/ */
/** /**
* addEdgeVertex(eOrg) creates a new edge eNew such that * addEdgeVertex(eOrg) creates a new edge eNew such that
* eNew == eOrg.lNext, and eNew.dst() is a newly created vertex. * eNew == eOrg.lNext, and eNew.dst() is a newly created vertex.
* eOrg and eNew will have the same left face. * eOrg and eNew will have the same left face.
* *
* @param {libtess.GluHalfEdge} eOrg [description] * @param {libtess.GluHalfEdge} eOrg [description].
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.mesh.addEdgeVertex = function(eOrg) { libtess.mesh.addEdgeVertex = function(eOrg) {
// TODO(bckenny): why is it named this? // TODO(bckenny): why is it named this?
@@ -226,13 +230,14 @@ libtess.mesh.addEdgeVertex = function(eOrg) {
return eNew; return eNew;
}; };
/** /**
* splitEdge(eOrg) splits eOrg into two edges eOrg and eNew, * splitEdge(eOrg) splits eOrg into two edges eOrg and eNew,
* such that eNew == eOrg.lNext. The new vertex is eOrg.dst() == eNew.org. * such that eNew == eOrg.lNext. The new vertex is eOrg.dst() == eNew.org.
* eOrg and eNew will have the same left face. * eOrg and eNew will have the same left face.
* *
* @param {libtess.GluHalfEdge} eOrg [description] * @param {libtess.GluHalfEdge} eOrg [description].
* @return {!libtess.GluHalfEdge} [description] * @return {!libtess.GluHalfEdge} [description].
*/ */
libtess.mesh.splitEdge = function(eOrg) { libtess.mesh.splitEdge = function(eOrg) {
var tempHalfEdge = libtess.mesh.addEdgeVertex(eOrg); var tempHalfEdge = libtess.mesh.addEdgeVertex(eOrg);
@@ -252,6 +257,7 @@ libtess.mesh.splitEdge = function(eOrg) {
return eNew; return eNew;
}; };
/** /**
* connect(eOrg, eDst) creates a new edge from eOrg.dst() * connect(eOrg, eDst) creates a new edge from eOrg.dst()
* to eDst.org, and returns the corresponding half-edge eNew. * to eDst.org, and returns the corresponding half-edge eNew.
@@ -263,9 +269,9 @@ libtess.mesh.splitEdge = function(eOrg) {
* If (eOrg.lNext == eDst), the old face is reduced to a single edge. * If (eOrg.lNext == eDst), the old face is reduced to a single edge.
* If (eOrg.lNext.lNext == eDst), the old face is reduced to two edges. * If (eOrg.lNext.lNext == eDst), the old face is reduced to two edges.
* *
* @param {libtess.GluHalfEdge} eOrg [description] * @param {libtess.GluHalfEdge} eOrg [description].
* @param {libtess.GluHalfEdge} eDst [description] * @param {libtess.GluHalfEdge} eDst [description].
* @return {!libtess.GluHalfEdge} [description] * @return {!libtess.GluHalfEdge} [description].
*/ */
libtess.mesh.connect = function(eOrg, eDst) { libtess.mesh.connect = function(eOrg, eDst) {
var joiningLoops = false; var joiningLoops = false;
@@ -299,6 +305,7 @@ libtess.mesh.connect = function(eOrg, eDst) {
/******************** Other Operations **********************/ /******************** Other Operations **********************/
/** /**
* zapFace(fZap) destroys a face and removes it from the * zapFace(fZap) destroys a face and removes it from the
* global face list. All edges of fZap will have a null pointer as their * global face list. All edges of fZap will have a null pointer as their
@@ -307,7 +314,7 @@ libtess.mesh.connect = function(eOrg, eDst) {
* An entire mesh can be deleted by zapping its faces, one at a time, * An entire mesh can be deleted by zapping its faces, one at a time,
* in any order. Zapped faces cannot be used in further mesh operations! * in any order. Zapped faces cannot be used in further mesh operations!
* *
* @param {libtess.GluFace} fZap [description] * @param {libtess.GluFace} fZap [description].
*/ */
libtess.mesh.zapFace = function(fZap) { libtess.mesh.zapFace = function(fZap) {
var eStart = fZap.anEdge; var eStart = fZap.anEdge;
@@ -355,13 +362,14 @@ libtess.mesh.zapFace = function(fZap) {
// TODO(bckenny): probably null at callsite // TODO(bckenny): probably null at callsite
}; };
/** /**
* meshUnion() forms the union of all structures in * meshUnion() forms the union of all structures in
* both meshes, and returns the new mesh (the old meshes are destroyed). * both meshes, and returns the new mesh (the old meshes are destroyed).
* *
* @param {libtess.GluMesh} mesh1 [description] * @param {libtess.GluMesh} mesh1 [description].
* @param {libtess.GluMesh} mesh2 [description] * @param {libtess.GluMesh} mesh2 [description].
* @return {libtess.GluMesh} [description] * @return {libtess.GluMesh} [description].
*/ */
libtess.mesh.meshUnion = function(mesh1, mesh2) { libtess.mesh.meshUnion = function(mesh1, mesh2) {
// TODO(bceknny): probably move to GluMesh method // TODO(bceknny): probably move to GluMesh method
@@ -400,9 +408,10 @@ libtess.mesh.meshUnion = function(mesh1, mesh2) {
return mesh1; return mesh1;
}; };
/** /**
* deleteMesh(mesh) will free all storage for any valid mesh. * deleteMesh(mesh) will free all storage for any valid mesh.
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.mesh.deleteMesh = function(mesh) { libtess.mesh.deleteMesh = function(mesh) {
// TODO(bckenny): unnecessary, I think. // TODO(bckenny): unnecessary, I think.
@@ -412,6 +421,7 @@ libtess.mesh.deleteMesh = function(mesh) {
/************************ Utility Routines ************************/ /************************ Utility Routines ************************/
/** /**
* Creates a new pair of half-edges which form their own loop. * Creates a new pair of half-edges which form their own loop.
* No vertex or face structures are allocated, but these must be assigned * No vertex or face structures are allocated, but these must be assigned
@@ -420,8 +430,8 @@ libtess.mesh.deleteMesh = function(mesh) {
* TODO(bckenny): warning about eNext strictly being first of pair? (see code) * TODO(bckenny): warning about eNext strictly being first of pair? (see code)
* *
* @private * @private
* @param {libtess.GluHalfEdge} eNext [description] * @param {libtess.GluHalfEdge} eNext [description].
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.mesh.makeEdgePair_ = function(eNext) { libtess.mesh.makeEdgePair_ = function(eNext) {
var e = new libtess.GluHalfEdge(); var e = new libtess.GluHalfEdge();
@@ -452,6 +462,7 @@ libtess.mesh.makeEdgePair_ = function(eNext) {
return e; return e;
}; };
/** /**
* splice_ is best described by the Guibas/Stolfi paper or the * splice_ is best described by the Guibas/Stolfi paper or the
* CS348a notes. Basically, it modifies the mesh so that * CS348a notes. Basically, it modifies the mesh so that
@@ -460,8 +471,8 @@ libtess.mesh.makeEdgePair_ = function(eNext) {
* For more explanation see mesh.meshSplice below. * For more explanation see mesh.meshSplice below.
* *
* @private * @private
* @param {libtess.GluHalfEdge} a [description] * @param {libtess.GluHalfEdge} a [description].
* @param {libtess.GluHalfEdge} b [description] * @param {libtess.GluHalfEdge} b [description].
*/ */
libtess.mesh.splice_ = function(a, b) { libtess.mesh.splice_ = function(a, b) {
var aONext = a.oNext; var aONext = a.oNext;
@@ -473,6 +484,7 @@ libtess.mesh.splice_ = function(a, b) {
b.oNext = aONext; b.oNext = aONext;
}; };
/** /**
* makeVertex_(eOrig, vNext) attaches a new vertex and makes it the * makeVertex_(eOrig, vNext) attaches a new vertex and makes it the
* origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives * origin of all edges in the vertex loop to which eOrig belongs. "vNext" gives
@@ -483,8 +495,8 @@ libtess.mesh.splice_ = function(a, b) {
* NOTE: unlike original, acutally allocates new vertex. * NOTE: unlike original, acutally allocates new vertex.
* *
* @private * @private
* @param {libtess.GluHalfEdge} eOrig [description] * @param {libtess.GluHalfEdge} eOrig [description].
* @param {libtess.GluVertex} vNext [description] * @param {libtess.GluVertex} vNext [description].
*/ */
libtess.mesh.makeVertex_ = function(eOrig, vNext) { libtess.mesh.makeVertex_ = function(eOrig, vNext) {
// insert in circular doubly-linked list before vNext // insert in circular doubly-linked list before vNext
@@ -505,6 +517,7 @@ libtess.mesh.makeVertex_ = function(eOrig, vNext) {
} while (e !== eOrig); } while (e !== eOrig);
}; };
/** /**
* makeFace_(eOrig, fNext) attaches a new face and makes it the left * makeFace_(eOrig, fNext) attaches a new face and makes it the left
* face of all edges in the face loop to which eOrig belongs. "fNext" gives * face of all edges in the face loop to which eOrig belongs. "fNext" gives
@@ -515,8 +528,8 @@ libtess.mesh.makeVertex_ = function(eOrig, vNext) {
* NOTE: unlike original, acutally allocates new face. * NOTE: unlike original, acutally allocates new face.
* *
* @private * @private
* @param {libtess.GluHalfEdge} eOrig [description] * @param {libtess.GluHalfEdge} eOrig [description].
* @param {libtess.GluFace} fNext [description] * @param {libtess.GluFace} fNext [description].
*/ */
libtess.mesh.makeFace_ = function(eOrig, fNext) { libtess.mesh.makeFace_ = function(eOrig, fNext) {
// insert in circular doubly-linked list before fNext // insert in circular doubly-linked list before fNext
@@ -539,12 +552,13 @@ libtess.mesh.makeFace_ = function(eOrig, fNext) {
} while (e !== eOrig); } while (e !== eOrig);
}; };
/** /**
* killEdge_ destroys an edge (the half-edges eDel and eDel.sym), * killEdge_ destroys an edge (the half-edges eDel and eDel.sym),
* and removes from the global edge list. * and removes from the global edge list.
* *
* @private * @private
* @param {libtess.GluHalfEdge} eDel [description] * @param {libtess.GluHalfEdge} eDel [description].
*/ */
libtess.mesh.killEdge_ = function(eDel) { libtess.mesh.killEdge_ = function(eDel) {
// TODO(bckenny): in this case, no need to worry(?), but check when checking mesh.makeEdgePair_ // TODO(bckenny): in this case, no need to worry(?), but check when checking mesh.makeEdgePair_
@@ -561,13 +575,14 @@ libtess.mesh.killEdge_ = function(eDel) {
// TODO(bckenny): need to null at callsites? // TODO(bckenny): need to null at callsites?
}; };
/** /**
* killVertex_ destroys a vertex and removes it from the global * killVertex_ destroys a vertex and removes it from the global
* vertex list. It updates the vertex loop to point to a given new vertex. * vertex list. It updates the vertex loop to point to a given new vertex.
* *
* @private * @private
* @param {libtess.GluVertex} vDel [description] * @param {libtess.GluVertex} vDel [description].
* @param {libtess.GluVertex} newOrg [description] * @param {libtess.GluVertex} newOrg [description].
*/ */
libtess.mesh.killVertex_ = function(vDel, newOrg) { libtess.mesh.killVertex_ = function(vDel, newOrg) {
var eStart = vDel.anEdge; var eStart = vDel.anEdge;
@@ -589,13 +604,14 @@ libtess.mesh.killVertex_ = function(vDel, newOrg) {
// TODO(bckenny): need to null at callsites? // TODO(bckenny): need to null at callsites?
}; };
/** /**
* killFace_ destroys a face and removes it from the global face * killFace_ destroys a face and removes it from the global face
* list. It updates the face loop to point to a given new face. * list. It updates the face loop to point to a given new face.
* *
* @private * @private
* @param {libtess.GluFace} fDel [description] * @param {libtess.GluFace} fDel [description].
* @param {libtess.GluFace} newLFace [description] * @param {libtess.GluFace} newLFace [description].
*/ */
libtess.mesh.killFace_ = function(fDel, newLFace) { libtess.mesh.killFace_ = function(fDel, newLFace) {
var eStart = fDel.anEdge; var eStart = fDel.anEdge;

View File

@@ -36,14 +36,16 @@
// requre libtess.GluHalfEdge // requre libtess.GluHalfEdge
/*global libtess */ /*global libtess */
/** /**
* Each face has a pointer to the next and previous faces in the * Each face has a pointer to the next and previous faces in the
* circular list, and a pointer to a half-edge with this face as * circular list, and a pointer to a half-edge with this face as
* the left face (null if this is the dummy header). There is also * the left face (null if this is the dummy header). There is also
* a field "data" for client data. * a field "data" for client data.
* *
* @param {libtess.GluFace=} opt_nextFace [description] * @param {libtess.GluFace=} opt_nextFace [description].
* @param {libtess.GluFace=} opt_prevFace [description] * @param {libtess.GluFace=} opt_prevFace [description].
* @constructor * @constructor
*/ */
libtess.GluFace = function(opt_nextFace, opt_prevFace) { libtess.GluFace = function(opt_nextFace, opt_prevFace) {

View File

@@ -38,6 +38,8 @@
// require libtess.ActiveRegion // require libtess.ActiveRegion
/*global libtess */ /*global libtess */
/** /**
* The fundamental data structure is the "half-edge". Two half-edges * The fundamental data structure is the "half-edge". Two half-edges
* go together to make an edge, but they point in opposite directions. * go together to make an edge, but they point in opposite directions.
@@ -63,7 +65,7 @@
* e.sym stores a pointer in the opposite direction, thus it is * e.sym stores a pointer in the opposite direction, thus it is
* always true that e.sym.next.sym.next === e. * always true that e.sym.next.sym.next === e.
* *
* @param {libtess.GluHalfEdge=} opt_nextEdge [description] * @param {libtess.GluHalfEdge=} opt_nextEdge [description].
* @constructor * @constructor
*/ */
libtess.GluHalfEdge = function(opt_nextEdge) { libtess.GluHalfEdge = function(opt_nextEdge) {
@@ -126,65 +128,73 @@ libtess.GluHalfEdge = function(opt_nextEdge) {
// TODO(bckenny): using methods as aliases for sym connections for now. // TODO(bckenny): using methods as aliases for sym connections for now.
// not sure about this approach. getters? renames? // not sure about this approach. getters? renames?
/** /**
* [rFace description] * [rFace description]
* @return {libtess.GluFace} [description] * @return {libtess.GluFace} [description].
*/ */
libtess.GluHalfEdge.prototype.rFace = function() { libtess.GluHalfEdge.prototype.rFace = function() {
return this.sym.lFace; return this.sym.lFace;
}; };
/** /**
* [dst description] * [dst description]
* @return {libtess.GluVertex} [description] * @return {libtess.GluVertex} [description].
*/ */
libtess.GluHalfEdge.prototype.dst = function() { libtess.GluHalfEdge.prototype.dst = function() {
return this.sym.org; return this.sym.org;
}; };
/** /**
* [oPrev description] * [oPrev description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.oPrev = function() { libtess.GluHalfEdge.prototype.oPrev = function() {
return this.sym.lNext; return this.sym.lNext;
}; };
/** /**
* [lPrev description] * [lPrev description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.lPrev = function() { libtess.GluHalfEdge.prototype.lPrev = function() {
return this.oNext.sym; return this.oNext.sym;
}; };
/** /**
* [dPrev description] * [dPrev description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.dPrev = function() { libtess.GluHalfEdge.prototype.dPrev = function() {
return this.lNext.sym; return this.lNext.sym;
}; };
/** /**
* [rPrev description] * [rPrev description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.rPrev = function() { libtess.GluHalfEdge.prototype.rPrev = function() {
return this.sym.oNext; return this.sym.oNext;
}; };
/** /**
* [dNext description] * [dNext description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.dNext = function() { libtess.GluHalfEdge.prototype.dNext = function() {
return this.rPrev().sym; return this.rPrev().sym;
}; };
/** /**
* [rNext description] * [rNext description]
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.GluHalfEdge.prototype.rNext = function() { libtess.GluHalfEdge.prototype.rNext = function() {
return this.oPrev().sym; return this.oPrev().sym;

View File

@@ -37,6 +37,8 @@
// require libtess.GluVertex // require libtess.GluVertex
/*global libtess */ /*global libtess */
/** /**
* Creates a new mesh with no edges, no vertices, * Creates a new mesh with no edges, no vertices,
* and no loops (what we usually call a "face"). * and no loops (what we usually call a "face").
@@ -73,6 +75,7 @@ libtess.GluMesh = function() {
this.eHeadSym.sym = this.eHead; this.eHeadSym.sym = this.eHead;
}; };
// TODO(bckenny): #ifndef NDEBUG // TODO(bckenny): #ifndef NDEBUG
/** /**
* Checks mesh for self-consistency. * Checks mesh for self-consistency.

View File

@@ -35,14 +35,16 @@
// requre libtess.GluHalfEdge // requre libtess.GluHalfEdge
/*global libtess */ /*global libtess */
/** /**
* Each vertex has a pointer to next and previous vertices in the * Each vertex has a pointer to next and previous vertices in the
* circular list, and a pointer to a half-edge with this vertex as * circular list, and a pointer to a half-edge with this vertex as
* the origin (null if this is the dummy header). There is also a * the origin (null if this is the dummy header). There is also a
* field "data" for client data. * field "data" for client data.
* *
* @param {libtess.GluVertex=} opt_nextVertex [description] * @param {libtess.GluVertex=} opt_nextVertex [description].
* @param {libtess.GluVertex=} opt_prevVertex [description] * @param {libtess.GluVertex=} opt_prevVertex [description].
* @constructor * @constructor
*/ */
libtess.GluVertex = function(opt_nextVertex, opt_prevVertex) { libtess.GluVertex = function(opt_nextVertex, opt_prevVertex) {

View File

@@ -40,6 +40,7 @@ libtess.normal = function() {
}; };
// TODO(bckenny): NOTE: // TODO(bckenny): NOTE:
/* The "feature merging" is not intended to be complete. There are /* The "feature merging" is not intended to be complete. There are
* special cases where edges are nearly parallel to the sweep line * special cases where edges are nearly parallel to the sweep line
@@ -62,6 +63,7 @@ libtess.normal = function() {
*/ */
libtess.normal.S_UNIT_X_ = 1.0; libtess.normal.S_UNIT_X_ = 1.0;
/** /**
* @type {number} * @type {number}
* @private * @private
@@ -69,11 +71,12 @@ libtess.normal.S_UNIT_X_ = 1.0;
*/ */
libtess.normal.S_UNIT_Y_ = 0.0; libtess.normal.S_UNIT_Y_ = 0.0;
/** /**
* projectPolygon determines the polygon normal * projectPolygon determines the polygon normal
* and projects vertices onto the plane of the polygon. * and projects vertices onto the plane of the polygon.
* *
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.normal.projectPolygon = function(tess) { libtess.normal.projectPolygon = function(tess) {
var computedNormal = false; var computedNormal = false;
@@ -136,21 +139,23 @@ libtess.normal.projectPolygon = function(tess) {
} }
}; };
/** /**
* Dot product. * Dot product.
* @private * @private
* @param {Array.<number>} u [description] * @param {Array.<number>} u [description].
* @param {Array.<number>} v [description] * @param {Array.<number>} v [description].
* @return {number} [description] * @return {number} [description].
*/ */
libtess.normal.dot_ = function(u, v) { libtess.normal.dot_ = function(u, v) {
return u[0] * v[0] + u[1] * v[1] + u[2] * v[2]; return u[0] * v[0] + u[1] * v[1] + u[2] * v[2];
}; };
/** /**
* Normalize vector v * Normalize vector v
* @private * @private
* @param {Array.<number>} v [description] * @param {Array.<number>} v [description].
*/ */
libtess.normal.normalize_ = function(v) { libtess.normal.normalize_ = function(v) {
var len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2]; var len = v[0] * v[0] + v[1] * v[1] + v[2] * v[2];
@@ -162,10 +167,11 @@ libtess.normal.normalize_ = function(v) {
v[2] /= len; v[2] /= len;
}; };
/** /**
* Returns the index of the longest component of vector v. * Returns the index of the longest component of vector v.
* @private * @private
* @param {Array.<number>} v [description] * @param {Array.<number>} v [description].
* @return {number} The index of the longest component. * @return {number} The index of the longest component.
*/ */
libtess.normal.longAxis_ = function(v) { libtess.normal.longAxis_ = function(v) {
@@ -181,12 +187,13 @@ libtess.normal.longAxis_ = function(v) {
return i; return i;
}; };
/** /**
* [computeNormal description] * [computeNormal description]
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {Array.<number>} norm [description] * @param {Array.<number>} norm [description].
*/ */
libtess.normal.computeNormal_ = function(tess, norm) { libtess.normal.computeNormal_ = function(tess, norm) {
// TODO(bckenny): better way to init these // TODO(bckenny): better way to init these
@@ -257,11 +264,12 @@ libtess.normal.computeNormal_ = function(tess, norm) {
} }
}; };
/** /**
* [checkOrientation description] * [checkOrientation description]
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.normal.checkOrientation_ = function(tess) { libtess.normal.checkOrientation_ = function(tess) {
// When we compute the normal automatically, we choose the orientation // When we compute the normal automatically, we choose the orientation

View File

@@ -37,6 +37,8 @@
// TODO(bckenny): more specific typing on key // TODO(bckenny): more specific typing on key
/** /**
* [PQHandleElem description] * [PQHandleElem description]
* @constructor * @constructor
@@ -57,14 +59,15 @@ libtess.PQHandleElem = function() {
this.node = 0; this.node = 0;
}; };
/** /**
* Allocate a PQHandleElem array of size size. If oldArray is not null, its * Allocate a PQHandleElem array of size size. If oldArray is not null, its
* contents are copied to the beginning of the new array. The rest of the array * contents are copied to the beginning of the new array. The rest of the array
* is filled with new PQHandleElems. * is filled with new PQHandleElems.
* *
* @param {?Array.<libtess.PQHandleElem>} oldArray [description] * @param {?Array.<libtess.PQHandleElem>} oldArray [description].
* @param {number} size [description] * @param {number} size [description].
* @return {Array.<libtess.PQHandleElem>} [description] * @return {Array.<libtess.PQHandleElem>} [description].
*/ */
libtess.PQHandleElem.realloc = function(oldArray, size) { libtess.PQHandleElem.realloc = function(oldArray, size) {
var newArray = new Array(size); var newArray = new Array(size);

View File

@@ -38,6 +38,8 @@
// TODO(bckenny): maybe just have these created inline as literals // TODO(bckenny): maybe just have these created inline as literals
// (or unboxed directly - PQHandle is just an array index number) // (or unboxed directly - PQHandle is just an array index number)
/** /**
* [PQNode description] * [PQNode description]
* @constructor * @constructor
@@ -50,14 +52,15 @@ libtess.PQNode = function() {
this.handle = 0; this.handle = 0;
}; };
/** /**
* Allocate a PQNode array of size size. If oldArray is not null, its contents * Allocate a PQNode array of size size. If oldArray is not null, its contents
* are copied to the beginning of the new array. The rest of the array is * are copied to the beginning of the new array. The rest of the array is
* filled with new PQNodes. * filled with new PQNodes.
* *
* @param {?Array.<libtess.PQNode>} oldArray [description] * @param {?Array.<libtess.PQNode>} oldArray [description].
* @param {number} size [description] * @param {number} size [description].
* @return {Array.<libtess.PQNode>} [description] * @return {Array.<libtess.PQNode>} [description].
*/ */
libtess.PQNode.realloc = function(oldArray, size) { libtess.PQNode.realloc = function(oldArray, size) {
var newArray = new Array(size); var newArray = new Array(size);

View File

@@ -39,10 +39,12 @@
// TODO(bckenny): preallocating arrays may actually be hurting us in sort // TODO(bckenny): preallocating arrays may actually be hurting us in sort
// performance (esp if theres some undefs in there) // performance (esp if theres some undefs in there)
/** /**
* [PriorityQ description] * [PriorityQ description]
* @constructor * @constructor
* @param {function(Object, Object): boolean} leq [description] * @param {function(Object, Object): boolean} leq [description].
*/ */
libtess.PriorityQ = function(leq) { libtess.PriorityQ = function(leq) {
/** /**
@@ -97,6 +99,7 @@ libtess.PriorityQ = function(leq) {
this.heap_ = new libtess.PriorityQHeap(this.leq_); this.heap_ = new libtess.PriorityQHeap(this.leq_);
}; };
/** /**
* [INIT_SIZE_ description] * [INIT_SIZE_ description]
* @private * @private
@@ -105,6 +108,7 @@ libtess.PriorityQ = function(leq) {
*/ */
libtess.PriorityQ.INIT_SIZE_ = 32; libtess.PriorityQ.INIT_SIZE_ = 32;
/** /**
* [deleteQ description] * [deleteQ description]
*/ */
@@ -117,6 +121,7 @@ libtess.PriorityQ.prototype.deleteQ = function() {
// NOTE(bckenny): nulled at callsite (sweep.donePriorityQ_) // NOTE(bckenny): nulled at callsite (sweep.donePriorityQ_)
}; };
/** /**
* [init description] * [init description]
*/ */
@@ -160,10 +165,11 @@ libtess.PriorityQ.prototype.init = function() {
// #endif // #endif
}; };
/** /**
* [insert description] * [insert description]
* @param {libtess.PQKey} keyNew [description] * @param {libtess.PQKey} keyNew [description].
* @return {libtess.PQHandle} [description] * @return {libtess.PQHandle} [description].
*/ */
libtess.PriorityQ.prototype.insert = function(keyNew) { libtess.PriorityQ.prototype.insert = function(keyNew) {
// NOTE(bckenny): originally returned LONG_MAX as alloc failure signal. no longer does. // NOTE(bckenny): originally returned LONG_MAX as alloc failure signal. no longer does.
@@ -184,15 +190,16 @@ libtess.PriorityQ.prototype.insert = function(keyNew) {
return -(curr + 1); return -(curr + 1);
}; };
/** /**
* Allocate a PQKey array of size size. If oldArray is not null, its * Allocate a PQKey array of size size. If oldArray is not null, its
* contents are copied to the beginning of the new array. The rest of the array * contents are copied to the beginning of the new array. The rest of the array
* is filled with nulls. * is filled with nulls.
* *
* @private * @private
* @param {?Array.<libtess.PQKey>} oldArray [description] * @param {?Array.<libtess.PQKey>} oldArray [description].
* @param {number} size [description] * @param {number} size [description].
* @return {Array.<(?libtess.PQKey)>} [description] * @return {Array.<(?libtess.PQKey)>} [description].
*/ */
libtess.PriorityQ.prototype.PQKeyRealloc_ = function(oldArray, size) { libtess.PriorityQ.prototype.PQKeyRealloc_ = function(oldArray, size) {
// TODO(bckenny): double check return type. can we have ? there? // TODO(bckenny): double check return type. can we have ? there?
@@ -213,12 +220,13 @@ libtess.PriorityQ.prototype.PQKeyRealloc_ = function(oldArray, size) {
return newArray; return newArray;
}; };
/** /**
* [keyLessThan_ description] * [keyLessThan_ description]
* @private * @private
* @param {number} x [description] * @param {number} x [description].
* @param {number} y [description] * @param {number} y [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.PriorityQ.prototype.keyLessThan_ = function(x, y) { libtess.PriorityQ.prototype.keyLessThan_ = function(x, y) {
// NOTE(bckenny): was macro LT // NOTE(bckenny): was macro LT
@@ -227,12 +235,13 @@ libtess.PriorityQ.prototype.keyLessThan_ = function(x, y) {
return !this.leq_(keyY, keyX); return !this.leq_(keyY, keyX);
}; };
/** /**
* [keyGreaterThan_ description] * [keyGreaterThan_ description]
* @private * @private
* @param {number} x [description] * @param {number} x [description].
* @param {number} y [description] * @param {number} y [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.PriorityQ.prototype.keyGreaterThan_ = function(x, y) { libtess.PriorityQ.prototype.keyGreaterThan_ = function(x, y) {
// NOTE(bckenny): was macro GT // NOTE(bckenny): was macro GT
@@ -241,9 +250,10 @@ libtess.PriorityQ.prototype.keyGreaterThan_ = function(x, y) {
return !this.leq_(keyX, keyY); return !this.leq_(keyX, keyY);
}; };
/** /**
* [extractMin description] * [extractMin description]
* @return {libtess.PQKey} [description] * @return {libtess.PQKey} [description].
*/ */
libtess.PriorityQ.prototype.extractMin = function() { libtess.PriorityQ.prototype.extractMin = function() {
if (this.size_ === 0) { if (this.size_ === 0) {
@@ -265,9 +275,10 @@ libtess.PriorityQ.prototype.extractMin = function() {
return sortMin; return sortMin;
}; };
/** /**
* [minimum description] * [minimum description]
* @return {libtess.PQKey} [description] * @return {libtess.PQKey} [description].
*/ */
libtess.PriorityQ.prototype.minimum = function() { libtess.PriorityQ.prototype.minimum = function() {
if (this.size_ === 0) { if (this.size_ === 0) {
@@ -285,17 +296,19 @@ libtess.PriorityQ.prototype.minimum = function() {
return sortMin; return sortMin;
}; };
/** /**
* [isEmpty description] * [isEmpty description]
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.PriorityQ.prototype.isEmpty = function() { libtess.PriorityQ.prototype.isEmpty = function() {
return (this.size_ === 0) && this.heap_.isEmpty(); return (this.size_ === 0) && this.heap_.isEmpty();
}; };
/** /**
* [remove description] * [remove description]
* @param {libtess.PQHandle} curr [description] * @param {libtess.PQHandle} curr [description].
*/ */
libtess.PriorityQ.prototype.remove = function(curr) { libtess.PriorityQ.prototype.remove = function(curr) {
if (curr >= 0) { if (curr >= 0) {

View File

@@ -39,10 +39,12 @@
// TODO(bckenny): keys appear to always be GluVertex in this case? // TODO(bckenny): keys appear to always be GluVertex in this case?
/** /**
* [PriorityQHeap description] * [PriorityQHeap description]
* @constructor * @constructor
* @param {function(libtess.PQKey, libtess.PQKey): boolean} leq [description] * @param {function(libtess.PQKey, libtess.PQKey): boolean} leq [description].
*/ */
libtess.PriorityQHeap = function(leq) { libtess.PriorityQHeap = function(leq) {
/** /**
@@ -107,6 +109,7 @@ libtess.PriorityQHeap = function(leq) {
this.nodes_[1].handle = 1; this.nodes_[1].handle = 1;
}; };
/** /**
* [INIT_SIZE_ description] * [INIT_SIZE_ description]
* @private * @private
@@ -115,6 +118,7 @@ libtess.PriorityQHeap = function(leq) {
*/ */
libtess.PriorityQHeap.INIT_SIZE_ = 32; libtess.PriorityQHeap.INIT_SIZE_ = 32;
/** /**
* [deleteHeap description] * [deleteHeap description]
*/ */
@@ -125,6 +129,7 @@ libtess.PriorityQHeap.prototype.deleteHeap = function() {
// NOTE(bckenny): nulled at callsite in PriorityQ.deleteQ // NOTE(bckenny): nulled at callsite in PriorityQ.deleteQ
}; };
/** /**
* Initializing ordering of the heap. Must be called before any method other than * Initializing ordering of the heap. Must be called before any method other than
* insert is called to ensure correctness when removing or querying. * insert is called to ensure correctness when removing or querying.
@@ -138,6 +143,7 @@ libtess.PriorityQHeap.prototype.init = function() {
this.initialized_ = true; this.initialized_ = true;
}; };
/** /**
* Insert a new key into the heap. * Insert a new key into the heap.
* @param {libtess.PQKey} keyNew The key to insert. * @param {libtess.PQKey} keyNew The key to insert.
@@ -172,6 +178,7 @@ libtess.PriorityQHeap.prototype.insert = function(keyNew) {
return free; return free;
}; };
/** /**
* @return {boolean} Whether the heap is empty. * @return {boolean} Whether the heap is empty.
*/ */
@@ -179,19 +186,21 @@ libtess.PriorityQHeap.prototype.isEmpty = function() {
return this.size_ === 0; return this.size_ === 0;
}; };
/** /**
* Returns the minimum key in the heap. If the heap is empty, null will be * Returns the minimum key in the heap. If the heap is empty, null will be
* returned. * returned.
* @return {libtess.PQKey} [description] * @return {libtess.PQKey} [description].
*/ */
libtess.PriorityQHeap.prototype.minimum = function() { libtess.PriorityQHeap.prototype.minimum = function() {
return this.handles_[this.nodes_[1].handle].key; return this.handles_[this.nodes_[1].handle].key;
}; };
/** /**
* Removes the minimum key from the heap and returns it. If the heap is empty, * Removes the minimum key from the heap and returns it. If the heap is empty,
* null will be returned. * null will be returned.
* @return {libtess.PQKey} [description] * @return {libtess.PQKey} [description].
*/ */
libtess.PriorityQHeap.prototype.extractMin = function() { libtess.PriorityQHeap.prototype.extractMin = function() {
var n = this.nodes_; var n = this.nodes_;
@@ -215,9 +224,10 @@ libtess.PriorityQHeap.prototype.extractMin = function() {
return min; return min;
}; };
/** /**
* Remove key associated with handle hCurr (returned from insert) from heap. * Remove key associated with handle hCurr (returned from insert) from heap.
* @param {libtess.PQHandle} hCurr [description] * @param {libtess.PQHandle} hCurr [description].
*/ */
libtess.PriorityQHeap.prototype.remove = function(hCurr) { libtess.PriorityQHeap.prototype.remove = function(hCurr) {
var n = this.nodes_; var n = this.nodes_;
@@ -242,10 +252,11 @@ libtess.PriorityQHeap.prototype.remove = function(hCurr) {
this.freeList_ = hCurr; this.freeList_ = hCurr;
}; };
/** /**
* [floatDown_ description] * [floatDown_ description]
* @private * @private
* @param {libtess.PQHandle} curr [description] * @param {libtess.PQHandle} curr [description].
*/ */
libtess.PriorityQHeap.prototype.floatDown_ = function(curr) { libtess.PriorityQHeap.prototype.floatDown_ = function(curr) {
var n = this.nodes_; var n = this.nodes_;
@@ -274,10 +285,11 @@ libtess.PriorityQHeap.prototype.floatDown_ = function(curr) {
} }
}; };
/** /**
* [floatUp_ description] * [floatUp_ description]
* @private * @private
* @param {libtess.PQHandle} curr [description] * @param {libtess.PQHandle} curr [description].
*/ */
libtess.PriorityQHeap.prototype.floatUp_ = function(curr) { libtess.PriorityQHeap.prototype.floatUp_ = function(curr) {
var n = this.nodes_; var n = this.nodes_;

View File

@@ -46,6 +46,7 @@ libtess.render = function() {
}; };
/** /**
* [SIGN_INCONSISTENT_ description] * [SIGN_INCONSISTENT_ description]
* @type {number} * @type {number}
@@ -54,6 +55,7 @@ libtess.render = function() {
*/ */
libtess.render.SIGN_INCONSISTENT_ = 2; libtess.render.SIGN_INCONSISTENT_ = 2;
/** /**
* render.renderMesh(tess, mesh) takes a mesh and breaks it into triangle * render.renderMesh(tess, mesh) takes a mesh and breaks it into triangle
* fans, strips, and separate triangles. A substantial effort is made * fans, strips, and separate triangles. A substantial effort is made
@@ -62,8 +64,8 @@ libtess.render.SIGN_INCONSISTENT_ = 2;
* *
* The rendering output is provided as callbacks (see the api). * The rendering output is provided as callbacks (see the api).
* *
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.render.renderMesh = function(tess, mesh) { libtess.render.renderMesh = function(tess, mesh) {
// Make a list of separate triangles so we can render them all at once // Make a list of separate triangles so we can render them all at once
@@ -94,8 +96,8 @@ libtess.render.renderMesh = function(tess, mesh) {
* contour for each face marked "inside". The rendering output is * contour for each face marked "inside". The rendering output is
* provided as callbacks (see the api). * provided as callbacks (see the api).
* *
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.render.renderBoundary = function(tess, mesh) { libtess.render.renderBoundary = function(tess, mesh) {
for (var f = mesh.fHead.next; f !== mesh.fHead; f = f.next) { for (var f = mesh.fHead.next; f !== mesh.fHead; f = f.next) {
@@ -113,6 +115,7 @@ libtess.render.renderBoundary = function(tess, mesh) {
} }
}; };
/** /**
* render.renderCache(tess) takes a single contour and tries to render it * render.renderCache(tess) takes a single contour and tries to render it
* as a triangle fan. This handles convex polygons, as well as some * as a triangle fan. This handles convex polygons, as well as some
@@ -121,8 +124,8 @@ libtess.render.renderBoundary = function(tess, mesh) {
* Returns true if the polygon was successfully rendered. The rendering * Returns true if the polygon was successfully rendered. The rendering
* output is provided as callbacks (see the api). * output is provided as callbacks (see the api).
* *
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.render.renderCache = function(tess) { libtess.render.renderCache = function(tess) {
if (tess.cacheCount < 3) { if (tess.cacheCount < 3) {
@@ -196,18 +199,19 @@ libtess.render.renderCache = function(tess) {
/** /**
* Returns true if face has been marked temporarily. * Returns true if face has been marked temporarily.
* @private * @private
* @param {libtess.GluFace} f [description] * @param {libtess.GluFace} f [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.render.marked_ = function(f) { libtess.render.marked_ = function(f) {
// NOTE(bckenny): originally macro // NOTE(bckenny): originally macro
return (!f.inside || f.marked); return (!f.inside || f.marked);
}; };
/** /**
* [freeTrail description] * [freeTrail description]
* @private * @private
* @param {libtess.GluFace} t [description] * @param {libtess.GluFace} t [description].
*/ */
libtess.render.freeTrail_ = function(t) { libtess.render.freeTrail_ = function(t) {
// NOTE(bckenny): originally macro // NOTE(bckenny): originally macro
@@ -217,13 +221,14 @@ libtess.render.freeTrail_ = function(t) {
} }
}; };
/** /**
* eOrig.lFace is the face we want to render. We want to find the size * eOrig.lFace is the face we want to render. We want to find the size
* of a maximal fan around eOrig.org. To do this we just walk around * of a maximal fan around eOrig.org. To do this we just walk around
* the origin vertex as far as possible in both directions. * the origin vertex as far as possible in both directions.
* @private * @private
* @param {libtess.GluHalfEdge} eOrig [description] * @param {libtess.GluHalfEdge} eOrig [description].
* @return {libtess.FaceCount} [description] * @return {libtess.FaceCount} [description].
*/ */
libtess.render.maximumFan_ = function(eOrig) { libtess.render.maximumFan_ = function(eOrig) {
// TODO(bckenny): probably have dest FaceCount passed in (see renderMaximumFaceGroup) // TODO(bckenny): probably have dest FaceCount passed in (see renderMaximumFaceGroup)
@@ -254,6 +259,7 @@ libtess.render.maximumFan_ = function(eOrig) {
return newFace; return newFace;
}; };
/** /**
* Here we are looking for a maximal strip that contains the vertices * Here we are looking for a maximal strip that contains the vertices
* eOrig.org, eOrig.dst(), eOrig.lNext.dst() (in that order or the * eOrig.org, eOrig.dst(), eOrig.lNext.dst() (in that order or the
@@ -265,8 +271,8 @@ libtess.render.maximumFan_ = function(eOrig) {
* We walk the strip starting on a side with an even number of triangles; * We walk the strip starting on a side with an even number of triangles;
* if both side have an odd number, we are forced to shorten one side. * if both side have an odd number, we are forced to shorten one side.
* @private * @private
* @param {libtess.GluHalfEdge} eOrig [description] * @param {libtess.GluHalfEdge} eOrig [description].
* @return {libtess.FaceCount} [description] * @return {libtess.FaceCount} [description].
*/ */
libtess.render.maximumStrip_ = function(eOrig) { libtess.render.maximumStrip_ = function(eOrig) {
// TODO(bckenny): probably have dest FaceCount passed in (see renderMaximumFaceGroup) // TODO(bckenny): probably have dest FaceCount passed in (see renderMaximumFaceGroup)
@@ -335,14 +341,15 @@ libtess.render.maximumStrip_ = function(eOrig) {
return newFace; return newFace;
}; };
/** /**
* Render as many CCW triangles as possible in a fan starting from * Render as many CCW triangles as possible in a fan starting from
* edge "e". The fan *should* contain exactly "size" triangles * edge "e". The fan *should* contain exactly "size" triangles
* (otherwise we've goofed up somewhere). * (otherwise we've goofed up somewhere).
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluHalfEdge} e [description] * @param {libtess.GluHalfEdge} e [description].
* @param {number} size [description] * @param {number} size [description].
*/ */
libtess.render.renderFan_ = function(tess, e, size) { libtess.render.renderFan_ = function(tess, e, size) {
tess.callBeginOrBeginData(libtess.primitiveType.GL_TRIANGLE_FAN); tess.callBeginOrBeginData(libtess.primitiveType.GL_TRIANGLE_FAN);
@@ -360,14 +367,15 @@ libtess.render.renderFan_ = function(tess, e, size) {
tess.callEndOrEndData(); tess.callEndOrEndData();
}; };
/** /**
* Render as many CCW triangles as possible in a strip starting from * Render as many CCW triangles as possible in a strip starting from
* edge e. The strip *should* contain exactly "size" triangles * edge e. The strip *should* contain exactly "size" triangles
* (otherwise we've goofed up somewhere). * (otherwise we've goofed up somewhere).
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluHalfEdge} e [description] * @param {libtess.GluHalfEdge} e [description].
* @param {number} size [description] * @param {number} size [description].
*/ */
libtess.render.renderStrip_ = function(tess, e, size) { libtess.render.renderStrip_ = function(tess, e, size) {
tess.callBeginOrBeginData(libtess.primitiveType.GL_TRIANGLE_STRIP); tess.callBeginOrBeginData(libtess.primitiveType.GL_TRIANGLE_STRIP);
@@ -393,13 +401,14 @@ libtess.render.renderStrip_ = function(tess, e, size) {
tess.callEndOrEndData(); tess.callEndOrEndData();
}; };
/** /**
* Just add the triangle to a triangle list, so we can render all * Just add the triangle to a triangle list, so we can render all
* the separate triangles at once. * the separate triangles at once.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluHalfEdge} e [description] * @param {libtess.GluHalfEdge} e [description].
* @param {number} size [description] * @param {number} size [description].
*/ */
libtess.render.renderTriangle_ = function(tess, e, size) { libtess.render.renderTriangle_ = function(tess, e, size) {
libtess.assert(size === 1); libtess.assert(size === 1);
@@ -409,6 +418,7 @@ libtess.render.renderTriangle_ = function(tess, e, size) {
e.lFace.marked = true; e.lFace.marked = true;
}; };
/** /**
* We want to find the largest triangle fan or strip of unmarked faces * We want to find the largest triangle fan or strip of unmarked faces
* which includes the given face fOrig. There are 3 possible fans * which includes the given face fOrig. There are 3 possible fans
@@ -417,8 +427,8 @@ libtess.render.renderTriangle_ = function(tess, e, size) {
* is to try all of these, and take the primitive which uses the most * is to try all of these, and take the primitive which uses the most
* triangles (a greedy approach). * triangles (a greedy approach).
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluFace} fOrig [description] * @param {libtess.GluFace} fOrig [description].
*/ */
libtess.render.renderMaximumFaceGroup_ = function(tess, fOrig) { libtess.render.renderMaximumFaceGroup_ = function(tess, fOrig) {
var e = fOrig.anEdge; var e = fOrig.anEdge;
@@ -460,12 +470,13 @@ libtess.render.renderMaximumFaceGroup_ = function(tess, fOrig) {
max.render(tess, max.eStart, max.size); max.render(tess, max.eStart, max.size);
}; };
/** /**
* Now we render all the separate triangles which could not be * Now we render all the separate triangles which could not be
* grouped into a triangle fan or strip. * grouped into a triangle fan or strip.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluFace} head [description] * @param {libtess.GluFace} head [description].
*/ */
libtess.render.renderLonelyTriangles_ = function(tess, head) { libtess.render.renderLonelyTriangles_ = function(tess, head) {
// TODO(bckenny): edgeState needs to be boolean, but != on first call // TODO(bckenny): edgeState needs to be boolean, but != on first call
@@ -499,6 +510,7 @@ libtess.render.renderLonelyTriangles_ = function(tess, head) {
tess.callEndOrEndData(); tess.callEndOrEndData();
}; };
/** /**
* If check==false, we compute the polygon normal and place it in norm[]. * If check==false, we compute the polygon normal and place it in norm[].
* If check==true, we check that each triangle in the fan from v0 has a * If check==true, we check that each triangle in the fan from v0 has a
@@ -507,10 +519,10 @@ libtess.render.renderLonelyTriangles_ = function(tess, head) {
* are degenerate return 0; otherwise (no consistent orientation) return * are degenerate return 0; otherwise (no consistent orientation) return
* render.SIGN_INCONSISTENT_. * render.SIGN_INCONSISTENT_.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {Array.<number>} norm [description] * @param {Array.<number>} norm [description].
* @param {boolean} check [description] * @param {boolean} check [description].
* @return {number} int * @return {number} int.
*/ */
libtess.render.computeNormal_ = function(tess, norm, check) { libtess.render.computeNormal_ = function(tess, norm, check) {
/* Find the polygon normal. It is important to get a reasonable /* Find the polygon normal. It is important to get a reasonable

View File

@@ -39,15 +39,17 @@
// TODO(bckenny): Used only in private functions of render.js // TODO(bckenny): Used only in private functions of render.js
/** /**
* This structure remembers the information we need about a primitive * This structure remembers the information we need about a primitive
* to be able to render it later, once we have determined which * to be able to render it later, once we have determined which
* primitive is able to use the most triangles. * primitive is able to use the most triangles.
* *
* @constructor * @constructor
* @param {number} size [description] * @param {number} size [description].
* @param {libtess.GluHalfEdge} eStart [description] * @param {libtess.GluHalfEdge} eStart [description].
* @param {!function(libtess.GluTesselator, libtess.GluHalfEdge, number)} renderFunction [description] * @param {!function(libtess.GluTesselator, libtess.GluHalfEdge, number)} renderFunction [description].
*/ */
libtess.FaceCount = function(size, eStart, renderFunction) { libtess.FaceCount = function(size, eStart, renderFunction) {
/** /**

View File

@@ -74,6 +74,7 @@ libtess.sweep = function() {
}; };
/** /**
* Make the sentinel coordinates big enough that they will never be * Make the sentinel coordinates big enough that they will never be
* merged with real input features. (Even with the largest possible * merged with real input features. (Even with the largest possible
@@ -85,6 +86,7 @@ libtess.sweep = function() {
*/ */
libtess.sweep.SENTINEL_COORD_ = 4 * libtess.GLU_TESS_MAX_COORD; libtess.sweep.SENTINEL_COORD_ = 4 * libtess.GLU_TESS_MAX_COORD;
/** /**
* Because vertices at exactly the same location are merged together * Because vertices at exactly the same location are merged together
* before we process the sweep event, some degenerate cases can't occur. * before we process the sweep event, some degenerate cases can't occur.
@@ -98,6 +100,7 @@ libtess.sweep.SENTINEL_COORD_ = 4 * libtess.GLU_TESS_MAX_COORD;
*/ */
libtess.sweep.TOLERANCE_NONZERO_ = false; libtess.sweep.TOLERANCE_NONZERO_ = false;
/** /**
* computeInterior(tess) computes the planar arrangement specified * computeInterior(tess) computes the planar arrangement specified
* by the given contours, and further subdivides this arrangement * by the given contours, and further subdivides this arrangement
@@ -105,7 +108,7 @@ libtess.sweep.TOLERANCE_NONZERO_ = false;
* to the polygon, according to the rule given by tess.windingRule. * to the polygon, according to the rule given by tess.windingRule.
* Each interior region is guaranteed be monotone. * Each interior region is guaranteed be monotone.
* *
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.computeInterior = function(tess) { libtess.sweep.computeInterior = function(tess) {
tess.fatalError = false; tess.fatalError = false;
@@ -161,13 +164,12 @@ libtess.sweep.computeInterior = function(tess) {
}; };
/** /**
* When we merge two edges into one, we need to compute the combined * When we merge two edges into one, we need to compute the combined
* winding of the new edge. * winding of the new edge.
* @private * @private
* @param {libtess.GluHalfEdge} eDst [description] * @param {libtess.GluHalfEdge} eDst [description].
* @param {libtess.GluHalfEdge} eSrc [description] * @param {libtess.GluHalfEdge} eSrc [description].
*/ */
libtess.sweep.addWinding_ = function(eDst, eSrc) { libtess.sweep.addWinding_ = function(eDst, eSrc) {
// NOTE(bckenny): from AddWinding macro // NOTE(bckenny): from AddWinding macro
@@ -175,6 +177,7 @@ libtess.sweep.addWinding_ = function(eDst, eSrc) {
eDst.sym.winding += eSrc.sym.winding; eDst.sym.winding += eSrc.sym.winding;
}; };
/** /**
* Both edges must be directed from right to left (this is the canonical * Both edges must be directed from right to left (this is the canonical
* direction for the upper edge of each region). * direction for the upper edge of each region).
@@ -187,10 +190,10 @@ libtess.sweep.addWinding_ = function(eDst, eSrc) {
* we sort the edges by slope (they would otherwise compare equally). * we sort the edges by slope (they would otherwise compare equally).
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} reg1 [description] * @param {libtess.ActiveRegion} reg1 [description].
* @param {libtess.ActiveRegion} reg2 [description] * @param {libtess.ActiveRegion} reg2 [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.sweep.edgeLeq_ = function(tess, reg1, reg2) { libtess.sweep.edgeLeq_ = function(tess, reg1, reg2) {
var event = tess.event; var event = tess.event;
@@ -221,11 +224,12 @@ libtess.sweep.edgeLeq_ = function(tess, reg1, reg2) {
return (t1 >= t2); return (t1 >= t2);
}; };
/** /**
* [deleteRegion_ description] * [deleteRegion_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
*/ */
libtess.sweep.deleteRegion_ = function(tess, reg) { libtess.sweep.deleteRegion_ = function(tess, reg) {
if (reg.fixUpperEdge) { if (reg.fixUpperEdge) {
@@ -244,11 +248,12 @@ libtess.sweep.deleteRegion_ = function(tess, reg) {
// TODO(bckenny): may need to null at callsite // TODO(bckenny): may need to null at callsite
}; };
/** /**
* Replace an upper edge which needs fixing (see connectRightVertex). * Replace an upper edge which needs fixing (see connectRightVertex).
* @private * @private
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
* @param {libtess.GluHalfEdge} newEdge [description] * @param {libtess.GluHalfEdge} newEdge [description].
*/ */
libtess.sweep.fixUpperEdge_ = function(reg, newEdge) { libtess.sweep.fixUpperEdge_ = function(reg, newEdge) {
libtess.assert(reg.fixUpperEdge); libtess.assert(reg.fixUpperEdge);
@@ -259,11 +264,12 @@ libtess.sweep.fixUpperEdge_ = function(reg, newEdge) {
newEdge.activeRegion = reg; newEdge.activeRegion = reg;
}; };
/** /**
* Find the region above the uppermost edge with the same origin. * Find the region above the uppermost edge with the same origin.
* @private * @private
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
* @return {libtess.ActiveRegion} [description] * @return {libtess.ActiveRegion} [description].
*/ */
libtess.sweep.topLeftRegion_ = function(reg) { libtess.sweep.topLeftRegion_ = function(reg) {
var org = reg.eUp.org; var org = reg.eUp.org;
@@ -284,11 +290,12 @@ libtess.sweep.topLeftRegion_ = function(reg) {
return reg; return reg;
}; };
/** /**
* Find the region above the uppermost edge with the same destination. * Find the region above the uppermost edge with the same destination.
* @private * @private
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
* @return {libtess.ActiveRegion} [description] * @return {libtess.ActiveRegion} [description].
*/ */
libtess.sweep.topRightRegion_ = function(reg) { libtess.sweep.topRightRegion_ = function(reg) {
var dst = reg.eUp.dst(); var dst = reg.eUp.dst();
@@ -300,6 +307,7 @@ libtess.sweep.topRightRegion_ = function(reg) {
return reg; return reg;
}; };
/** /**
* Add a new active region to the sweep line, *somewhere* below "regAbove" * Add a new active region to the sweep line, *somewhere* below "regAbove"
* (according to where the new edge belongs in the sweep-line dictionary). * (according to where the new edge belongs in the sweep-line dictionary).
@@ -307,9 +315,9 @@ libtess.sweep.topRightRegion_ = function(reg) {
* Winding number and "inside" flag are not updated. * Winding number and "inside" flag are not updated.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regAbove [description] * @param {libtess.ActiveRegion} regAbove [description].
* @param {libtess.GluHalfEdge} eNewUp [description] * @param {libtess.GluHalfEdge} eNewUp [description].
*/ */
libtess.sweep.addRegionBelow_ = function(tess, regAbove, eNewUp) { libtess.sweep.addRegionBelow_ = function(tess, regAbove, eNewUp) {
var regNew = new libtess.ActiveRegion(); var regNew = new libtess.ActiveRegion();
@@ -321,12 +329,13 @@ libtess.sweep.addRegionBelow_ = function(tess, regAbove, eNewUp) {
return regNew; return regNew;
}; };
/** /**
* [isWindingInside_ description] * [isWindingInside_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {number} n int * @param {number} n int.
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.sweep.isWindingInside_ = function(tess, n) { libtess.sweep.isWindingInside_ = function(tess, n) {
switch (tess.windingRule) { switch (tess.windingRule) {
@@ -347,17 +356,19 @@ libtess.sweep.isWindingInside_ = function(tess, n) {
return false; return false;
}; };
/** /**
* [computeWinding_ description] * [computeWinding_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
*/ */
libtess.sweep.computeWinding_ = function(tess, reg) { libtess.sweep.computeWinding_ = function(tess, reg) {
reg.windingNumber = reg.regionAbove().windingNumber + reg.eUp.winding; reg.windingNumber = reg.regionAbove().windingNumber + reg.eUp.winding;
reg.inside = libtess.sweep.isWindingInside_(tess, reg.windingNumber); reg.inside = libtess.sweep.isWindingInside_(tess, reg.windingNumber);
}; };
/** /**
* Delete a region from the sweep line. This happens when the upper * Delete a region from the sweep line. This happens when the upper
* and lower chains of a region meet (at a vertex on the sweep line). * and lower chains of a region meet (at a vertex on the sweep line).
@@ -366,8 +377,8 @@ libtess.sweep.computeWinding_ = function(tess, reg) {
* changing, this face may not have even existed until now). * changing, this face may not have even existed until now).
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} reg [description] * @param {libtess.ActiveRegion} reg [description].
*/ */
libtess.sweep.finishRegion_ = function(tess, reg) { libtess.sweep.finishRegion_ = function(tess, reg) {
// TODO(bckenny): may need to null reg at callsite // TODO(bckenny): may need to null reg at callsite
@@ -380,6 +391,7 @@ libtess.sweep.finishRegion_ = function(tess, reg) {
libtess.sweep.deleteRegion_(tess, reg); libtess.sweep.deleteRegion_(tess, reg);
}; };
/** /**
* We are given a vertex with one or more left-going edges. All affected * We are given a vertex with one or more left-going edges. All affected
* edges should be in the edge dictionary. Starting at regFirst.eUp, * edges should be in the edge dictionary. Starting at regFirst.eUp,
@@ -393,10 +405,10 @@ libtess.sweep.finishRegion_ = function(tess, reg) {
* same as in the dictionary. * same as in the dictionary.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regFirst [description] * @param {libtess.ActiveRegion} regFirst [description].
* @param {libtess.ActiveRegion} regLast [description] * @param {libtess.ActiveRegion} regLast [description].
* @return {libtess.GluHalfEdge} [description] * @return {libtess.GluHalfEdge} [description].
*/ */
libtess.sweep.finishLeftRegions_ = function(tess, regFirst, regLast) { libtess.sweep.finishLeftRegions_ = function(tess, regFirst, regLast) {
var regPrev = regFirst; var regPrev = regFirst;
@@ -439,6 +451,7 @@ libtess.sweep.finishLeftRegions_ = function(tess, regFirst, regLast) {
return ePrev; return ePrev;
}; };
/** /**
* Purpose: insert right-going edges into the edge dictionary, and update * Purpose: insert right-going edges into the edge dictionary, and update
* winding numbers and mesh connectivity appropriately. All right-going * winding numbers and mesh connectivity appropriately. All right-going
@@ -450,12 +463,12 @@ libtess.sweep.finishLeftRegions_ = function(tess, regFirst, regLast) {
* should be null. * should be null.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @param {libtess.GluHalfEdge} eFirst [description] * @param {libtess.GluHalfEdge} eFirst [description].
* @param {libtess.GluHalfEdge} eLast [description] * @param {libtess.GluHalfEdge} eLast [description].
* @param {libtess.GluHalfEdge} eTopLeft [description] * @param {libtess.GluHalfEdge} eTopLeft [description].
* @param {boolean} cleanUp [description] * @param {boolean} cleanUp [description].
*/ */
libtess.sweep.addRightEdges_ = function(tess, regUp, eFirst, eLast, eTopLeft, cleanUp) { libtess.sweep.addRightEdges_ = function(tess, regUp, eFirst, eLast, eTopLeft, cleanUp) {
var firstTime = true; var firstTime = true;
@@ -515,14 +528,15 @@ libtess.sweep.addRightEdges_ = function(tess, regUp, eFirst, eLast, eTopLeft, cl
} }
}; };
/** /**
* [callCombine_ description] * [callCombine_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluVertex} isect [description] * @param {libtess.GluVertex} isect [description].
* @param {Array.<Object>} data [description] * @param {Array.<Object>} data [description].
* @param {Array.<number>} weights [description] * @param {Array.<number>} weights [description].
* @param {boolean} needed [description] * @param {boolean} needed [description].
*/ */
libtess.sweep.callCombine_ = function(tess, isect, data, weights, needed) { libtess.sweep.callCombine_ = function(tess, isect, data, weights, needed) {
// Copy coord data in case the callback changes it. // Copy coord data in case the callback changes it.
@@ -549,13 +563,14 @@ libtess.sweep.callCombine_ = function(tess, isect, data, weights, needed) {
} }
}; };
/** /**
* Two vertices with idential coordinates are combined into one. * Two vertices with idential coordinates are combined into one.
* e1.org is kept, while e2.org is discarded. * e1.org is kept, while e2.org is discarded.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluHalfEdge} e1 [description] * @param {libtess.GluHalfEdge} e1 [description].
* @param {libtess.GluHalfEdge} e2 [description] * @param {libtess.GluHalfEdge} e2 [description].
*/ */
libtess.sweep.spliceMergeVertices_ = function(tess, e1, e2) { libtess.sweep.spliceMergeVertices_ = function(tess, e1, e2) {
// TODO(bckenny): better way to init these? save them? // TODO(bckenny): better way to init these? save them?
@@ -568,6 +583,7 @@ libtess.sweep.spliceMergeVertices_ = function(tess, e1, e2) {
libtess.mesh.meshSplice(e1, e2); libtess.mesh.meshSplice(e1, e2);
}; };
/** /**
* Find some weights which describe how the intersection vertex is * Find some weights which describe how the intersection vertex is
* a linear combination of org and dst. Each of the two edges * a linear combination of org and dst. Each of the two edges
@@ -576,11 +592,11 @@ libtess.sweep.spliceMergeVertices_ = function(tess, e1, e2) {
* relative distance to "isect". * relative distance to "isect".
* *
* @private * @private
* @param {libtess.GluVertex} isect [description] * @param {libtess.GluVertex} isect [description].
* @param {libtess.GluVertex} org [description] * @param {libtess.GluVertex} org [description].
* @param {libtess.GluVertex} dst [description] * @param {libtess.GluVertex} dst [description].
* @param {Array.<number>} weights [description] * @param {Array.<number>} weights [description].
* @param {number} weightIndex Index into weights for first weight to supply * @param {number} weightIndex Index into weights for first weight to supply.
*/ */
libtess.sweep.vertexWeights_ = function(isect, org, dst, weights, weightIndex) { libtess.sweep.vertexWeights_ = function(isect, org, dst, weights, weightIndex) {
// TODO(bckenny): think through how we can use L1dist here and be correct for coords // TODO(bckenny): think through how we can use L1dist here and be correct for coords
@@ -599,17 +615,18 @@ libtess.sweep.vertexWeights_ = function(isect, org, dst, weights, weightIndex) {
isect.coords[2] += weights[i0] * org.coords[2] + weights[i1] * dst.coords[2]; isect.coords[2] += weights[i0] * org.coords[2] + weights[i1] * dst.coords[2];
}; };
/** /**
* We've computed a new intersection point, now we need a "data" pointer * We've computed a new intersection point, now we need a "data" pointer
* from the user so that we can refer to this new vertex in the * from the user so that we can refer to this new vertex in the
* rendering callbacks. * rendering callbacks.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluVertex} isect [description] * @param {libtess.GluVertex} isect [description].
* @param {libtess.GluVertex} orgUp [description] * @param {libtess.GluVertex} orgUp [description].
* @param {libtess.GluVertex} dstUp [description] * @param {libtess.GluVertex} dstUp [description].
* @param {libtess.GluVertex} orgLo [description] * @param {libtess.GluVertex} orgLo [description].
* @param {libtess.GluVertex} dstLo [description] * @param {libtess.GluVertex} dstLo [description].
*/ */
libtess.sweep.getIntersectData_ = function(tess, isect, orgUp, dstUp, orgLo, dstLo) { libtess.sweep.getIntersectData_ = function(tess, isect, orgUp, dstUp, orgLo, dstLo) {
// TODO(bckenny): called for every intersection event, should these be from a pool? // TODO(bckenny): called for every intersection event, should these be from a pool?
@@ -633,6 +650,7 @@ libtess.sweep.getIntersectData_ = function(tess, isect, orgUp, dstUp, orgLo, dst
libtess.sweep.callCombine_(tess, isect, data, weights, true); libtess.sweep.callCombine_(tess, isect, data, weights, true);
}; };
/** /**
* Check the upper and lower edge of regUp, to make sure that the * Check the upper and lower edge of regUp, to make sure that the
* eUp.org is above eLo, or eLo.org is below eUp (depending on which * eUp.org is above eLo, or eLo.org is below eUp (depending on which
@@ -659,9 +677,9 @@ libtess.sweep.getIntersectData_ = function(tess, isect, orgUp, dstUp, orgLo, dst
* Basically this is a combinatorial solution to a numerical problem. * Basically this is a combinatorial solution to a numerical problem.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.sweep.checkForRightSplice_ = function(tess, regUp) { libtess.sweep.checkForRightSplice_ = function(tess, regUp) {
// TODO(bckenny): fully learn how these two checks work // TODO(bckenny): fully learn how these two checks work
@@ -703,6 +721,7 @@ libtess.sweep.checkForRightSplice_ = function(tess, regUp) {
return true; return true;
}; };
/** /**
* Check the upper and lower edge of regUp to make sure that the * Check the upper and lower edge of regUp to make sure that the
* eUp.dst() is above eLo, or eLo.dst() is below eUp (depending on which * eUp.dst() is above eLo, or eLo.dst() is below eUp (depending on which
@@ -722,9 +741,9 @@ libtess.sweep.checkForRightSplice_ = function(tess, regUp) {
* other edge. * other edge.
* *
* @private * @private
* @param {libtess.GluTesselator} tess description] * @param {libtess.GluTesselator} tess description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.sweep.checkForLeftSplice_ = function(tess, regUp) { libtess.sweep.checkForLeftSplice_ = function(tess, regUp) {
var regLo = regUp.regionBelow(); var regLo = regUp.regionBelow();
@@ -760,6 +779,7 @@ libtess.sweep.checkForLeftSplice_ = function(tess, regUp) {
return true; return true;
}; };
/** /**
* Check the upper and lower edges of the given region to see if * Check the upper and lower edges of the given region to see if
* they intersect. If so, create the intersection and add it * they intersect. If so, create the intersection and add it
@@ -770,9 +790,9 @@ libtess.sweep.checkForLeftSplice_ = function(tess, regUp) {
* checked for intersections, and possibly regUp has been deleted. * checked for intersections, and possibly regUp has been deleted.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @return {boolean} [description] * @return {boolean} [description].
*/ */
libtess.sweep.checkForIntersect_ = function(tess, regUp) { libtess.sweep.checkForIntersect_ = function(tess, regUp) {
var regLo = regUp.regionBelow(); var regLo = regUp.regionBelow();
@@ -926,6 +946,7 @@ libtess.sweep.checkForIntersect_ = function(tess, regUp) {
return false; return false;
}; };
/** /**
* When the upper or lower edge of any region changes, the region is * When the upper or lower edge of any region changes, the region is
* marked "dirty". This routine walks through all the dirty regions * marked "dirty". This routine walks through all the dirty regions
@@ -934,8 +955,8 @@ libtess.sweep.checkForIntersect_ = function(tess, regUp) {
* new dirty regions can be created as we make changes to restore * new dirty regions can be created as we make changes to restore
* the invariants. * the invariants.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
*/ */
libtess.sweep.walkDirtyRegions_ = function(tess, regUp) { libtess.sweep.walkDirtyRegions_ = function(tess, regUp) {
var regLo = regUp.regionBelow(); var regLo = regUp.regionBelow();
@@ -1013,6 +1034,7 @@ libtess.sweep.walkDirtyRegions_ = function(tess, regUp) {
} }
}; };
/** /**
* Purpose: connect a "right" vertex vEvent (one where all edges go left) * Purpose: connect a "right" vertex vEvent (one where all edges go left)
* to the unprocessed portion of the mesh. Since there are no right-going * to the unprocessed portion of the mesh. Since there are no right-going
@@ -1045,9 +1067,9 @@ libtess.sweep.walkDirtyRegions_ = function(tess, regUp) {
* closest one, in which case we won't need to make any changes. * closest one, in which case we won't need to make any changes.
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @param {libtess.GluHalfEdge} eBottomLeft [description] * @param {libtess.GluHalfEdge} eBottomLeft [description].
*/ */
libtess.sweep.connectRightVertex_ = function(tess, regUp, eBottomLeft) { libtess.sweep.connectRightVertex_ = function(tess, regUp, eBottomLeft) {
var eTopLeft = eBottomLeft.oNext; var eTopLeft = eBottomLeft.oNext;
@@ -1096,14 +1118,15 @@ libtess.sweep.connectRightVertex_ = function(tess, regUp, eBottomLeft) {
libtess.sweep.walkDirtyRegions_(tess, regUp); libtess.sweep.walkDirtyRegions_(tess, regUp);
}; };
/** /**
* The event vertex lies exacty on an already-processed edge or vertex. * The event vertex lies exacty on an already-processed edge or vertex.
* Adding the new vertex involves splicing it into the already-processed * Adding the new vertex involves splicing it into the already-processed
* part of the mesh. * part of the mesh.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.ActiveRegion} regUp [description] * @param {libtess.ActiveRegion} regUp [description].
* @param {libtess.GluVertex} vEvent [description] * @param {libtess.GluVertex} vEvent [description].
*/ */
libtess.sweep.connectLeftDegenerate_ = function(tess, regUp, vEvent) { libtess.sweep.connectLeftDegenerate_ = function(tess, regUp, vEvent) {
var e = regUp.eUp; var e = regUp.eUp;
@@ -1161,6 +1184,7 @@ libtess.sweep.connectLeftDegenerate_ = function(tess, regUp, vEvent) {
libtess.sweep.addRightEdges_(tess, regUp, eTopRight.oNext, eLast, eTopLeft, true); libtess.sweep.addRightEdges_(tess, regUp, eTopRight.oNext, eLast, eTopLeft, true);
}; };
/** /**
* Connect a "left" vertex (one where both edges go right) * Connect a "left" vertex (one where both edges go right)
* to the processed portion of the mesh. Let R be the active region * to the processed portion of the mesh. Let R be the active region
@@ -1177,8 +1201,8 @@ libtess.sweep.connectLeftDegenerate_ = function(tess, regUp, vEvent) {
* - merging with an already-processed portion of U or L * - merging with an already-processed portion of U or L
* *
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluVertex} vEvent [description] * @param {libtess.GluVertex} vEvent [description].
*/ */
libtess.sweep.connectLeftVertex_ = function(tess, vEvent) { libtess.sweep.connectLeftVertex_ = function(tess, vEvent) {
// TODO(bckenny): tmp only used for sweep. better to keep tmp across calls? // TODO(bckenny): tmp only used for sweep. better to keep tmp across calls?
@@ -1228,12 +1252,13 @@ libtess.sweep.connectLeftVertex_ = function(tess, vEvent) {
} }
}; };
/** /**
* Does everything necessary when the sweep line crosses a vertex. * Does everything necessary when the sweep line crosses a vertex.
* Updates the mesh and the edge dictionary. * Updates the mesh and the edge dictionary.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {libtess.GluVertex} vEvent [description] * @param {libtess.GluVertex} vEvent [description].
*/ */
libtess.sweep.sweepEvent_ = function(tess, vEvent) { libtess.sweep.sweepEvent_ = function(tess, vEvent) {
tess.event = vEvent; // for access in edgeLeq_ // TODO(bckenny): wuh? tess.event = vEvent; // for access in edgeLeq_ // TODO(bckenny): wuh?
@@ -1279,12 +1304,13 @@ libtess.sweep.sweepEvent_ = function(tess, vEvent) {
} }
}; };
/** /**
* We add two sentinel edges above and below all other edges, * We add two sentinel edges above and below all other edges,
* to avoid special cases at the top and bottom. * to avoid special cases at the top and bottom.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
* @param {number} t [description] * @param {number} t [description].
*/ */
libtess.sweep.addSentinel_ = function(tess, t) { libtess.sweep.addSentinel_ = function(tess, t) {
var reg = new libtess.ActiveRegion(); var reg = new libtess.ActiveRegion();
@@ -1306,11 +1332,12 @@ libtess.sweep.addSentinel_ = function(tess, t) {
reg.nodeUp = tess.dict.insert(reg); reg.nodeUp = tess.dict.insert(reg);
}; };
/** /**
* We maintain an ordering of edge intersections with the sweep line. * We maintain an ordering of edge intersections with the sweep line.
* This order is maintained in a dynamic dictionary. * This order is maintained in a dynamic dictionary.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.initEdgeDict_ = function(tess) { libtess.sweep.initEdgeDict_ = function(tess) {
// TODO(bckenny): need to cast edgeLeq_? // TODO(bckenny): need to cast edgeLeq_?
@@ -1321,10 +1348,11 @@ libtess.sweep.initEdgeDict_ = function(tess) {
libtess.sweep.addSentinel_(tess, libtess.sweep.SENTINEL_COORD_); libtess.sweep.addSentinel_(tess, libtess.sweep.SENTINEL_COORD_);
}; };
/** /**
* [doneEdgeDict_ description] * [doneEdgeDict_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.doneEdgeDict_ = function(tess) { libtess.sweep.doneEdgeDict_ = function(tess) {
var fixedEdges = 0; var fixedEdges = 0;
@@ -1346,10 +1374,11 @@ libtess.sweep.doneEdgeDict_ = function(tess) {
tess.dict = null; tess.dict = null;
}; };
/** /**
* Remove zero-length edges, and contours with fewer than 3 vertices. * Remove zero-length edges, and contours with fewer than 3 vertices.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.removeDegenerateEdges_ = function(tess) { libtess.sweep.removeDegenerateEdges_ = function(tess) {
var eHead = tess.mesh.eHead; var eHead = tess.mesh.eHead;
@@ -1384,11 +1413,12 @@ libtess.sweep.removeDegenerateEdges_ = function(tess) {
} }
}; };
/** /**
* Construct priority queue and insert all vertices into it, which determines * Construct priority queue and insert all vertices into it, which determines
* the order in which vertices cross the sweep line. * the order in which vertices cross the sweep line.
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.initPriorityQ_ = function(tess) { libtess.sweep.initPriorityQ_ = function(tess) {
// TODO(bckenny): libtess.geom.vertLeq needs cast? // TODO(bckenny): libtess.geom.vertLeq needs cast?
@@ -1405,10 +1435,11 @@ libtess.sweep.initPriorityQ_ = function(tess) {
pq.init(); pq.init();
}; };
/** /**
* [donePriorityQ_ description] * [donePriorityQ_ description]
* @private * @private
* @param {libtess.GluTesselator} tess [description] * @param {libtess.GluTesselator} tess [description].
*/ */
libtess.sweep.donePriorityQ_ = function(tess) { libtess.sweep.donePriorityQ_ = function(tess) {
// TODO(bckenny): probably don't need deleteQ. check that function for comment // TODO(bckenny): probably don't need deleteQ. check that function for comment
@@ -1416,6 +1447,7 @@ libtess.sweep.donePriorityQ_ = function(tess) {
tess.pq = null; tess.pq = null;
}; };
/** /**
* Delete any degenerate faces with only two edges. walkDirtyRegions() * Delete any degenerate faces with only two edges. walkDirtyRegions()
* will catch almost all of these, but it won't catch degenerate faces * will catch almost all of these, but it won't catch degenerate faces
@@ -1431,7 +1463,7 @@ libtess.sweep.donePriorityQ_ = function(tess) {
* will sometimes be keeping a pointer to that edge. * will sometimes be keeping a pointer to that edge.
* *
* @private * @private
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.sweep.removeDegenerateFaces_ = function(mesh) { libtess.sweep.removeDegenerateFaces_ = function(mesh) {
var fNext; var fNext;

View File

@@ -41,6 +41,8 @@
// TODO(bckenny): apparently only visible outside of sweep for debugging routines. // TODO(bckenny): apparently only visible outside of sweep for debugging routines.
// find out if we can hide // find out if we can hide
/** /**
* For each pair of adjacent edges crossing the sweep line, there is * For each pair of adjacent edges crossing the sweep line, there is
* an ActiveRegion to represent the region between them. The active * an ActiveRegion to represent the region between them. The active
@@ -97,18 +99,20 @@ libtess.ActiveRegion = function() {
this.fixUpperEdge = false; this.fixUpperEdge = false;
}; };
/** /**
* [regionBelow description] * [regionBelow description]
* @return {libtess.ActiveRegion} [description] * @return {libtess.ActiveRegion} [description].
*/ */
libtess.ActiveRegion.prototype.regionBelow = function() { libtess.ActiveRegion.prototype.regionBelow = function() {
// TODO(bckenny): better typing? or is cast unavoidable // TODO(bckenny): better typing? or is cast unavoidable
return /** @type {libtess.ActiveRegion} */ (this.nodeUp.getPred().getKey()); return /** @type {libtess.ActiveRegion} */ (this.nodeUp.getPred().getKey());
}; };
/** /**
* [regionAbove description] * [regionAbove description]
* @return {libtess.ActiveRegion} [description] * @return {libtess.ActiveRegion} [description].
*/ */
libtess.ActiveRegion.prototype.regionAbove = function() { libtess.ActiveRegion.prototype.regionAbove = function() {
// TODO(bckenny): better typing? or is cast unavoidable // TODO(bckenny): better typing? or is cast unavoidable

View File

@@ -42,6 +42,7 @@ libtess.tessmono = function() {
}; };
/** /**
* tessellateMonoRegion(face) tessellates a monotone region * tessellateMonoRegion(face) tessellates a monotone region
* (what else would it do??). The region must consist of a single * (what else would it do??). The region must consist of a single
@@ -52,7 +53,7 @@ libtess.tessmono = function() {
* Tessellation consists of adding interior edges (actually pairs of * Tessellation consists of adding interior edges (actually pairs of
* half-edges), to split the region into non-overlapping triangles. * half-edges), to split the region into non-overlapping triangles.
* @private * @private
* @param {libtess.GluFace} face [description] * @param {libtess.GluFace} face [description].
*/ */
libtess.tessmono.tessellateMonoRegion_ = function(face) { libtess.tessmono.tessellateMonoRegion_ = function(face) {
/* The basic idea is explained in Preparata and Shamos (which I don''t /* The basic idea is explained in Preparata and Shamos (which I don''t
@@ -122,12 +123,13 @@ libtess.tessmono.tessellateMonoRegion_ = function(face) {
} }
}; };
/** /**
* tessellateInterior(mesh) tessellates each region of * tessellateInterior(mesh) tessellates each region of
* the mesh which is marked "inside" the polygon. Each such region * the mesh which is marked "inside" the polygon. Each such region
* must be monotone. * must be monotone.
* *
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.tessmono.tessellateInterior = function(mesh) { libtess.tessmono.tessellateInterior = function(mesh) {
var next; var next;
@@ -140,13 +142,14 @@ libtess.tessmono.tessellateInterior = function(mesh) {
} }
}; };
/** /**
* discardExterior(mesh) zaps (ie. sets to null) all faces * discardExterior(mesh) zaps (ie. sets to null) all faces
* which are not marked "inside" the polygon. Since further mesh operations * which are not marked "inside" the polygon. Since further mesh operations
* on null faces are not allowed, the main purpose is to clean up the * on null faces are not allowed, the main purpose is to clean up the
* mesh so that exterior loops are not represented in the data structure. * mesh so that exterior loops are not represented in the data structure.
* *
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
*/ */
libtess.tessmono.discardExterior = function(mesh) { libtess.tessmono.discardExterior = function(mesh) {
var next; var next;
@@ -159,6 +162,7 @@ libtess.tessmono.discardExterior = function(mesh) {
} }
}; };
/** /**
* setWindingNumber(mesh, value, keepOnlyBoundary) resets the * setWindingNumber(mesh, value, keepOnlyBoundary) resets the
* winding numbers on all edges so that regions marked "inside" the * winding numbers on all edges so that regions marked "inside" the
@@ -168,7 +172,7 @@ libtess.tessmono.discardExterior = function(mesh) {
* If keepOnlyBoundary is true, it also deletes all edges which do not * If keepOnlyBoundary is true, it also deletes all edges which do not
* separate an interior region from an exterior one. * separate an interior region from an exterior one.
* *
* @param {libtess.GluMesh} mesh [description] * @param {libtess.GluMesh} mesh [description].
* @param {number} value Winding number to set (int). * @param {number} value Winding number to set (int).
*/ */
libtess.tessmono.setWindingNumber = function(mesh, value, keepOnlyBoundary) { libtess.tessmono.setWindingNumber = function(mesh, value, keepOnlyBoundary) {