5

I am making a desktop app in netbeans platform using Java technology. I did some image processing, database functionality, image capturing process; but now I want to draw images in 3D view.
So, I think first of all I have to make point array of my .tiff 16 bit gray scale image and then use this point array. I tried something and my code is below, but it does not work.
So how should I use this point array to draw my image in 3D view?

import java.awt.BorderLayout;
import com.sun.j3d.utils.universe.*;
import java.awt.image.BufferedImage;
import javax.media.j3d.*;
import javax.media.jai.JAI;
import javax.media.jai.PlanarImage;
import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.vecmath.Color3f;
import javax.vecmath.Point3f;

public final class HelloJava3Da extends JPanel {

    PlanarImage plImg3 = JAI.create("fileload", "C:\\Users\\Desktop\\myImage.tiff");
    BufferedImage histImage = plImg3.getAsBufferedImage();
    int s = 0, count = 0;

    public HelloJava3Da() {
        setLayout(new BorderLayout());
        Canvas3D canvas3D = new Canvas3D(null);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[histImage.getWidth()*histImage.getHeight()];

        for (int i = 0; i < histImage.getWidth(); i++) {
            for (int j = 0; j < histImage.getHeight(); j++) {
                s=histImage.getRaster().getSample(i, j, 0);
                plaPts[count] = new Point3f(i,j,s);
                count++;
            }
        }
        PointArray pla = new PointArray(histImage.getWidth()*histImage.getHeight(), GeometryArray.COORDINATES);
        pla.setCoordinates(0, plaPts);
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new HelloJava3Da()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}
OroshiX
  • 712
  • 1
  • 8
  • 28
Jay
  • 1,235
  • 10
  • 28
  • 49
  • Are you seeing a black screen? – huseyin tugrul buyukisik Sep 07 '12 at 09:23
  • 1
    Okay, if you dont specify point-size, you will hardly see anything because this is only a 1-pixel-width point array. If you want to link them, use linestriparray. If you want a surface, use triangle array or trianglestriparray or trianglefanarray. After all these, you specify polygon style as "fill" "line" or "point" – huseyin tugrul buyukisik Sep 07 '12 at 09:24
  • @tuğrulbüyükışık can you modified in my code, please? i m not able to do it. – Jay Sep 07 '12 at 09:29
  • 1
    Okay, you are giving your points integer numbers. For example, 1 is a big length for a starting shape. I mean, your point array building is for your image height which could be 800--->too big. Divide it by 1000 please. – huseyin tugrul buyukisik Sep 07 '12 at 09:38
  • my Image's width is 1580, and height is 1050 because my image is 16 bit tiff image which comes from our teeth's sensor. – Jay Sep 07 '12 at 09:47
  • Have a look at my question here, if this satisfies your needed things, i will create a simple 4-point drawing algortihm for you but im gonna do important work for 6.5 hours . Here: http://stackoverflow.com/questions/12314324/java3d-with-canvas3d-and-button-overlapping – huseyin tugrul buyukisik Sep 07 '12 at 10:09
  • @tuğrulbüyükışık , yes satisfies. – Jay Sep 07 '12 at 10:25
  • I updated with a few changes because i did not have a tiff. But you can put the parts i ommitted again. I just added a few things. – huseyin tugrul buyukisik Sep 07 '12 at 13:57
  • I put 4-points to answer. Can you send me a tiff file so i can try your app with a tiff or how can i create one? – huseyin tugrul buyukisik Sep 07 '12 at 14:08
  • i added mouse-interaction in the last example. – huseyin tugrul buyukisik Sep 07 '12 at 16:51
  • @tuğrulbüyükışık i made image in 3D view, but it shows white image, and black background. now i want to give color to particular point of image, So, how can do that? i made and draw image from pointarray of image. – Jay Sep 08 '12 at 09:59
  • you need to set emissive color for custom-colors without needing any light. If you are using only points, then you just change the point color with point-attributes class – huseyin tugrul buyukisik Sep 08 '12 at 11:15
  • i used Color[] for seeting color of Point3f[] in PointArray, but it give RGB color and i want GrayScale color.my image is .tiff,16 bit, and gray scale . so how can i use point attributes to set color(Gray-Scale) of points.if you have any simple example of setting color of point using point attribute. then suggest me. – Jay Sep 08 '12 at 11:28
  • Im very sorry but i had to work some more for 2 hours. then i will compose another example – huseyin tugrul buyukisik Sep 08 '12 at 11:30
  • 1
    Gray-scale---->just cast it to float, then usi it for all 3 parameters(r g b) of Color3f(r,g,b) Color3f(gry,gry,gry) – huseyin tugrul buyukisik Sep 08 '12 at 11:32
  • @tuğrulbüyükışık. ya, you are right. i know for Gray scale image R=G=B. but how to use Color3f[] or Color4f[] to set color of that particular point? – Jay Sep 08 '12 at 11:38
  • Okay, added the last change to the end of answer. Have fun. – huseyin tugrul buyukisik Sep 08 '12 at 14:12
  • @tuğrulbüyükışık, how to make triangleArray[] from this Point3f[]? and can i use TriangleArray[] to make 3d image? which is best TriangleArray[] or PointArray[] ? – Jay Sep 09 '12 at 07:45
  • if you use just different elements for triangle array, there would be separated triangles around. If you want to join them together, you use double-use(used twice) coordinates to make them union. – huseyin tugrul buyukisik Sep 09 '12 at 07:47
  • You got the color-changin i wrote in answer? – huseyin tugrul buyukisik Sep 09 '12 at 07:48
  • For your situation, point array is cool because you got millions of points and your picture is actually 2D right? – huseyin tugrul buyukisik Sep 09 '12 at 07:50
  • If you want to add depth to your projected picture, you could change point Z coordinate according to its color. TriangleArray is just like PointArray but you need to know that consequent 3 points form a triangle when you choose POLYGON.LINE and if you want to see surface, use POLYGON.FILL in the polygon attributes. I have similar thing in the (last-1)st example i gave – huseyin tugrul buyukisik Sep 09 '12 at 07:52
  • @tuğrulbüyükışık ya, i got color, and i can't understand one thing that how to give Vertex means Vectore3f[] to set Normals of TriangleArray? – Jay Sep 09 '12 at 09:29
  • It auto generates normals if you define that at the polygonproperties. like CULL_FACE CULL_BACK CULL_NONE – huseyin tugrul buyukisik Sep 09 '12 at 09:31
  • @tuğrulbüyükışık means i take Point3f[] from image and make one PointArray pla object and pla.setCordinates(0,Point3f[]), and i dont sset normals, like setNormals(0,Vectore3f[]). so my written code give me image but not good as compared to PointArray. So, in my code any mistake is there? or not? – Jay Sep 09 '12 at 11:30
  • @tuğrulbüyükışık ,hey mann, how to give light to this my 3d image? means i want to give diffuse light to my 3D image. So , how can i do that? – Jay Sep 10 '12 at 10:20
  • Hmm, there is no diffuse light :) can you elaborate a bit? – huseyin tugrul buyukisik Sep 10 '12 at 10:34
  • You want to add normal vector for each point? It is done in the last example – huseyin tugrul buyukisik Sep 10 '12 at 11:23
  • You can use triangulator for your picture to get a 3D-shape(or surface). Last edit has the example. – huseyin tugrul buyukisik Sep 10 '12 at 14:35
  • @tuğrulbüyükışık , now i made perfact 3D image of .tiff 16 bit image in java3D. thanks a lot mannnnnn. – Jay Sep 19 '12 at 11:37
  • @tuğrulbüyükışık , hey mann. now 1 thing is irritiate that, when i run 3Dapp in xp or low Graphics configuration pc at that time 3Dimage take so much time to create. i think this problem because of i used GraphicsConfiguration Object in code. GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();. and in some laptop like have i5, 4GB RAM, and some Graphics Card then in that pc my 3DApp make 3D image faster(with in 2 second after click). so how can i make general perpose code to run my 3DApp , whcih no take longer time to create 3D image? – Jay Sep 29 '12 at 16:01
  • This exceeds my limits :) but java3D must be using cpu for this. You should ask a new question for that. I dont have time to search for now. Im sorry :(. – huseyin tugrul buyukisik Sep 29 '12 at 23:06

1 Answers1

27

Create a SimpleUniverse and Canvas3D using SimpleUniverse.getPreferredConfiguration() GraphicsConfiguration class. Then create a BranchGraph. Add a TransformGraph as a child of BranchGraph. Then add your Shape3D as a child of TransformGraph. Shape3D must have 2 things: geometry(your point array) and appearance. From appearance, you make many specifications of material and lighting.

If you just use point array, you see only points. Should use TriangleStripArray or similar thing if you want to fill polygons or LineStripArray if you want lines.

Use TransformGroup to rotate&translate. Dont forget to add light too.

TransformGroup needs a Transform3D class as parameter to rotate and translate or scale.

If your Shape3D is a surface, you may give custom-color to it or use material and put a light near it otherwise you cannot see it. Dont forget to set lightsource bound range so light reaches the object.

  • PointArray--->Cloud-like shapes
  • LineArray--->For dashed-line
  • LineStripArray-->for lines
  • TriangleArray--->divorced triangles(for a surface)
  • TriangleStripArray--->neighboring triangles(for a surface)
  • TriangleFanArray---->like building triangles arount a point(for a surface)
  • QuadArray---->Need six quads to have a cube
  • QuadStripArray--->Can construct a cube with a smaller coordinate array

Another important thing:

simpleU.getViewingPlatform().getViewPlatform().setActivationRadius(300);
    SimpleU.getViewer().getView().setBackClipDistance ( 300.0 );

makes your viewing range even more far so object dont disappear when you move.

Attach mouse-interactions to your transform-group

    MouseRotate m1=new MouseRotate();
    MouseZoom m2=new MouseZoom();
    MouseTranslate m3=new MouseTranslate();

If you want to map your 1580 x 1050 image into your default 3D view range, you should divide the point coordinates by 1000. (or scale down to 1000th in transformgroup)

Look for tutorials:

http://www.java3d.org/

http://www.java3d.org/tutorial.html

Here, i tweaked your tutorial into energon.class

//skipped imports(char limit in this post)
public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);//See the added gc? this is a preferred config
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                //Look up line, i and j are divided by 10.0f to be able to
                //see the points inside the view screen
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES);
        pla.setCoordinates(0, plaPts);
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Output:

