001/*
002
003*/
004
005package renderer.scene;
006
007import java.util.List;
008import java.util.ArrayList;
009import java.awt.Color;
010
011/**
012   A {@code Model} data structure represents a distinct geometric object
013   in a {@link Scene}. A {@code Model} data structure is mainly a {@link List}
014   of {@link Vertex} object and another list of {@link LineSegment} objects.
015   Each {@link LineSegment} object contains two integers that are the indices
016   of two {@link Vertex} objects from the {@code Models}'s vertex list. The
017   two {@link Vertex} objects contain the coordinates, in the camera coordinate
018   system, of the line segment's two endpoints.
019<p>
020   A {@code Model} represent the geometric object as a "wire-frame" of line
021   segments, that is, the geometric object is drawn as a collection of "edges".
022   This is a fairly simplistic way of doing 3D graphics and we will
023   improve this in later renderers.
024<p>
025   See
026<br> <a href="http://en.wikipedia.org/wiki/Wire-frame_model" target="_top">
027              http://en.wikipedia.org/wiki/Wire-frame_model</a>
028<br>or
029<br> <a href="https://www.google.com/search?q=graphics+wireframe&tbm=isch" target="_top">
030              https://www.google.com/search?q=graphics+wireframe&tbm=isch</a>
031*/
032public class Model
033{
034   public List<Vertex> vertexList = new ArrayList<>();
035   public List<LineSegment> lineSegmentList = new ArrayList<>();
036
037   public boolean visible;
038
039
040   /**
041      Construct an empty {@code Model} object.
042   */
043   public Model()
044   {
045      visible = true;
046   }
047
048
049   /**
050      A "copy constructor". This constructor should make a deep copy
051      of the given {@code Model}'s {@link Vertex} list and
052      {@link LineSegment} list.
053
054      @param model  {@code Model} to make a copy of
055   */
056   public Model(Model model) // a "copy constructor"
057   {
058      super();
059
060      this.visible = model.visible;
061      for (Vertex v : model.vertexList)
062      {
063         this.vertexList.add(new Vertex(v)); // deep copy of each Vertex
064      }
065      for (LineSegment ls : model.lineSegmentList)
066      {
067         this.lineSegmentList.add(new LineSegment(ls, this));
068      }
069   }
070
071
072   /**
073      Add a {@link Vertex} (or vertices) to this {@code Model}'s
074      {@link List} of vertices.
075
076      @param vArray  array of {@link Vertex} objects to add to this {@code Model}
077   */
078   public void addVertex(Vertex... vArray)
079   {
080      for (Vertex v : vArray)
081      {
082         this.vertexList.add(new Vertex(v)); // NOTE: deep copy!
083      }
084   }
085
086
087   /**
088      Add a {@link LineSegment} to this {@code Model}'s {@link List} of
089      line segments.
090      <p>
091      NOTE: This method does not add any vertices to the {@code Model}'s
092      {@link Vertex} list. This method assumes that the appropriate vertices
093      have been added to the {@code Model}'s {@link Vertex} list.
094
095      @param i0  1st integer index of {@link LineSegment} to add to this {@code Model}
096      @param i1  2nd integer index of {@link LineSegment} to add to this {@code Model}
097   */
098   public void addLineSegment(int i0, int i1)
099   {
100      this.lineSegmentList.add(new LineSegment(i0, i1, this));
101   }
102
103
104   /**
105      Add a {@link LineSegment} to this {@code Model}'s {@link List} of
106      line segments.
107      <p>
108      This method adds (copies of) the two give {@link Vertex} objects to
109      this {@code Model}'s vertex list and then costructs an appropriate
110      {@link LineSegment} object to add to this {@code Model}'s line
111      segment list.
112      <p>
113      This method provides a convenient way to build up a {@code Model} but
114      it may not build an efficient {@code Model}. Using this mehtod may lead
115      to a lot of redundant {@link Vertex} objects in this {@code Model}'s
116      vertex list.
117
118      @param v0  1st {@link Vertex} of {@link LineSegment} to add to this {@code Model}
119      @param v1  2nd {@link Vertex} of {@link LineSegment} to add to this {@code Model}
120   */
121   public void addLineSegment(Vertex v0, Vertex v1)
122   {
123      int index = this.vertexList.size();
124      this.vertexList.add(new Vertex(v0)); // NOTE: deep copy!
125      this.vertexList.add(new Vertex(v1)); // NOTE: deep copy!
126      this.lineSegmentList.add(new LineSegment(index, index+1, this));
127   }
128
129
130   /**
131      Set each {@link Vertex} in this {@code Model}
132      to the same {@link Color}.
133
134      @param c  {@link Color} for all of this model's {@link Vertex} objects
135   */
136   public void setColor(Color c)
137   {
138      for (Vertex v : this.vertexList)
139      {
140         v.setColor(c);
141      }
142   }
143
144
145   /**
146      Set each {@link Vertex} in this {@code Model}
147      to the same random {@link Color}.
148   */
149   public void setColorRandom()
150   {
151      if ( ! this.vertexList.isEmpty() )
152      {
153         this.vertexList.get(0).setColorRandom();
154         Color c = this.vertexList.get(0).getColor();
155         for (Vertex v : this.vertexList)
156         {
157            v.setColor(c);
158         }
159      }
160   }
161
162
163   /**
164      Set each {@link Vertex} in this {@code Model}
165      to a different random {@link Color}.
166   */
167   public void setRandomColors()
168   {
169      for (Vertex v : this.vertexList)
170      {
171         v.setColorRandom();
172      }
173   }
174
175
176   /**
177      Set each {@link LineSegment} in this {@code Model}
178      to a different random {@link Color}.
179      <p>
180      NOTE: This works best when the {@link LineSegment}
181      objects in this {@link Model} do not share any
182      {@link Vertex} objects.
183   */
184   public void setRandomLineSegmentColors()
185   {
186      for (LineSegment ls : this.lineSegmentList)
187      {
188         ls.setColorRandom();
189      }
190   }
191
192
193   /**
194      For debugging.
195
196      @return {@link String} representation of this {@code Model} object
197   */
198   @Override
199   public String toString()
200   {
201      String result = "";
202      result += "Model has " + vertexList.size() + " vertices.\n";
203      result += "Model has " + lineSegmentList.size() + " line segments.\n";
204      int i = 0;
205      for (Vertex v : this.vertexList)
206      {
207         result += i + ": " + v.toString();
208         i++;
209      }
210      //result = "Printing out this Model's " + lineSegmentList.size() + " Line segments:\n";
211      for (LineSegment ls : this.lineSegmentList)
212      {
213         result += ls.toString();
214      }
215      //result += "Done printing out Model\n";
216      return result;
217   }
218}