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