Viewer : Appearance « 3D « Java

Java
1. 2D Graphics GUI
2. 3D
3. Advanced Graphics
4. Ant
5. Apache Common
6. Chart
7. Collections Data Structure
8. Database SQL JDBC
9. Design Pattern
10. Development Class
11. Email
12. Event
13. File Input Output
14. Game
15. Hibernate
16. J2EE
17. J2ME
18. JDK 6
19. JSP
20. JSTL
21. Language Basics
22. Network Protocol
23. PDF RTF
24. Regular Expressions
25. Security
26. Servlets
27. Spring
28. Swing Components
29. Swing JFC
30. SWT JFace Eclipse
31. Threads
32. Tiny Application
33. Velocity
34. Web Services SOA
35. XML
Microsoft Office Word 2007 Tutorial
Java Tutorial
Java Source Code / Java Documentation
Java Open Source
Jar File Download
Java Articles
Java Products
Java by API
C# / C Sharp
C# / CSharp Tutorial
ASP.Net
JavaScript DHTML
JavaScript Tutorial
JavaScript Reference
HTML / CSS
HTML CSS Reference
C / ANSI-C
C Tutorial
C++
C++ Tutorial
PHP
Python
SQL Server / T-SQL
Oracle PL / SQL
Oracle PL/SQL Tutorial
PostgreSQL
SQL / MySQL
MySQL Tutorial
VB.Net
VB.Net Tutorial
Java » 3D » AppearanceScreenshots 
Viewer
Viewer


/*
 * %Z%%M% %I% %E% %U%
 
 * ************************************************************** "Copyright (c)
 * 2001 Sun Microsystems, Inc. All Rights Reserved.
 
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 
 * -Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 
 * -Redistribution in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 
 * Neither the name of Sun Microsystems, Inc. or the names of contributors may
 * be used to endorse or promote products derived from this software without
 * specific prior written permission.
 
 * This software is provided "AS IS," without a warranty of any kind. ALL
 * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING ANY
 * IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR
 * NON-INFRINGEMENT, ARE HEREBY EXCLUDED. SUN AND ITS LICENSORS SHALL NOT BE
 * LIABLE FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING
 * OR DISTRIBUTING THE SOFTWARE OR ITS DERIVATIVES. IN NO EVENT WILL SUN OR ITS
 * LICENSORS BE LIABLE FOR ANY LOST REVENUE, PROFIT OR DATA, OR FOR DIRECT,
 * INDIRECT, SPECIAL, CONSEQUENTIAL, INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER
 * CAUSED AND REGARDLESS OF THE THEORY OF LIABILITY, ARISING OUT OF THE USE OF
 * OR INABILITY TO USE SOFTWARE, EVEN IF SUN HAS BEEN ADVISED OF THE POSSIBILITY
 * OF SUCH DAMAGES.
 
 * You acknowledge that Software is not designed,licensed or intended for use in
 * the design, construction, operation or maintenance of any nuclear facility."
 
 * ***************************************************************************
 */

import java.applet.Applet;
import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.GraphicsConfiguration;
import java.awt.GridBagConstraints;
import java.awt.GridBagLayout;
import java.awt.GridLayout;
import java.awt.Insets;
import java.awt.Point;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.FileOutputStream;
import java.text.NumberFormat;
import java.util.Enumeration;
import java.util.EventListener;
import java.util.EventObject;
import java.util.Hashtable;
import java.util.Vector;

import javax.media.j3d.Alpha;
import javax.media.j3d.Appearance;
import javax.media.j3d.Background;
import javax.media.j3d.BoundingSphere;
import javax.media.j3d.BranchGroup;
import javax.media.j3d.Canvas3D;
import javax.media.j3d.ColoringAttributes;
import javax.media.j3d.ImageComponent;
import javax.media.j3d.ImageComponent2D;
import javax.media.j3d.LineArray;
import javax.media.j3d.LineAttributes;
import javax.media.j3d.LineStripArray;
import javax.media.j3d.PolygonAttributes;
import javax.media.j3d.RotationInterpolator;
import javax.media.j3d.Screen3D;
import javax.media.j3d.Shape3D;
import javax.media.j3d.Transform3D;
import javax.media.j3d.TransformGroup;
import javax.media.j3d.TriangleFanArray;
import javax.media.j3d.View;
import javax.swing.Box;
import javax.swing.BoxLayout;
import javax.swing.JButton;
import javax.swing.JLabel;
import javax.swing.JPanel;
import javax.swing.JSlider;
import javax.swing.event.ChangeEvent;
import javax.swing.event.ChangeListener;
import javax.vecmath.AxisAngle4f;
import javax.vecmath.Color3f;
import javax.vecmath.Matrix4d;
import javax.vecmath.Point3d;
import javax.vecmath.Point3f;
import javax.vecmath.Vector3f;
import javax.vecmath.Vector4d;

