123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228 |
- import { HalfEdge } from './HalfEdge';
- import { Vector3 } from '../Vector3';
- import { Triangle } from '../Triangle';
- import { Visible, NonConvex, Deleted } from '../../constants';
- /**
- * @author Mugen87 / https://github.com/Mugen87
- *
- */
- function Face() {
- this.normal = new Vector3();
- this.midpoint = new Vector3();
- this.area = 0;
- this.constant = 0; // signed distance from face to the origin
- this.outside = null; // reference to the a vertex in a vertex list this face can see
- this.mark = Visible;
- this.edge = null;
- }
- Object.assign( Face, {
- create: function( a, b, c ) {
- var face = new Face();
- var e0 = new HalfEdge( a, face );
- var e1 = new HalfEdge( b, face );
- var e2 = new HalfEdge( c, face );
- // join edges
- e0.next = e2.prev = e1;
- e1.next = e0.prev = e2;
- e2.next = e1.prev = e0;
- // main half edge reference
- face.edge = e0;
- return face.compute();
- }
- } );
- Object.assign( Face.prototype, {
- getEdge: function ( i ) {
- var edge = this.edge;
- while ( i > 0 ) {
- edge = edge.next;
- i --;
- }
- while ( i < 0 ) {
- edge = edge.prev;
- i ++;
- }
- return edge;
- },
- compute: function () {
- var triangle;
- return function compute () {
- if ( triangle === undefined ) triangle = new Triangle();
- var a = this.edge.tail();
- var b = this.edge.head();
- var c = this.edge.next.head();
- triangle.set( a.point, b.point, c.point );
- triangle.normal( this.normal );
- triangle.midpoint( this.midpoint );
- this.area = triangle.area();
- this.constant = this.normal.dot( this.midpoint );
- return this;
- };
- }(),
- distanceToPoint: function ( point ) {
- return this.normal.dot( point ) - this.constant;
- },
- // Connects two edges assuming that prev.head().point === next.tail().point
- connectHalfEdges: function ( prev, next ) {
- var discardedFace;
- if ( prev.twin.face === next.twin.face ) {
- var oppositeFace = next.twin.face;
- var twinEdge;
- if ( prev === this.edge ) {
- this.edge = next;
- }
- twinEdge = next.twin.prev.twin;
- oppositeFace.mark = Deleted;
- discardedFace = oppositeFace;
- next.prev = prev.prev;
- next.prev.next = next;
- next.setTwin( twinEdge );
- oppositeFace.compute();
- } else {
- prev.next = next;
- next.prev = prev;
- }
- return discardedFace;
- },
- mergeAdjacentFaces: function( adjacentEdge, discardedFaces ) {
- var twinEdge = adjacentEdge.twin;
- var oppositeFace = twinEdge.face;
- discardedFaces.push( oppositeFace );
- oppositeFace.mark = Deleted;
- // find the chain of edges whose opposite face is 'oppositeFace'
- var adjacentEdgePrev = adjacentEdge.prev;
- var adjacentEdgeNext = adjacentEdge.next;
- var twinEdgePrev = twinEdge.prev;
- var twinEdgeNext = twinEdge.next;
- // left edge
- while ( adjacentEdgePrev.twin.face === oppositeFace ) {
- adjacentEdgePrev = adjacentEdgePrev.prev;
- twinEdgeNext = twinEdgeNext.next;
- }
- // right edge
- while ( adjacentEdgeNext.twin.face === oppositeFace ) {
- adjacentEdgeNext = adjacentEdgeNext.next;
- twinEdgePrev = twinEdgePrev.prev;
- }
- // fix the face reference of all the twin edges that are not part of
- // the edges whose opposite face is not 'face' i.e. all the edges that
- // 'face' and 'oppositeFace' do not have in common
- var edge = twinEdgeNext;
- do {
- edge.face = this;
- edge = edge.next;
- } while ( edge !== twinEdgePrev.next );
- // make sure that 'face.edge' is not one of the edges to be destroyed
- // Note: it's important for it to be a 'next' edge since 'prev' edges
- // might be destroyed on 'connectHalfEdges'
- this.edge = adjacentEdgeNext;
- // connect the extremes
- // Note: it might be possible that after connecting the edges a triangular face might be redundant
- var discardedFace;
- discardedFace = this.connectHalfEdges( twinEdgePrev, adjacentEdgeNext );
- if ( discardedFace !== undefined ) {
- discardedFaces.push( discardedFace );
- }
- discardedFace = this.connectHalfEdges( adjacentEdgePrev, twinEdgeNext );
- if ( discardedFace !== undefined ) {
- discardedFaces.push( discardedFace );
- }
- this.compute();
- return discardedFaces;
- }
- } );
- export { Face };
|