001/**
002 * TriangleShape3D -- A Java 3D Shape3D representation of a single Triangle.
003 *
004 * Copyright (C) 2015-2023, by Joseph A. Huwaldt
005 * All rights reserved.
006 *
007 * This library is free software; you can redistribute it and/or modify it under the terms
008 * of the GNU Lesser General Public License as published by the Free Software Foundation;
009 * either version 2.1 of the License, or (at your option) any later version.
010 *
011 * This library is distributed in the hope that it will be useful, but WITHOUT ANY
012 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
013 * PARTICULAR PURPOSE. See the GNU Library General Public License for more details.
014 *
015 * You should have received a copy of the GNU Lesser General Public License along with
016 * this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place -
017 * Suite 330, Boston, MA 02111-1307, USA. Or visit: http://www.gnu.org/licenses/lgpl.html
018 */
019package geomss.j3d;
020
021import geomss.geom.*;
022import static java.util.Objects.requireNonNull;
023import javax.measure.quantity.Dimensionless;
024import javax.measure.unit.SI;
025import org.jogamp.java3d.*;
026import org.jogamp.vecmath.*;
027
028/**
029 * A Shape3D object based on a {@link geomss.geom.GeomTriangle Triangle}. The default
030 * appearance of the geometry is solid filled gray with lighting enabled.
031 *
032 * <p> Modified by: Joseph A. Huwaldt </p>
033 *
034 * @author Joseph A. Huwaldt, Date: August 27, 2015
035 * @version June 4, 2023
036 */
037public class TriangleShape3D extends GeomShape3D {
038
039    /**
040     * @param parent The GeomSS geometry element that this Shape3D is associated with.
041     */
042    private TriangleShape3D(GeomElement parent) {
043        super(parent);
044    }
045
046    /**
047     * Construct a TriangleShape3D object from the specified AbstactTriangle.
048     *
049     * @param parent The GeomSS geometry element that this Shape3D is associated with.
050     * @param tri    The triangle to be converted into a J3D Shape3D object.
051     */
052    public TriangleShape3D(GeomElement parent, GeomTriangle tri) {
053        super(parent);
054
055        setGeometry(createGeometry(requireNonNull(tri)));
056    }
057
058    /**
059     * Construct a TriangleShape3D object from the specified AbstactTriangle.
060     *
061     * @param parent     The GeomSS geometry element that this Shape3D is associated with.
062     * @param tri        The triangle to be converted into a J3D Shape3D object.
063     * @param appearance The Appearance to use when rendering the triangle.
064     */
065    public TriangleShape3D(GeomElement parent, GeomTriangle tri, Appearance appearance) {
066        this(parent, tri);
067        setAppearance(requireNonNull(appearance));
068    }
069
070    /**
071     * Used to create a new instance of this node.
072     *
073     * @param forceDuplicate when set to <code>true</code>, causes the
074     *                       <code>duplicateOnCloneTree</code> flag to be ignored. When
075     *                       <code>false</code>, the value of each node's
076     *                       <code>duplicateOnCloneTree</code> variable determines whether
077     *                       NodeComponent data is duplicated or copied.
078     * @return A new instance of this Java3D node.
079     */
080    @Override
081    public Node cloneNode(boolean forceDuplicate) {
082        TriangleShape3D usc = new TriangleShape3D(this.getGeometryElement());
083        usc.duplicateNode(this, forceDuplicate);
084        return usc;
085    }
086
087    /**
088     * Convert the GeomTriangle into a J3D Geometry object here.
089     */
090    private Geometry createGeometry(GeomTriangle tri) {
091
092        // Convert GeomTriangle object into a J3D triangle array.
093        int vertexCount = 3;
094        int numDims = tri.getPhyDimension();
095
096        // Load in the geometry into required 1D arrays.
097        Point3f[] coordinates = new Point3f[vertexCount];
098        PointString<? extends GeomPoint> pnts = tri.getPoints();
099        Vector3f[] normalsArr = new Vector3f[vertexCount];
100        GeomVector<Dimensionless> normal = tri.getNormal();
101
102        for (int i = 0; i < 3; ++i) {
103            GeomPoint point = pnts.get(i);
104
105            //  Convert all geometry to meters.
106            double x = point.getValue(Point.X, SI.METER);
107            double y = point.getValue(Point.Y, SI.METER);
108            double z = (numDims > 2 ? point.getValue(Point.Z, SI.METER) : 0);
109            coordinates[i] = new Point3f((float)x, (float)y, (float)z);
110
111            //  Create an array of normals in Java3D format.
112            x = normal.getValue(GeomVector.X);
113            y = normal.getValue(GeomVector.Y);
114            z = (numDims > 2 ? normal.getValue(GeomVector.Z) : 0);
115            normalsArr[i] = new Vector3f((float)x, (float)y, (float)z);
116        }
117
118        // Create a TriangleArray object for our geometry.
119        TriangleArray triArr = new TriangleArray(vertexCount,
120                GeometryArray.COORDINATES | GeometryArray.NORMALS);
121        triArr.setCoordinates(0, coordinates);
122        triArr.setNormals(0, normalsArr);
123
124        return triArr;
125    }
126}