Example usage for javax.media.j3d TransformGroup getTransform

List of usage examples for javax.media.j3d TransformGroup getTransform

Introduction

In this page you can find the example usage for javax.media.j3d TransformGroup getTransform.

Prototype

public void getTransform(Transform3D t1) 

Source Link

Document

Copies the transform component of this TransformGroup into the passed transform object.

Usage

From source file:TreePrinter.java

private void printNode(Object o, int indent, Set sharedGroups) {
    for (int i = 0; i < indent; i++)
        printStream.print(">");
    printStream.print(nodeString(o) + ": ");
    if (o instanceof SceneGraphObject) {
        SceneGraphObject sgo = (SceneGraphObject) o;
        int capBits = 0;
        // TODO: how to make sure we always check all the valid bits?
        for (int i = 0; i < 64; i++) {
            if (sgo.getCapability(i)) {
                capBits |= 1 << i;
            }/*from   w w w .  j a  v  a2s  .  c om*/
        }
        printStream.print("capBits:Ox" + Integer.toHexString(capBits));
        if (o instanceof javax.media.j3d.Group) {
            javax.media.j3d.Group g = (javax.media.j3d.Group) o;
            int numChildren = 0;
            try {
                numChildren = g.numChildren();
            } catch (CapabilityNotSetException e) {
                //anyone who is using treePrinter, is debugging, so it is
                //alright to blindly allow read. you should first detach
                //browser.curScene, print the tree, then add it back to
                //browser.locale when finished.
                g.setCapability(javax.media.j3d.Group.ALLOW_CHILDREN_READ);
                numChildren = g.numChildren();
                //System.out.println("Can't read children on group");
                //return;
            }
            printStream.print(" children:" + numChildren);
            if (o instanceof TransformGroup) {
                Transform3D transform = new Transform3D();
                Transform3D identity = new Transform3D();
                TransformGroup t = (TransformGroup) o;
                t.getTransform(transform);
                // TODO: use getBestType() when implemented
                if (transform.equals(identity)) {
                    printStream.print(" xform:IDENTITY ");
                } else {
                    printStream.print(" xform:NON-IDENTITY ");
                }
            }
        } else if (o instanceof Link) {
            Link l = (Link) o;
            SharedGroup sg = l.getSharedGroup();
            printStream.print(" sg:" + nodeString(sg));
            sharedGroups.add(sg);
        } else {
            printStream.print(": leaf");
        }
    }
    printStream.println();
}

From source file:SimpleSounds.java

/**
 * Add a sound to the transform group. This takes a point sound object and
 * loads into it a sounds from a given file. The edge of the sound's extent
 * is also defined in a parameter.//from   ww w  .  j  a  va 2  s.  c  o  m
 * 
 * @param tg
 *            TransformGroup that the sound is to be added to
 * @param sound
 *            PointSound to be used
 * @param soundFile
 *            String that is the name of the sound file to be loaded
 * @param edge
 *            float that represents the sound's maximum extent
 */
protected void addObjectSound(TransformGroup tg, PointSound sound, String soundFile, float edge) {
    //First we get the current transform so that we can
    //position the sound in the same place
    Transform3D objXfm = new Transform3D();
    Vector3f objPosition = new Vector3f();
    tg.getTransform(objXfm);
    objXfm.get(objPosition);
    //Create the media container to load the sound
    MediaContainer soundContainer = new MediaContainer(soundFile);
    //Use the loaded data in the sound
    sound.setSoundData(soundContainer);
    sound.setInitialGain(1.0f);
    //Set the position to that of the given transform
    sound.setPosition(new Point3f(objPosition));
    //Allow use to switch the sound on and off
    sound.setCapability(PointSound.ALLOW_ENABLE_READ);
    sound.setCapability(PointSound.ALLOW_ENABLE_WRITE);
    sound.setSchedulingBounds(bounds);
    //Set it off to start with
    sound.setEnable(false);
    //Set it to loop forever
    sound.setLoop(BackgroundSound.INFINITE_LOOPS);
    //Use the edge value to set to extent of the sound
    Point2f[] attenuation = { new Point2f(0.0f, 1.0f), new Point2f(edge, 0.1f) };
    sound.setDistanceGain(attenuation);
    //Add the sound to the transform group
    tg.addChild(sound);
}

From source file:edu.uci.ics.jung.visualization3d.VisualizationViewer.java