enter image description here

Okay, lets add a point-size so we can see them clearly(will add in a minute)

New code(just added 2-3 lines)

import java.awt.BorderLayout;
import java.awt.GraphicsConfiguration;

import com.sun.j3d.utils.universe.*;

import java.awt.image.BufferedImage;
import javax.media.j3d.*;

import javax.swing.JFrame;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.vecmath.Color3f;
import javax.vecmath.Point3f;

public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];

        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES);

        pla.setCoordinates(0, plaPts);
        //between here!
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point
        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        //and here! sets the point-attributes so it is easily seen.
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

output:

enter image description here

Here is another using trianglestriparray to draw a kind of arrow-shape while you can zoom-in-out, rotate and translate with using mouse buttons(3 of them).

//skipped imports beause of char limit in this post
public final class energon extends JPanel {



    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);
        Point3f[] plaPts = new Point3f[5];
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                count++;
            }
        }
        plaPts[count] = new Point3f(3.0f/10.0f,2.0f/10.0f,0);
        int[]intArr=new int[5];
        intArr[0]=3;intArr[1]=4;intArr[2]=4;intArr[3]=3;intArr[4]=3;

        TriangleStripArray pla =new TriangleStripArray(20, GeometryArray.COLOR_3|GeometryArray.NORMALS|GeometryArray.COORDINATES,intArr);
        pla.setCoordinates(0, plaPts);
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point
        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        PolygonAttributes la=new PolygonAttributes();
        la.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        la.setCullFace(PolygonAttributes.CULL_NONE);
        app.setPolygonAttributes(la);
        Material matt=new Material();
        matt.setAmbientColor(new Color3f(1,1,1));
        matt.setDiffuseColor(new Color3f(0.5f,0.5f,0.7f));
        matt.setEmissiveColor(new Color3f(0.2f,0.2f,0.3f));
        matt.setShininess(0.5f);
        matt.setSpecularColor(new Color3f(0.4f,0.6f,0.9f));
        matt.setLightingEnable(true);

        app.setMaterial(matt);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        app.setRenderingAttributes(ra);
        Shape3D plShape = new Shape3D(pla, app);

        TransformGroup objRotate = new TransformGroup();

        MouseRotate mr=new MouseRotate();
        mr.setTransformGroup(objRotate);
        mr.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(mr);
        MouseZoom mz=new MouseZoom();
        mz.setTransformGroup(objRotate);
        mz.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(mz);
        MouseTranslate msl=new MouseTranslate();
        msl.setTransformGroup(objRotate);
        msl.setSchedulingBounds(new BoundingSphere());
        lineGroup.addChild(msl);


        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        AmbientLight al=new AmbientLight();
      //  al.addScope(objRotate);
        al.setBounds(new BoundingSphere());
        al.setEnable(true);
        al.setColor(new Color3f(1,1,1));

        lineGroup.addChild(objRotate);
        lineGroup.addChild(al);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

