001/**
002 * J3DGeomGroupFactory -- A factory for creating J3DGeomGroup objects appropriate for a
003 * given GeomElement.
004 *
005 * Copyright (C) 2009-2017, Joseph A. Huwaldt. 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 Lesser 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.app.GeomSSCanvas3D;
022import geomss.geom.*;
023import static java.util.Objects.requireNonNull;
024
025/**
026 * A factory for creating {@link J3DGeomGroup} objects appropriate to the provided
027 * GeomElement object.
028 *
029 * <p> Modified by: Joseph A. Huwaldt </p>
030 *
031 * @author Joseph A. Huwaldt, Date: May 1, 2009
032 * @version January 30, 2017
033 */
034public class J3DGeomGroupFactory {
035
036    /**
037     * Return a {@link J3DGeomGroup} object appropriate to the supplied GeomElement or
038     * <code>null</code> if an appropriate J3DGeomGroup can not be found.
039     *
040     * @param canvas  The 3D canvas the geometry is being rendered into.
041     * @param element The geometry element to have a J3DGeomGroup created for.
042     * @return A J3DGeomGroup object representing the supplied GeomElement or null.
043     */
044    public static J3DGeomGroup newGroup(GeomSSCanvas3D canvas, GeomElement element) {
045        requireNonNull(canvas, "null canvas");
046        
047        //      Reject non-numeric geometry elements.
048        if (element == null || !element.isValid())
049            return null;
050
051        //  Try to recycle a previous rendering of this geometry element if at all possible.
052        J3DGeomGroup j3dGroup = (J3DGeomGroup)element.getUserData(J3DGeomGroup.USERDATA_KEY);
053        if (j3dGroup != null) {
054            //  This geometry was previously rendered.  Have the rendering preferences changed?
055            J3DRenderingPrefs currentPrefs = J3DGeomGroup.getDefaultRenderingPrefs();
056            J3DRenderingPrefs oldPrefs = j3dGroup.getRenderingPrefs();
057
058            //  Does this group already have a parent (it is already displayed)?
059            //  If it is already displayed and the draw prefs have not changed, detach it from
060            //  the 3D scene graph (it will get re-attached when it is re-used).
061            if (j3dGroup.getParent() != null && oldPrefs.equals(currentPrefs)) {
062                try {
063                    j3dGroup.detach();
064
065                    //  The "detach()" method may have removed the group from the object's meta-data
066                    //  as a way of indicating that the group should not be re-used.
067                    j3dGroup = (J3DGeomGroup)element.getUserData(J3DGeomGroup.USERDATA_KEY);
068
069                } catch (Exception e) {
070                    //  Just force the creation of a new group.
071                    j3dGroup = null;
072                }
073            }
074            if (j3dGroup != null) {
075                //  This geometry was previously rendered.  Have the rendering preferences changed?
076                if (oldPrefs.equals(currentPrefs)) {
077                    //System.out.println("Recycling " + element.getID());
078                    //  The rendering prefs are unchanged, so re-use as is.
079                    return j3dGroup;
080                }
081                j3dGroup = null;
082            }
083        }
084
085        if (element instanceof GeomPoint)
086            j3dGroup = new J3DGeomPoint(canvas, (GeomPoint)element);
087        else if (element instanceof PointString) {
088            PointString<?> str = (PointString)element;
089            if (str.isEmpty())
090                return null;
091            if (str.size() < 2)
092                j3dGroup = new J3DGeomPoint(canvas, str.get(0));
093            else
094                j3dGroup = new J3DPointString(canvas, str);
095
096        } else if (element instanceof PointArray) {
097            PointArray<?> arr = (PointArray)element;
098            if (arr.isEmpty())
099                return null;
100            if (arr.size() < 2)
101                j3dGroup = new J3DPointString(canvas, arr.get(0));
102            else
103                j3dGroup = new J3DPointArray(canvas, arr);
104
105        } else if (element instanceof TriangleList) {
106            TriangleList<? extends GeomTriangle> lst = (TriangleList)element;
107            if (lst.isEmpty())
108                return null;
109            j3dGroup = new J3DTriangleList(canvas, lst);
110
111        } else if (element instanceof AbstractGeomList) {
112            AbstractGeomList list = (AbstractGeomList)element;
113            if (!list.containsGeometry())
114                return null;
115            j3dGroup = new J3DGeomList(canvas, list);
116
117        } else if (element instanceof GeomVector)
118            j3dGroup = new J3DGeomVector(canvas, (GeomVector)element);
119        else if (element instanceof GeomPlane)
120            j3dGroup = new J3DGeomPlane(canvas, (GeomPlane)element);
121        else if (element instanceof Curve)
122            j3dGroup = new J3DCurve(canvas, (Curve)element);
123        else if (element instanceof Surface)
124            j3dGroup = new J3DSurface(canvas, (Surface)element);
125        else if (element instanceof GenScreenNote)
126            j3dGroup = new J3DGenScreenNote(canvas, (GenScreenNote)element);
127        else if (element instanceof GenModelNote)
128            j3dGroup = new J3DGenModelNote(canvas, (GenModelNote)element);
129        else if (element instanceof GeomTriangle) {
130            if (!((GeomTriangle)element).getArea().isApproxZero())
131                j3dGroup = new J3DTriangle(canvas, (GeomTriangle)element);
132        }
133
134        return j3dGroup;
135    }
136}