public BranchGroup createSceneGraph(final Canvas3D canvas) {

    objRoot = new BranchGroup();
    objRoot.setCapability(Group.ALLOW_CHILDREN_EXTEND);
    objRoot.setCapability(Group.ALLOW_CHILDREN_WRITE);

    TransformGroup objScale = new TransformGroup();
    Transform3D t3d = new Transform3D();
    //      t3d.setScale(0.05);
    objScale.setTransform(t3d);/*ww w .j  a  va2s . c  om*/
    objRoot.addChild(objScale);

    Transform3D tt = new Transform3D();
    tt.setScale(.05);
    tt.setTranslation(new Vector3f(0, 0, -30.f));
    objTrans = new TransformGroup(tt);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    objTrans.setCapability(TransformGroup.ALLOW_CHILDREN_EXTEND);
    objScale.addChild(objTrans);
    //      objRoot.addChild(objTrans);

    // Create Colors, Materials,  and Appearances.
    Appearance look = new Appearance();
    Color3f objColor = new Color3f(0.7f, 0.7f, 0.7f);
    Color3f black = new Color3f(0.f, 0.f, 0.f);
    Color3f white = new Color3f(1.0f, 1.0f, 0.6f);
    Color3f gray = new Color3f(.2f, .2f, .2f);
    Color3f red = new Color3f(1.0f, 0, 0);
    Color3f yellow = new Color3f(1, 1, 0);

    Material objMaterial = new Material(objColor, black, objColor, white, 100.0f);
    Material blackMaterial = new Material(objColor, black, black, objColor, 10.0f);
    Material whiteMaterial = new Material(white, white, white, white, 100.0f);
    Material grayMaterial = new Material(gray, black, gray, gray, 100.0f);

    Material redMaterial = new Material(red, black, red, red, 100.0f);
    Material yellowMaterial = new Material(yellow, black, yellow, yellow, 100);

    look.setMaterial(new Material(objColor, black, objColor, white, 100.0f));
    Appearance blackLook = new Appearance();
    blackLook.setMaterial(blackMaterial);

    Appearance whiteLook = new Appearance();
    whiteLook.setMaterial(whiteMaterial);

    Appearance grayLook = new Appearance();
    grayLook.setMaterial(grayMaterial);
    grayLook.setCapability(Appearance.ALLOW_MATERIAL_READ);
    grayLook.setCapability(Appearance.ALLOW_MATERIAL_WRITE);

    final Appearance redLook = new Appearance();
    redLook.setMaterial(redMaterial);
    //      vertexLook = redLook;

    Appearance objLook = new Appearance();
    objLook.setMaterial(objMaterial);
    grayLook = objLook;
    final Appearance yellowLook = new Appearance();
    yellowLook.setMaterial(yellowMaterial);
    Bounds bounds = new BoundingSphere(new Point3d(), 300);

    MouseRotate behavior1 = new MouseRotate();
    behavior1.setTransformGroup(objTrans);
    objTrans.addChild(behavior1);
    behavior1.setSchedulingBounds(bounds);

    MouseWheelZoom behavior2 = new MouseWheelZoom();
    behavior2.setTransformGroup(objTrans);
    //      behavior2.setFactor(10);
    objTrans.addChild(behavior2);
    behavior2.setSchedulingBounds(bounds);

    MouseTranslate behavior3 = new MouseTranslate();
    behavior3.setTransformGroup(objTrans);
    objTrans.addChild(behavior3);
    behavior3.setSchedulingBounds(bounds);

    PickTranslateBehavior ptb = new PickTranslateBehavior(objRoot, canvas, bounds, PickTool.GEOMETRY);
    ptb.setSchedulingBounds(bounds);
    //      objTrans.addChild(ptb);
    ptb.setupCallback(new PickingCallback() {

        public void transformChanged(int type, TransformGroup tg) {
            if (tg == null)
                return;
            Transform3D t3d = new Transform3D();
            tg.getTransform(t3d);
            //            System.err.println(tg+" transformChanged \n"+t3d);
            Point3f p1 = new Point3f();
            V v = vertexMap.getKey(tg);
            //            Transform3D lvw = new Transform3D();
            //            tg.getLocalToVworld(lvw);
            //            System.err.println("lvw = \n"+lvw);
            //            lvw.invert();
            //            System.err.println("invert lvw = \n"+lvw);
            Point3f p0 = layout.transform(v);
            //            Transform3D vwip = new Transform3D();
            //            canvas.getVworldToImagePlate(vwip);
            //            System.err.println("vwip=\n"+vwip);
            //            t3d.mul(lvw);
            t3d.transform(p1);
            //            scale.transform(p1);
            System.err.println(
                    "change location for vertex " + v + ", transformGroup " + tg + " from " + p0 + " to " + p1);
            //            p1.set(p1.getX()*2,p1.getY()*2,p1.getZ()*2);
            //            layout.setLocation(v, p1);

        }
    });

    PickSphereBehavior psb = new PickSphereBehavior(objRoot, canvas, bounds);

    PickVertexBehavior pvb = new PickVertexBehavior(objRoot, canvas, bounds,
            renderContext.getPickedVertexState());
    objTrans.addChild(pvb);
    pvb.addChangeListener(new ChangeListener() {

        public void stateChanged(ChangeEvent e) {
            for (V v : graph.getVertices()) {
                VertexGroup<V> vg = vertexMap.get(v);
                Appearance look = redLook;
                if (renderContext.getPickedVertexState().isPicked(v)) {
                    look = yellowLook;
                }
                Node node = vg.getShape();
                if (node instanceof Primitive) {
                    ((Primitive) node).setAppearance(look);
                }
            }

        }
    });

    //Shine it with two colored lights.
    Color3f lColor1 = new Color3f(.5f, .5f, .5f);
    Color3f lColor2 = new Color3f(1.0f, 1.0f, 1.0f);
    Vector3f lDir2 = new Vector3f(-1.0f, 0.0f, -1.0f);
    DirectionalLight lgt2 = new DirectionalLight(lColor2, lDir2);
    AmbientLight ambient = new AmbientLight(lColor1);
    lgt2.setInfluencingBounds(bounds);
    ambient.setInfluencingBounds(bounds);
    objRoot.addChild(lgt2);
    objRoot.addChild(ambient);

    // Let Java 3D perform optimizations on this scene graph.
    objRoot.compile();

    //      VisRunner runner = new VisRunner((IterativeContext)elayout);
    //      runner.relax();

    return objRoot;
}