output:

enter image description here

You want to change color of points? Here is the new version:

//skipping imports..
public final class energon extends JPanel {


    int s = 0, count = 0;

    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();
        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();
        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        ColoringAttributes ca = new ColoringAttributes(new Color3f(204.0f, 204.0f,          204.0f), ColoringAttributes.SHADE_FLAT);
        app.setColoringAttributes(ca);

        Point3f[] plaPts = new Point3f[4];
        Color3f[] colPts=new Color3f[4]; //parallel to coordinates, colors.
        for (int i = 0; i < 2; i++) {
            for (int j = 0; j <2; j++) {
                plaPts[count] = new Point3f(i/10.0f,j/10.0f,0);
                colPts[count]=new Color3f(i/3.0f,j/3.0f,(float) ((i+j)/3.0));//my arbitrary color set :)
                count++;
            }
        }
        PointArray pla = new PointArray(4, GeometryArray.COORDINATES|GeometryArray.COLOR_3);
        pla.setColors(0,colPts); //this is the color-array setting
        pla.setCoordinates(0, plaPts); 
        //between here!
        PointAttributes a_point_just_bigger=new PointAttributes();
        a_point_just_bigger.setPointSize(10.0f);//10 pixel-wide point

        a_point_just_bigger.setPointAntialiasingEnable(true);//now points are sphere-like(not a cube)
        app.setPointAttributes(a_point_just_bigger);
        //and here! sets the point-attributes so it is easily seen.
        Shape3D plShape = new Shape3D(pla, app);
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(plShape);
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Output:

enter image description here

New example with custom-cube-shape and two directional-lights with lft-mouse button interaction:

//skipped imports relating with char limit in this post
public final class energon extends JPanel {
    int s = 0, count = 0;

