use of maspack.geometry.HalfEdge in project artisynth_core by artisynth.
the class GtsWriter method writeMesh.
public void writeMesh(PolygonalMesh mesh) throws IOException {
PrintWriter pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(myOstream)));
int[] oldIdxs = new int[mesh.numVertices()];
int vidx = 0;
for (Vertex3d vtx : mesh.getVertices()) {
// protect vertex indices numbers
oldIdxs[vidx] = vtx.getIndex();
vtx.setIndex(vidx);
vidx++;
}
LinkedHashMap<Edge, Integer> edgeList = new LinkedHashMap<Edge, Integer>();
for (Face f : mesh.getFaces()) {
HalfEdge he0 = f.firstHalfEdge();
HalfEdge he = he0;
do {
HalfEdge next = he.getNext();
Edge edge = new Edge(he.head, next.head);
if (edgeList.get(edge) == null) {
edgeList.put(edge, edgeList.size());
}
he = next;
} while (he != he0);
}
pw.println(mesh.numVertices() + " " + edgeList.size() + " " + mesh.numFaces());
for (Vertex3d vtx : mesh.getVertices()) {
vtx.pnt.write(pw, myFmt);
pw.println("");
}
for (Edge edge : edgeList.keySet()) {
pw.println((edge.myVtx1.getIndex() + 1) + " " + (edge.myVtx2.getIndex() + 1));
}
for (Face f : mesh.getFaces()) {
HalfEdge he0 = f.firstHalfEdge();
HalfEdge he = he0;
do {
HalfEdge next = he.getNext();
Edge edge = new Edge(he.head, next.head);
Integer idx = edgeList.get(edge);
pw.print((idx + 1) + " ");
he = next;
} while (he != he0);
pw.println("");
}
// restore vertex indices
vidx = 0;
for (Vertex3d vtx : mesh.getVertices()) {
vtx.setIndex(oldIdxs[vidx]);
vidx++;
}
}
use of maspack.geometry.HalfEdge in project artisynth_core by artisynth.
the class MeshIntersectingProbe method findNextEdge.
// NOTE: only works for convex faces (so, triangular is okay)
// finds the next edge while clipping around in a circle
private static HalfEdge findNextEdge(LinkedList<Point3d> contour, ArrayList<Face> faceList, Intersector2d ti, SplitStorage info, Vector3d vx, Vector3d vy, Point3d o) {
Vector3d dir = new Vector3d();
Point3d vtxp = info.vtx.getWorldPoint();
Point2d vtx2d = Intersector2d.get2dCoordinate(vtxp, vx, vy, o);
dir.sub(contour.get(info.idx + 1), contour.get(info.idx));
for (Face face : faceList) {
HalfEdge he0 = face.getEdge(0);
HalfEdge he = he0;
do {
if (info.vtx != he.head && info.vtx != he.tail) {
Point2d p1 = Intersector2d.get2dCoordinate(he.head.getWorldPoint(), vx, vy, o);
Point2d p2 = Intersector2d.get2dCoordinate(he.tail.getWorldPoint(), vx, vy, o);
ArrayList<Point2d> pnts = new ArrayList<Point2d>();
Vector2d lineDir = Intersector2d.get2dVector(dir, vx, vy);
int npoints = ti.intersectLineLineSegment(vtx2d, lineDir, p1, p2, pnts);
if (npoints == 1) {
Point3d p = Intersector2d.get3dCoordinate(pnts.get(0), vx, vy, o);
Vector3d ldir = new Vector3d(p.x - vtxp.x, p.y - vtxp.y, p.z - vtxp.z);
// check direction
if (ldir.dot(dir) > -ti.epsilon) {
// check if we passed the next point
Point3d pNext = contour.get(info.idx + 1);
if (ldir.norm() < pNext.distance(vtxp) + ti.epsilon) {
if (p.distance(pNext) < ti.epsilon) {
// move to next point
info.idx++;
}
info.vtx = createOrGetVertex(p, face.getVertices(), ti.epsilon);
return he;
} else {
// advance to next vertex
info.vtx = createOrGetVertex(pNext, face.getVertices(), ti.epsilon);
info.face = face;
// move to next point
info.idx++;
return null;
}
}
}
}
he = he.getNext();
} while (he != he0);
}
info.face = null;
return null;
}
use of maspack.geometry.HalfEdge in project artisynth_core by artisynth.
the class MeshIntersectingProbe method clipMesh.
// does the clipping of a planar surface based on a contour
private void clipMesh(PolygonalMesh surface, LinkedList<Point3d> contour, double tol) {
SplitStorage info = new SplitStorage();
Intersector2d ti = new Intersector2d();
ti.setEpsilon(tol);
// coordinate system
Vector3d vx = new Vector3d();
Vector3d vy = new Vector3d();
Point3d o = getPosition();
XGridToWorld.R.getColumn(0, vx);
XGridToWorld.R.getColumn(1, vy);
OBBTree obbt = new OBBTree(surface, 2, tol);
ArrayList<Face> faceList = null;
while (info.idx + 1 < contour.size()) {
if (info.vtx == null) {
Face face = findNextFace(contour.get(info.idx), contour, obbt, ti, vx, vy, o, info);
// so now I have a vertex and a face it lies on
if (face != null) {
// we may be on multiple faces
faceList = findFaces(info.vtx.getWorldPoint(), obbt, vx, vy, o, tol);
for (Face f : faceList) {
splitFace(surface, f, info.vtx, tol);
}
}
} else {
// find all faces this vertex is on, project in direction of contour
faceList = getFaces(info.vtx);
HalfEdge he = findNextEdge(contour, faceList, ti, info, vx, vy, o);
if (he != null) {
// we landed on an edge
Face oppFace = null;
if (he.opposite != null) {
oppFace = he.opposite.getFace();
}
splitFace(surface, he.getFace(), info.vtx, tol);
if (oppFace != null) {
splitFace(surface, oppFace, info.vtx, tol);
}
} else if (info.face != null) {
splitFace(surface, info.face, info.vtx, tol);
} else {
// move to next point
info.idx++;
info.vtx = null;
}
}
}
}
use of maspack.geometry.HalfEdge in project artisynth_core by artisynth.
the class SurfaceMeshContourIxer method robustIntersectionWithFace.
/*
* Test for intersection using adaptive exact arithmetic and SOS tiebreaking.
*/
protected boolean robustIntersectionWithFace(HalfEdge he, Face face, IntersectionPoint mip, boolean edgeOnMesh0) {
HalfEdge he0 = face.firstHalfEdge();
Vertex3d v = he0.tail;
if (v == he.head)
return false;
if (v == he.tail)
return false;
v = he0.head;
if (v == he.head)
return false;
if (v == he.tail)
return false;
v = he0.getNext().head;
if (v == he.head)
return false;
if (v == he.tail)
return false;
int res = RobustPreds.intersectEdgeTriangle(mip, he, face, myMaxLength, edgeOnMesh0, /*worldCoords=*/
true);
if (res == 0) {
return false;
} else {
mip.edge = he;
mip.face = face;
// mip.edgeOnMesh0 = edgeOnMesh0;
mip.intersectionCode = res;
// mip.degeneracies = (res & RobustPreds.DEGENERACY_MASK);
return true;
}
}
use of maspack.geometry.HalfEdge in project artisynth_core by artisynth.
the class MeshThicken method adjacentFacesCrossNormal.
private boolean adjacentFacesCrossNormal(Vertex3d vtx, Vector3d nrm) {
double lastdot = 1;
Iterator<HalfEdge> it = vtx.getIncidentHalfEdges();
while (it.hasNext()) {
HalfEdge he = it.next();
double dot = he.getFace().getNormal().dot(nrm);
if (dot * lastdot <= 0) {
return true;
}
lastdot = dot;
}
return false;
}
Aggregations