use of artisynth.core.mechmodels.DynamicAttachment in project artisynth_core by artisynth.
the class FemModel3d method subdivideHex.
public void subdivideHex(HexElement hex) {
if (hex.getParent() != myElements) {
throw new IllegalArgumentException("Hex is not contained in this model");
}
LinkedList<FemNode3d> addedNodes = new LinkedList<FemNode3d>();
LinkedList<FemElement3d> addedElements = new LinkedList<FemElement3d>();
LinkedList<DynamicAttachment> addedAttachments = new LinkedList<DynamicAttachment>();
LinkedList<DynamicAttachment> removedAttachments = new LinkedList<DynamicAttachment>();
int idx = 0;
FemNode3d[] nodes = new FemNode3d[27];
for (FemNode3d n : hex.getNodes()) {
nodes[idx++] = n;
}
for (int i = 0; i < 12; i++) {
// for each edge ...
FemNode3d n0 = nodes[HexElement.edgeIdxs[2 * i + 0]];
FemNode3d n1 = nodes[HexElement.edgeIdxs[2 * i + 1]];
PointFem3dAttachment edgeAttach = getEdgeAttachment(n0, n1);
FemNode3d edgeNode;
if (edgeAttach != null) {
// use the existing mid node as the edge node
edgeNode = (FemNode3d) edgeAttach.getSlave();
if (numElementsWithEdge(n0, n1) == 1) {
// don't need the attachment any more, so remove it
removedAttachments.add(edgeAttach);
}
} else {
edgeNode = createNode(new FemNode3d[] { n0, n1 });
addedNodes.add(edgeNode);
if (numElementsWithEdge(n0, n1) > 1) {
PointFem3dAttachment a = new PointFem3dAttachment(edgeNode);
a.setFromNodes(new FemNode[] { n0, n1 }, edgeWeights);
addedAttachments.add(a);
}
}
nodes[idx++] = edgeNode;
}
for (int i = 0; i < 6; i++) {
// for each face ...
FemNode3d n0 = nodes[HexElement.faceIdxs[4 * i + 0]];
FemNode3d n1 = nodes[HexElement.faceIdxs[4 * i + 1]];
FemNode3d n2 = nodes[HexElement.faceIdxs[4 * i + 2]];
FemNode3d n3 = nodes[HexElement.faceIdxs[4 * i + 3]];
PointFem3dAttachment faceAttach = getFaceAttachment(n0, n1, n2, n3);
FemNode3d faceNode;
if (faceAttach != null) {
// use the existing center node as the face node
faceNode = (FemNode3d) faceAttach.getSlave();
if (numElementsWithFace(n0, n1, n2, n3) == 1) {
// don't need the attachment any more, so remove it
removedAttachments.add(faceAttach);
}
} else {
faceNode = createNode(new FemNode3d[] { n0, n1, n2, n3 });
addedNodes.add(faceNode);
if (numElementsWithFace(n0, n1, n2, n3) > 1) {
PointFem3dAttachment a = new PointFem3dAttachment(faceNode);
a.setFromNodes(new FemNode[] { n0, n1, n2, n3 }, faceWeights);
addedAttachments.add(a);
}
}
nodes[idx++] = faceNode;
}
FemNode3d centerNode = createNode((FemNode3d[]) hex.getNodes());
addedNodes.add(centerNode);
nodes[idx++] = centerNode;
addedElements.add(createHex(nodes, 0, 8, 20, 11, 16, 24, 26, 23));
addedElements.add(createHex(nodes, 8, 1, 9, 20, 24, 17, 21, 26));
addedElements.add(createHex(nodes, 20, 9, 2, 10, 26, 21, 18, 25));
addedElements.add(createHex(nodes, 11, 20, 10, 3, 23, 26, 25, 19));
addedElements.add(createHex(nodes, 16, 24, 26, 23, 4, 12, 22, 15));
addedElements.add(createHex(nodes, 24, 17, 21, 26, 12, 5, 13, 22));
addedElements.add(createHex(nodes, 26, 21, 18, 25, 22, 13, 6, 14));
addedElements.add(createHex(nodes, 23, 26, 25, 19, 15, 22, 14, 7));
for (DynamicAttachment a : removedAttachments) {
removeAttachment(a);
}
removeElement(hex);
for (FemNode3d n : addedNodes) {
addNode(n);
}
for (FemElement3d e : addedElements) {
addElement(e);
}
for (DynamicAttachment a : addedAttachments) {
addAttachment(a);
}
}
use of artisynth.core.mechmodels.DynamicAttachment in project artisynth_core by artisynth.
the class FemModel3d method copy.
@Override
public FemModel3d copy(int flags, Map<ModelComponent, ModelComponent> copyMap) {
if (copyMap == null) {
copyMap = new HashMap<ModelComponent, ModelComponent>();
flags = CopyableComponent.COPY_REFERENCES;
}
FemModel3d fem = (FemModel3d) super.copy(flags, copyMap);
// fem.myFrame was created in super.copy(), but we redo this
// so as to create an exact copy of the orginal frame
FemModelFrame newFrame = myFrame.copy(flags, copyMap);
newFrame.setName(myFrame.getName());
copyMap.put(myFrame, newFrame);
fem.myFrame = newFrame;
if (myFrameConstraint != null) {
fem.attachFrame(myFrame.getPose());
} else {
fem.attachFrame(null);
}
fem.myFrameRelativeP = myFrameRelativeP;
for (FemNode3d n : myNodes) {
FemNode3d newn = n.copy(flags, copyMap);
newn.setName(n.getName());
copyMap.put(n, newn);
fem.myNodes.addNumbered(newn, n.getNumber());
fem.myNodes.setRenderProps(myNodes.getRenderProps());
}
for (FemElement3d e : myElements) {
FemElement3d newe = e.copy(flags, copyMap);
newe.setName(e.getName());
copyMap.put(e, newe);
fem.myElements.addNumbered(newe, e.getNumber());
fem.myElements.setRenderProps(myElements.getRenderProps());
}
for (FemMarker m : myMarkers) {
FemMarker newm = m.copy(flags, copyMap);
newm.setName(m.getName());
fem.myMarkers.addNumbered(newm, m.getNumber());
fem.myMarkers.setRenderProps(myMarkers.getRenderProps());
}
for (DynamicAttachment a : myAttachments) {
DynamicAttachment newa = a.copy(flags, copyMap);
newa.setName(a.getName());
fem.myAttachments.addNumbered(newa, a.getNumber());
}
fem.ansysElemProps = new HashMap<FemElement3d, int[]>();
for (Map.Entry<FemElement3d, int[]> ent : ansysElemProps.entrySet()) {
FemElement3d newe = (FemElement3d) copyMap.get(ent.getKey());
int[] props = ArraySupport.copy(ent.getValue());
fem.ansysElemProps.put(newe, props);
}
for (int i = 0; i < myMeshList.size(); i++) {
FemMeshComp mc = myMeshList.get(i);
FemMeshComp newFmc = mc.copy(flags, copyMap);
if (i == 0) {
fem.myMeshList.addFixed(newFmc);
} else {
fem.addMeshComp(newFmc);
}
// do this this since addMesh sets collidability by default
newFmc.setCollidable(mc.getCollidable());
}
fem.myAutoGenerateSurface = myAutoGenerateSurface;
fem.mySurfaceMeshValid = mySurfaceMeshValid;
fem.myInternalSurfaceMeshComp = null;
fem.setElementWidgetSizeMode(myElementWidgetSizeMode);
if (myElementWidgetSizeMode == PropertyMode.Explicit) {
fem.setElementWidgetSize(myElementWidgetSize);
}
fem.clearCachedData(null);
fem.myAABBTree = null;
fem.myBVTreeValid = false;
fem.mySolveMatrixFile = null;
fem.myNumIncompressConstraints = 0;
fem.myHardIncompUpdateTime = -1;
fem.myComputeNodalStress = myComputeNodalStress;
fem.myComputeNodalStrain = myComputeNodalStrain;
fem.myHardIncompMethod = myHardIncompMethod;
fem.myHardIncompMethodValidP = myHardIncompMethodValidP;
fem.mySoftIncompMethod = mySoftIncompMethod;
fem.mySoftIncompMethodValidP = mySoftIncompMethodValidP;
fem.myNodalIncompBlocksAllocatedP = false;
fem.myNodalIncompConstraintsAllocatedP = false;
fem.myPressures = new VectorNd(MAX_PRESSURE_VALS);
fem.myKp = new double[MAX_PRESSURE_VALS];
fem.myNodalConstraints = new Vector3d[MAX_NODAL_INCOMP_NODES];
for (int i = 0; i < MAX_NODAL_INCOMP_NODES; i++) {
fem.myNodalConstraints[i] = new Vector3d();
}
return fem;
}
use of artisynth.core.mechmodels.DynamicAttachment in project artisynth_core by artisynth.
the class FemMeshComp method getEdgeNodes.
// public static FemMeshComp createSurface (FemModel3d fem, int resolution) {
// return createSurface (new FemMeshComp (fem), resolution);
// }
// private static boolean containsNode(FemNode3d n, FemNode[] nodes) {
// for (int i = 0; i < nodes.length; i++) {
// if (nodes[i] == n) {
// return true;
// }
// }
// return false;
// }
private ArrayList<FemNode3d> getEdgeNodes(FemNode3d n0, FemNode3d n1, FemModel3d fem) {
LinkedList<DynamicAttachment> masters = n0.getMasterAttachments();
if (masters == null) {
return null;
}
ArrayList<FemNode3d> nodes = new ArrayList<FemNode3d>();
ArrayList<Double> weights = new ArrayList<Double>();
for (DynamicAttachment a : masters) {
if (a instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) a;
if (pfa.numMasters() == 2 && pfa.getSlave() instanceof FemNode3d) {
FemNode3d slaveNode = (FemNode3d) pfa.getSlave();
if (slaveNode.getGrandParent() == fem && FemModel3d.containsNode(n1, pfa.getNodes())) {
nodes.add(slaveNode);
double w = pfa.getCoordinates().get(0);
if (n0 == pfa.getNodes()[0]) {
weights.add(w);
} else {
weights.add(1 - w);
}
}
}
}
}
// just do a bubble sort; easier to implement
for (int i = 0; i < nodes.size() - 1; i++) {
for (int j = i + 1; j < nodes.size(); j++) {
if (weights.get(j) < weights.get(i)) {
double w = weights.get(i);
weights.set(i, weights.get(j));
weights.set(j, w);
FemNode3d n = nodes.get(i);
nodes.set(i, nodes.get(j));
nodes.set(j, n);
}
}
}
return nodes;
}
use of artisynth.core.mechmodels.DynamicAttachment in project artisynth_core by artisynth.
the class FemModel3d method getEdgeAttachment.
static PointFem3dAttachment getEdgeAttachment(FemNode3d n0, FemNode3d n1) {
double weight = 0;
PointFem3dAttachment attachment = null;
LinkedList<DynamicAttachment> masters = n0.getMasterAttachments();
if (masters == null) {
return null;
}
for (DynamicAttachment a : masters) {
if (a instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) a;
if (pfa.numMasters() == 2 && pfa.getSlave() instanceof FemNode3d) {
if (containsNode(n1, pfa.getNodes())) {
double w = pfa.getCoordinates().get(0);
if (Math.abs(w - 0.5) < Math.abs(weight - 0.5)) {
// this point is closer
attachment = pfa;
}
}
}
}
}
return attachment;
}
use of artisynth.core.mechmodels.DynamicAttachment in project artisynth_core by artisynth.
the class FemModel3d method getFaceAttachment.
private PointFem3dAttachment getFaceAttachment(FemNode3d n0, FemNode3d n1, FemNode3d n2, FemNode3d n3) {
VectorNd idealWeights = new VectorNd(faceWeights);
double mindist = Double.MAX_VALUE;
PointFem3dAttachment attachment = null;
LinkedList<DynamicAttachment> masters = n0.getMasterAttachments();
if (masters == null) {
return null;
}
for (DynamicAttachment a : masters) {
if (a instanceof PointFem3dAttachment) {
PointFem3dAttachment pfa = (PointFem3dAttachment) a;
if (pfa.numMasters() == 4 && pfa.getSlave() instanceof FemNode3d) {
FemNode[] nodes = pfa.getNodes();
if (containsNode(n1, nodes) && containsNode(n2, nodes) && containsNode(n3, nodes)) {
double d = idealWeights.distance(pfa.getCoordinates());
if (d < mindist) {
mindist = d;
attachment = pfa;
}
}
}
}
}
return attachment;
}
Aggregations