import com.sun.image.codec.jpeg.JPEGCodec;
import com.sun.image.codec.jpeg.JPEGEncodeParam;
import com.sun.image.codec.jpeg.JPEGImageEncoder;
import com.sun.j3d.utils.applet.MainFrame;
import com.sun.j3d.utils.geometry.Sphere;
import com.sun.j3d.utils.universe.SimpleUniverse;
import com.sun.j3d.utils.universe.ViewingPlatform;

public class ViewProj extends Applet implements Java3DExplorerConstants {

  PolygonAttributes solidPa;

  PolygonAttributes wirePa;

  JSlider dynamicOffsetSlider;

  JSlider staticOffsetSlider;

  JLabel dynamicSliderValueLabel;

  JLabel staticSliderValueLabel;

  float dynamicOffset = 1.0f;

  float staticOffset = 1.0f;

  float frontClipDist = 1.413f;

  float backClipDist = 3.309f;

  float backClipRatio = backClipDist / frontClipDist;

  View view;

  ViewingPlatform viewingPlatform;

  float innerScale = 0.94f;

  TransformGroup innerTG;

  Transform3D scale;

  Transform3D projTrans = new Transform3D();

  int numClipGridPts;

  int maxClipGridPts = 180;

  Point3f[] clipGridPtsVW = new Point3f[maxClipGridPts];

  Point3f[] clipGridPtsProj = new Point3f[maxClipGridPts];

  int numCirclePts = 36;

  Point3f[] circlePtsVW = new Point3f[numCirclePts];

  Point3f[] circlePtsProj = new Point3f[numCirclePts];

  Point3f eyePtVW = new Point3f();

  float fov;

  float sphereRadius = 0.85f;

  BranchGroup urScene;

  BranchGroup lrScene;

  SimpleUniverse urUniverse;

  SimpleUniverse lrUniverse;

  boolean isApplication;

  Canvas3D canvas;

  Canvas3D urCanvas;

  Canvas3D lrCanvas;

  OffScreenCanvas3D offScreenCanvas;

  OffScreenCanvas3D urOffScreenCanvas;

  OffScreenCanvas3D lrOffScreenCanvas;

  String snapImageString = "Snap Main";

  String urSnapImageString = "Snap UR";

  String lrSnapImageString = "Snap LR";

  String outFileBase = "vproj";

  int outFileSeq = 0;

  float offScreenScale = 1.0f;

  String urOutFileBase = "vprojur";

  int urOutFileSeq = 0;

  float urOffScreenScale = 1.0f;

  String lrOutFileBase = "vprojlr";

  int lrOutFileSeq = 0;

  float lrOffScreenScale = 1.0f;

  NumberFormat nf;

  Vector4d projPt = new Vector4d();

  public BranchGroup createSceneGraph() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();

    // Create the transform group node and initialize it to the
    // identity. Enable the TRANSFORM_WRITE capability so that
    // our behavior code can modify it at runtime. Add it to the
    // root of the subgraph.
    TransformGroup objTrans = new TransformGroup();
    objTrans.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    objRoot.addChild(objTrans);

    // Create a Sphere. We will display this as both wireframe and
    // solid to make a hidden line display
    // wireframe
    Appearance wireApp = new Appearance();
    ColoringAttributes ca = new ColoringAttributes(black,
        ColoringAttributes.SHADE_FLAT);
    wireApp.setColoringAttributes(ca);
    wirePa = new PolygonAttributes(PolygonAttributes.POLYGON_LINE,
        PolygonAttributes.CULL_BACK, 0.0f);
    wireApp.setPolygonAttributes(wirePa);
    Sphere outWireSphere = new Sphere(sphereRadius, 010, wireApp);
    objTrans.addChild(outWireSphere);

    // solid
    ColoringAttributes outCa = new ColoringAttributes(red,
        ColoringAttributes.SHADE_FLAT);
    Appearance outSolid = new Appearance();
    outSolid.setColoringAttributes(outCa);
    solidPa = new PolygonAttributes(PolygonAttributes.POLYGON_FILL,
        PolygonAttributes.CULL_BACK, 0.0f);
    solidPa.setPolygonOffsetFactor(dynamicOffset);
    solidPa.setPolygonOffset(staticOffset);
    solidPa.setCapability(PolygonAttributes.ALLOW_OFFSET_WRITE);
    outSolid.setPolygonAttributes(solidPa);
    Sphere outSolidSphere = new Sphere(sphereRadius, 010, outSolid);
    objTrans.addChild(outSolidSphere);

    innerTG = new TransformGroup();
    innerTG.setCapability(TransformGroup.ALLOW_TRANSFORM_WRITE);
    scale = new Transform3D();
    updateInnerScale();
    objTrans.addChild(innerTG);

    // Create a smaller sphere to go inside. This sphere has a different
    // tesselation and color
    Sphere inWireSphere = new Sphere(sphereRadius, 015, wireApp);
    innerTG.addChild(inWireSphere);

    // inside solid
    ColoringAttributes inCa = new ColoringAttributes(blue,
        ColoringAttributes.SHADE_FLAT);
    Appearance inSolid = new Appearance();
    inSolid.setColoringAttributes(inCa);
    inSolid.setPolygonAttributes(solidPa);
    Sphere inSolidSphere = new Sphere(sphereRadius, 015, inSolid);
    innerTG.addChild(inSolidSphere);

