Search code examples
javajava-3d

Multiple Containers Loading Java3D


I am trying to make a 3D interface using Java3D for the Multiple Container Loading problem.

I want to visualize each container and items already packed in it in seperate frames. (for example , if I have 3 containers , there will be 3 different frames )

In the container's class , I added a BranchGroup variable :

 private static BranchGroup scene ; 

and in the constructor, I created the BranchGroup scene and a frame (I will post the Interface class above)

public ContainerW(final int iD) {
        super();
        cRef = iD;
        this.emptyBreadth = 0;
        this.length = 0.8;
        this.height = 0.6;
        this.breadth = 0.5 - emptyBreadth;
        this.usedVolume = 0;
        volume = length * breadth * height;
        this.packedItems = new ArrayList<ItemsUnit>();
        scene = new BranchGroup();
        Frame frame = new MainFrame(new Interface(scene),800, 800); 

    }

when a new item is packed, I add this (I added the new Node to the BranchGroup scene ) :

  scene.addChild(Interface.addItem(item[p].getLength(), item[p].getBreadth(), item[p].getBreadth(), x, y, z));

( x, y and z are the translation parameters )

In the Interface class, I wrote a method to create the frame and draw the container in it and another method to add the item's 3D Node.

package Interface3D;
import java.applet.Applet;
import java.awt.BorderLayout;
import javax.media.j3d.Appearance;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TransparencyAttributes;
import javax.vecmath.AxisAngle4d;
import javax.vecmath.Vector3f;
import com.sun.j3d.utils.geometry.Box;
import com.sun.j3d.utils.universe.SimpleUniverse;
import Classes.ContainerW;

public class Interface extends Applet{


    public Interface(BranchGroup scene) {


         this.setLayout(new BorderLayout());
           Canvas3D canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
            this.add(canvas3D, BorderLayout.CENTER);

            SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
            simpleU.getViewingPlatform().setNominalViewingTransform();

        //create an appearance for the container
        Appearance app = new Appearance();
        //Create the polygon attributes
        PolygonAttributes polyAttr = new PolygonAttributes();
        //Set them so that the draw mode is polygon line
        polyAttr.setPolygonMode(PolygonAttributes.POLYGON_LINE);
        polyAttr.setCullFace(PolygonAttributes.CULL_NONE);
        //Use these in the appearance
        app.setPolygonAttributes(polyAttr);

        //rotate the view angle 
        Transform3D rotateCube = new Transform3D();
        rotateCube.set(new AxisAngle4d(1.0, 1.0, 0.0, Math.PI /4.0));

        //create a transform Group for the container
        TransformGroup tg1 = new TransformGroup(rotateCube);
        tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);

        //create a box: container
        Box container = new Box ( (float) ContainerW.getLength() , (float) ContainerW.getBreadth(), (float) ContainerW.getHeight(), app);

        //add the container to the first transform group
        tg1.addChild(container);

        //add the first transform group to the branch group
        scene.addChild(tg1);

        scene.compile();

        simpleU.addBranchGraph(scene);


    }





       /**
        * adding an item box into the container in the position (x, y, z)
        * @param x
        * @param y
        * @param z
        */
       public static TransformGroup addItem(double l, double b, double h, double x, double y, double z) {

           TransformGroup tg2 = new TransformGroup ();
           //set the appearance of the product boxes (transparent) 
           Appearance app = new Appearance(); 
           app.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED,0.2f));
           //create a box having length = l, breadth = b and height = h
           Box box = new Box( (float )l, (float)  b, (float) h, app);

           // vector to translate the item box to the position (x, y, z)
           Vector3f position = new Vector3f((float) x, (float) y, (float) z);
           //creation of a 3D transform group
           Transform3D transform = new Transform3D();
           transform.setTranslation(position);
           tg2.setTransform(transform);
           //add new item box to the transform group
           tg2.addChild(box);   

           return tg2;

         } 
}

When running the program I get multiple frames with containers drawn in them but no items

I know that my problem is in the BranchGroup scene because I get this error :

javax.media.j3d.RestrictedAccessException: Group: only a BranchGroup node may be added   