    public energon() {

        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);

        BranchGroup scene = createSceneGraph();
        scene.compile();

        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);


        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();

        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();

        QuadArray lsa = new QuadArray(48,QuadArray.COORDINATES|QuadArray.NORMALS);
        Vector3f [] normals=new Vector3f[24];
        for(int i=0;i<24;i++)normals[i]=new Vector3f();
        Point3f [] pts=new Point3f[24];
        for(int i=0;i<24;i++)pts[i]=new Point3f();
        Color3f [] clrs=new Color3f[24];
        for(int i=0;i<24;i++)clrs[i]=new Color3f(0.5f,0.5f,0.5f);
        //cube=6 quads 
        //first quad
        pts[0].x=-0.5f;pts[0].y=-0.5f;pts[0].z=-0.5f;
        pts[1].x=-0.5f;pts[1].y=-0.5f;pts[1].z=0.5f;
        pts[2].x=-0.5f;pts[2].y=0.5f;pts[2].z=0.5f;
        pts[3].x=-0.5f;pts[3].y=0.5f;pts[3].z=-0.5f;
        normals[0].x=-1;normals[1].x=-1;normals[2].x=-1;normals[3].x=-1;
        //second quad
        pts[4].x=0.5f;pts[4].y=-0.5f;pts[4].z=-0.5f;
        pts[5].x=0.5f;pts[5].y=-0.5f;pts[5].z=0.5f;
        pts[6].x=0.5f;pts[6].y=0.5f;pts[6].z=0.5f;
        pts[7].x=0.5f;pts[7].y=0.5f;pts[7].z=-0.5f;
        normals[4].x=1;normals[5].x=1;normals[6].x=1;normals[7].x=1;