    // Create a new Behavior object that will perform the desired
    // operation on the specified transform object and add it into
    // the scene graph.
    AxisAngle4f axisAngle = new AxisAngle4f(0.0f0.0f1.0f,
        -(floatMath.PI / 2.0f);
    Transform3D yAxis = new Transform3D();
    Alpha rotationAlpha = new Alpha(-1, Alpha.INCREASING_ENABLE, 00,
        8000000000);

    RotationInterpolator rotator = new RotationInterpolator(rotationAlpha,
        objTrans, yAxis, 0.0f(floatMath.PI * 2.0f);
    BoundingSphere bounds = new BoundingSphere(new Point3d(0.00.00.0),
        100.0);
    rotator.setSchedulingBounds(bounds);
    //objTrans.addChild(rotator);

    Background bgWhite = new Background(white);
    bgWhite.setApplicationBounds(bounds);
    objTrans.addChild(bgWhite);

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

    return objRoot;
  }

  void updateInnerScale() {
    scale.set(innerScale);
    innerTG.setTransform(scale);
  }

  public BranchGroup createVWorldViewSG() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();
    objRoot.setCapability(BranchGroup.ALLOW_DETACH);

    // setup a transform group to hold the scaled scene
    TransformGroup objTrans = new TransformGroup();
    objRoot.addChild(objTrans);

    // get the eye point, field of view and clip distances
    float fov = (floatview.getFieldOfView();

    // figure out the angle factors to find points along the edges
    // of the FOV
    // X = fovSpreadX * (Y - eyeVW.y) + eyeVW.x;
    float fovSpreadX = (floatMath.tan(fov / 2);
    // Z = fovSpreadZ * (X - eyeVW.x) + eyeVW.z;
    float fovSpreadZ = 1.0f / fovSpreadX;
    //System.out.println("fovSpreadX = " + fovSpreadX);
    //System.out.println("fovSpreadZ = " + fovSpreadZ);

    Transform3D vpTransform = new Transform3D();
    viewingPlatform.getViewPlatformTransform().getTransform(vpTransform);
    Vector3f vpTranslation = new Vector3f();
    vpTransform.get(vpTranslation);
    eyePtVW.set(vpTranslation);
    eyePtVW.negate();
    // get the eye point in our 2D coord system.
    Point3f eyePt = new Point3f(0.0f, eyePtVW.z, 0.1f);
    float frontClipDist = (floatview.getFrontClipDistance();
    float backClipDist = (floatview.getBackClipDistance();

    // set up the clip plane lines
    Point3f[] cpPoints = new Point3f[5];
    cpPoints[0new Point3f(frontClipDist * fovSpreadX, eyePtVW.z
        + frontClipDist, 0.1f);
    cpPoints[1new Point3f(cpPoints[0]);
    cpPoints[1].x *= -1;
    Point3f backLeft = new Point3f(-backClipDist * fovSpreadX, eyePtVW.z
        + backClipDist, 0.1f);
    cpPoints[2= backLeft;
    Point3f backRight = new Point3f(backLeft);
    backRight.x *= -1;
    cpPoints[3= backRight;
    cpPoints[4= cpPoints[0];
    //for (int i = 0; i < 4; i++) {
    //    System.out.println("cpPoints[" + i + "] = " + cpPoints[i]);
    //}
    int[] cpLength = new int[1];
    cpLength[05;
    LineStripArray cpLines = new LineStripArray(5, LineArray.COORDINATES,
        cpLength);
    cpLines.setCoordinates(0, cpPoints);
    Appearance cpApp = new Appearance();
    ColoringAttributes cpCa = new ColoringAttributes(blue,
        ColoringAttributes.SHADE_FLAT);
    cpApp.setColoringAttributes(cpCa);
    Shape3D cpShape = new Shape3D(cpLines, cpApp);
    objTrans.addChild(cpShape);

    // get the limits of the space
    float minY = eyePt.y;
    float maxY = backLeft.y;
    float minX = backLeft.x;
    float maxX = backRight.x;

    // figure out the X and Y extents and offsets
    float deltaX = maxX - minX;
    float deltaY = maxY - minY;
    float offsetX = -(maxX + minX2.0f;
    float offsetY = -(maxY + minY2.0f;
    float gridSize = Math.max(deltaX, deltaY);

    // scale the grid slightly to give a border around the edge
    gridSize *= 1.1f;

    //System.out.println("offsetX = " + offsetX);
    //System.out.println("offsetY = " + offsetY);

    // Scale the view to fit -1 to 1
    Transform3D trans = new Transform3D();
    trans.set(new Vector3f(offsetX, offsetY, 0.0f)2.0f / gridSize);
    objTrans.setTransform(trans);

    // figure out a grid step that is a multiple of 10 which keeps the
    // number of steps less than 30.
    float gridStep = 1.0f;
    while ((gridSize / gridStep30.0) {
      gridStep *= 10;
    }
    int gridNumSteps = (intMath.ceil(gridSize / gridStep1;

    // allocate the grid points array, four points for each step (x and y)
    // with a couple extra points for the extra grid points added
    // below
    int gridNumPoints = (gridNumSteps + 4);
    Point3f[] gridPts = new Point3f[gridNumPoints];
    for (int i = 0; i < gridNumPoints; i++) {
      gridPts[inew Point3f();
    }

    // find the grid limits. Add a step on each side to make sure
    // the grid is larger than the view
    float gridMinY = gridStepFloor(minY, gridStep- gridStep;
    float gridMaxY = gridStepCeil(maxY, gridStep+ gridStep;
    float gridMinX = gridStepFloor(minX, gridStep- gridStep;
    float gridMaxX = gridStepCeil(maxX, gridStep+ gridStep;
    //System.out.println("gridMinY = " + gridMinY);
    //System.out.println("gridMaxY = " + gridMaxY);
    //System.out.println("gridMinX = " + gridMinX);
    //System.out.println("gridMaxX = " + gridMaxX);

    // set up the background grid
    Appearance bgApp = new Appearance();
    ColoringAttributes bgCa = new ColoringAttributes();
    bgCa.setColor(grey);
    LineAttributes bgLa = new LineAttributes();
    bgApp.setColoringAttributes(bgCa);

    // clear out the clip grid point list
    numClipGridPts = 0;

    // set up the vertical lines
    int numPts = 0;
    for (float x = gridMinX; x <= gridMaxX; x += gridStep) {
      gridPts[numPts].x = x;
      gridPts[numPts].y = gridMinY;
      gridPts[numPts].z = -0.2f;
      gridPts[numPts + 1].x = x;
      gridPts[numPts + 1].y = gridMaxY;
      gridPts[numPts + 1].z = -0.2f;
      numPts += 2;

      // try to add a line to the clipped grid
      // find the intersection of the clipped line with the FOV sides
      // this is a distance relative to the eye
      float clipZ = fovSpreadZ * Math.abs(x - eyePtVW.x);
      if (clipZ < frontClipDist) { // clip to front clip plane
        clipZ = frontClipDist;
      }
      if (clipZ < backClipDist) { // clip to back clip plane
        // line is not clipped
        clipGridPtsVW[numClipGridPts].x = x;
        clipGridPtsVW[numClipGridPts].y = clipZ + eyePtVW.z;
        clipGridPtsVW[numClipGridPts].z = -0.1f;
        clipGridPtsVW[numClipGridPts + 1].x = x;
        clipGridPtsVW[numClipGridPts + 1].y = backClipDist + eyePtVW.z;
        clipGridPtsVW[numClipGridPts + 1].z = -0.1f;
        numClipGridPts += 2;
      }
    }
    LineArray vertLa = new LineArray(numPts, LineArray.COORDINATES);
    vertLa.setCoordinates(0, gridPts, 0, numPts);
    Shape3D vertShape = new Shape3D(vertLa, bgApp);
    objTrans.addChild(vertShape);

    // set up the horizontal lines
    numPts = 0;
    for (float y = gridMinY; y <= gridMaxY; y += gridStep) {
      gridPts[numPts].x = gridMinX;
      gridPts[numPts].y = y;
      gridPts[numPts++].z = -0.2f;
      gridPts[numPts].x = gridMaxX;
      gridPts[numPts].y = y;
      gridPts[numPts++].z = -0.2f;

      // try to add a line to the clipped grid
      // find the intersection of the clipped line with the FOV sides
      // this is a distance relative to the eye
      float clipDist = (y - eyePtVW.z);
      if ((clipDist > frontClipDist&& (clipDist < backClipDist)) {

        float clipX = fovSpreadX * clipDist;
        clipGridPtsVW[numClipGridPts].x = -clipX;
        clipGridPtsVW[numClipGridPts].y = y;
        clipGridPtsVW[numClipGridPts].z = -0.1f;
        clipGridPtsVW[numClipGridPts + 1].x = clipX;
        clipGridPtsVW[numClipGridPts + 1].y = y;
        clipGridPtsVW[numClipGridPts + 1].z = -0.1f;
        numClipGridPts += 2;
      }
    }
    LineArray horizLa = new LineArray(numPts, LineArray.COORDINATES);
    horizLa.setCoordinates(0, gridPts, 0, numPts);
    Shape3D horizShape = new Shape3D(horizLa, bgApp);
    objTrans.addChild(horizShape);

    // draw the clipped grid.
    if (numClipGridPts > 0) {
      LineArray clipLa = new LineArray(numClipGridPts,
          LineArray.COORDINATES);
      clipLa.setCoordinates(0, clipGridPtsVW, 0, numClipGridPts);
      Appearance clipGridApp = new Appearance();
      ColoringAttributes clipCa = new ColoringAttributes(black,
          ColoringAttributes.SHADE_FLAT);
      clipGridApp.setColoringAttributes(clipCa);
      LineAttributes clipGridLa = new LineAttributes();
      Shape3D clipShape = new Shape3D(clipLa, clipGridApp);
      objTrans.addChild(clipShape);
    }

    // set up the coordinate system
    Appearance coordSysApp = new Appearance();
    LineAttributes coordSysLa = new LineAttributes();
    coordSysLa.setLineWidth(3.0f);
    coordSysApp.setLineAttributes(coordSysLa);
    ColoringAttributes coordSysCa = new ColoringAttributes(grey,
        ColoringAttributes.SHADE_FLAT);
    coordSysApp.setColoringAttributes(coordSysCa);
    Point3f[] coordSysPts = new Point3f[4];
    coordSysPts[0new Point3f(gridMinX, 0, -0.5f);
    coordSysPts[1new Point3f(gridMaxX, 0, -0.5f);
    coordSysPts[2new Point3f(0, gridMinY, -0.5f);
    coordSysPts[3new Point3f(0, gridMaxY, -0.5f);
    LineArray coordSysLines = new LineArray(4, LineArray.COORDINATES);
    coordSysLines.setCoordinates(0, coordSysPts);
    Shape3D coordSysShape = new Shape3D(coordSysLines, coordSysApp);
    objTrans.addChild(coordSysShape);

    // set up the circle
    Appearance circleApp = new Appearance();
    ColoringAttributes circleCa = new ColoringAttributes();
    circleCa.setColor(red);
    circleApp.setColoringAttributes(circleCa);
    PolygonAttributes pa = new PolygonAttributes();
    pa.setCullFace(PolygonAttributes.CULL_NONE);
    circleApp.setPolygonAttributes(pa);
    int step = 360 (numCirclePts - 1);
    for (int deg = 0; deg < 360; deg += step) {
      double angle = Math.toRadians(deg);
      circlePtsVW[deg / 10].x = sphereRadius * (floatMath.sin(angle);
      circlePtsVW[deg / 10].y = sphereRadius * (floatMath.cos(angle);
      circlePtsVW[deg / 10].z = -0.3f;
    }
    circlePtsVW[numCirclePts - 1].set(circlePtsVW[0]);
    int[] lineStripLength = new int[1];
    lineStripLength[0= numCirclePts;
    //LineStripArray circleLineStrip = new LineStripArray(numCirclePts,
    //        LineArray.COORDINATES, lineStripLength);
    TriangleFanArray circleLineStrip = new TriangleFanArray(numCirclePts,
        LineArray.COORDINATES, lineStripLength);
    circleLineStrip.setCoordinates(0, circlePtsVW);
    Shape3D circleShape = new Shape3D(circleLineStrip, circleApp);
    objTrans.addChild(circleShape);

    return objRoot;
  }

  // return the closest multiple of step less than value
  float gridStepFloor(float value, float step) {
    return (float) (step * (Math.floor(value / step)));
  }

  // return the closest multiple of step greater than value
  float gridStepCeil(float value, float step) {
    return (float) (step * (Math.ceil(value / step)));
  }

  public BranchGroup createProjViewSG() {
    // Create the root of the branch graph
    BranchGroup objRoot = new BranchGroup();
    objRoot.setCapability(BranchGroup.ALLOW_DETACH);

    // setup a transform group to hold the scaled scene
    TransformGroup objTrans = new TransformGroup();
    Transform3D scale = new Transform3D();
    scale.set(0.9);
    objTrans.setTransform(scale);
    objRoot.addChild(objTrans);

    // create the clip limits line
    Point3f[] cpPoints = new Point3f[5];
    cpPoints[0new Point3f(-1, -10.1f);
    cpPoints[1new Point3f(1, -10.1f);
    cpPoints[2new Point3f(110.1f);
    cpPoints[3new Point3f(-110.1f);
    cpPoints[4= cpPoints[0];
    int[] cpLength = new int[1];
    cpLength[05;
    LineStripArray cpLines = new LineStripArray(5, LineArray.COORDINATES,
        cpLength);
    cpLines.setCoordinates(0, cpPoints);
    Appearance cpApp = new Appearance();
    ColoringAttributes cpCa = new ColoringAttributes(blue,
        ColoringAttributes.SHADE_FLAT);
    cpApp.setColoringAttributes(cpCa);
    LineAttributes cpLa = new LineAttributes();
    Shape3D cpShape = new Shape3D(cpLines, cpApp);
    objTrans.addChild(cpShape);

    // transform and render the clip grid points
    updateProjTrans();

    if (numClipGridPts > 0) {
      // transform the clipGridPts
      for (int i = 0; i < numClipGridPts; i++) {
        projectPoint(clipGridPtsVW[i], clipGridPtsProj[i]);
      }

      LineArray clipLn = new LineArray(numClipGridPts,
  &nbs