From source file:LoaderTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    // create a TransformGroup to flip the hand onto its end and enlarge it.
    TransformGroup objTrans1 = new TransformGroup();
    Transform3D tr = new Transform3D();
    objTrans1.getTransform(tr);
    tr.rotX(90.0 * Math.PI / 180.0);
    tr.setScale(10.0);/*from  w  w w.  jav  a2 s . c  om*/
    objTrans1.setTransform(tr);

    // create a TransformGroup to rotate the hand
    TransformGroup objTrans2 = new TransformGroup();
    objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans2.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    BoundingSphere bounds = new BoundingSphere(new Point3d(0.0, 0.0, 0.0), 100.0);

    // create a RotationInterpolator behavior to rotate the hand
    Transform3D yAxis = new Transform3D();
    Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 0, 0, 4000, 0, 0, 0, 0, 0);

    RotationInterpolator rotator = new RotationInterpolator(rotationAlpha, objTrans2, yAxis, 0.0f,
            (float) Math.PI * 2.0f);
    rotator.setSchedulingBounds(bounds);
    objTrans2.addChild(rotator);

    // Set up the global lights
    Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
    Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
    Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);

    AmbientLight aLgt = new AmbientLight(alColor);
    aLgt.setInfluencingBounds(bounds);
    DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
    lgt1.setInfluencingBounds(bounds);

    objRoot.addChild(aLgt);
    objRoot.addChild(lgt1);

    // load the object file
    Scene scene = null;
    Shape3D shape = null;

    // read in the geometry information from the data file
    ObjectFile objFileloader = new ObjectFile(ObjectFile.RESIZE);

    try {
        scene = objFileloader.load("hand1.obj");
    } catch (Exception e) {
        scene = null;
        System.err.println(e);
    }

    if (scene == null)
        System.exit(1);

    // retrieve the Shape3D object from the scene
    BranchGroup branchGroup = scene.getSceneGroup();
    shape = (Shape3D) branchGroup.getChild(0);

    // create an Appearance and Material
    Appearance app = new Appearance();
    Color3f objColor = new Color3f(1.0f, 0.7f, 0.8f);
    Color3f black = new Color3f(0.0f, 0.0f, 0.0f);
    app.setMaterial(new Material(objColor, black, objColor, black, 80.0f));

    // assign the appearance to the Shape
    shape.setAppearance(app);

    // connect the scenegraph
    objTrans2.addChild(scene.getSceneGroup());
    objTrans1.addChild(objTrans2);
    objRoot.addChild(objTrans1);

    return objRoot;
}

From source file:MouseNavigateTest.java

