use of maspack.geometry.Face in project artisynth_core by artisynth.
the class ContactInfo method computePenetratingPoints.
ArrayList<PenetratingPoint> computePenetratingPoints(PolygonalMesh mesh0, PolygonalMesh mesh1) {
BVFeatureQuery query = new BVFeatureQuery();
Point3d wpnt = new Point3d();
Point3d nearest = new Point3d();
Vector2d uv = new Vector2d();
Vector3d disp = new Vector3d();
ArrayList<PenetratingPoint> points = new ArrayList<PenetratingPoint>();
for (Vertex3d vtx : mesh0.getVertices()) {
// John Lloyd, Jan 3, 2014: rewrote to use isInsideOrientedMesh()
// to determine if a vertex is inside another mesh. Previous code
// would not always work and broke when the BVTree code was
// refactored.
vtx.getWorldPoint(wpnt);
if (query.isInsideOrientedMesh(mesh1, wpnt, -1)) {
Face f = query.getFaceForInsideOrientedTest(nearest, uv);
mesh1.transformToWorld(nearest);
disp.sub(nearest, wpnt);
points.add(new PenetratingPoint(vtx, f, uv, nearest, disp, /*region=*/
null));
}
}
return points;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class FemMeshComp method writeMesh.
public boolean writeMesh(PrintWriter pw, boolean nodeFormat) {
PolygonalMesh mesh = null;
if (!(getMesh() instanceof PolygonalMesh)) {
return false;
}
mesh = (PolygonalMesh) getMesh();
pw.print("[ ");
NumberFormat fmt = new NumberFormat("%.8g");
IndentingPrintWriter.addIndentation(pw, 2);
if (!nodeFormat) {
for (Vertex3d vtx : mesh.getVertices()) {
writeVertexInfo(pw, vtx, fmt);
}
}
ArrayList<Integer> nodeNums = new ArrayList<Integer>();
for (Face face : mesh.getFaces()) {
HalfEdge he0 = face.firstHalfEdge();
HalfEdge he = he0;
pw.print("f");
do {
int vidx = he.head.getIndex();
if (nodeFormat) {
PointParticleAttachment ppa = (PointParticleAttachment) getAttachment(vidx);
FemNode3d node = (FemNode3d) ppa.getParticle();
pw.print(" " + node.getNumber());
} else {
pw.print(" " + (vidx + 1));
}
he = he.getNext();
} while (he != he0);
pw.println("");
}
IndentingPrintWriter.addIndentation(pw, -2);
pw.println("]");
return true;
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class FemMeshComp method createFineSurface.
protected void createFineSurface(int resolution, ElementFilter efilter) {
// build from nodes/element filter
createSurface(efilter);
if (resolution < 2) {
// if resolution < 2, just return regular surface
return;
}
// Note: can no longer rely on the surface mesh consisting of only
// FemMeshVertex
// PolygonalMesh baseMesh = myFem.getSurfaceMesh();
// since previously built
PolygonalMesh baseMesh = (PolygonalMesh) getMesh();
ArrayList<Face> baseFaces = baseMesh.getFaces();
ArrayList<Vertex3d> baseVertices = baseMesh.getVertices();
ArrayList<PointAttachment> baseAttachments = myVertexAttachments;
// num vertices along the edge of each sub face
int numv = resolution + 1;
initializeSurfaceBuild();
HashMap<EdgeDesc, Vertex3d[]> edgeVtxMap = new HashMap<EdgeDesc, Vertex3d[]>();
// get newly empty mesh
PolygonalMesh surfMesh = (PolygonalMesh) getMesh();
for (Vertex3d vtx : baseVertices) {
FemNode3d node = getNodeForVertex(baseAttachments.get(vtx.getIndex()));
createVertex(node, vtx);
// myNodeVertexMap.put (node, newVtx);
}
System.out.println("num base faces: " + baseFaces.size());
for (int k = 0; k < baseFaces.size(); k++) {
Face face = baseFaces.get(k);
// store sub vertices for the face in the upper triangular half of
// subv.
MeshFactory.VertexSet subv = new MeshFactory.VertexSet(numv);
FemElement3d elem = getFaceElement(face);
if (elem == null) {
continue;
}
HalfEdge he = face.firstHalfEdge();
Vertex3d v0 = (Vertex3d) he.getHead();
FemNode3d n0 = getNodeForVertex(baseAttachments.get(v0.getIndex()));
he = he.getNext();
Vertex3d v1 = (Vertex3d) he.getHead();
FemNode3d n1 = getNodeForVertex(baseAttachments.get(v1.getIndex()));
he = he.getNext();
Vertex3d v2 = (Vertex3d) he.getHead();
FemNode3d n2 = getNodeForVertex(baseAttachments.get(v2.getIndex()));
subv.set(0, 0, getVertex(v0.getIndex()));
subv.set(0, numv - 1, getVertex(v2.getIndex()));
subv.set(numv - 1, numv - 1, getVertex(v1.getIndex()));
Vertex3d[] vtxs01 = collectEdgeVertices(edgeVtxMap, v0, v1, n0, n1, elem, resolution);
for (int i = 1; i < numv - 1; i++) {
subv.set(i, i, vtxs01[i]);
}
Vertex3d[] vtxs02 = collectEdgeVertices(edgeVtxMap, v0, v2, n0, n2, elem, resolution);
for (int j = 1; j < numv - 1; j++) {
subv.set(0, j, vtxs02[j]);
}
Vertex3d[] vtxs21 = collectEdgeVertices(edgeVtxMap, v2, v1, n2, n1, elem, resolution);
for (int i = 1; i < numv - 1; i++) {
subv.set(i, numv - 1, vtxs21[i]);
}
for (int i = 1; i < numv - 1; i++) {
for (int j = i + 1; j < numv - 1; j++) {
double s1 = i / (double) resolution;
double s0 = 1 - j / (double) resolution;
Vertex3d vtx = createVertex(s0, s1, 1 - s0 - s1, elem, n0, n1, n2);
subv.set(i, j, vtx);
}
}
subv.check();
for (int i = 0; i < resolution; i++) {
for (int j = i; j < resolution; j++) {
surfMesh.addFace(subv.get(i, j), subv.get(i + 1, j + 1), subv.get(i, j + 1));
if (i != j) {
surfMesh.addFace(subv.get(i, j), subv.get(i + 1, j), subv.get(i + 1, j + 1));
}
}
}
}
finalizeSurfaceBuild();
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class FemIntersector method nonConvexTriangulate.
// ear splitting technique
protected static void nonConvexTriangulate(PolygonalMesh mesh, Vector3d normal, double tol) {
ArrayList<Face> faces = new ArrayList<Face>(mesh.getFaces());
for (Face face : faces) {
if (!face.isTriangle()) {
makeConvexFace(mesh, face, normal, tol);
}
}
mesh.triangulate();
}
use of maspack.geometry.Face in project artisynth_core by artisynth.
the class FemIntersector method removeBackFaces.
private void removeBackFaces(PolygonalMesh mesh, Vector3d normal) {
ArrayList<Face> remove = new ArrayList<Face>();
Vector3d v1 = new Vector3d();
Vector3d v2 = new Vector3d();
for (Face face : mesh.getFaces()) {
// deem a face to be on the back if sum of convex angles outweights concave ones
double a = 0;
for (int i = 0; i < face.numVertices(); i++) {
int b = (i + face.numVertices() - 1) % (face.numVertices());
int f = (i + 1) % face.numVertices();
v1.sub(face.getVertex(i).getWorldPoint(), face.getVertex(b).getWorldPoint());
v2.sub(face.getVertex(f).getWorldPoint(), face.getVertex(i).getWorldPoint());
a += getAngle(1, v1, 1, v2, normal);
}
if (a > 0) {
remove.add(face);
}
}
for (Face face : remove) {
mesh.removeFace(face);
}
}
Aggregations