because of this line :

scene.addChild(Interface.addItem(item[p].getLength(), item[p].getBreadth(), item[p].getBreadth(), x, y, z));

I tried fixing the problem with the scene.detach() but nothing changed (maybe

I put the detach method in the wrong place, I am not sure)

Does anyone know how to create multiple scenes and in each scene I draw the container and the packed items?

I hope you understood my problem.

I cannot post the full code and all the classes here because it is too complicated.

Thank you.


Solution

  • So, what I did to make it work is as follows:

    I made the BranchGroup scene1 , the canvas and the universe global variables:

    private static SimpleUniverse simpleU ;
    private static Canvas3D canvas3D;
    private static BranchGroup scene1;
    

    I created the 3D inteface within the container's class constructor:

    public ContainerW(final int iD) {
    
        super();
        cRef = iD;
        this.emptyBreadth = 0;
        this.length = 0.8;
        this.height = 0.6;
        this.breadth = 0.5 - emptyBreadth;
        this.usedVolume = 0;
        volume = length * breadth * height;
        this.packedItems = new ArrayList<ItemsUnit>();
    
    
        //----------------------INTERFACE----------------------------
    
            this.setLayout(new BorderLayout());
    
            //create a canvas3D
            canvas3D = new Canvas3D(SimpleUniverse.getPreferredConfiguration());
            this.add(canvas3D, BorderLayout.CENTER);
    
            //create a universe
            simpleU = new SimpleUniverse(canvas3D);
            simpleU.getViewingPlatform().setNominalViewingTransform();
    
            //create a branch group scene 
            scene1 = new BranchGroup();
    
    
           //create an appearance for the container
            Appearance app = new Appearance();
            //Create the polygon attributes
            PolygonAttributes polyAttr = new PolygonAttributes();
            //Set them so that the draw mode is polygon line
            polyAttr.setPolygonMode(PolygonAttributes.POLYGON_LINE);
            polyAttr.setCullFace(PolygonAttributes.CULL_NONE);
            //Use these in the appearance
            app.setPolygonAttributes(polyAttr);
    
            //rotate the view angle 
            Transform3D rotateCube = new Transform3D();
            rotateCube.set(new AxisAngle4d(1.0, 1.0, 0.0, Math.PI /4.0));
    
            //create a transform Group for the container
            TransformGroup tg1 = new TransformGroup(rotateCube);
            tg1.setCapability(TransformGroup.ALLOW_TRANSFORM_READ);
    
            //create a box: container
            Box container = new Box ( (float) length , (float) breadth, (float)height, app);
    
            //add the container to the first transform group
            tg1.addChild(container);
    
            //add the first transform group to the branch group
            scene1.addChild(tg1);
    
            scene1.setCapability(BranchGroup.ALLOW_CHILDREN_EXTEND);
    
            scene1.compile();
    
            simpleU.addBranchGraph(scene1);
    
    
           Frame frame = new MainFrame(this,800, 800); 
    
    
    }
    

    and with every new item added I make another BranchGroup scene and add it to the global BranchGroup scene1 as follows:

                TransformGroup tg2 = new TransformGroup ();
                   //set the appearance of the product boxes (transparent) 
                   Appearance app = new Appearance(); 
                   app.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED,0.2f));
                   //create a box having length = l, breadth = b and height = h
                   Box box = new Box( (float )item[p].getLength(), (float) item[p].getBreadth(), (float) item[p].getHeight(), app);
    
                   // vector to translate the item box to the position (x, y, z)
                   Vector3f position = new Vector3f((float) x, (float) y, (float) z);
                   //creation of a 3D transform group
                   Transform3D transform = new Transform3D();
                   transform.setTranslation(position);
                   tg2.setTransform(transform);
                   //add new item box to the transform group
                   tg2.addChild(box);
                   tg2.setCapability(Group.ALLOW_CHILDREN_EXTEND);
                   BranchGroup scene = new BranchGroup();
                   scene.addChild(tg2);
                   scene1.addChild(scene);
    

    Now, I get both ,container and packed items, in the frame.