protected void applyVectorToObject(Vector3f vector) {
    TransformGroup tg = getTransformGroup();

    if (tg != null) {
        tg.getTransform(m_Transform3D);

        double x_angle = vector.y * m_FactorX;
        double y_angle = vector.x * m_FactorY;

        m_TransformX.rotX(x_angle);//from  w w w .  j  a v a2s.  c o  m
        m_TransformY.rotY(y_angle);

        Matrix4d mat = new Matrix4d();

        // Remember old matrix
        m_Transform3D.get(mat);

        // Translate to origin
        m_Transform3D.setTranslation(new Vector3d(0.0, 0.0, 0.0));

        if (m_bInvert != false) {
            m_Transform3D.mul(m_Transform3D, m_TransformX);
            m_Transform3D.mul(m_Transform3D, m_TransformY);
        } else {
            m_Transform3D.mul(m_TransformX, m_Transform3D);
            m_Transform3D.mul(m_TransformY, m_Transform3D);
        }

        // Set old translation back
        Vector3d translation = new Vector3d(mat.m03, mat.m13, mat.m23);
        m_Transform3D.setTranslation(translation);

        // save the new Transform3D
        applyTransform();

        if (m_Listener != null) {
            Point3d rotate = Euler.getEulerRotation(m_Transform3D);
            ((RotationChangeListener) m_Listener).onRotate(m_Object, rotate);
        }
    }
}

From source file:MouseNavigateTest.java

protected void applyVectorToObject(Vector3f vector) {
    TransformGroup tg = getTransformGroup();

    if (tg != null) {
        tg.getTransform(m_Transform3D);

        Vector3d vScale = new Vector3d();
        m_Transform3D.getScale(vScale);

        Vector3f delta = new Vector3f();

        if (vector.x > m_Threshold)
            delta.x = m_Delta;//from   ww  w. ja v a 2  s .co m
        else if (vector.x < -m_Threshold)
            delta.x = -m_Delta;

        if (vector.y > m_Threshold)
            delta.y = m_Delta;
        else if (vector.y < -m_Threshold)
            delta.y = -m_Delta;

        if (vector.z > m_Threshold)
            delta.z = m_Delta;
        else if (vector.z < -m_Threshold)
            delta.z = -m_Delta;

        Vector3d objectScale = new Vector3d(vScale.x + delta.x, vScale.y + delta.y, vScale.z + delta.z);

        if (objectScale.x >= m_MinScale.x && objectScale.y >= m_MinScale.y && objectScale.z >= m_MinScale.z) {
            if (objectScale.x <= m_MaxScale.x && objectScale.y <= m_MaxScale.y
                    && objectScale.z <= m_MaxScale.z) {
                m_Transform3D.setScale(objectScale);

                // save the new Transform3D
                applyTransform();

                if (m_Listener != null)
                    ((ScaleChangeListener) m_Listener).onScale(m_Object, objectScale);
            }
        }
    }
}

From source file:MouseNavigateTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    // note that we are creating a TG *above* the TG
    // the is being controlled by the mouse behaviors.
    // The SUN mouse translate behavior would fail in this
    // instance as all movement would be in the X-Y plane
    // irrespective of any TG above the object.
    // The TornadoMouseTranslate behavior always moves an object
    // parrallel to the image plane
    TransformGroup objTrans1 = new TransformGroup();
    Transform3D t3d = new Transform3D();
    objTrans1.getTransform(t3d);
    t3d.setEuler(new Vector3d(0.9, 0.8, 0.3));
    objTrans1.setTransform(t3d);/*from  w  ww.  j a v a 2  s.c om*/

    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    // create the mouse scale behavior and set limits
    TornadoMouseScale mouseScale = new TornadoMouseScale(5, 0.1f);
    mouseScale.setMinScale(new Point3d(0.5, 0.5, 0.5));
    mouseScale.setMaxScale(new Point3d(2, 2, 2));
    mouseScale.setObject(objTrans);
    mouseScale.setChangeListener(this);
    mouseScale.setSchedulingBounds(getApplicationBounds());
    objTrans.addChild(mouseScale);

    // create the mouse rotate behavior
    TornadoMouseRotate mouseRotate = new TornadoMouseRotate(0.001, 0.001);
    mouseRotate.setInvert(true);
    mouseRotate.setObject(objTrans);
    mouseRotate.setChangeListener(this);
    mouseRotate.setSchedulingBounds(getApplicationBounds());
    objTrans.addChild(mouseRotate);

    // create the mouse translate behavior and set limits
    TornadoMouseTranslate mouseTrans = new TornadoMouseTranslate(0.005f);
    mouseTrans.setObject(objTrans);
    mouseTrans.setChangeListener(this);
    mouseTrans.setMinTranslate(new Point3d(-4, -4, -4));
    mouseTrans.setMaxTranslate(new Point3d(4, 4, 4));
    mouseTrans.setSchedulingBounds(getApplicationBounds());
    objTrans.addChild(mouseTrans);

    objTrans.addChild(new ColorCube(0.5));

    // create some axis for the world to show it has been rotated
    ColorCube axis = new ColorCube(5.0);
    Appearance app = new Appearance();
    app.setPolygonAttributes(
            new PolygonAttributes(PolygonAttributes.POLYGON_LINE, PolygonAttributes.CULL_NONE, 0));
    axis.setAppearance(app);
    objTrans1.addChild(axis);

    objTrans1.addChild(objTrans);
    objRoot.addChild(objTrans1);

    return objRoot;
}

