use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.
the class PointFem3dAttachment method updateMasterBlocks.
@Override
protected int updateMasterBlocks() {
int idx = super.updateMasterBlocks();
RotationMatrix3d R1 = null;
RotationMatrix3d R2 = null;
if (idx == 1) {
// then the point also has a frame; set R1 to that frame's rotation
R1 = myPoint.getPointFrame().getPose().R;
}
myNoFrameRelativeP = false;
if (myFemFrame != null) {
R2 = myFemFrame.getPose().R;
// local position in FemFrame
Point3d lpos = new Point3d();
lpos.inverseTransform(myFemFrame.getPose(), myPoint.getPosition());
myFemFrame.computeLocalPointForceJacobian(myMasterBlocks[idx++], lpos, R1);
} else if (R1 == null) {
myNoFrameRelativeP = true;
}
if (!myNoFrameRelativeP) {
RotationMatrix3d R = new RotationMatrix3d();
if (R1 != null && R2 != null) {
R.mulInverseLeft(R2, R1);
} else if (R1 != null) {
R.set(R1);
} else if (R2 != null) {
R.transpose(R2);
}
for (int i = 0; i < myNodes.length; i++) {
Matrix3x3Block pblk = (Matrix3x3Block) myMasterBlocks[idx++];
pblk.scale(myCoords.get(i), R);
}
} else {
// no need to update blocks since blocks will not be used
}
return idx;
}
use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.
the class PointSkinAttachment method computePosState.
/**
* Computes this attachment's point value from all the underlying master
* components to which it is connected.
*/
protected void computePosState(Vector3d pos, SkinMeshBody skinMesh) {
DualQuaternion tmpQ = null;
DualQuaternion[] dualqs = null;
double[] weights = null;
pos.setZero();
Point3d tmp = new Point3d();
// frame counter for interative dualQuaternion blending
int fidx = 0;
// weight for just the dual quaternion part
double dualw = 0;
for (int k = 0; k < myNumConnections; k++) {
Connection c = myConnections[k];
if (!c.accumulate(pos, tmp)) {
// Go case-by-case when accumulate method is inactive
if (c instanceof FrameConnection) {
FrameInfo finfo = ((FrameConnection) c).myFrameInfo;
switch(skinMesh.getFrameBlending()) {
case DUAL_QUATERNION_LINEAR:
{
if (tmpQ == null) {
tmpQ = new DualQuaternion();
tmpQ.scale(c.myWeight, finfo.myBlendQuaternion);
} else {
tmpQ.scaledAdd(c.myWeight, finfo.myBlendQuaternion);
}
dualw += c.myWeight;
break;
}
case DUAL_QUATERNION_ITERATIVE:
{
if (weights == null) {
int numf = skinMesh.numFrames();
weights = new double[numf];
dualqs = new DualQuaternion[numf];
}
dualqs[fidx] = finfo.myBlendQuaternion;
weights[fidx] = c.myWeight;
dualw += c.myWeight;
fidx++;
break;
}
default:
break;
}
}
}
}
if (tmpQ != null) {
tmpQ.normalize();
tmpQ.transform(tmp, myBasePos);
pos.scaledAdd(dualw, tmp);
} else if (skinMesh.getFrameBlending() == FrameBlending.DUAL_QUATERNION_ITERATIVE && fidx > 0) {
tmpQ = new DualQuaternion();
tmpQ.dualQuaternionIterativeBlending(weights, dualqs, fidx, SkinMeshBody.DQ_BLEND_TOLERANCE, SkinMeshBody.DQ_MAX_BLEND_STEPS);
tmpQ.transform(tmp, myBasePos);
pos.scaledAdd(dualw, tmp);
}
}
use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.
the class MFreeMeshComp 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 artisynth.core.mechmodels.Point in project artisynth_core by artisynth.
the class MFreeModel3d method findNaturalCoordinates.
/**
* Finds the containing element and node coordinates
* @param pnt 3D point in world coordinates to find natural coordinates of
* @param coords natural coordinates
* @param N shape function values
* @return the containing element if it exists
*/
public FemNode3d[] findNaturalCoordinates(Point3d pnt, Point3d coords, VectorNd N) {
BVFeatureQuery query = new BVFeatureQuery();
NearestIPointCalculator dcalc = new NearestIPointCalculator(pnt);
query.nearestObject(getElementBVTree(), dcalc);
FemElement3d elem = dcalc.nearestObject();
MFreeIntegrationPoint3d ipnt = dcalc.nearestIPoint();
// try to compute coords
coords.set(ipnt.getRestPosition());
int n = ((MFreeElement3d) elem).getNaturalCoordinates(coords, pnt, 1000, N);
return elem.getNodes();
}
use of artisynth.core.mechmodels.Point in project artisynth_core by artisynth.
the class MFreeModel3d method findDependentNodesAtRest.
/**
* Finds nodes containing the given point at rest
* @param pnt point to find nodes for
* @param out output list of nodes influencing region
* @return number of nodes found
*/
public int findDependentNodesAtRest(Point3d pnt, List<FemNode3d> out) {
AABBTree nodeTree = myRestNodeTree;
if (nodeTree == null) {
nodeTree = buildRestNodeTree(myNodes);
myRestNodeTree = nodeTree;
}
ArrayList<BVNode> bvNodes = new ArrayList<BVNode>(16);
nodeTree.intersectPoint(bvNodes, pnt);
if (bvNodes.size() == 0) {
return 0;
}
int count = 0;
for (BVNode n : bvNodes) {
Boundable[] elements = n.getElements();
for (int i = 0; i < elements.length; i++) {
RestNode rnode = (RestNode) elements[i];
FemNode3d node = rnode.getNode();
if (((MFreeNode3d) node).isInDomain(pnt, 0)) {
out.add(node);
++count;
}
}
}
return count;
}
Aggregations