        //third quad
        pts[8].x=-0.5f;pts[8].y=-0.5f;pts[8].z=-0.5f;
        pts[9].x=0.5f;pts[9].y=-0.5f;pts[9].z=-0.5f;
        pts[10].x=0.5f;pts[10].y=0.5f;pts[10].z=-0.5f;
        pts[11].x=-0.5f;pts[11].y=0.5f;pts[11].z=-0.5f;
        normals[8].z=-1;normals[9].z=-1;normals[10].z=-1;normals[11].z=-1;
        //fourth quad
        pts[12].x=-0.5f;pts[12].y=-0.5f;pts[12].z=0.5f;
        pts[13].x=0.5f;pts[13].y=-0.5f;pts[13].z=0.5f;
        pts[14].x=0.5f;pts[14].y=0.5f;pts[14].z=0.5f;
        pts[15].x=-0.5f;pts[15].y=0.5f;pts[15].z=0.5f;
        normals[12].z=1;normals[13].z=1;normals[14].z=1;normals[15].z=1;
        //fifth quad
        pts[16].x=-0.5f;pts[16].y=-0.5f;pts[16].z=-0.5f;
        pts[17].x=-0.5f;pts[17].y=-0.5f;pts[17].z=0.5f;
        pts[18].x=0.5f;pts[18].y=-0.5f;pts[18].z=0.5f;
        pts[19].x=0.5f;pts[19].y=-0.5f;pts[19].z=-0.5f;
        normals[16].y=-1;normals[17].y=-1;normals[18].y=-1;normals[19].y=-1;
        //sixth quad
        pts[20].x=-0.5f;pts[20].y=0.5f;pts[20].z=-0.5f;
        pts[21].x=-0.5f;pts[21].y=0.5f;pts[21].z=0.5f;
        pts[22].x=0.5f;pts[22].y=0.5f;pts[22].z=0.5f;
        pts[23].x=0.5f;pts[23].y=0.5f;pts[23].z=-0.5f;
        normals[20].y=1;normals[21].y=1;normals[22].y=1;normals[23].y=1;
        lsa.setNormals(0, normals);
        lsa.setCoordinates(0, pts);
        Shape3D sh=new Shape3D();
        PolygonAttributes pa=new PolygonAttributes();
        pa.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        pa.setCullFace(PolygonAttributes.CULL_NONE);
        Material mat=new Material();
        mat.setEmissiveColor(new Color3f(0.5f,0.5f,0.5f));
        mat.setAmbientColor(new Color3f(0.1f,0.1f,0.1f));
        mat.setDiffuseColor(new Color3f(0.2f,0.3f,0.4f));
        mat.setSpecularColor(new Color3f(0.6f,0.3f,0.2f));
        mat.setLightingEnable(true);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        ColoringAttributes ca=new ColoringAttributes();
        ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
        ca.setColor(new Color3f(0.2f,0.5f,0.9f));
        app.setColoringAttributes(ca);
        app.setRenderingAttributes(ra);   
        app.setMaterial(mat);
        app.setPolygonAttributes(pa);
        sh.setGeometry(lsa);
        sh.setAppearance(app);
        sh.setPickable(true); 
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(sh);

