use of maspack.matrix.VectorNd in project artisynth_core by artisynth.
the class MFreeFactory method createModel.
public static MFreeModel3d createModel(MFreeModel3d model, MFreeNode3d[] nodes, PolygonalMesh surface, CubaturePoint3d[] cpnts) {
MFreeShapeFunction func = new MLSShapeFunction();
FunctionTimer timer = new FunctionTimer();
// timer.start();
// boolean[][] iChart = buildIntersectionChart(nodeArray);
// timer.stop();
// System.out.println("Intersection chart: " + timer.getTimeUsec()/1000 +
// " ms");
AABBTree nodeTree = new AABBTree();
RestNode[] rnodes = new RestNode[nodes.length];
for (int i = 0; i < nodes.length; ++i) {
rnodes[i] = new RestNode(nodes[i], nodes[i].getInfluenceRadius());
}
timer.start();
nodeTree.build(rnodes, nodes.length);
timer.stop();
System.out.println("Node BVTree: " + timer.getTimeUsec() / 1000 + " ms");
// compute node dependencies and coordinates
timer.start();
for (MFreeNode3d node : nodes) {
MFreeNode3d[] deps = findNodesContaining(node.getRestPosition(), nodeTree, 0);
VectorNd coords = new VectorNd();
getShapeCoords(func, coords, node.getRestPosition(), deps);
node.setDependentNodes(deps, coords);
}
timer.stop();
System.out.println("Node coordinates: " + timer.getTimeUsec() / 1000 + " ms");
// timer.start();
// DirectedGraph<int[], Integer> connectivityGraph =
// IntersectionFactory.buildConnectivityGraph(iChart);
// timer.stop();
// System.out.println("Connectivity graph: " + timer.getTimeUsec()/1000 +
// " ms");
// timer.start();
// ArrayList<MFreeElement3d> elemList = createPartitionedElements(nodes,
// connectivityGraph);
// timer.stop();
// System.out.println("Partitioned elements: " + timer.getTimeUsec()/1000
// + " ms");
timer.start();
MFreeIntegrationPoint3d[] ipnts = createIntegrationPoints(func, cpnts, nodeTree);
timer.stop();
System.out.println("Integration points: " + timer.getTimeUsec() / 1000 + " ms");
HashMap<MFreeIntegrationPoint3d, MFreeElement3d> pntMap = new HashMap<MFreeIntegrationPoint3d, MFreeElement3d>(ipnts.length);
timer.start();
ArrayList<MFreeElement3d> elemList = createPartitionedElementsFromPoints(ipnts, pntMap);
timer.stop();
System.out.println("Building elements from points: " + timer.getTimeUsec() / 1000 + " ms");
timer.start();
distributeIPointsFromMap(pntMap);
timer.stop();
System.out.println("Distributing integration Points: " + timer.getTimeUsec() / 1000 + " ms");
// trimEmptyElements(elemList);
addWarpingPoints(elemList, nodeTree);
if (model == null) {
model = new MFreeModel3d();
}
model.addNodes(Arrays.asList(nodes));
model.addElements(elemList);
model.setSurfaceMesh(surface);
model.updateNodeMasses(-1, null);
return model;
}
use of maspack.matrix.VectorNd in project artisynth_core by artisynth.
the class MFreeFactory method cloneFem.
public static MFreeModel3d cloneFem(MFreeModel3d model, FemModel3d fem) {
if (model == null) {
model = new MFreeModel3d();
}
HashMap<FemNode3d, MFreeNode3d> nodeMap = new HashMap<FemNode3d, MFreeNode3d>();
HashMap<MFreeNode3d, FemNode3d> nodeMapInv = new HashMap<MFreeNode3d, FemNode3d>();
ArrayList<MFreeNode3d> nodeList = new ArrayList<MFreeNode3d>();
// duplicate nodes
for (FemNode3d node : fem.getNodes()) {
MFreeNode3d mnode = new MFreeNode3d(node.getRestPosition());
// explicit node masses
mnode.setMassExplicit(true);
mnode.setMass(node.getMass());
MFreeNode3d[] deps = new MFreeNode3d[1];
deps[0] = mnode;
VectorNd coords = new VectorNd(new double[] { 1 });
mnode.setDependentNodes(deps, coords);
nodeMap.put(node, mnode);
nodeMapInv.put(mnode, node);
nodeList.add(mnode);
}
// convert surface mesh
FemMeshComp surfaceFem = fem.getSurfaceMeshComp();
PolygonalMesh mesh = (PolygonalMesh) surfaceFem.getMesh();
// build mesh
PolygonalMesh mesh2 = mesh.copy();
// index vertices
int idx = 0;
for (Vertex3d vtx : mesh.getVertices()) {
vtx.setIndex(idx++);
}
idx = 0;
for (Vertex3d vtx : mesh2.getVertices()) {
vtx.setIndex(idx++);
}
MFreeMeshComp surfaceMFree = new MFreeMeshComp(model, "surface");
surfaceMFree.setMesh(mesh2);
// manually build surface attachments
for (Vertex3d vtx : mesh.getVertices()) {
PointAttachment pa = surfaceFem.getAttachment(vtx.getIndex());
if (pa instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) pa;
FemNode[] masters = pfa.getNodes();
MFreeNode3d[] deps = new MFreeNode3d[masters.length];
VectorNd coords = new VectorNd(masters.length);
for (int j = 0; j < masters.length; j++) {
// mlist.add (new ContactMaster (masters[j], pfa.getCoordinate(j)));
deps[j] = nodeMap.get(masters[j]);
coords.set(j, pfa.getCoordinate(j));
}
surfaceMFree.setVertexAttachment(vtx.getIndex(), coords.getBuffer(), deps);
} else {
PointParticleAttachment ppa = (PointParticleAttachment) pa;
DynamicComponent[] masters = ppa.getMasters();
MFreeNode3d[] deps = new MFreeNode3d[1];
deps[0] = nodeMap.get(masters[0]);
VectorNd coords = new VectorNd(new double[] { 1 });
surfaceMFree.setVertexAttachment(vtx.getIndex(), coords.getBuffer(), deps);
}
}
// integration regions by copying elements
ArrayList<MFreeElement3d> elemList = new ArrayList<MFreeElement3d>(fem.numElements());
HashMap<FemElement3d, MFreeElement3d> elemMap = new HashMap<FemElement3d, MFreeElement3d>(fem.numElements());
for (FemElement3d elem : fem.getElements()) {
MFreeNode3d[] elemNodes = new MFreeNode3d[elem.numNodes()];
FemNode3d[] fnodes = elem.getNodes();
for (int i = 0; i < elem.numNodes(); i++) {
elemNodes[i] = nodeMap.get(fnodes[i]);
}
MFreeElement3d region = new MFreeElement3d(null, elemNodes);
// region.setAllTermsActive(true);
MFreeIntegrationPoint3d[] mpnts = new MFreeIntegrationPoint3d[elem.numIntegrationPoints()];
IntegrationData3d[] mdata = new IntegrationData3d[elem.numIntegrationPoints()];
IntegrationPoint3d[] ipnts = elem.getIntegrationPoints();
IntegrationData3d[] idata = elem.getIntegrationData();
for (int i = 0; i < ipnts.length; i++) {
Point3d pos = new Point3d();
ipnts[i].computePosition(pos, elem.getNodes());
Vector3d[] gradU = ipnts[i].getGNs();
ArrayList<Vector3d> grads = new ArrayList<Vector3d>();
for (Vector3d g : gradU) {
grads.add(g);
}
MFreeIntegrationPoint3d mpnt = MFreeIntegrationPoint3d.create(elemNodes, ipnts[i].getShapeWeights(), grads, ipnts[i].getWeight());
IntegrationData3d mdat = new IntegrationData3d();
mdat.setRestInverseJacobian(idata[i].getInvJ0(), idata[i].getDetJ0());
mpnts[i] = mpnt;
mdata[i] = mdat;
}
// set warping point
if (region.getWarpingPoint() == null) {
IntegrationPoint3d wpnt = elem.getWarpingPoint();
IntegrationData3d wdat = elem.getWarpingData();
Point3d pos = new Point3d();
wpnt.computePosition(pos, elem.getNodes());
// Vector3d [] gradU = wpnt.updateShapeGradient(wdat.getInvJ0());
Vector3d[] gradU = wpnt.getGNs();
ArrayList<Vector3d> grads = new ArrayList<Vector3d>();
for (Vector3d g : gradU) {
grads.add(g);
}
// MFreeIntegrationPoint3d mpnt =
// MFreeIntegrationPoint3d.create(pos, deps,
// wpnt.getShapeWeights(), grads, wpnt.getWeight()*wdat.getDetJ0());
MFreeIntegrationPoint3d mpnt = MFreeIntegrationPoint3d.create(elemNodes, wpnt.getShapeWeights(), grads, wpnt.getWeight());
region.setWarpingPoint(mpnt);
IntegrationData3d wdata = new IntegrationData3d();
wdata.setRestInverseJacobian(wdat.getInvJ0(), wdat.getDetJ0());
region.setWarpingPoint(mpnt, wdata);
}
region.setIntegrationPoints(mpnts, mdata);
elemList.add(region);
elemMap.put(elem, region);
}
// add everything to model
model.addNodes(nodeList);
model.addElements(elemList);
model.setSurfaceMeshComp(surfaceMFree);
// copy properties
model.setDensity(fem.getDensity());
model.setParticleDamping(fem.getParticleDamping());
model.setStiffnessDamping(fem.getStiffnessDamping());
// copy over all masses
for (FemNode3d node : fem.getNodes()) {
nodeMap.get(node).setMass(node.getMass());
}
for (FemElement3d elem : fem.getElements()) {
elemMap.get(elem).setMass(elem.getMass());
}
model.setMaterial(fem.getMaterial());
return model;
}
use of maspack.matrix.VectorNd in project artisynth_core by artisynth.
the class MFreeFactory method createWarpingPoint.
private static MFreeIntegrationPoint3d createWarpingPoint(MFreeElement3d elem, Point3d pos, BVTree nodeTree) {
if (pos == null) {
pos = new Point3d();
elem.computeCentroid(pos);
}
MFreeNode3d[] deps = findNodesContaining(pos, nodeTree, 0);
VectorNd coords = new VectorNd(deps.length);
ArrayList<Vector3d> grad = new ArrayList<Vector3d>(deps.length);
getShapeCoordsAndGradients(elem.getShapeFunction(), coords, grad, pos, deps);
return MFreeIntegrationPoint3d.create(deps, coords, grad, 1);
}
use of maspack.matrix.VectorNd in project artisynth_core by artisynth.
the class MFreeIntegrationPoint3d method setDependentNodes.
public void setDependentNodes(FemNode3d[] nodes, VectorNd coords) {
myDependentNodes = Arrays.copyOf(nodes, nodes.length);
super.init(myDependentNodes.length, 1);
// XXX default pressure weights?
setPressureWeights(new VectorNd(new double[] { 1 }));
setNodeCoordinates(coords);
updateSlavePos();
computeRestPosition(myRest);
setCoords(myRest.x, myRest.y, myRest.z);
}
use of maspack.matrix.VectorNd in project artisynth_core by artisynth.
the class MFreeMeshComp method createEmbedded.
/**
* Assumes the mesh is in "rest" coordinates, not current coordinates
* @param surf mfree surface to populate (or null to create one)
* @param mesh mesh to embed
* @param mfree model to embed mesh in
* @return populated or created mesh
*/
public static MFreeMeshComp createEmbedded(MFreeMeshComp surf, MeshBase mesh, MFreeModel3d mfree) {
double reduceTol = 1e-8;
ArrayList<MFreeNode3d> nodes = new ArrayList<MFreeNode3d>();
VectorNd weights = new VectorNd();
if (surf == null) {
surf = new MFreeMeshComp(mfree);
}
surf.setMesh(mesh);
ArrayList<Vertex3d> verts = mesh.getVertices();
Point3d coords = new Point3d();
ArrayList<FemNode3d> deps = new ArrayList<>();
MLSShapeFunction sfunc = new MLSShapeFunction();
surf.myVertexAttachments.clear();
for (int i = 0; i < verts.size(); i++) {
// this could works very similarly to the code that adds
// marker points into a mesh
Vertex3d vtx = verts.get(i);
deps.clear();
mfree.findDependentNodesAtRest(vtx.pnt, deps);
// compute shape function
VectorNd N = new VectorNd(deps.size());
MFreeNode3d[] dnodes = deps.toArray(new MFreeNode3d[deps.size()]);
sfunc.update(vtx.pnt, dnodes);
sfunc.eval(N);
// first see if there's a node within reduceTol of the point,
// and if so just use that
double maxDist = Double.NEGATIVE_INFINITY;
double minDist = Double.POSITIVE_INFINITY;
MFreeNode3d nearestNode = null;
for (int k = 0; k < dnodes.length; k++) {
double d = vtx.pnt.distance(dnodes[k].getRestPosition());
if (d > maxDist) {
maxDist = d;
}
if (d < minDist) {
minDist = d;
nearestNode = dnodes[k];
}
}
if (minDist / maxDist <= reduceTol) {
// weight everything to the nearest node
nodes.clear();
nodes.add(nearestNode);
weights.setSize(0);
weights.append(1.0);
} else {
nodes.clear();
weights.setSize(0);
for (int k = 0; k < N.size(); k++) {
if (Math.abs(N.get(k)) >= reduceTol) {
nodes.add(dnodes[k]);
weights.append(N.get(k));
}
}
}
if (weights.size() > 1) {
PointFem3dAttachment attacher = new PointFem3dAttachment();
attacher.setFromNodes(nodes, weights);
surf.myVertexAttachments.add(attacher);
} else if (weights.size() == 1) {
PointParticleAttachment attacher = new PointParticleAttachment(nodes.get(0), null);
surf.myVertexAttachments.add(attacher);
}
}
surf.buildNodeVertexMap();
return surf;
}
Aggregations