📄 polyhedralboundedsolidsetoperator.java
字号:
} else { cl = BonAminus; } break; } } } public String toString() { String msg = "Sector("; msg = msg + sector + " | "; switch ( cl ) { case ABOVE: msg = msg + " ABOVE"; break; case BELOW: msg = msg + " BELOW"; break; case ON: msg = msg + " ON"; break; case AinB: msg = msg + "AinB"; break; case AoutB: msg = msg + "AoutB"; break; case BinA: msg = msg + "BinA"; break; case BoutA: msg = msg + "BoutA"; break; case AonBplus: msg = msg + "AonBplus"; break; case AonBminus: msg = msg + "AonBminus"; break; case BonAplus: msg = msg + "BonAplus"; break; case BonAminus: msg = msg + "BonAminus"; break; default: msg = msg + "<INVALID!>"; break; } msg = msg + " "; if ( isWide ) { msg = msg + "(W) "; } //msg = msg + ", pos: " + position; switch ( situation ) { case COPLANAR_FACE: msg = msg + "<COPLANAR_FACE>"; break; case INPLANE_EDGE: msg = msg + "<INPLANE_EDGE>"; break; case CROSSING_EDGE: msg = msg + "<CROSSING_EDGE>"; break; default: msg = msg + "<UNDEFINED>"; break; } msg = msg + ")"; return msg; }}class _PolyhedralBoundedSolidSetOperatorVertexVertex extends PolyhedralBoundedSolidOperator{ public _PolyhedralBoundedSolidVertex va; public _PolyhedralBoundedSolidVertex vb; public String toString() { String msg = "(" + va + ") / (" + vb + "}"; return msg; }}class _PolyhedralBoundedSolidSetOperatorVertexFace extends PolyhedralBoundedSolidOperator{ public _PolyhedralBoundedSolidVertex v; public _PolyhedralBoundedSolidFace f; public String toString() { String msg = "{" + v + " / " + f + "}"; return msg; }}/**This class encapsulates the set operations algorithms for boundaryrepresentation solids in VitralSDK. Basically, this class implements theoriginal algorithm published in the paper [MANT1986] and in the secondpart of the book [MANT1988].The algorithm is structured in 5 big phases: 0. Calculate vertex/face and vertex/vertex crossings. 1. Classify and split for vertex/face cases. 2. Classify and split for vertex/vertex cases. 3. Connect. 4. Finish.Note that each big phase is controlled in a method (mark as "big phase" inits documentation).*/public class PolyhedralBoundedSolidSetOperator extends PolyhedralBoundedSolidOperator{ /** Debug flags. */ private static final int DEBUG_01_STRUCTURE = 0x01; private static final int DEBUG_02_GENERATOR = 0x02; private static final int DEBUG_03_VERTEXFACECLASIFFIER = 0x04; private static final int DEBUG_04_VERTEXVERTEXCLASIFFIER = 0x08; private static final int DEBUG_05_CONNECT = 0x10; private static final int DEBUG_06_FINISH = 0x20; private static final int DEBUG_99_SHOWOPERATIONS = 0x20; /** The integer `debugFlags` is a bitwise combination of debugging flags used to control debug messages printed on the standard output. */ private static int debugFlags = 0; /** Following variable `sonvv` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorVertexVertex> sonvv; /** Following variable `sonva` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorVertexFace> sonva; /** Following variable `sonvb` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorVertexFace> sonvb; /** Following variable `sonea` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorNullEdge> sonea; /** Following variable `soneb` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorNullEdge> soneb; /** Following variable `sonfa` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidFace> sonfa; /** Following variable `sonfb` from program [MANT1988].15.1. */ private static ArrayList<_PolyhedralBoundedSolidFace> sonfb; /** Following variable `nba` from program [MANT1988].15.6. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnVertex> nba; /** Following variable `nba` from program [MANT1988].15.6. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnVertex> nbb; /** Following variable `sectors` from program [MANT1988].15.6. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnSector> sectors; /** Following variable `endsa` from program [MANT1988].15.13. */ private static ArrayList<_PolyhedralBoundedSolidHalfEdge> endsa; /** Following variable `endsb` from program [MANT1988].15.13. */ private static ArrayList<_PolyhedralBoundedSolidHalfEdge> endsb; /** Procedure `updmaxnames` functionality is described on section [MANT1988].15.4. This method increments the face and vertex identifiers of `solidToUpdate` so that they do not overlap with `referenceSolid` identifiers. */ private static void updmaxnames(PolyhedralBoundedSolid solidToUpdate, PolyhedralBoundedSolid referenceSolid) { _PolyhedralBoundedSolidVertex v; _PolyhedralBoundedSolidFace f; int i; for ( i = 0; i < solidToUpdate.verticesList.size(); i++ ) { v = solidToUpdate.verticesList.get(i); v.id += referenceSolid.getMaxVertexId(); if ( v.id > solidToUpdate.maxVertexId ) { solidToUpdate.maxVertexId = v.id; } } for ( i = 0; i < solidToUpdate.polygonsList.size(); i++ ) { f = solidToUpdate.polygonsList.get(i); f.id += referenceSolid.getMaxFaceId(); if ( f.id > solidToUpdate.maxFaceId ) { solidToUpdate.maxFaceId = f.id; } } } /** */ private static int nextVertexId(PolyhedralBoundedSolid current, PolyhedralBoundedSolid other) { int a, b, m; a = current.getMaxVertexId(); b = other.getMaxVertexId(); m = a; if ( b > a ) { m = b; } return m+1; } /** */ private static void addsovf(_PolyhedralBoundedSolidHalfEdge he, _PolyhedralBoundedSolidFace f, int BvsA) { //----------------------------------------------------------------- _PolyhedralBoundedSolidSetOperatorVertexFace elem; ArrayList<_PolyhedralBoundedSolidSetOperatorVertexFace> sonv; if ( BvsA == 0 ) { sonv = sonva; } else { sonv = sonvb; } int i; for ( i = 0; i < sonv.size(); i++ ) { elem = sonv.get(i); if ( elem.v == he.startingVertex && elem.f == f ) { return; } } //----------------------------------------------------------------- elem = new _PolyhedralBoundedSolidSetOperatorVertexFace(); elem.v = he.startingVertex; elem.f = f; sonv.add(elem); } /** */ private static void addsovv(_PolyhedralBoundedSolidVertex a, _PolyhedralBoundedSolidVertex b, int BvsA) { //----------------------------------------------------------------- _PolyhedralBoundedSolidSetOperatorVertexVertex elem; int i; for ( i = 0; i < sonvv.size(); i++ ) { elem = sonvv.get(i); if ( BvsA == 0 && elem.va == a && elem.vb == b || BvsA != 0 && elem.va == b && elem.vb == a ) { return; } } //----------------------------------------------------------------- elem = new _PolyhedralBoundedSolidSetOperatorVertexVertex(); if ( BvsA == 0 ) { elem.va = a; elem.vb = b; } else { elem.va = b; elem.vb = a; } sonvv.add(elem); } /** Following [MANT1988].15.4. */ private static void doVertexOnFace( _PolyhedralBoundedSolidVertex v, _PolyhedralBoundedSolidFace f, int BvsA, PolyhedralBoundedSolid current, PolyhedralBoundedSolid other) { int cont; double d; d = f.containingPlane.pointDistance(v.position); if ( PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON) == 0 ) { cont = cont = f.testPointInside(v.position, VSDK.EPSILON); if ( cont == Geometry.INSIDE ) { addsovf(v.emanatingHalfEdge, f, BvsA); } else if ( cont == Geometry.LIMIT && f.lastIntersectedHalfedge != null ) { current.lmev( f.lastIntersectedHalfedge, f.lastIntersectedHalfedge.mirrorHalfEdge().next(), nextVertexId(current, other), v.position); addsovv(v, f.lastIntersectedHalfedge.startingVertex, BvsA); } else if ( cont == Geometry.LIMIT && f.lastIntersectedVertex != null ) { addsovv(v, f.lastIntersectedVertex, BvsA); } } } /** Following program [MANT1988].3. */ private static void doSetOpGenerate( _PolyhedralBoundedSolidEdge e, _PolyhedralBoundedSolidFace f, int BvsA, PolyhedralBoundedSolid current, PolyhedralBoundedSolid other) { _PolyhedralBoundedSolidVertex v1, v2; double d1, d2, d3, t; Vector3D p; int s1, s2, cont; v1 = e.rightHalf.startingVertex; v2 = e.leftHalf.startingVertex; d1 = f.containingPlane.pointDistance(v1.position); d2 = f.containingPlane.pointDistance(v2.position); s1 = PolyhedralBoundedSolid.compareValue(d1, 0.0, VSDK.EPSILON); s2 = PolyhedralBoundedSolid.compareValue(d2, 0.0, VSDK.EPSILON); if ( (s1 == -1 && s2 == 1) || (s1 == 1 && s2 == -1) ) { t = d1 / (d1 - d2); p = v1.position.add( (v2.position.substract( v1.position)).multiply(t)); d3 = f.containingPlane.pointDistance(p); if ( PolyhedralBoundedSolid.compareValue(d3, 0.0, VSDK.EPSILON) == 0 ) { cont = f.testPointInside(p, VSDK.EPSILON); if ( cont != Geometry.OUTSIDE ) { current.lmev(e.rightHalf, e.leftHalf.next(), nextVertexId(current, other), p); if ( cont == Geometry.INSIDE ) { // Reduction step phase 5/6: Edge crosses inside a face // No subdivide? // Reduction step phase 7/8: stop vertex/face addsovf(e.rightHalf, f, BvsA); } else if ( cont == Geometry.LIMIT && f.lastIntersectedHalfedge != null ) { // Reduction step phase 1: Edge crosses other edge // Subdivide both edges (here one of them, the other // is this same code but when called from other solid), // at their intersection point (`p`), i.e. replace // each edge by two edges and a new vertex lying at `p`. current.lmev(f.lastIntersectedHalfedge, f.lastIntersectedHalfedge.mirrorHalfEdge().next(), nextVertexId(current, other), p); // Reduction step phase 4: store vertex/vertex addsovv(e.rightHalf.startingVertex, f.lastIntersectedHalfedge.startingVertex, BvsA); } else if ( cont == Geometry.LIMIT && f.lastIntersectedVertex != null ) { // Reduction step phase 2/3: Edge touches vertex // No subdivide? // Reduction step phase 4: store vertex/vertex
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -