001/**
002 * J3DGeomPoint -- A Java3D node that represents a GeomPoint in a J3D scene graph.
003 * 
004 * Copyright (C) 2009-2016, Joseph A. Huwaldt. All rights reserved.
005 * 
006 * This library is free software; you can redistribute it and/or modify it under the terms
007 * of the GNU Lesser General Public License as published by the Free Software Foundation;
008 * either version 2.1 of the License, or (at your option) any later version.
009 * 
010 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
011 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
012 * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details.
013 * 
014 * You should have received a copy of the GNU Lesser General Public License along with
015 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
016 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
017 */
018package geomss.j3d;
019
020import geomss.app.GeomSSCanvas3D;
021import geomss.geom.GeomPoint;
022import static java.util.Objects.requireNonNull;
023import javax.measure.unit.SI;
024import javax.media.j3d.*;
025import javax.vecmath.*;
026
027/**
028 * A Java 3D node that represents a GeomPoint in a Java 3D scene graph.
029 *
030 * <p> Modified by: Joseph A. Huwaldt </p>
031 *
032 * @author Joseph A. Huwaldt, Date: April 13, 2009
033 * @version September 9, 2016
034 */
035public class J3DGeomPoint extends J3DGeomGroup<GeomPoint> {
036
037    //  The switch for main or mirrored geometry.
038    private Switch _symmSG;
039
040    /**
041     * Construct a J3DGeomPoint using the specified GeomPoint as a reference.
042     *
043     * @param canvas   The canvas that the geometry is being rendered into.
044     * @param geometry The GeomSS geometry to be turned into a Java3D node.
045     */
046    public J3DGeomPoint(GeomSSCanvas3D canvas, GeomPoint geometry) {
047        super(requireNonNull(canvas), requireNonNull(geometry));
048    }
049
050    /**
051     * Set the display of a mirrored copy of this geometry. This is called from
052     * "setDisplayed()" to turn on and off the display of mirrored geometry without
053     * changing the "mirrored state" of the object. This call does not affect the output
054     * of "isMirrored()".
055     *
056     * @param mirrored Flag indicating if the mirrored geometry should be displayed or
057     *                 not.
058     * @see #setMirrored(boolean)
059     * @see #isMirrored()
060     */
061    @Override
062    protected void internalSetMirrored(boolean mirrored) {
063        if (mirrored)
064            _symmSG.setWhichChild(Switch.CHILD_ALL);
065        else
066            _symmSG.setWhichChild(0);
067    }
068
069    /**
070     * Create a new Java 3D <code>Group</code> that contains the geometry contained in
071     * this object. This method is called from <code>createSceneGraph</code>. Sub-classes
072     * must over-ride this method to provide geometry specific implementations.
073     *
074     * @return New Java 3D Group that contains the geometry in this object.
075     * @see #createSceneGraph
076     */
077    @Override
078    protected Group createGeometry() {
079        J3DRenderingPrefs drawPrefs = getRenderingPrefs();
080
081        //      Create a point array with a single point in it.
082        PointArray pointA = new PointArray(1, PointArray.COORDINATES | PointArray.COLOR_4);
083        GeomPoint thisPoint = this.getGeomElement();
084        GeomPoint point = thisPoint.to(SI.METER);               //      Convert all geometry to meters.
085        int dims = point.getPhyDimension();
086        double x = point.getValue(0);
087        double y = (dims > 1 ? point.getValue(1) : 0);
088        double z = (dims > 2 ? point.getValue(2) : 0);
089        pointA.setCoordinate(0, new Point3d(x, y, z));
090        pointA.setColor(0, drawPrefs.getPointColorJ3D());
091
092        //      Create a 3D shape from the point array
093        Shape3D pointShape = new GeomShape3D(thisPoint, pointA);
094        Appearance pApp = new Appearance();
095        pointShape.setAppearance(pApp);
096        pApp.setPointAttributes(new PointAttributes(drawPrefs.getPointSize(), true));
097
098        //      Add the basic unmirrored geometry to the switch.
099        _symmSG = new Switch();
100        _symmSG.setCapability(Switch.ALLOW_SWITCH_READ);
101        _symmSG.setCapability(Switch.ALLOW_SWITCH_WRITE);
102        _symmSG.addChild(pointShape);
103
104        //      Clone the basic geometry to make the mirrored geometry.
105        Node mirrored = pointShape.cloneTree();
106
107        //      Create a mirror across the XZ plane of symmetry transform.
108        Transform3D symmT = new Transform3D();
109        symmT.setScale(new Vector3d(1, -1, 1));
110        TransformGroup symmTG = new TransformGroup(symmT);
111
112        //      Add the mirrored geometry to the symmetry transform group.
113        symmTG.addChild(mirrored);
114
115        //      Add the mirrored geometry to the switch.
116        _symmSG.addChild(symmTG);
117
118        //      By default, display only the main geometry (not the mirrored).
119        _symmSG.setWhichChild(0);
120
121        return _symmSG;
122    }
123
124    /**
125     * Creates a new instance of the node. This routine is called by
126     * <code>cloneTree</code> to duplicate the current node.
127     *
128     * @param forceDuplicate when set to <code>true</code>, causes the
129     *                       <code>duplicateOnCloneTree</code> flag to be ignored. When
130     *                       <code>false</code>, the value of each node's
131     *                       <code>duplicateOnCloneTree</code> variable determines whether
132     *                       NodeComponent data is duplicated or copied.
133     * @return A new instance of this Java3D node.
134     */
135    @Override
136    public Node cloneNode(boolean forceDuplicate) {
137        J3DGeomPoint node = new J3DGeomPoint(this.getCanvas3D(), this.getGeomElement());
138        node.duplicateNode(this, forceDuplicate);
139        return node;
140    }
141}