001/** 002 * TriangleListShape3D -- A Java 3D Shape3D representation of a TriangleList. 003 * 004 * Copyright (C) 2015-2016, by 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 Library 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 com.sun.j3d.utils.geometry.GeometryInfo; 021import com.sun.j3d.utils.geometry.NormalGenerator; 022import com.sun.j3d.utils.geometry.Stripifier; 023import geomss.geom.*; 024import jahuwaldt.js.param.Parameter; 025import static java.util.Objects.requireNonNull; 026import javax.measure.unit.SI; 027import javax.media.j3d.*; 028import javax.vecmath.*; 029 030/** 031 * A Shape3D object based on a {@link geomss.geom.TriangleList TriangleList}. The default 032 * appearance of the geometry is solid filled grey with lighting enabled. 033 * 034 * <p> Modified by: Joseph A. Huwaldt </p> 035 * 036 * @author Joseph A. Huwaldt, Date: August 29, 2015 037 * @version September 9, 2016 038 */ 039public class TriangleListShape3D extends GeomShape3D { 040 041 /** 042 * @param parent The GeomSS geometry element that this Shape3D is associated with. 043 */ 044 private TriangleListShape3D(GeomElement parent) { 045 super(parent); 046 } 047 048 /** 049 * Construct a TriangleListShape3D object from the specified {@link TriangleList}. 050 * 051 * @param parent The GeomSS geometry element that this Shape3D is associated with. 052 * @param list The TriangleList to be converted into a J3D Shape3D object. 053 */ 054 public TriangleListShape3D(GeomElement parent, TriangleList<? extends GeomTriangle> list) { 055 super(parent); 056 057 setGeometry(createGeometry(requireNonNull(list), true)); 058 } 059 060 /** 061 * Construct a TriangleListShape3D object from the specified {@link TriangleList}. 062 * 063 * @param parent The GeomSS geometry element that this Shape3D is associated with. 064 * @param list The TriangleList to be converted into a J3D Shape3D object. 065 * @param appearance The Appearance to use when rendering the list of triangles. 066 */ 067 public TriangleListShape3D(GeomElement parent, TriangleList<? extends GeomTriangle> list, Appearance appearance) { 068 this(parent, list); 069 setAppearance(requireNonNull(appearance)); 070 } 071 072 /** 073 * Construct a TriangleListShape3D object from the specified {@link TriangleList}. 074 * 075 * @param parent The GeomSS geometry element that this Shape3D is associated with. 076 * @param list The TriangleList to be converted into a J3D Shape3D object. 077 * @param appearance The Appearance to use when rendering the list of triangles. 078 * @param stripify Flag indicating if the list of individual triangles should be 079 * converted into triangle strips for rendering or not. 080 */ 081 public TriangleListShape3D(GeomElement parent, TriangleList<? extends GeomTriangle> list, 082 Appearance appearance, boolean stripify) { 083 super(parent); 084 085 setGeometry(createGeometry(requireNonNull(list), stripify)); 086 setAppearance(requireNonNull(appearance)); 087 } 088 089 /** 090 * Used to create a new instance of the node. 091 * 092 * @param forceDuplicate when set to <code>true</code>, causes the 093 * <code>duplicateOnCloneTree</code> flag to be ignored. When 094 * <code>false</code>, the value of each node's 095 * <code>duplicateOnCloneTree</code> variable determines whether 096 * NodeComponent data is duplicated or copied. 097 * @return A new instance of this Java3D node. 098 */ 099 @Override 100 public Node cloneNode(boolean forceDuplicate) { 101 TriangleListShape3D usc = new TriangleListShape3D(this.getGeometryElement()); 102 usc.duplicateNode(this, forceDuplicate); 103 return usc; 104 } 105 106 /** 107 * Convert the TriangleList, and an optional list of vertex normals, into a J3D 108 * Geometry object here. 109 */ 110 private Geometry createGeometry(TriangleList<? extends GeomTriangle> triLst, boolean stripify) { 111 112 // Extract a minimal set of vertices and indexes from the triangle list. 113 TriangleVertData triData = triLst.toVertData(Parameter.valueOf(Parameter.SQRT_EPS, triLst.getUnit())); 114 PointString<? extends GeomPoint> verts = triData.vertices; 115 int[] coordIndices = triData.tris; 116 117 // Convert the list of GeomPoint vertices into J3D points. 118 int numDims = triLst.getPhyDimension(); 119 int vertexCount = verts.size(); 120 Point3f[] coordinates = new Point3f[vertexCount]; 121 for (int i = 0; i < vertexCount; ++i) { 122 GeomPoint point = verts.get(i); 123 124 // Convert all geometry to meters. 125 double x = point.getValue(0, SI.METER); 126 double y = point.getValue(1, SI.METER); 127 double z = (numDims > 2 ? point.getValue(2, SI.METER) : 0); 128 coordinates[i] = new Point3f((float)x, (float)y, (float)z); 129 } 130 131 // Create a GeomInfo object for our geometry. 132 GeometryInfo geomInfo = new GeometryInfo(GeometryInfo.TRIANGLE_ARRAY); 133 geomInfo.setCoordinates(coordinates); 134 geomInfo.setCoordinateIndices(coordIndices); 135 136 // Generate vertex normals automatically. 137 NormalGenerator ng = new NormalGenerator(0); // Use facet normals only (no smoothing). 138 ng.generateNormals(geomInfo); 139 140 if (stripify) { 141 // Stripify the geometry for increased performance. 142 Stripifier st = new Stripifier(); 143 st.stripify(geomInfo); 144 } 145 146 return geomInfo.getGeometryArray(); 147 } 148}