        DirectionalLight light1=new DirectionalLight();
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(-5.0,0,0),10.0));
        light1.setColor(new Color3f(1f,1f,1f));
        light1.setDirection(new Vector3f(0,1,0));
        objRotate.addChild(light1);
        DirectionalLight light2=new DirectionalLight();
        light2.setInfluencingBounds(new BoundingSphere(new Point3d(5.0,0,0),10.0));
        light2.setColor(new Color3f(0.5f,1f,0.5f));
        light2.setDirection(new Vector3f(0,-1,0));
        objRotate.addChild(light2);
        MouseRotate f1=new MouseRotate();
        f1.setSchedulingBounds(new BoundingSphere());
        f1.setTransformGroup(objRotate);
        lineGroup.addChild(f1);
        objRotate.addChild(new Sphere(0.60f,1,128));
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Output:

enter image description here

Most important part is, you can use triangulator to get a real 3D shape using just point coordinates

        GeometryInfo ginfo=new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
        Triangulator tr = new Triangulator();
        NormalGenerator normalGenerator = new NormalGenerator();
        Stripifier st = new Stripifier();  
        int [] iint=new int[]{4,4,4,4,4,4};-->each face of cube has 4 points
        ginfo.setStripCounts(iint);
        ginfo.setCoordinates(pts); 
        tr.triangulate(ginfo); // ginfo contains the geometry     
        normalGenerator.generateNormals( ginfo );
        st.stripify(ginfo);
        sh.setGeometry(ginfo.getGeometryArray()); // shape is a Shape3D.
        //now you can use Shape3D-type sh as a 3D-surface-containing shape

In the last example, you had to use the quadarray but now, you can do same with only using points and the triangulator:

