?? polyhedralboundedsolidsetoperator.java
字號:
addsovv(e.rightHalf.startingVertex, f.lastIntersectedVertex, BvsA); } processEdge(e.rightHalf.previous().parentEdge, current, BvsA, other); } } } else { if ( s1 == 0 ) { doVertexOnFace(v1, f, BvsA, current, other); } if ( s2 == 0 ) { doVertexOnFace(v2, f, BvsA, current, other); } } } /** Following program [MANT1988].15.2. */ private static void processEdge(_PolyhedralBoundedSolidEdge e, PolyhedralBoundedSolid s, int BvsA, PolyhedralBoundedSolid other) { _PolyhedralBoundedSolidFace f; int i; for ( i = 0; i < s.polygonsList.size(); i++ ) { f = s.polygonsList.get(i); doSetOpGenerate(e, f, BvsA, s, other); } } /** Initial vertex intersection detector for the set operations algorithm (big phase 0). Following program [MANT1988].15.2. */ private static void setOpGenerate(PolyhedralBoundedSolid inSolidA, PolyhedralBoundedSolid inSolidB) { _PolyhedralBoundedSolidEdge e; sonvv = new ArrayList<_PolyhedralBoundedSolidSetOperatorVertexVertex>(); sonva = new ArrayList<_PolyhedralBoundedSolidSetOperatorVertexFace>(); sonvb = new ArrayList<_PolyhedralBoundedSolidSetOperatorVertexFace>(); int i; for ( i = 0; i < inSolidA.edgesList.size(); i++ ) { e = inSolidA.edgesList.get(i); processEdge(e, inSolidB, 0, inSolidA); } for ( i = 0; i < inSolidB.edgesList.size(); i++ ) { e = inSolidB.edgesList.get(i); processEdge(e, inSolidA, 1, inSolidB); } } /** Current method is the first step for the initial vertex/face classification of sectors (vertex neighborhood) for `vtx`, as indicated on section [MANT1988].14.5.2. and program [MANT1988].14.4., but biased towards the set operator classifier, as proposed on section [MANT1988].15.6.1. and problem [MANT1988].15.4. Vitral SDK's implementation of this procedure extends the original from [MANT1988] by adding extra information flags to sector classifications `.isWide`, `.position` and `.situation`. Those flags are an additional aid for debugging purposes and specifically the `situation` flag will be later used on `splitClassify` to correct the ordering of sectors in order to keep consistency with Vitral SDK's interpretation of coordinate system. */ private static ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> vertexFaceGetNeighborhood( _PolyhedralBoundedSolidVertex vtx, InfinitePlane referencePlane, int BvsA) { _PolyhedralBoundedSolidHalfEdge he; Vector3D bisect; double d; _PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace c; ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> neighborSectorsInfo; neighborSectorsInfo = new ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace>(); he = vtx.emanatingHalfEdge; do { c = new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace(); c.sector = he; d = referencePlane.pointDistance((he.next()).startingVertex.position); c.cl = PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON); c.isWide = false; c.position = new Vector3D((he.next()).startingVertex.position); c.situation = c.UNDEFINED; c.referencePlane = referencePlane; neighborSectorsInfo.add(c); if ( checkWideness(he) ) { bisect = inside(he).add(vtx.position); c.situation = c.CROSSING_EDGE; c = new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace(); c.sector = he; d = referencePlane.pointDistance(bisect); c.cl = PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON); c.isWide = true; c.position = new Vector3D(bisect); c.situation = c.CROSSING_EDGE; c.referencePlane = referencePlane; neighborSectorsInfo.add(c); } he = (he.mirrorHalfEdge()).next(); } while ( he != vtx.emanatingHalfEdge ); //----------------------------------------------------------------- // Extra pass, not from original [MANT1988] code int i; for ( i = 0; i < neighborSectorsInfo.size(); i++ ) { c = neighborSectorsInfo.get(i); if ( c.cl == c.ON && c.situation == c.UNDEFINED ) { c.situation = c.INPLANE_EDGE; } } return neighborSectorsInfo; } /** Current method applies the first reclassification rule presented at sections [MANT1988].14.5.1 and [MANT1988].14.5.2., but biased towards the set operator classifier, as proposed on section [MANT1988].15.6.1. and problem [MANT1988].15.4.: For the given vertex neigborhood, classify each edge according to whether its final vertex lies above (out), on or below (in) the `referencePlane`. Tag the edge with the corresponding label ABOVE, ON or BELOW. Following program [MANT1988].14.5. */ private static void vertexFaceReclassifyOnSectorsNoPeekVersion( ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> nbr, InfinitePlane referencePlane, int BvsA, int op) { _PolyhedralBoundedSolidFace f; Vector3D c; double d; int i; int nnbr = nbr.size(); _PolyhedralBoundedSolidSetOperatorSectorClassificationOnSector ni; ni = new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnSector(); //----------------------------------------------------------------- // Backup neighborhood to prevent empty case ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> backup; backup = new ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace>(); for ( i = 0; i < nnbr; i++ ) { backup.add(new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace(nbr.get(i))); } //----------------------------------------------------------------- // Only will be activated if non empty case result (force to intersect) for ( i = 0; i < nnbr; i++ ) { // Test coplanarity f = nbr.get(i).sector.parentLoop.parentFace; c = f.containingPlane.getNormal().crossProduct(referencePlane.getNormal()); d = c.dotProduct(c); if ( PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON) == 0 ) { // Entering this means "faces are coplanar" //System.out.println("**** UNTESTED CASE!"); d = f.containingPlane.getNormal().dotProduct(referencePlane.getNormal()); if ( PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON) == 1 ) { // Identical if ( BvsA != 0 ) { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } else { nbr.get(i).cl = (op == UNION)?ni.OUT:ni.IN; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.OUT:ni.IN; } } else { // Opposite if ( BvsA != 0 ) { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } else { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } } } } //----------------------------------------------------------------- // Restore original neighborhood if result is empty case int ins = 0; int outs = 0; for ( i = 0; i < nnbr; i++ ) { if ( nbr.get(i).cl == ni.OUT ) { outs++; } else { ins++; } } if ( outs == nnbr || ins == nnbr) { //System.out.println("**** WRONG ON SECTOR RECLASSIFICATION! REVERSED!"); for ( i = 0; i < nnbr; i++ ) { nbr.get(i).cl = backup.get(i).cl; //nbr.get(i).reverse = true; } } } /** Current method applies the first reclassification rule presented at sections [MANT1988].14.5.1 and [MANT1988].14.5.2., but biased towards the set operator classifier, as proposed on section [MANT1988].15.6.1. and problem [MANT1988].15.4.: For the given vertex neigborhood, classify each edge according to whether its final vertex lies above (out), on or below (in) the `referencePlane`. Tag the edge with the corresponding label ABOVE, ON or BELOW. Following program [MANT1988].14.5. ----------------------------------------------------------------- Reclassification procedure for "on"-sectors on the vertex/face clasiffier, Original answer from [.WMANT2008]. */ private static void vertexFaceReclassifyOnSectors( ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> nbr, InfinitePlane referencePlane, int BvsA, int op) { _PolyhedralBoundedSolidFace f; Vector3D c; double d; int i; int nnbr = nbr.size(); _PolyhedralBoundedSolidSetOperatorSectorClassificationOnSector ni; ni = new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnSector(); //----------------------------------------------------------------- // Backup neighborhood to prevent empty case ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> backup; backup = new ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace>(); for ( i = 0; i < nnbr; i++ ) { backup.add(new _PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace(nbr.get(i))); } //----------------------------------------------------------------- // Only will be activated if non empty case result (force to intersect) for ( i = 0; i < nnbr; i++ ) { // Test coplanarity f = nbr.get(i).sector.mirrorHalfEdge().parentLoop.parentFace; c = f.containingPlane.getNormal().crossProduct(referencePlane.getNormal()); d = c.dotProduct(c); if ( PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON) == 0 ) { // Entering this means "faces are coplanar" d = f.containingPlane.getNormal().dotProduct(referencePlane.getNormal()); // Test orientation if ( PolyhedralBoundedSolid.compareValue(d, 0.0, VSDK.EPSILON) == 1 ) { // Identical if ( BvsA != 0 ) { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } else { nbr.get(i).cl = (op == UNION)?ni.OUT:ni.IN; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.OUT:ni.IN; } } else { // Opposite if ( BvsA != 0 ) { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } else { nbr.get(i).cl = (op == UNION)?ni.IN:ni.OUT; nbr.get((i+1)%nnbr).cl = (op == UNION)?ni.IN:ni.OUT; } } } } //----------------------------------------------------------------- // Restore original neighborhood if result is empty case int ins = 0; int outs = 0; for ( i = 0; i < nnbr; i++ ) { if ( nbr.get(i).cl == ni.OUT ) { outs++; } else { ins++; } } if ( outs == nnbr || ins == nnbr) { System.out.println("**** WRONG ON SECTOR RECLASSIFICATION! REVERSED!"); for ( i = 0; i < nnbr; i++ ) { nbr.get(i).cl = backup.get(i).cl; //nbr.get(i).reverse = true; } } } private static void printNbr(ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> neighborSectorsInfo) { int i; for ( i = 0; i < neighborSectorsInfo.size(); i++ ) { System.out.println(" . " + neighborSectorsInfo.get(i)); } } private static boolean inplaneEdgesOn( ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> nbr) { int i; for ( i = 0; i < nbr.size(); i++ ) { if ( nbr.get(i).situation == nbr.get(i).INPLANE_EDGE ) return true; } return false; } private static void vertexFaceReclassifyOnEdges( ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> nbr, int op, boolean useBorrowed) { if ( useBorrowed ) { vertexFaceReclassifyOnEdgesBorrowed(nbr, op); } else { vertexFaceReclassifyOnEdgesNoPeekVersion(nbr, op); } } /** Current method implements the set of changes from table [MANT1988].15.3. for the reclassification rules. */ private static void vertexFaceReclassifyOnEdgesNoPeekVersion( ArrayList<_PolyhedralBoundedSolidSetOperatorSectorClassificationOnFace> nbr, int op)
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -