Search in sources :

Example 1 with FemMeshComp

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

the class FemModel3dEditor method addNewSurfaceMesh.

private void addNewSurfaceMesh(FemModel3d model) {
    GLViewer v = myMain.getViewer();
    ElementFilter efilter = new ClippedElementFilter(v.getClipPlanes());
    FemMeshComp mcomp = FemMeshComp.createSurface(null, model, efilter);
    mcomp.setSurfaceRendering(SurfaceRender.Shaded);
    model.addMeshComp(mcomp);
}
Also used : GLViewer(maspack.render.GL.GLViewer) FemMeshComp(artisynth.core.femmodels.FemMeshComp) ElementFilter(artisynth.core.femmodels.FemModel.ElementFilter)

Example 2 with FemMeshComp

use of artisynth.core.femmodels.FemMeshComp 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;
}
Also used : Vertex3d(maspack.geometry.Vertex3d) HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) PointAttachment(artisynth.core.mechmodels.PointAttachment) IntegrationData3d(artisynth.core.femmodels.IntegrationData3d) PolygonalMesh(maspack.geometry.PolygonalMesh) Point3d(maspack.matrix.Point3d) IntegrationPoint3d(artisynth.core.femmodels.IntegrationPoint3d) FemNode3d(artisynth.core.femmodels.FemNode3d) DynamicComponent(artisynth.core.mechmodels.DynamicComponent) FemNode(artisynth.core.femmodels.FemNode) FemElement3d(artisynth.core.femmodels.FemElement3d) FemMeshComp(artisynth.core.femmodels.FemMeshComp) IntegrationPoint3d(artisynth.core.femmodels.IntegrationPoint3d) Vector3d(maspack.matrix.Vector3d) VectorNd(maspack.matrix.VectorNd) PointFem3dAttachment(artisynth.core.femmodels.PointFem3dAttachment) PointParticleAttachment(artisynth.core.mechmodels.PointParticleAttachment)

Example 3 with FemMeshComp

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

the class FemCollisions method build.

@Override
public void build(String[] args) throws IOException {
    super.build(args);
    // Reduce step size to better resolve collisions
    setMaxStepSize(0.0002);
    // Create and add main MechModel
    MechModel mech = new MechModel("mech");
    addModel(mech);
    // -------------------------------------------------------------
    // BEAM
    // -------------------------------------------------------------
    // Create FEM beam
    FemModel3d beam = new FemModel3d("beam");
    mech.addModel(beam);
    // widths
    double[] size = { 0.003, 0.0015, 0.0015 };
    // resolution
    int[] res = { 4, 2, 2 };
    FemFactory.createGrid(beam, FemElementType.Hex, size[0], size[1], size[2], res[0], res[1], res[2]);
    // Set properties
    beam.setDensity(1000);
    beam.setMaterial(new LinearMaterial(300, 0.33));
    // -------------------------------------------------------------
    // ELLIPSOID
    // -------------------------------------------------------------
    // Create FEM ellipsoid
    FemModel3d ellipsoid = new FemModel3d("ellipsoid");
    mech.addModel(ellipsoid);
    // radii (z, x, y)
    double[] radii = { 0.002, 0.001, 0.001 };
    // resolution (theta, phi, r)
    int[] eres = { 16, 4, 3 };
    FemFactory.createEllipsoid(ellipsoid, radii[0], radii[1], radii[2], eres[0], eres[1], eres[2]);
    // Set properties
    ellipsoid.setDensity(1000);
    ellipsoid.setMaterial(new LinearMaterial(300, 0.33));
    // Transform: rotate 90 degrees about X-Axis
    // translate up by 0.003
    RigidTransform3d trans = new RigidTransform3d();
    trans.setRotation(new AxisAngle(1, 0, 0, Math.PI / 2));
    trans.setTranslation(new Vector3d(0, 0.0005, 0.003));
    ellipsoid.transformGeometry(trans);
    // -------------------------------------------------------------
    // BLOCK WITH EMBEDDED SPHERE
    // -------------------------------------------------------------
    // Create FEM block
    FemModel3d block = new FemModel3d("block");
    mech.addModel(block);
    FemFactory.createHexGrid(block, 0.002, 0.002, 0.002, 3, 3, 3);
    // Set properties
    block.setDensity(1000);
    block.setMaterial(new LinearMaterial(300, 0.33));
    // Create embedded sphere
    double r = 0.0008;
    // level of refinement
    int ref = 2;
    PolygonalMesh sphere = MeshFactory.createOctahedralSphere(r, ref);
    FemMeshComp embeddedSphere = block.addMesh("embedded", sphere);
    // Transform: rotate 90 degrees about X-Axis
    // translate left by 0.003
    trans = new RigidTransform3d();
    trans.setTranslation(new Vector3d(0, 0.003, 0));
    block.transformGeometry(trans);
    // -------------------------------------------------------------
    // TABLE AND COLLISIONS
    // -------------------------------------------------------------
    RigidBody table = RigidBody.createBox("table", 0.005, 0.0075, 0.0008, 0);
    table.setDynamic(false);
    table.setPose(new RigidTransform3d(new Vector3d(0, 0.0015, -0.002), AxisAngle.IDENTITY));
    mech.addRigidBody(table);
    // Set up collisions
    mech.setCollisionBehavior(ellipsoid, beam, true, 0.1);
    mech.setCollisionBehavior(ellipsoid, table, true, 0.1);
    mech.setCollisionBehavior(embeddedSphere, table, true, 0.1);
    mech.setCollisionBehavior(ellipsoid, embeddedSphere, true, 0.1);
    mech.setCollisionBehavior(table, beam, true, 0.1);
    // -------------------------------------------------------------
    // RENDER PROPERTIES
    // -------------------------------------------------------------
    // Draw beam element widgets
    beam.setElementWidgetSize(0.8);
    RenderProps.setLineWidth(beam.getElements(), 0);
    // Make beam blue, and give it a transparent surface
    RenderProps.setFaceColor(beam, Color.BLUE);
    beam.setSurfaceRendering(SurfaceRender.Shaded);
    RenderProps.setAlpha(beam.getMeshComp("surface"), 0.4);
    // Make the ellipsoid red
    RenderProps.setFaceColor(ellipsoid, Color.RED);
    RenderProps.setLineColor(ellipsoid, Color.RED.darker());
    ellipsoid.setSurfaceRendering(SurfaceRender.Shaded);
    // Make the block green
    RenderProps.setFaceColor(block, Color.GREEN);
    RenderProps.setLineColor(block, Color.GREEN.darker());
}
Also used : RigidTransform3d(maspack.matrix.RigidTransform3d) FemModel3d(artisynth.core.femmodels.FemModel3d) FemMeshComp(artisynth.core.femmodels.FemMeshComp) LinearMaterial(artisynth.core.materials.LinearMaterial) PolygonalMesh(maspack.geometry.PolygonalMesh) MechModel(artisynth.core.mechmodels.MechModel) AxisAngle(maspack.matrix.AxisAngle) Vector3d(maspack.matrix.Vector3d) RigidBody(artisynth.core.mechmodels.RigidBody)

Example 4 with FemMeshComp

use of artisynth.core.femmodels.FemMeshComp 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 5 with FemMeshComp

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

the class FemModel3dEditor method addNewSurfaceMeshForSelectedElements.

private void addNewSurfaceMeshForSelectedElements(FemModel3d model) {
    ElementFilter efilter = new SelectedElementFilter();
    FemMeshComp mcomp = FemMeshComp.createSurface(null, model, efilter);
    mcomp.setSurfaceRendering(SurfaceRender.Shaded);
    model.addMeshComp(mcomp);
}
Also used : FemMeshComp(artisynth.core.femmodels.FemMeshComp) ElementFilter(artisynth.core.femmodels.FemModel.ElementFilter)

Aggregations

FemMeshComp (artisynth.core.femmodels.FemMeshComp)5 PolygonalMesh (maspack.geometry.PolygonalMesh)3 Vector3d (maspack.matrix.Vector3d)3 FemElement3d (artisynth.core.femmodels.FemElement3d)2 ElementFilter (artisynth.core.femmodels.FemModel.ElementFilter)2 LinearMaterial (artisynth.core.materials.LinearMaterial)2 MechModel (artisynth.core.mechmodels.MechModel)2 RigidBody (artisynth.core.mechmodels.RigidBody)2 Point3d (maspack.matrix.Point3d)2 RigidTransform3d (maspack.matrix.RigidTransform3d)2 FemModel3d (artisynth.core.femmodels.FemModel3d)1 FemMuscleModel (artisynth.core.femmodels.FemMuscleModel)1 FemNode (artisynth.core.femmodels.FemNode)1 FemNode3d (artisynth.core.femmodels.FemNode3d)1 IntegrationData3d (artisynth.core.femmodels.IntegrationData3d)1 IntegrationPoint3d (artisynth.core.femmodels.IntegrationPoint3d)1 MuscleBundle (artisynth.core.femmodels.MuscleBundle)1 PointFem3dAttachment (artisynth.core.femmodels.PointFem3dAttachment)1 FemMaterial (artisynth.core.materials.FemMaterial)1 MuscleMaterial (artisynth.core.materials.MuscleMaterial)1