Search in sources :

Example 1 with FemMuscleModel

use of artisynth.core.femmodels.FemMuscleModel in project artisynth_core by artisynth.

the class FemMuscleDemo method createMusclePanel.

public void createMusclePanel() {
    ControlPanel myControlPanel = new ControlPanel("options", "LiveUpdate");
    FemControlPanel.addMuscleControls(myControlPanel, tissue, myModel);
    myControlPanel.addWidget(tissue, "profile");
    ComponentList<MuscleBundle> muscles = ((FemMuscleModel) tissue).getMuscleBundles();
    for (int i = 0; i < muscles.size(); ++i) {
        DoubleFieldSlider slider = (DoubleFieldSlider) myControlPanel.addWidget("activation [N per Muscle]", this, "models/FemBeam/models/fem/bundles/" + i + ":excitation", 0, 1);
        slider.setRoundingTolerance(0.00001);
        slider.getLabel().setForeground(getMuscleColor(i));
        BooleanSelector checkBox = (BooleanSelector) PropertyWidget.create("", muscles.get(i), "renderProps.visible");
        checkBox.addValueChangeListener(new ValueChangeListener() {

            public void valueChange(ValueChangeEvent e) {
                rerender();
            }
        });
        slider.add(checkBox);
    }
    for (int i = 0; i < muscles.size(); ++i) {
        BooleanSelector selector = (BooleanSelector) myControlPanel.addWidget("fibres active", this, "models/FemBeam/models/fem/bundles/" + i + ":fibresActive");
        selector.getLabel().setForeground(getMuscleColor(i));
        BooleanSelector checkBox = (BooleanSelector) PropertyWidget.create("", muscles.get(i).getFibres(), "renderProps.visible");
        checkBox.addValueChangeListener(new ValueChangeListener() {

            public void valueChange(ValueChangeEvent e) {
                rerender();
            }
        });
        selector.add(checkBox);
    }
    addControlPanel(myControlPanel);
}
Also used : MuscleBundle(artisynth.core.femmodels.MuscleBundle) ValueChangeEvent(maspack.widgets.ValueChangeEvent) ValueChangeListener(maspack.widgets.ValueChangeListener) BooleanSelector(maspack.widgets.BooleanSelector) ControlPanel(artisynth.core.gui.ControlPanel) FemControlPanel(artisynth.core.gui.FemControlPanel) FemMuscleModel(artisynth.core.femmodels.FemMuscleModel) Point(artisynth.core.mechmodels.Point) DoubleFieldSlider(maspack.widgets.DoubleFieldSlider)

Example 2 with FemMuscleModel

use of artisynth.core.femmodels.FemMuscleModel in project artisynth_core by artisynth.

the class FemMuscleDemo method initializeModel.