//skipping imports since char limit is reached in this answer
public final class energon extends JPanel {
    int s = 0, count = 0;
    public energon() {
        setLayout(new BorderLayout());
        GraphicsConfiguration gc=SimpleUniverse.getPreferredConfiguration();
        Canvas3D canvas3D = new Canvas3D(gc);
        add("Center", canvas3D);
        BranchGroup scene = createSceneGraph();
        scene.compile();
        // SimpleUniverse is a Convenience Utility class
        SimpleUniverse simpleU = new SimpleUniverse(canvas3D);
        // This moves the ViewPlatform back a bit so the
        // objects in the scene can be viewed.
        simpleU.getViewingPlatform().setNominalViewingTransform();
        simpleU.addBranchGraph(scene);
    }
    public BranchGroup createSceneGraph() {
        BranchGroup lineGroup = new BranchGroup();
        Appearance app = new Appearance();
        Vector3f [] normals=new Vector3f[24];
        for(int i=0;i<24;i++)normals[i]=new Vector3f();
        Point3f [] pts=new Point3f[24];
        for(int i=0;i<24;i++)pts[i]=new Point3f();
        Color3f [] clrs=new Color3f[24];
        for(int i=0;i<24;i++)clrs[i]=new Color3f(0.5f,0.5f,0.5f);
        //cube=6 quads 
        //first quad
        pts[0].x=-0.5f;pts[0].y=-0.5f;pts[0].z=-0.5f;
        pts[1].x=-0.5f;pts[1].y=-0.5f;pts[1].z=0.5f;
        pts[2].x=-0.5f;pts[2].y=0.5f;pts[2].z=0.5f;
        pts[3].x=-0.5f;pts[3].y=0.5f;pts[3].z=-0.5f;
        normals[0].x=-1;normals[1].x=-1;normals[2].x=-1;normals[3].x=-1;
        //second quad
        pts[4].x=0.5f;pts[4].y=-0.5f;pts[4].z=-0.5f;
        pts[5].x=0.5f;pts[5].y=-0.5f;pts[5].z=0.5f;
        pts[6].x=0.5f;pts[6].y=0.5f;pts[6].z=0.5f;
        pts[7].x=0.5f;pts[7].y=0.5f;pts[7].z=-0.5f;
        normals[4].x=1;normals[5].x=1;normals[6].x=1;normals[7].x=1;
        //third quad
        pts[8].x=-0.5f;pts[8].y=-0.5f;pts[8].z=-0.5f;
        pts[9].x=0.5f;pts[9].y=-0.5f;pts[9].z=-0.5f;
        pts[10].x=0.5f;pts[10].y=0.5f;pts[10].z=-0.5f;
        pts[11].x=-0.5f;pts[11].y=0.5f;pts[11].z=-0.5f;
        normals[8].z=-1;normals[9].z=-1;normals[10].z=-1;normals[11].z=-1;
        //fourth quad
        pts[12].x=-0.5f;pts[12].y=-0.5f;pts[12].z=0.5f;
        pts[13].x=0.5f;pts[13].y=-0.5f;pts[13].z=0.5f;
        pts[14].x=0.5f;pts[14].y=0.5f;pts[14].z=0.5f;
        pts[15].x=-0.5f;pts[15].y=0.5f;pts[15].z=0.5f;
        normals[12].z=1;normals[13].z=1;normals[14].z=1;normals[15].z=1;
        //fifth quad
        pts[16].x=-0.5f;pts[16].y=-0.5f;pts[16].z=-0.5f;
        pts[17].x=-0.5f;pts[17].y=-0.5f;pts[17].z=0.5f;
        pts[18].x=0.5f;pts[18].y=-0.5f;pts[18].z=0.5f;
        pts[19].x=0.5f;pts[19].y=-0.5f;pts[19].z=-0.5f;
        normals[16].y=-1;normals[17].y=-1;normals[18].y=-1;normals[19].y=-1;
        //sixth quad
        pts[20].x=-0.5f;pts[20].y=0.5f;pts[20].z=-0.5f;
        pts[21].x=-0.5f;pts[21].y=0.5f;pts[21].z=0.5f;
        pts[22].x=0.5f;pts[22].y=0.5f;pts[22].z=0.5f;
        pts[23].x=0.5f;pts[23].y=0.5f;pts[23].z=-0.5f;
        normals[20].y=1;normals[21].y=1;normals[22].y=1;normals[23].y=1;
        Shape3D sh=new Shape3D();
        PolygonAttributes pa=new PolygonAttributes();
        pa.setPolygonMode(PolygonAttributes.POLYGON_FILL);
        pa.setCullFace(PolygonAttributes.CULL_NONE);
        Material mat=new Material();
        mat.setEmissiveColor(new Color3f(0.5f,0.5f,0.5f));
        mat.setAmbientColor(new Color3f(0.1f,0.1f,0.1f));
        mat.setDiffuseColor(new Color3f(0.2f,0.3f,0.4f));
        mat.setSpecularColor(new Color3f(0.6f,0.3f,0.2f));
        mat.setLightingEnable(true);
        RenderingAttributes ra=new RenderingAttributes();
        ra.setIgnoreVertexColors(true);
        ColoringAttributes ca=new ColoringAttributes();
        ca.setShadeModel(ColoringAttributes.SHADE_GOURAUD);
        ca.setColor(new Color3f(0.2f,0.5f,0.9f));
        app.setColoringAttributes(ca);
        app.setRenderingAttributes(ra);
        app.setMaterial(mat);
        app.setPolygonAttributes(pa);
        sh.setAppearance(app);
        sh.setPickable(true);
        GeometryArray ga=null;
        GeometryInfo ginfo=new GeometryInfo(GeometryInfo.POLYGON_ARRAY);
        Triangulator tr = new Triangulator();
        NormalGenerator normalGenerator = new NormalGenerator();
        Stripifier st = new Stripifier();  
        int [] iint=new int[]{4,4,4,4,4,4};
        ginfo.setStripCounts(iint);
        ginfo.setCoordinates(pts); 
        tr.triangulate(ginfo); // ginfo contains the geometry     
        normalGenerator.generateNormals( ginfo );
        st.stripify(ginfo);
        sh.setGeometry(ginfo.getGeometryArray()); // shape is a Shape3D.
        TransformGroup objRotate = new TransformGroup();
        objRotate.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
        objRotate.addChild(sh);   
        DirectionalLight light1=new DirectionalLight();
        light1.setInfluencingBounds(new BoundingSphere(new Point3d(-5.0,0,0),10.0));
        light1.setColor(new Color3f(1f,1f,1f));
        light1.setDirection(new Vector3f(0,1,0));
        objRotate.addChild(light1);
        DirectionalLight light2=new DirectionalLight();
        light2.setInfluencingBounds(new BoundingSphere(new Point3d(5.0,0,0),10.0));
        light2.setColor(new Color3f(0.5f,1f,0.5f));
        light2.setDirection(new Vector3f(0,-1,0));
        objRotate.addChild(light2);
        MouseRotate f1=new MouseRotate();
        f1.setSchedulingBounds(new BoundingSphere());
        f1.setTransformGroup(objRotate);
        lineGroup.addChild(f1);
        objRotate.addChild(new Sphere(0.60f,1,128));
        lineGroup.addChild(objRotate);
        return lineGroup;
    }

