use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class MFreeMeshComp method buildNodeVertexMap.
protected void buildNodeVertexMap() {
myNodeVertexMap = new HashMap<MFreeNode3d, Vertex3d>();
myNumSingleAttachments = 0;
for (int i = 0; i < myVertexAttachments.size(); i++) {
PointAttachment pa = myVertexAttachments.get(i);
if (pa instanceof PointParticleAttachment) {
MFreeNode3d node = (MFreeNode3d) ((PointParticleAttachment) pa).getParticle();
myNodeVertexMap.put(node, getMesh().getVertex(i));
myNumSingleAttachments++;
} else if (pa instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) pa;
for (FemNode node : pfa.getNodes()) {
if (myNodeVertexMap.get(node) == null) {
myNodeVertexMap.put((MFreeNode3d) node, NO_SINGLE_VERTEX);
}
}
}
}
}
use of maspack.geometry.Vertex3d 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;
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class MFreeMeshComp method copy.
@Override
public MFreeMeshComp copy(int flags, Map<ModelComponent, ModelComponent> copyMap) {
MFreeMeshComp fm = (MFreeMeshComp) super.copy(flags, copyMap);
MFreeModel3d newFem = (MFreeModel3d) copyMap.get(myModel);
if (newFem != null) {
fm.myModel = newFem;
} else {
fm.myModel = myModel;
}
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 MFreeMuscleModel method getSegmentInsideSphere.
// intersects segment with the given sphere, and returns
// the portion inside or null if no intersection
private static LineSegment getSegmentInsideSphere(LineSegment segment, Point3d pos, double rad) {
Point3d p1 = segment.myVtx0.getPosition();
Point3d p2 = segment.myVtx1.getPosition();
// check if segment starts inside
boolean isP1Inside = isInsideSphere(p1, pos, rad);
// p2-c
Point3d p = new Point3d();
// p1-p2
Point3d dp = new Point3d();
double r2 = rad * rad;
// for use with quadratic equation
double a, b, c, d, lambda1, lambda2;
p.sub(p2, pos);
dp.sub(p1, p2);
// find intersection with sphere
a = dp.normSquared();
b = 2 * dp.dot(p);
c = p.normSquared() - r2;
d = b * b - 4 * a * c;
if (d >= 0) {
d = Math.sqrt(d);
lambda1 = (-b + d) / (2 * a);
lambda2 = (-b - d) / (2 * a);
} else {
lambda1 = Double.NaN;
lambda2 = Double.NaN;
}
// if p2 is inside, return
if (p.normSquared() <= r2) {
if (isP1Inside) {
return segment;
} else {
// find intersection
if (lambda1 >= 0 && lambda1 <= 1) {
p1.scaledAdd(lambda1, dp, p2);
} else {
p1.scaledAdd(lambda2, dp, p2);
}
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
}
} else {
// if p1 inside, find single intersection
if (isP1Inside) {
if (lambda1 >= 0 && lambda1 <= 1) {
p2.scaledAdd(lambda1, dp);
} else {
p2.scaledAdd(lambda2, dp);
}
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
} else {
// check if passes entirely through sphere
if (d >= 0) {
if (lambda1 >= 0 && lambda1 <= 1 && lambda2 >= 0 && lambda2 <= 1) {
p1.scaledAdd(lambda1, dp, p2);
p2.scaledAdd(lambda2, dp);
return new LineSegment(new Vertex3d(p1), new Vertex3d(p2));
}
}
// done checking if crossed sphere
}
// done checking if p1 outside
}
return null;
}
use of maspack.geometry.Vertex3d in project artisynth_core by artisynth.
the class FemDisplayProbe method updateVertexColoringRest.
/**
* Updates vertex colors
*/
protected void updateVertexColoringRest() {
RenderProps rprops = getRenderProps();
float alpha = (float) rprops.getAlpha();
Color faceColor = rprops.getFaceColor();
float backAlpha = (float) myBackgroundAlpha * alpha;
Color femFaceColor = null;
double stressVal = 0;
if (mySurfaceRendering == SurfaceRender.Stress || mySurfaceRendering == SurfaceRender.Strain) {
if (myStressPlotRanging == Ranging.Auto) {
myStressPlotRange.merge(myFem.getNodalPlotRange(mySurfaceRendering));
}
} else {
femFaceColor = myFem.getRenderProps().getFaceColor();
}
float[] carray = new float[3];
// use our stored map of values
for (Vertex3d vtx : myPlaneSurface.getVertices()) {
if (!vtxIndicatorMap.containsKey(vtx) || !vtxIndicatorMap.get(vtx)) {
setColor(vtx, faceColor, backAlpha);
} else {
VtxInfo vtxInfo;
switch(mySurfaceRendering) {
case None:
setColor(vtx, faceColor, alpha);
break;
case Strain:
vtxInfo = clippedVtxMap.get(vtx);
if (vtxInfo != null) {
stressVal = getStrainValue(vtxInfo);
myColorMap.getRGB(stressVal / myStressPlotRange.getRange(), carray);
setColor(vtx, carray[0], carray[1], carray[2], alpha);
} else {
setColor(vtx, femFaceColor, backAlpha);
}
break;
case Stress:
vtxInfo = clippedVtxMap.get(vtx);
if (vtxInfo != null) {
stressVal = getStressValue(clippedVtxMap.get(vtx));
myColorMap.getRGB(stressVal / myStressPlotRange.getRange(), carray);
setColor(vtx, carray[0], carray[1], carray[2], alpha);
} else {
setColor(vtx, femFaceColor, backAlpha);
}
break;
default:
setColor(vtx, femFaceColor, alpha);
}
}
}
}
Aggregations