protected void initializeModel(int xn) throws IOException {
    double widthX = 0.09;
    double widthY = 0.03;
    double widthZ = 0.03;
    int numX = xn * 9;
    int numY = xn * 3;
    int numZ = xn * 3;
    tissue = new FemMuscleModel("fem");
    FemFactory.createHexGrid(tissue, widthX, widthY, widthZ, numX, numY, numZ);
    tissue.setBounds(new Point3d(-widthX, 0, 0), new Point3d(widthX, 0, 0));
    // XXX fix the leftmost nodes
    double EPS = 1e-9;
    double xmin = Double.POSITIVE_INFINITY;
    for (FemNode3d n : tissue.getNodes()) {
        if (n.getPosition().x < xmin) {
            xmin = n.getPosition().x;
        }
    }
    for (FemNode3d n : tissue.getNodes()) {
        if (Math.abs(n.getPosition().x - xmin) < 1e-10) {
            n.setDynamic(false);
        }
    }
    LinkedList<FemElement3d> topElems = new LinkedList<FemElement3d>();
    LinkedList<FemElement3d> midElems = new LinkedList<FemElement3d>();
    LinkedList<FemElement3d> botElems = new LinkedList<FemElement3d>();
    for (FemElement3d e : tissue.getElements()) {
        if (defaultMidElements == ALL) {
            midElems.add(e);
        }
        for (FemNode3d n : e.getNodes()) {
            if (Math.abs(n.getPosition().z - widthZ / 2) < EPS) {
                topElems.add(e);
                break;
            } else if (Math.abs(n.getPosition().z + widthZ / 2) < EPS) {
                botElems.add(e);
                break;
            } else if (defaultMidElements == MIDDLE && Math.abs(n.getPosition().z - widthZ / (2 * numZ)) < EPS) {
                midElems.add(e);
                break;
            }
        }
    }
    RenderProps.setLineWidth(tissue, 2);
    RenderProps.setLineColor(tissue, Color.PINK);
    RenderProps.setPointStyle(tissue, Renderer.PointStyle.SPHERE);
    RenderProps.setPointRadius(tissue, 0.03);
    RenderProps.setPointColor(tissue, Color.PINK);
    RenderProps.setFaceColor(tissue, Color.PINK.darker());
    GenericMuscle mm = new GenericMuscle();
    mm.setMaxStress(5000);
    BlemkerMuscle bm = new BlemkerMuscle();
    // bm.setMaxStress (5000);
    tissue.setMuscleMaterial(bm);
    MuscleBundle top, mid, bot;
    top = createBundle("top", topElems);
    mid = createBundle("mid", midElems);
    bot = createBundle("bot", botElems);
    int k = 0;
    setBundleRenderProps(top, getMuscleColor(k++));
    if (addMidMuscle) {
        setBundleRenderProps(mid, getMuscleColor(k++));
    }
    setBundleRenderProps(bot, getMuscleColor(k));
    tissue.addMuscleBundle(top);
    if (addMidMuscle) {
        tissue.addMuscleBundle(mid);
    }
    tissue.addMuscleBundle(bot);
    double qt = midQuadTerm;
    addStrand(top, -0.035, -0.005, 0.015, 0.035, -0.005, 0.015, 0, 8);
    addStrand(top, -0.035, 0.005, 0.015, 0.035, 0.005, 0.015, 0, 8);
    if (addMidMuscle) {
        addStrand(mid, -0.035, -0.005, 0.000, 0.035, -0.005, 0.000, qt, 8);
        addStrand(mid, -0.035, 0.005, 0.000, 0.035, 0.005, 0.000, qt, 8);
    }
    addStrand(bot, -0.035, -0.005, -0.015, 0.035, -0.005, -0.015, 0, 8);
    addStrand(bot, -0.035, 0.005, -0.015, 0.035, 0.005, -0.015, 0, 8);
    if (addMidMuscle) {
        if (addMidElementsWithin > 0) {
            mid.addElementsNearFibres(addMidElementsWithin);
        }
        if (autoComputeMidDirections) {
            mid.computeElementDirections();
        }
    }
    tissue.setDirectionRenderLen(0.5);
    RenderProps.setPointRadius(tissue, 0.001);
    tissue.setGravity(0, 0, 0);
    tissue.setDensity(1000);
    tissue.setMaterial(new MooneyRivlinMaterial(1037, 0, 0, 486, 0, 10000));
    // tissue.setPoissonsRatio (0.499);
    // tissue.setYoungsModulus (6912);
    tissue.setParticleDamping(6.22);
    // more stable with 0 stiffness damping ...
    tissue.setStiffnessDamping(0.01);
    // tissue.setMaxStepSize(100*TimeBase.USEC);
    tissue.setMaxStepSize(0.01);
    tissue.setIntegrator(Integrator.ConstrainedBackwardEuler);
    myModel.addModel(tissue);
    addModel(myModel);
    for (MuscleBundle b : tissue.getMuscleBundles()) {
        RenderProps.setVisible(b.getFibres(), false);
    }
    for (FemMarker m : tissue.markers()) {
        RenderProps.setVisible(m, false);
    }
    addProbes(tissue);
    createMusclePanel();
// int numWays = 20;
// double res = 0.1;
// for (int i = 0; i < numWays; i++) {
// addWayPoint (new WayPoint (TimeBase.secondsToTicks ((i + 1) * res)));
// }
}
Also used : FemElement3d(artisynth.core.femmodels.FemElement3d) MooneyRivlinMaterial(artisynth.core.materials.MooneyRivlinMaterial) BlemkerMuscle(artisynth.core.materials.BlemkerMuscle) FemMarker(artisynth.core.femmodels.FemMarker) Point(artisynth.core.mechmodels.Point) LinkedList(java.util.LinkedList) MuscleBundle(artisynth.core.femmodels.MuscleBundle) Point3d(maspack.matrix.Point3d) FemMuscleModel(artisynth.core.femmodels.FemMuscleModel) FemNode3d(artisynth.core.femmodels.FemNode3d) GenericMuscle(artisynth.core.materials.GenericMuscle)

Example 3 with FemMuscleModel

use of artisynth.core.femmodels.FemMuscleModel in project artisynth_core by artisynth.

the class FemMuscleHeart method build.

