//Half-Edge Mesh //Source: http://www.flipcode.com/archives/The_Half-Edge_Data_Structure.shtml class HE_Mesh{ ArrayList vertices; ArrayList faces; ArrayList halfEdges; ArrayList edges; PVector bodyCenter; ArrayList faceCenters; ArrayList faceNormals; ArrayList vertexNormals; ArrayList edgeCenters; ArrayList edgeNormals; boolean bodyCenterUpdated; boolean faceCentersUpdated; boolean faceNormalsUpdated; boolean vertexNormalsUpdated; boolean edgeCentersUpdated; boolean edgeNormalsUpdated; boolean indicesUpdated; boolean lastOperationFailed; //CONSTRUCTOR HE_Mesh(){ vertices=new ArrayList(); faces=new ArrayList(); halfEdges=new ArrayList(); edges=new ArrayList(); faceCenters=new ArrayList(); faceNormals=new ArrayList(); vertexNormals=new ArrayList(); edgeCenters=new ArrayList(); edgeNormals=new ArrayList(); bodyCenter=new PVector(0,0,0) ; bodyCenterUpdated=false; faceCentersUpdated=false; faceNormalsUpdated=false; vertexNormalsUpdated=false; edgeCentersUpdated=false; edgeNormalsUpdated=false; indicesUpdated=false; } //DRAWING ROUTINES void draw(){ if(!faceCentersUpdated) setFaceCenters(); Iterator faceItr = faces.iterator(); Iterator faceCtrItr = faceCenters.iterator(); while(faceItr.hasNext()){ HE_Face face=(HE_Face)faceItr.next(); HE_Vertex faceCenter =(HE_Vertex)faceCtrItr.next(); if(face.visible){ HE_HalfEdge halfEdge=face.halfEdge; beginShape(TRIANGLE_STRIP); do{ HE_Vertex v=halfEdge.vert; vertex(v.x,v.y,v.z); vertex(faceCenter.x,faceCenter.y,faceCenter.z); halfEdge= halfEdge.next; } while(halfEdge!=face.halfEdge); HE_Vertex v=halfEdge.vert; vertex(v.x,v.y,v.z); endShape(); //} } } } void drawVertices(float s){ Iterator vertexItr = vertices.iterator(); while(vertexItr.hasNext()){ HE_Vertex v=(HE_Vertex)vertexItr.next(); pushMatrix(); translate(v.x,v.y,v.z); box(s); popMatrix(); } } void drawFaceCenters(){ Iterator vertexItr = faceCenters.iterator(); while(vertexItr.hasNext()){ HE_Vertex v=(HE_Vertex)vertexItr.next(); pushMatrix(); translate(v.x,v.y,v.z); box(5); popMatrix(); } } void drawEdgeCenters(){ Iterator vertexItr = edgeCenters.iterator(); while(vertexItr.hasNext()){ HE_Vertex v=(HE_Vertex)vertexItr.next(); pushMatrix(); translate(v.x,v.y,v.z); box(5); popMatrix(); } } void drawEdges(boolean all){ Iterator eItr = edges.iterator(); while(eItr.hasNext()){ HE_Edge e=(HE_Edge)eItr.next(); if((e.visible)||(all))line(e.halfEdge.vert.x,e.halfEdge.vert.y,e.halfEdge.vert.z,e.halfEdge.next.vert.x,e.halfEdge.next.vert.y,e.halfEdge.next.vert.z); } } void drawEdgesSketch(int r, float d){ for(int i=0;i0) v.set(rotatePointAboutAxis(v,i*a,p1,p2)); result.vertices.add(v); } } for(int i=0;ithreshold) type+=1; if(v1>threshold) type+=2; if(v2>threshold) type+=4; if(v3>threshold) type+=8; HE_Face f=new HE_Face(); HE_HalfEdge he0=new HE_HalfEdge(); HE_HalfEdge he1=new HE_HalfEdge(); HE_HalfEdge he2=new HE_HalfEdge(); switch(type) { case 0: case 15: break; case 1: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 14: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 2: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 13: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 3: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 12: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 4: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 11: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 5: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 10: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i2))+"_"+str(max(i1,i2))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 6: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 9: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i1))+"_"+str(max(i0,i1))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); f=new HE_Face(); he0=new HE_HalfEdge(); he1=new HE_HalfEdge(); he2=new HE_HalfEdge(); he0.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i0,i2))+"_"+str(max(i0,i2))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 7: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he0.next=he2; he1.next=he0; he2.next=he1; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; case 8: he0.vert=(HE_Vertex)isoVertices.get(str(min(i0,i3))+"_"+str(max(i0,i3))); he1.vert=(HE_Vertex)isoVertices.get(str(min(i1,i3))+"_"+str(max(i1,i3))); he2.vert=(HE_Vertex)isoVertices.get(str(min(i2,i3))+"_"+str(max(i2,i3))); he0.next=he1; he1.next=he2; he2.next=he0; he0.face=f; he1.face=f; he2.face=f; f.halfEdge=he0; he0.vert.halfEdge=he0; he1.vert.halfEdge=he1; he2.vert.halfEdge=he2; result.faces.add(f); result.halfEdges.add(he0); result.halfEdges.add(he1); result.halfEdges.add(he2); break; default: break; } } } } } for(int i=0;i4) polyFaces.add(f); } for(int i=0;i0f)&&(f<1f)){ HE_HalfEdge origHE1= origE.halfEdge; HE_HalfEdge origHE2= origHE1.pair; HE_Vertex v1=origHE1.vert; HE_Vertex v2=origHE2.vert; HE_Vertex v; v=new HE_Vertex(0,0,0,0); v.x=v1.x+f*(v2.x-v1.x); v.y=v1.y+f*(v2.y-v1.y); v.z=v1.z+f*(v2.z-v1.z); vertices.add(v); HE_HalfEdge newHE1=new HE_HalfEdge(); halfEdges.add(newHE1); HE_HalfEdge newHE2=new HE_HalfEdge(); halfEdges.add(newHE2); newHE1.vert=v; newHE1.next=origHE1.next; newHE1.face=origHE1.face; newHE1.pair=origHE2; origHE1.next=newHE1; origHE1.pair=newHE2; newHE2.vert=v; newHE2.next=origHE2.next; newHE2.face=origHE2.face; newHE2.pair=origHE1; origHE2.next=newHE2; origHE2.pair=newHE1; v.halfEdge=newHE1; HE_Edge newE= new HE_Edge(); edges.add(newE); newE.halfEdge=newHE1; newHE1.edge=newE; origHE2.edge=newE; newHE2.edge=origE; origHE1.edge=origE; newE.visible=origE.visible; } clearSecondaries(); return this; } HE_Mesh divideEdge(int id, int n){ if(n>1){ HE_Edge origE=(HE_Edge)edges.get(id); float f=1f/n; HE_HalfEdge origHE1= origE.halfEdge; HE_HalfEdge origHE2= origHE1.pair; HE_Vertex v1=origHE1.vert; HE_Vertex v2=origHE2.vert; HE_Vertex v; v=new HE_Vertex(0,0,0,0); v.x=v1.x+f*(v2.x-v1.x); v.y=v1.y+f*(v2.y-v1.y); v.z=v1.z+f*(v2.z-v1.z); vertices.add(v); HE_HalfEdge newHE1=new HE_HalfEdge(); halfEdges.add(newHE1); HE_HalfEdge newHE2=new HE_HalfEdge(); halfEdges.add(newHE2); newHE1.vert=v; newHE1.next=origHE1.next; newHE1.face=origHE1.face; newHE1.pair=origHE2; origHE1.next=newHE1; origHE1.pair=newHE2; newHE2.vert=v; newHE2.next=origHE2.next; newHE2.face=origHE2.face; newHE2.pair=origHE1; origHE2.next=newHE2; origHE2.pair=newHE1; v.halfEdge=newHE1; HE_Edge newE= new HE_Edge(); edges.add(newE); newE.halfEdge=newHE1; newHE1.edge=newE; origHE2.edge=newE; newHE2.edge=origE; origHE1.edge=origE; newE.visible=origE.visible; divideEdge(edges.size()-1, n-1); clearSecondaries(); } return this; } HE_Mesh cutSurface(Plane P){ if(!indicesUpdated) reindex(); ArrayList verticesOnPlane=new ArrayList(); ArrayList newVertices=new ArrayList(); int n=edges.size(); int numOfIntersections=0; for(int i=0;i0f) { splitEdge(i,u); newVertices.add((HE_Vertex)vertices.get(vertices.size()-1)); numOfIntersections++; } } for(int i=0;i0f){ if(!bodyCenterUpdated)setBodyCenter(); if(pol*P.side(bodyCenter,0.0001f)>=0f){ return this; }else{ HE_Mesh nothing=new HE_Mesh(); set(nothing); return this; } } HE_Mesh backup=new HE_Mesh(); if(safe) backup=get(); backup.lastOperationFailed=true; if(!indicesUpdated) reindex(); if(!faceCentersUpdated) setFaceCenters(); ArrayList verticesOnPlane=new ArrayList(); ArrayList newVertices=new ArrayList(); int n=edges.size(); int numOfIntersections=0; for(int i=0;i0f) { splitEdge(i,u); newVertices.add((HE_Vertex)vertices.get(vertices.size()-1)); numOfIntersections++; } } for(int i=0;i=0f){ newFaces.add(nf); } else{ newFaces.add(f); } } else{ if(pol*P.side((PVector)faceCenters.get(i),0.0001f)>=0f)newFaces.add(f); } } faces=newFaces; cleanUnusedElements(); capOpenLoop(closed); clearSecondaries(); if(safe){ return (validate(false, false))?this:backup; } else { return this; } } HE_Mesh[] splitMesh(final Plane P, boolean safe, boolean closed){ HE_Mesh[] result=new HE_Mesh[2]; result[0]=get(); result[1]=get(); result[0].cutMesh(P,safe,closed); result[1].cutMesh(P,safe,closed, true); return result; } HE_Mesh cutMesh(ArrayList cutPlanes, PVector c, boolean safe, boolean closed, boolean retry){ ArrayList cutPlanesToRetry=new ArrayList(); float[] r=new float[cutPlanes.size()]; for(int k=0;k= 0; ) { for (int m = 0; m < k; m++) { Plane pl = (Plane)cutPlanes.get(m); Plane pll = (Plane)cutPlanes.get(m+1); if (r[m] > r[m+1]) { Collections.swap(cutPlanes,m,m+1); float tmp=r[m]; r[m]=r[m+1]; r[m+1]=tmp; } } } for(int k=0;k0)){ cutMesh(cutPlanesToRetry,c,safe, closed, false); } return this; } HE_Mesh extrudeFace(int id, float d, float t){ if(!faceNormalsUpdated) setFaceNormals(); if(!faceCentersUpdated) setFaceCenters(); HE_Face f=(HE_Face)faces.get(id); PVector n=(PVector)faceNormals.get(id); PVector fc=(PVector)faceCenters.get(id); n.mult(d); HE_HalfEdge he=f.halfEdge; ArrayList faceVertices=new ArrayList(); ArrayList extFaceVertices=new ArrayList(); do{ faceVertices.add(he.vert); extFaceVertices.add(he.vert.get()); he=he.next; } while(he!=f.halfEdge); for (int i=0;i0){ if(!reverse){ for(int j=0;j0){ ArrayList loopedHalfEdges=new ArrayList(); HE_HalfEdge start = (HE_HalfEdge)unpairedEdges.get(0); loopedHalfEdges.add(start); HE_HalfEdge he=start; HE_HalfEdge hen=start; boolean stuck=false; do{ for(int i=0;i1f+cutoff)) return -1f;// intersection beyond endpoints if(abs(u)<=cutoff) return 0f;// intersection at startpoint if((u>=1f-cutoff)&&(u<=1f+cutoff))return 1f;//intersection at endpoint return u;//intersection on edge } } class HE_Vertex extends PVector{ int id; HE_HalfEdge halfEdge; HE_Vertex(float x, float y, float z, int id){ super(x,y,z); this.id=id; } HE_Vertex(PVector v, int id){ super(v.x,v.y,v.z); this.id=id; } HE_Vertex get(){ return new HE_Vertex(x,y,z,id); } void projectToPlane(Plane P){ float d=P.A*x+P.B*y+P.C*z+P.D; float x0=x-P.A*d; float y0=y-P.B*d; float z0=z-P.C*d; set(x0,y0,z0); } void interpolateSelf(HE_Vertex v1, HE_Vertex v2, float f){ x=v1.x+f*(v2.x-v1.x); y=v1.y+f*(v2.y-v1.y); z=v1.z+f*(v2.z-v1.z); } } class HE_Face{ int id; boolean visible; boolean fixed; HE_HalfEdge halfEdge; HE_Face(){ } } float sign(float v){ return (v<0)?-1:((v>0)?1:0); } boolean between(float vt, float v1, float v2){ return(vtmin(v1,v2)); }