    public static void main(String[] args) {
        JFrame frame = new JFrame();
        frame.add(new JScrollPane(new energon()));
        frame.setSize(300, 300);
        frame.setVisible(true);
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
    }
}

Output:Same! you just give the coordinates of points and the face-vertex numbers

enter image description hereenter image description here

  • set the strip counts
  • set the coordinates(from your tiff)
  • triangulate
  • generate normals
  • stripify
  • .getGeometry(finished)
huseyin tugrul buyukisik
  • 11,469
  • 4
  • 45
  • 97
  • i made all object according to you said, but its not work well for me. my code is above now, if any wrong thing then tell me or suggest me. – Jay Sep 07 '12 at 09:14
  • i don't know deeply about java3D , i think that image made from multi points(pixels) in (x,y, intensity). so i want ot draw this image in 3D view as using it's x as X-cordinate, y as Y-Cordinate, and intensity as Z-zordinate, so image become like 3D view because every pixel of image have its own and different imtensity value. So, how can i draw myImage.tiff in 3d view? and seriously i don't know deeply about Java 3D, but i know very well Java SE. – Jay Sep 07 '12 at 09:42
  • Have you any example for drawing any 4 points in 3d view? if yes then sugges me. – Jay Sep 07 '12 at 09:44
  • Okay, im in a hurry for another job for now, i will add the 4-point drawing ~7 hourse later. Sorry – huseyin tugrul buyukisik Sep 07 '12 at 09:48
  • thanks mannnn.i can send you one tiff image, but i dont know your email id. – Jay Sep 08 '12 at 05:38
  • 1
    now if i want to add lights, either AmbientLight or DirectionalLight then how could i do? – Jony Sep 10 '12 at 06:40
  • 1
    add light just as a shape. While creating, use BoundingSphere or BoundingBox to tell its range. Ambient light is a little dark so you cana use directional light. I will add light in some minutes – huseyin tugrul buyukisik Sep 10 '12 at 07:29
  • add light just as a shape. While creating, use BoundingSphere or BoundingBox to tell its range. Ambient light is a little dark so you cana use directional light. I will add light in some minutes – huseyin tugrul buyukisik Sep 10 '12 at 07:29
  • But, without a polygon array, it wont use the normals. You need trainglearray, quadarray or their strip counterparts as a geometry. Otherwise you see only lines or dots – huseyin tugrul buyukisik Sep 10 '12 at 11:44
  • Okay, i used triangulator to get rid of quadarray, so you can use only your coordinates of points to generate 3D shape geometry. Checkout the last edit – huseyin tugrul buyukisik Sep 10 '12 at 14:35
  • Thanks for this very comprehensive post. – Kamil Jun 29 '13 at 22:13
  • @Kamil If you are interested in 3D in java, jmonkey engine is more advanced and more frequently updated then java3D but it has no auto optimization for dynamic geometries. – huseyin tugrul buyukisik Jun 29 '13 at 22:18
  • Im not intrested in more advanced engines. Im interested in simple 3d solutions for data presentation etc. – Kamil Jun 29 '13 at 22:22
  • @Kamil: Then this is simpler and quicker. Have fun. – huseyin tugrul buyukisik Jun 29 '13 at 22:26