From source file:MouseNavigateTest.java

protected void applyVectorToObject(Vector3f vector) {
    TransformGroup tg = getTransformGroup();

    if (tg != null) {
        // scale the mouse movements so the objects roughly tracks with the
        // mouse/* w w w  .  j a va 2  s.co  m*/
        vector.scale(m_Scale);

        Vector3d vTranslation = new Vector3d();
        tg.getTransform(m_Transform3D);
        m_Transform3D.get(vTranslation);

        vTranslation.x += vector.x;
        vTranslation.y += vector.y;
        vTranslation.z += vector.z;

        if (vTranslation.x >= m_MinTranslate.x && vTranslation.y >= m_MinTranslate.y
                && vTranslation.z >= m_MinTranslate.z) {
            if (vTranslation.x <= m_MaxTranslate.x && vTranslation.y <= m_MaxTranslate.y
                    && vTranslation.z <= m_MaxTranslate.z) {
                m_Transform3D.setTranslation(vTranslation);
                applyTransform();

                if (m_Listener != null)
                    ((TranslationChangeListener) m_Listener).onTranslate(m_Object, vTranslation);
            }
        }
    }
}

From source file:AppearanceTest.java

protected BranchGroup createSceneBranchGroup() {
    BranchGroup objRoot = super.createSceneBranchGroup();

    TransformGroup zoomTg = new TransformGroup();
    zoomTg.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    zoomTg.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

    // attach a navigation behavior to the position of the viewer
    KeyNavigatorBehavior key = new KeyNavigatorBehavior(zoomTg);
    key.setSchedulingBounds(createApplicationBounds());
    key.setEnable(true);/*w  w  w  .j  a v  a2s.  c o  m*/
    objRoot.addChild(key);

    // create a TransformGroup to flip the hand onto its end and enlarge it.
    TransformGroup objTrans1 = new TransformGroup();
    Transform3D tr = new Transform3D();
    objTrans1.getTransform(tr);
    tr.setEuler(new Vector3d(0.5 * Math.PI, 0.6, 0));
    objTrans1.setTransform(tr);

    // Set up the global lights
    Color3f lColor1 = new Color3f(0.7f, 0.7f, 0.7f);
    Vector3f lDir1 = new Vector3f(-1.0f, -1.0f, -1.0f);
    Color3f alColor = new Color3f(0.2f, 0.2f, 0.2f);

    AmbientLight aLgt = new AmbientLight(alColor);
    aLgt.setInfluencingBounds(getApplicationBounds());
    DirectionalLight lgt1 = new DirectionalLight(lColor1, lDir1);
    lgt1.setInfluencingBounds(getApplicationBounds());

    objRoot.addChild(aLgt);
    objRoot.addChild(lgt1);

    int nScale = 50;

    Box box = new Box(nScale, nScale, nScale, Primitive.GENERATE_NORMALS | Primitive.GENERATE_TEXTURE_COORDS,
            m_Appearance);

    Shape3D frontFace = box.getShape(Box.LEFT);

    // create a new left face so we can
    // assign per-vertex colors

    GeometryArray geometry = new QuadArray(4, GeometryArray.COORDINATES | GeometryArray.NORMALS
            | GeometryArray.COLOR_4 | GeometryArray.TEXTURE_COORDINATE_2);

    nScale = 40;

    final float[] verts = {
            // left face
            -1.0f * nScale, -1.0f * nScale, 1.0f * nScale, -1.0f * nScale, 1.0f * nScale, 1.0f * nScale,
            -1.0f * nScale, 1.0f * nScale, -1.0f * nScale, -1.0f * nScale, -1.0f * nScale, -1.0f * nScale };

    final float[] colors = {
            // left face
            1, 0, 0, 0, 0, 1, 0, 0.2f, 0, 0, 1, 0.8f, 0, 0, 0, 1, };

    float[] tcoords = {
            // left
            1, 0, 1, 1, 0, 1, 0, 0 };

    Vector3f normalVector = new Vector3f(-1.0f, 0.0f, 0.0f);

    geometry.setColors(0, colors, 0, 4);

    for (int n = 0; n < 4; n++)
        geometry.setNormal(n, normalVector);

    geometry.setTextureCoordinates(0, tcoords, 0, 4);

    geometry.setCoordinates(0, verts);

    frontFace.setGeometry(geometry);

    // connect the scenegraph
    objTrans1.addChild(box);
    zoomTg.addChild(objTrans1);
    objRoot.addChild(zoomTg);

    return objRoot;
}