// Model builder
@Override
public void build(String[] args) throws IOException {
    super.build(args);
    setMaxStepSize(0.005);
    // Root mechanical model
    MechModel mech = new MechModel("mech");
    mech.setGravity(0, 0, -9.8);
    addModel(mech);
    // -------------------------------------------------------------
    // HEART LOAD / ADD GEOMETRY
    // -------------------------------------------------------------
    // Heart surface mesh, with texture
    String heartFile = ArtisynthPath.getSrcRelativePath(this, "data/HumanHeart.obj");
    WavefrontReader wfr = new WavefrontReader(new File(heartFile));
    PolygonalMesh heartMesh = new PolygonalMesh();
    wfr.readMesh(heartMesh);
    // triangulate for interaction
    heartMesh.triangulate();
    // FEM heart:
    // - FEM mesh of heart convex hull
    // - embedded heart surface geometry
    FemMuscleModel heart = new FemMuscleModel("heart");
    TetGenReader.read(heart, ArtisynthPath.getSrcRelativePath(this, "data/HumanHeartHull.node"), ArtisynthPath.getSrcRelativePath(this, "data/HumanHeartHull.ele"));
    // add real-looking mesh
    FemMeshComp embeddedHeart = heart.addMesh(heartMesh);
    embeddedHeart.setName("embedded");
    // Allow inverted elements (poor quality mesh)
    heart.setWarnOnInvertedElements(false);
    heart.setAbortOnInvertedElements(false);
    // Convert unites to metres (original was cm)
    heart.scaleDistance(0.01);
    heart.setGravity(0, 0, -9.8);
    heart.setStiffnessDamping(0.02);
    // Set material properties
    heart.setDensity(1000);
    FemMaterial femMat = new LinearMaterial(2500, 0.33, true);
    // simple muscle
    MuscleMaterial muscleMat = new SimpleForceMuscle(500.0);
    heart.setMaterial(femMat);
    // Add heart to model
    mech.addModel(heart);
    // -------------------------------------------------------------
    // MUSCLE BUNDLES
    // -------------------------------------------------------------
    // One "long" direction muscle bundle
    // One "radial" muscle bundle
    // LONG BUNDLE
    // Compute the "long" direction of the heart
    PolygonalMesh hull = heart.getSurfaceMesh();
    RigidTransform3d trans = hull.computePrincipalAxes();
    Vector3d longAxis = new Vector3d();
    // first column of rotation
    trans.R.getColumn(0, longAxis);
    // Create the long axis muscle bundle
    MuscleBundle longBundle = new MuscleBundle("long");
    for (FemElement3d elem : heart.getElements()) {
        longBundle.addElement(elem, longAxis);
    }
    longBundle.setMuscleMaterial(muscleMat);
    heart.addMuscleBundle(longBundle);
    // RADIAL BUNDLE
    // Compute a plane through centre of heart
    Plane plane = new Plane(longAxis, new Point3d(trans.p));
    Point3d centroid = new Point3d();
    Vector3d radialDir = new Vector3d();
    // Create the radial muscle bundle
    MuscleBundle radialBundle = new MuscleBundle("radial");
    for (FemElement3d elem : heart.getElements()) {
        elem.computeCentroid(centroid);
        // project to plane and compute radial direction
        plane.project(centroid, centroid);
        radialDir.sub(centroid, trans.p);
        radialDir.normalize();
        radialBundle.addElement(elem, radialDir);
    }
    radialBundle.setMuscleMaterial(muscleMat);
    heart.addMuscleBundle(radialBundle);
    // -------------------------------------------------------------
    // RIGID TABLE AND COLLISION
    // -------------------------------------------------------------
    // Create a rigid box for the heart to fall on
    RigidBody box = RigidBody.createBox("box", 0.2, 0.2, 0.02, 0, /*addnormals*/
    true);
    box.setPose(new RigidTransform3d(new Vector3d(0, 0, -0.2), AxisAngle.IDENTITY));
    box.setDynamic(false);
    mech.addRigidBody(box);
    // Enable collisions between the heart and table
    mech.setCollisionBehavior(heart, box, true);
    // -------------------------------------------------------------
    // RENDER PROPERTIES
    // -------------------------------------------------------------
    // Hide elements and nodes
    RenderProps.setVisible(heart.getElements(), false);
    RenderProps.setVisible(heart.getNodes(), false);
    RenderProps.setLineColor(radialBundle, Color.BLUE);
    RenderProps.setLineColor(longBundle, Color.RED);
    radialBundle.setDirectionRenderLen(0.1);
    longBundle.setDirectionRenderLen(0.1);
    RenderProps.setVisible(radialBundle, false);
    RenderProps.setVisible(longBundle, false);
    RenderProps.setVisible(heart.getSurfaceMeshComp(), false);
    // adjust table render properties
    RenderProps.setShading(box, Shading.METAL);
    RenderProps.setSpecular(box, new Color(0.8f, 0.8f, 0.8f));
    // adjust heart mesh render properties
    RenderProps rprops = embeddedHeart.getRenderProps();
    rprops.getBumpMap().setScaling(0.01f);
    // don't modify specular
    rprops.getColorMap().setSpecularColoring(false);
    rprops.setShading(Shading.SMOOTH);
    rprops.setFaceColor(new Color(0.8f, 0.8f, 0.8f));
    rprops.getColorMap().setColorMixing(ColorMixing.MODULATE);
    rprops.setSpecular(new Color(0.4f, 0.4f, 0.4f));
    rprops.setShininess(128);
    // -------------------------------------------------------------
    // INPUT PROBES
    // -------------------------------------------------------------
    // Add heart probe
    addHeartProbe(longBundle, radialBundle);
}
Also used : WavefrontReader(maspack.geometry.io.WavefrontReader) SimpleForceMuscle(artisynth.core.materials.SimpleForceMuscle) RigidTransform3d(maspack.matrix.RigidTransform3d) FemElement3d(artisynth.core.femmodels.FemElement3d) Plane(maspack.matrix.Plane) FemMeshComp(artisynth.core.femmodels.FemMeshComp) FemMaterial(artisynth.core.materials.FemMaterial) MuscleMaterial(artisynth.core.materials.MuscleMaterial) Color(java.awt.Color) RenderProps(maspack.render.RenderProps) LinearMaterial(artisynth.core.materials.LinearMaterial) PolygonalMesh(maspack.geometry.PolygonalMesh) MechModel(artisynth.core.mechmodels.MechModel) MuscleBundle(artisynth.core.femmodels.MuscleBundle) Vector3d(maspack.matrix.Vector3d) Point3d(maspack.matrix.Point3d) FemMuscleModel(artisynth.core.femmodels.FemMuscleModel) RigidBody(artisynth.core.mechmodels.RigidBody) File(java.io.File)

