001/*
002 *   EntityFactory  -- A factory for creating Entity instances.
003 *
004 *   Copyright (C) 2010-2016, Joseph A. Huwaldt.
005 *   All rights reserved.
006 *   
007 *   part library is free software; you can redistribute it and/or
008 *   modify it under the terms of the GNU Lesser General Public
009 *   License as published by the Free Software Foundation; either
010 *   version 2.1 of the License, or (at your option) any later version.
011 *   
012 *   part library is distributed in the hope that it will be useful,
013 *   but WITHOUT ANY WARRANTY; without even the implied warranty of
014 *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
015 *   Lesser General Public License for more details.
016 *
017 *   You should have received a copy of the GNU Lesser General Public License
018 *   along with part program; if not, write to the Free Software
019 *   Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
020 *   Or visit:  http://www.gnu.org/licenses/lgpl.html
021 */
022package geomss.geom.reader.iges;
023
024import geomss.geom.*;
025import geomss.geom.nurbs.NurbsCurve;
026import geomss.geom.nurbs.NurbsSurface;
027import java.util.List;
028
029/**
030 * A factory class that provides methods for creating Entity instances.
031 * 
032 * <p> Modified by: Joseph A. Huwaldt </p>
033 * 
034 * @author Joseph A. Huwaldt, Date: April 27, 2013
035 * @version September 13, 2016
036 */
037public class EntityFactory {
038
039    /**
040     * Return an Entity that corresponds to the specified Directory Entry.
041     *
042     * @param part     The part that the entity is associated with.
043     * @param drawings A list that any Entity 404 Drawing objects will be added to.
044     * @param views    A list that any Entity 410 Views will be added to.
045     * @param de       The Directory Entry for the part entity (which defines the type for
046     *                 the Entity).
047     * @return The newly created entity that corresponds to the specified Directory Entry.
048     */
049    public static Entity create(Part part, List<Entity> drawings, List<Entity> views, DirEntry de) {
050        Entity e;
051
052        switch (de.getType()) {
053            case   0: e = new Entity000_Null(part,de); break;                       //  Null entity
054            case 100: e = new Entity100_CircularArc(part,de); break;                //  Circle or circular arc
055            case 102: e = new Entity102_CompositeCurve(part,de); break;             //  Composite curve
056            case 104: switch(de.getForm()) {
057                    case 1:  e = new Entity104_1_EllipticalArc(part,de);  break;    //  Elliptical arc
058                    case 2:  e = new Entity104_2_HyperbolicArc(part,de);  break;    //  Hyperbolic arc
059                    case 3:  e = new Entity104_3_ParabolicArc(part,de);  break;     //  Parabolic arc
060                    default: e = new Entity104_0_GenConicArc(part,de);  break;      //  General conic arc
061                }
062                break;
063            case 106: switch(de.getForm()) {
064                    case 1:  e = new Entity106_1_2DPoints(part,de); break;          //  Copious Data: 2D points
065                    case 2:  e = new Entity106_2_3DPoints(part,de); break;          //  Copious Data: 3D points
066                    case 3:  e = new Entity106_3_3DVectors(part,de); break;         //  Copious Data: 3D vectors
067                    case 11: e = new Entity106_11_2DLinearString(part,de); break;   //  Copious Data: 2D consecutive points
068                    case 12: e = new Entity106_12_3DLinearString(part,de); break;   //  Copious Data: 3D consecutive points
069                    case 13: e = new Entity106_13_3DVectorString(part,de); break;   //  Copious Data: 3D consecutive vectors
070                    case 63: e = new Entity106_63_ClosedPlanarLinearCurve(part,de); break;  //  Copious Data: Closed planar curve string
071                    default: e = new Entity106_XX_Unsupported(part,de); break;      //  Copious Data: Unsupported
072                }
073                break;
074            case 108: switch(de.getForm()) {
075                    case 0:  e = new Entity108_0_UnboundedPlane(part,de); break;    //  Unbounded plane
076                    default: e = new Entity108_XX_Unsupported(part,de); break;      //  Plane: Unsupported
077                }
078                break;
079            case 110: e = new Entity110_Line(part,de); break;                       //  Line segement
080            case 116: e = new Entity116_Point(part,de); break;                      //  Point
081            case 112: e = new Entity112_ParSplineCurve(part,de); break;             //  Parametric cubic spline curve
082            case 118: switch(de.getForm()) {
083                case 0:  e = new Entity118_0_RuledSurface(part,de); break;          //  Ruled Surface with arc-length spacing
084                case 1:  e = new Entity118_1_RuledSurface(part,de); break;          //  Ruled Surface with parametric spacing
085                default: e = new Entity118_XX_Unsupported(part,de); break;
086            } break;
087            case 120: e = new Entity120_SurfaceOfRevolution(part,de); break;        //  Surface of Revolution
088            case 124: e = new Entity124_TransformationMatrix(part,de); break;       //  Transformation matrix
089            case 126: e = new Entity126_BSplineCurve(part,de); break;               //  Rational B-Spline curve
090            case 128: e = new Entity128_BSplineSurface(part,de); break;             //  Rational B-Spline surface
091            case 142: e = new Entity142_CurveOnSurface(part,de); break;             //  Curve on Parametric Surface
092            case 144: e = new Entity144_TrimmedSurface(part,de); break;             //  Trimmedn Parametric Surface
093/*          case 132: e = new Entity132(part,de); break;                            //  Connect point
094            case 212: switch(de.getForm()) {
095                    case  0: e = new Entity212_00(part,de); break;                  //  Simple note
096                    default: e = new Entity212_XX(part,de); break;                  //  Unsupported note
097                }
098                break;
099            case 230: e = new Entity230(part,de); break;                            //  Sectioned area
100            case 232: e = new Entity232(part,de); break;                            //  Annotation of inclusion of multimedia
101*/          case 308: e = new Entity308_Subfigure(part,de); break;                  //  Subfigure definition
102/*          case 320: e = new Entity320(part,de); break;                            //  Network subfigure definition
103*/          case 402: switch(de.getForm()) {
104                    case 15: e = new Entity402_15_OrderedGroupNoBackPointers(part,de); break;   //  Ordered group.
105                    default: e = new Entity402_XX_Unsupported(part,de); break;      //  Unsupported associativity.
106                }
107                break;
108            case 404: e = new Entity404_Drawing(part,de); drawings.add(e); break;   //  Drawing
109/*          case 406: switch(de.getForm()) {
110                    case  15: e = new Entity406_15(part,de);  break;                //  Name property
111                    case  16: e = new Entity406_16(part,de);  break;                //  Drawing size property
112                    case  17: e = new Entity406_17(part,de);  break;                //  Drawing units property
113                    case  18: e = new Entity406_18(part,de);  break;                //  Intercharacter spacing property
114                    case  38: e = new Entity406_38(part,de);  break;                //  URL anchor property
115                    default:  e = new Entity406_XX(part,de);  break;                //  Unsupported property
116                }
117                break;
118*/          case 408: e = new Entity408_SingularSubfigure(part,de); break;          //  Singular subfigure
119            case 410: e = new Entity410_View(part,de); views.add(e); break;         //  View
120/*          case 412: e = new Entity412(part,de); break;                            //  Rectangular array
121            case 414: e = new Entity414(part,de); break;                            //  Circular array
122            case 420: e = new Entity420(part,de); break;                            //  Network subfigure
123*/          default:  e = new EntityXXX_Unsupported(part,de); break;                //  Unsupported entity
124        }
125
126        return e;
127    }
128
129    /**
130     * Return an entity that corresponds to the specified GeomSS geometry object.
131     *
132     * @param part  The part that the entity is associated with.
133     * @param DEnum The line count from the start of the Directory Entry Section for this
134     *              entry (odd number).
135     * @param geom  The GeomSS geometry to return an Entity for.
136     * @return An Entity that corresponds to the specified geometry object or
137     *         <code>null</code> if no match could be found.
138     */
139    public static GeomSSEntity create(Part part, int DEnum, GeomElement geom) {
140        GeomSSEntity entity = null;
141        int dim = geom.getPhyDimension();
142
143        if (dim > 3) {
144            part.getErrors().add(Constants.RESOURCES.getString("noMoreThan3D"));
145            return entity;
146        }
147
148        if (geom instanceof GeomPoint) {
149            entity = new Entity116_Point(part, DEnum, (GeomPoint)geom.toDimension(3));
150
151        } else if (geom instanceof PointString) {
152            if (dim == 2)
153                entity = new Entity106_11_2DLinearString(part, DEnum, (PointString)geom);
154            else
155                entity = new Entity106_12_3DLinearString(part, DEnum, (PointString)geom.toDimension(3));
156
157        } else if (geom instanceof GeomPlane) {
158            entity = new Entity108_0_UnboundedPlane(part, DEnum, (GeomPlane)geom);
159
160        } else if (geom instanceof NurbsCurve) {
161            entity = new Entity126_BSplineCurve(part, DEnum, (NurbsCurve)geom.toDimension(3));
162
163        } else if (geom instanceof LineSegment) {
164            entity = new Entity110_Line(part, DEnum, (LineSegment)geom.toDimension(3));
165
166        } else if (geom instanceof NurbsSurface) {
167            entity = new Entity128_BSplineSurface(part, DEnum, (NurbsSurface)geom.toDimension(3));
168
169        } else if (geom instanceof GeomList) {
170            GeomList<GeomElement> glst = (GeomList)geom;
171            //  Does it contain only vectors?
172            if (isGeomVectorList(glst))
173                entity = new Entity106_13_3DVectorString(part, DEnum, glst.toDimension(3));
174        }
175
176        return entity;
177    }
178
179    /**
180     * Return true if the input list contains only instances of GeomVector.
181     */
182    private static boolean isGeomVectorList(GeomList<GeomElement> lst) {
183        boolean isType = true;
184        for (GeomElement elem : lst) {
185            if (!(elem instanceof GeomVector)) {
186                isType = false;
187                break;
188            }
189        }
190        return isType;
191    }
192
193    /**
194     * Return an entity that corresponds to the a Type 402-15 Associativity (List).
195     *
196     * @param part     The part that the entity is associated with.
197     * @param DEnum    The line count from the start of the Directory Entry Section for
198     *                 this entry (odd number).
199     * @param children The entities that are contained in this list.
200     * @param name     The name to apply to the entity or null for no name.
201     * @return An Entity that corresponds to the specified geometry object or
202     *         <code>null</code> if no match could be found.
203     */
204    public static GeomSSEntity createList(Part part, int DEnum, List<Entity> children, String name) {
205        if (children == null || children.isEmpty())
206            return null;
207        return new Entity402_15_OrderedGroupNoBackPointers(part, DEnum, children, name);
208    }
209
210}