use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class FemMeshComp method copy.
@Override
public FemMeshComp copy(int flags, Map<ModelComponent, ModelComponent> copyMap) {
FemMeshComp fm = (FemMeshComp) super.copy(flags, copyMap);
FemModel3d newFem = (FemModel3d) copyMap.get(myFem);
if (newFem != null) {
fm.myFem = newFem;
} else {
fm.myFem = myFem;
}
HashMap<Vertex3d, Vertex3d> vertMap = null;
if (getMesh() != fm.getMesh()) {
vertMap = new HashMap<Vertex3d, Vertex3d>(myMeshInfo.numVertices());
for (int i = 0; i < myMeshInfo.numVertices(); i++) {
vertMap.put(getVertex(i), fm.getVertex(i));
}
}
fm.myVertexAttachments = new ArrayList<PointAttachment>(myVertexAttachments.size());
for (PointAttachment pa : myVertexAttachments) {
PointAttachment newPa = pa.copy(flags, copyMap);
fm.myVertexAttachments.add(newPa);
}
fm.buildNodeVertexMap();
// fm.myEdgeVtxs = new HashMap<EdgeDesc,Vertex3d[]>(myEdgeVtxs.size());
// for (Entry<EdgeDesc,Vertex3d[]> het : myEdgeVtxs.entrySet()) {
// het.getKey();
// Vertex3d[] oldVerts = het.getValue();
// EdgeDesc newEdge = het.getKey().copy(vertMap);
// Vertex3d[] newVerts = new Vertex3d[oldVerts.length];
//
// if (vertMap != null) {
// for (int i=0; i<newVerts.length; i++) {
// newVerts[i] = vertMap.get(oldVerts[i]);
// }
// } else {
// for (int i=0; i<newVerts.length; i++) {
// newVerts[i] = oldVerts[i];
// }
// }
// fm.myEdgeVtxs.put(newEdge, newVerts);
// }
fm.isSurfaceMesh = isSurfaceMesh();
return fm;
}
use of maspack.geometry.Vertex3d 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.Vertex3d in project artisynth_core by artisynth.
the class FemMeshComp method createVertex.
private Vertex3d createVertex(FemNode3d node, Vertex3d v) {
Vertex3d vtx = new Vertex3d(v.getPosition());
PointParticleAttachment attacher = new PointParticleAttachment(node, null);
myVertexAttachments.add(attacher);
getMesh().addVertex(vtx);
return vtx;
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class FemIntersector method makeConvexFace.
// ear splitting technique
protected static void makeConvexFace(PolygonalMesh mesh, Face face, Vector3d normal, double tol) {
if (face.isTriangle()) {
return;
}
Vector3d v1 = new Vector3d();
Vector3d v2 = new Vector3d();
Vertex3d[] vtxs = face.getVertices();
for (int i = 0; i < vtxs.length; i++) {
Vertex3d vm1 = vtxs[(i + vtxs.length - 1) % vtxs.length];
Vertex3d v0 = vtxs[i];
Vertex3d vp1 = vtxs[(i + 1) % vtxs.length];
v1.sub(v0.getWorldPoint(), vm1.getWorldPoint());
v2.sub(vp1.getWorldPoint(), v0.getWorldPoint());
double ang = getAngle(1, v1, 1, v2, normal);
if (ang > -tol) {
for (int j = 1; j < vtxs.length - 1; j++) {
vp1 = vtxs[(i + j + 1) % vtxs.length];
v2.sub(vp1.getWorldPoint(), v0.getWorldPoint());
ang = getAngle(1, v1, 1, v2, normal);
if (ang < -tol) {
// XXX check that doesn't intersect any edges?
Vertex3d[] f1 = new Vertex3d[j + 2];
Vertex3d[] f2 = new Vertex3d[vtxs.length - j];
for (int k = 0; k < f1.length; k++) {
f1[k] = vtxs[(i + k) % vtxs.length];
}
for (int k = 0; k < f2.length - 2; k++) {
f2[k] = vtxs[(i + k + f1.length) % vtxs.length];
}
f2[f2.length - 2] = v0;
f2[f2.length - 1] = f1[f1.length - 1];
mesh.removeFace(face);
Face face1 = mesh.addFace(f1);
Face face2 = mesh.addFace(f2);
makeConvexFace(mesh, face1, normal, tol);
makeConvexFace(mesh, face2, normal, tol);
return;
}
}
}
}
}
use of maspack.geometry.Vertex3d 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