Example 4 with FemMuscleModel

use of artisynth.core.femmodels.FemMuscleModel in project artisynth_core by artisynth.

the class FemSurfaceTargetDemo method build.

@Override
public void build(String[] args) throws IOException {
    super.build(args);
    mech = new MechModel("mech");
    mech.setGravity(Vector3d.ZERO);
    addModel(mech);
    fem = new FemMuscleModel("fem");
    fem.setStiffnessDamping(0.1);
    mech.addModel(fem);
    // boundary conditions
    FemFactory.createHexGrid(fem, l, w, w, nl, nw, nw);
    for (FemNode n : fem.getNodes()) {
        if (n.getPosition().x > l / 2 - eps) {
            n.setDynamic(false);
        }
    }
    // muscles
    addMuscle("vert", Color.RED, Vector3d.Z_UNIT);
    addMuscle("trans", Color.BLUE, Vector3d.Y_UNIT);
    body = new RigidBody("plate");
    body.setMesh(MeshFactory.createBox(l, l, l / 10));
    body.setPose(new RigidTransform3d(-1.2 * w - l / 20, 0, 0, 0, 1, 0, Math.PI / 2));
    body.setDynamic(false);
    mech.addRigidBody(body);
    mech.setCollisionBehavior(body, fem, true);
    addTrackingController();
    setupRenderProps();
}
Also used : MechModel(artisynth.core.mechmodels.MechModel) FemNode(artisynth.core.femmodels.FemNode) RigidTransform3d(maspack.matrix.RigidTransform3d) FemMuscleModel(artisynth.core.femmodels.FemMuscleModel) RigidBody(artisynth.core.mechmodels.RigidBody)

Aggregations

FemMuscleModel (artisynth.core.femmodels.FemMuscleModel)4 MuscleBundle (artisynth.core.femmodels.MuscleBundle)3 FemElement3d (artisynth.core.femmodels.FemElement3d)2 MechModel (artisynth.core.mechmodels.MechModel)2 Point (artisynth.core.mechmodels.Point)2 RigidBody (artisynth.core.mechmodels.RigidBody)2 Point3d (maspack.matrix.Point3d)2 RigidTransform3d (maspack.matrix.RigidTransform3d)2 FemMarker (artisynth.core.femmodels.FemMarker)1 FemMeshComp (artisynth.core.femmodels.FemMeshComp)1 FemNode (artisynth.core.femmodels.FemNode)1 FemNode3d (artisynth.core.femmodels.FemNode3d)1 ControlPanel (artisynth.core.gui.ControlPanel)1 FemControlPanel (artisynth.core.gui.FemControlPanel)1 BlemkerMuscle (artisynth.core.materials.BlemkerMuscle)1 FemMaterial (artisynth.core.materials.FemMaterial)1 GenericMuscle (artisynth.core.materials.GenericMuscle)1 LinearMaterial (artisynth.core.materials.LinearMaterial)1 MooneyRivlinMaterial (artisynth.core.materials.MooneyRivlinMaterial)1 MuscleMaterial (artisynth.core.materials.MuscleMaterial)1