From source file:ffx.ui.MainPanel.java

/**
 * Merge two or more selected FSystem Nodes into one FSystem node. There are
 * a few gotchas that need to be fixed//from   w w  w  .  j  av a2s . c  o  m
 *
 * @param nodesToMerge a {@link java.util.ArrayList} object.
 */
public void merge(ArrayList<MSNode> nodesToMerge) {
    ArrayList<MSNode> activeNodes = new ArrayList<MSNode>();
    for (MSNode node : nodesToMerge) {
        if (node != null && !(node instanceof MSRoot)) {
            activeNodes.add(node);
        }
    }
    if (activeNodes.size() <= 1) {
        return;
    }
    // Set up a structure to hold the new system
    FFXSystem active = hierarchy.getActive();
    File file = SystemFilter.version(hierarchy.getActive().getFile());
    FFXSystem system = new FFXSystem(file, "Merge Result", active.getProperties());
    system.setKeyFile(active.getKeyFile());
    system.setKeywords(KeyFilter.open(active.getKeyFile()));
    // Fill arrays with the atoms and bonds from the systems to be combined
    ArrayList<Atom> mergedAtoms = new ArrayList<Atom>();
    ArrayList<Bond> mergedBonds = new ArrayList<Bond>();
    ArrayList<FFXSystem> systems = new ArrayList<FFXSystem>();
    TransformGroup parentTransformGroup = null;
    FFXSystem parentSystem;
    Transform3D parentTransform3D = new Transform3D();
    Vector3d parentPosition = new Vector3d();
    Vector3d atomPosition = new Vector3d();
    // TINKER Atom Numbers start at 1
    int atomNum = 1;
    Vector3d zero = new Vector3d(0.0, 0.0, 0.0);
    for (MSNode m : activeNodes) {
        parentSystem = (FFXSystem) m.getMSNode(FFXSystem.class);
        if (parentSystem == null) {
            return;
        }
        if (!systems.contains(parentSystem)) {
            graphicsCanvas.updateSceneWait(parentSystem, false, true, RendererCache.ViewModel.WIREFRAME, false,
                    null);
            systems.add(parentSystem);
        }
        // Move each atom into the global frame by applying the System
        // Transform to
        // relative atomic position
        parentTransformGroup = parentSystem.getOriginToRot();
        parentTransformGroup.getTransform(parentTransform3D);
        parentTransform3D.get(parentPosition);
        parentTransform3D.setTranslation(zero);
        // parentTransform3D.setScale(1.0d);
        ArrayList<Atom> atoms = m.getAtomList();
        ArrayList<ROLS> bonds = m.getBondList();
        for (Atom atom : atoms) {
            atom.removeFromParent();
            atom.setXYZIndex(atomNum++);
            mergedAtoms.add(atom);
            atom.getV3D(atomPosition);
            parentTransform3D.transform(atomPosition);
            atomPosition.add(parentPosition);
            atom.moveTo(atomPosition);
        }
        for (ROLS msm : bonds) {
            Bond bond = (Bond) msm;
            bond.removeFromParent();
            mergedBonds.add((Bond) msm);
        }
    }
    for (FFXSystem sys : systems) {
        close(sys);
    }
    MergeFilter mergeFilter = new MergeFilter(system, mergedAtoms, mergedBonds);
    UIFileOpener fileOpener = new UIFileOpener(mergeFilter, this);
    if (fileOpenerThreads > 0) {
        fileOpener.setNThreads(fileOpenerThreads);
    }
    Thread thread = new Thread(fileOpener);
    thread.start();
}