use of maspack.geometry.PolygonalMesh in project artisynth_core by artisynth.
the class TetGenReader method readFaces.
public static PolygonalMesh readFaces(Vector3d scale, Reader nodeReader, Reader faceReader) throws IOException {
PolygonalMesh mesh = new PolygonalMesh();
ReaderTokenizer nodeFile = new ReaderTokenizer(new BufferedReader(nodeReader));
nodeFile.nextToken();
nodeFile.nextToken();
nodeFile.nextToken();
nodeFile.nextToken();
while (nodeFile.nextToken() != ReaderTokenizer.TT_EOF) {
Point3d coords = new Point3d();
for (int i = 0; i < 3; i++) {
coords.set(i, nodeFile.scanNumber());
}
if (scale != null) {
coords.x *= scale.x;
coords.y *= scale.y;
coords.z *= scale.z;
}
mesh.addVertex(coords.x, coords.y, coords.z);
}
ReaderTokenizer faceFile = new ReaderTokenizer(new BufferedReader(faceReader));
faceFile.nextToken();
faceFile.nextToken();
while (faceFile.nextToken() != ReaderTokenizer.TT_EOF) {
Vertex3d[] vtxs = new Vertex3d[3];
for (int i = 0; i < vtxs.length; i++) {
vtxs[i] = mesh.getVertices().get(faceFile.scanInteger());
}
// discard
faceFile.scanInteger();
mesh.addFace(vtxs);
}
return mesh;
}
use of maspack.geometry.PolygonalMesh in project artisynth_core by artisynth.
the class FemMeshComp method createPointAttachment.
public PointFem3dAttachment createPointAttachment(Point pnt) {
if (!(getMesh() instanceof PolygonalMesh)) {
return null;
}
PolygonalMesh mesh = (PolygonalMesh) getMesh();
if (!mesh.isTriangular()) {
return null;
}
// Find nearest face to the point. The vertices of this face will be used
// to find the nodes and weight for the attachment.
BVFeatureQuery query = new BVFeatureQuery();
Point3d near = new Point3d();
Vector2d uv = new Vector2d();
Face face = query.nearestFaceToPoint(near, uv, mesh, pnt.getPosition());
Vertex3d[] vtxs = face.getTriVertices();
double[] wgts = new double[] { 1 - uv.x - uv.y, uv.x, uv.y };
HashMap<FemNode, Double> nodeWeights = new HashMap<FemNode, Double>();
for (int i = 0; i < vtxs.length; i++) {
PointAttachment va = myVertexAttachments.get(vtxs[i].getIndex());
if (va instanceof PointParticleAttachment) {
PointParticleAttachment ppa = (PointParticleAttachment) va;
FemNode node = (FemNode) ppa.getParticle();
accumulateNodeWeights(node, wgts[i], nodeWeights);
} else if (va instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) va;
for (int k = 0; k < pfa.numMasters(); k++) {
FemNode node = pfa.getNodes()[k];
double w = pfa.getCoordinate(k);
accumulateNodeWeights(node, w * wgts[i], nodeWeights);
}
}
}
// Create a new PointFem3dAttachment
PointFem3dAttachment ax = new PointFem3dAttachment(pnt);
VectorNd weightVec = new VectorNd();
for (Double d : nodeWeights.values()) {
weightVec.append(d);
}
ax.setFromNodes(nodeWeights.keySet(), weightVec);
return ax;
}
use of maspack.geometry.PolygonalMesh in project artisynth_core by artisynth.
the class FemMeshComp method createSurface.
// Throwable throwable = null;
public void createSurface(Collection<FemElement3d> elems) {
initializeSurfaceBuild();
// nodeVertexMap is used during the construction of this surface,
// so we build it during the construction rather then letting
// it be built in finalizeSurfaceBuild()
myNodeVertexMap = new HashMap<FemNode3d, Vertex3d>();
myNumSingleAttachments = 0;
LinkedList<FaceNodes3d> allFaces = new LinkedList<FaceNodes3d>();
// faces adjacent to each node
ArrayList<LinkedList<FaceNodes3d>> nodeFaces = new ArrayList<LinkedList<FaceNodes3d>>(myFem.numNodes());
for (int i = 0; i < myFem.numNodes(); i++) {
nodeFaces.add(new LinkedList<FaceNodes3d>());
}
PointList<FemNode3d> femNodes = myFem.getNodes();
// each node, create a list of all the faces it is associated with
for (FemElement3d e : elems) {
FaceNodes3d[] faces = e.getFaces();
for (FaceNodes3d f : faces) {
addEdgeNodesToFace(f, myFem);
for (FemNode3d n : f.getAllNodes()) {
int idx = femNodes.indexOf(n);
if (idx == -1) {
throw new InternalErrorException("Element " + e.getNumber() + ": bad node " + n.getNumber());
}
nodeFaces.get(femNodes.indexOf(n)).add(f);
}
allFaces.add(f);
}
}
// now for each face, check to see if it is overlapping with other faces
HashSet<FaceNodes3d> adjacentFaces = new HashSet<FaceNodes3d>();
for (FaceNodes3d f : allFaces) {
if (!f.isHidden()) {
adjacentFaces.clear();
for (FemNode3d n : f.getAllNodes()) {
Iterator<FaceNodes3d> it = nodeFaces.get(femNodes.indexOf(n)).iterator();
while (it.hasNext()) {
FaceNodes3d g = it.next();
if (g.isHidden()) {
it.remove();
} else if (g.getElement() != f.getElement()) {
adjacentFaces.add(g);
}
}
}
for (FaceNodes3d g : adjacentFaces) {
if (f.isContained(g)) {
f.setHidden(true);
g.setOverlapping(true);
}
if (g.isContained(f)) {
g.setHidden(true);
f.setOverlapping(true);
}
}
}
}
int num = 0;
for (FaceNodes3d f : allFaces) {
if (!f.isOverlapping() && !f.isSelfAttachedToFace()) {
num++;
}
}
// form the surface mesh from the non-overlapping faces
PolygonalMesh mesh = (PolygonalMesh) getMesh();
for (FaceNodes3d f : allFaces) {
if (!f.isOverlapping() && !f.hasSelfAttachedNode() && !f.isSelfAttachedToFace()) {
FemNode3d[][] triangles = f.triangulate();
boolean triangulatedQuad = (triangles.length == 2 && triangles[0][0] == triangles[1][0]);
for (int i = 0; i < triangles.length; i++) {
FemNode3d[] tri = triangles[i];
Vertex3d[] vtxs = new Vertex3d[3];
for (int j = 0; j < 3; j++) {
FemNode3d node = tri[j];
if ((vtxs[j] = myNodeVertexMap.get(node)) == null) {
Vertex3d vtx = new Vertex3d(new Point3d(node.getPosition()));
mesh.addVertex(vtx);
myVertexAttachments.add(new PointParticleAttachment(node, null));
myNumSingleAttachments++;
myNodeVertexMap.put(node, vtx);
vtxs[j] = vtx;
}
}
Face face = mesh.addFace(vtxs);
if (triangulatedQuad && i == 0) {
face.setFirstQuadTriangle(true);
}
}
}
}
finalizeSurfaceBuild();
// throwable = null;
}
use of maspack.geometry.PolygonalMesh in project artisynth_core by artisynth.
the class FemIntersector method intersectPlane.
/**
* Intersects a FEM 3d model with a plane, returning a Polygonal mesh
* on the plane corresponding to inside the FEM
* @param fem model to intersect with the plane
* @param plane plane to intersect with
* @return intersection mesh
*/
public PolygonalMesh intersectPlane(FemModel3d fem, Plane plane) {
AABBTree aabb = new AABBTree();
FemElement3d[] elements = fem.getElements().toArray(new FemElement3d[fem.numElements()]);
aabb.build(elements, fem.numElements());
ArrayList<BVNode> nodes = new ArrayList<BVNode>();
aabb.intersectPlane(nodes, plane);
DirectedGraph<Point3d, Vector3d> nodeGraph = new DirectedGraph<Point3d, Vector3d>();
TriangleIntersector ti = new TriangleIntersector();
ti.setEpsilon(epsilon);
for (BVNode node : nodes) {
Boundable[] elems = node.getElements();
for (int i = 0; i < node.getNumElements(); i++) {
FemElement3d elem = (FemElement3d) elems[i];
FaceNodes3d[] faceNodes = elem.getFaces();
for (FaceNodes3d fn : faceNodes) {
FemNode3d[][] faces = fn.triangulate();
for (FemNode3d[] face : faces) {
addIfUnique(ti.intersectTrianglePlane(face[0].getPosition(), face[1].getPosition(), face[2].getPosition(), plane), nodeGraph, epsilon);
}
// end loop through faces
}
// end loop through "face nodes"
}
// end looping through elements
}
// end looping through BVNodes
// reduceGraph(nodeGraph, tol);
fixOverlaps(nodeGraph, epsilon);
PolygonalMesh mesh = buildMesh(nodeGraph, plane.normal);
removeBackFaces(mesh, plane.normal);
nonConvexTriangulate(mesh, plane.normal, epsilon);
return mesh;
}
use of maspack.geometry.PolygonalMesh in project artisynth_core by artisynth.
the class FemIntersector method buildMesh.
private PolygonalMesh buildMesh(DirectedGraph<Point3d, Vector3d> graph, Vector3d normal) {
PolygonalMesh mesh = new PolygonalMesh();
LinkedList<DirectedEdge<Point3d, Vector3d>> remainingEdges = new LinkedList<DirectedEdge<Point3d, Vector3d>>(graph.getEdges());
HashMap<Point3d, Vertex3d> vtxMap = new HashMap<Point3d, Vertex3d>(graph.numVertices());
for (Vertex<Point3d, Vector3d> v : graph.getVertices()) {
Vertex3d vtx = mesh.addVertex(v.getData());
vtxMap.put(v.getData(), vtx);
}
while (remainingEdges.size() > 0) {
DirectedEdge<Point3d, Vector3d> e = remainingEdges.get(0);
ArrayList<DirectedEdge<Point3d, Vector3d>> face = findFace(e, graph, normal);
if (face == null) {
remainingEdges.remove(0);
} else {
Vertex3d[] vtxs = new Vertex3d[face.size()];
int idx = 0;
for (DirectedEdge<Point3d, Vector3d> edge : face) {
vtxs[idx++] = vtxMap.get(edge.getVertex(0).getData());
remainingEdges.remove(edge);
}
mesh.addFace(vtxs);
}
}
return mesh;
}
Aggregations