Panda3D
geomLinestrips.cxx
Go to the documentation of this file.
1 /**
2  * PANDA 3D SOFTWARE
3  * Copyright (c) Carnegie Mellon University. All rights reserved.
4  *
5  * All use of this software is subject to the terms of the revised BSD
6  * license. You should have received a copy of this license along
7  * with this source code in a file named "LICENSE."
8  *
9  * @file geomLinestrips.cxx
10  * @author drose
11  * @date 2005-03-22
12  */
13 
14 #include "geomLinestrips.h"
15 #include "geomLines.h"
16 #include "geomVertexRewriter.h"
17 #include "pStatTimer.h"
18 #include "bamReader.h"
19 #include "bamWriter.h"
22 
23 using std::map;
24 
25 TypeHandle GeomLinestrips::_type_handle;
26 
27 /**
28  *
29  */
30 GeomLinestrips::
31 GeomLinestrips(GeomLinestrips::UsageHint usage_hint) :
32  GeomPrimitive(usage_hint)
33 {
34 }
35 
36 /**
37  *
38  */
39 GeomLinestrips::
40 GeomLinestrips(const GeomLinestrips &copy) :
41  GeomPrimitive(copy)
42 {
43 }
44 
45 /**
46  *
47  */
48 GeomLinestrips::
49 ~GeomLinestrips() {
50 }
51 
52 /**
53  *
54  */
55 PT(GeomPrimitive) GeomLinestrips::
56 make_copy() const {
57  return new GeomLinestrips(*this);
58 }
59 
60 /**
61  * Returns the fundamental rendering type of this primitive: whether it is
62  * points, lines, or polygons.
63  *
64  * This is used to set up the appropriate antialiasing settings when
65  * AntialiasAttrib::M_auto is in effect; it also implies the type of primitive
66  * that will be produced when decompose() is called.
67  */
68 GeomPrimitive::PrimitiveType GeomLinestrips::
69 get_primitive_type() const {
70  return PT_lines;
71 }
72 
73 /**
74  * Returns the set of GeomRendering bits that represent the rendering
75  * properties required to properly render this primitive.
76  */
77 int GeomLinestrips::
78 get_geom_rendering() const {
79  if (is_indexed()) {
80  if (get_num_primitives() > 1) {
81  return GR_line_strip | GR_indexed_other | GR_strip_cut_index;
82  } else {
83  return GR_line_strip | GR_indexed_other;
84  }
85  } else {
86  return GR_line_strip;
87  }
88 }
89 
90 /**
91  * Adds adjacency information to this primitive. May return null if this type
92  * of geometry does not support adjacency information.
93  */
94 CPT(GeomPrimitive) GeomLinestrips::
95 make_adjacency() const {
96  Thread *current_thread = Thread::get_current_thread();
98 
99  GeomPrimitivePipelineReader from(this, current_thread);
100  int num_vertices = from.get_num_vertices();
101  CPTA_int ends = get_ends();
102 
103  const int num_unused = 1;
104 
105  // First, build a map of each vertex to its next vertex, and another map
106  // doing the exact reverse.
107  map<int, int> forward_map, reverse_map;
108  int vi = -num_unused;
109  int li = 0;
110  while (li < (int)ends.size()) {
111  // Skip unused vertices between linestrips.
112  vi += num_unused;
113  int end = ends[li];
114  nassertr(vi + 1 <= end, nullptr);
115  int v0 = from.get_vertex(vi++);
116  while (vi < end) {
117  int v1 = from.get_vertex(vi++);
118  forward_map[v0] = v1;
119  reverse_map[v1] = v0;
120  v0 = v1;
121  }
122  ++li;
123  }
124  nassertr(vi == num_vertices, nullptr);
125 
126  // Now build up the new vertex data. For each linestrip, we prepend and
127  // append the appropriate connecting vertices.
128  vi = -num_unused;
129  li = 0;
130  while (li < (int)ends.size()) {
131  // Skip unused vertices between linestrips.
132  vi += num_unused;
133  int end = ends[li];
134  nassertr(vi + 1 <= end, nullptr);
135 
136  // Look for the line segment connected to the beginning of this strip.
137  int v0 = from.get_vertex(vi++);
138  auto it = reverse_map.find(v0);
139  if (it != reverse_map.end()) {
140  adj->add_vertex(it->second);
141  } else {
142  // Um, no adjoining line segment? Just repeat the vertex, I guess.
143  adj->add_vertex(v0);
144  }
145 
146  // Add the actual vertices in the strip.
147  adj->add_vertex(v0);
148  int v1 = v0;
149  while (vi < end) {
150  v1 = from.get_vertex(vi++);
151  adj->add_vertex(v1);
152  }
153 
154  // Do the same for the last vertex in the strip.
155  it = forward_map.find(v1);
156  if (it != forward_map.end()) {
157  adj->add_vertex(it->second);
158  } else {
159  adj->add_vertex(v1);
160  }
161 
162  adj->close_primitive();
163  ++li;
164  }
165  nassertr(vi == num_vertices, nullptr);
166 
167  return adj;
168 }
169 
170 /**
171  * Returns the minimum number of vertices that must be added before
172  * close_primitive() may legally be called.
173  */
174 int GeomLinestrips::
175 get_min_num_vertices_per_primitive() const {
176  return 2;
177 }
178 
179 /**
180  * Returns the number of vertices that are added between primitives that
181  * aren't, strictly speaking, part of the primitives themselves. This is
182  * used, for instance, to define degenerate triangles to connect otherwise
183  * disconnected triangle strips.
184  */
185 int GeomLinestrips::
186 get_num_unused_vertices_per_primitive() const {
187  return 1;
188 }
189 
190 /**
191  * Calls the appropriate method on the GSG to draw the primitive.
192  */
193 bool GeomLinestrips::
195  bool force) const {
196  return gsg->draw_linestrips(reader, force);
197 }
198 
199 /**
200  * Decomposes a complex primitive type into a simpler primitive type, for
201  * instance line strips to lines, and returns a pointer to the new primitive
202  * definition. If the decomposition cannot be performed, this might return
203  * the original object.
204  *
205  * This method is useful for application code that wants to iterate through
206  * the set of lines on the primitive without having to write handlers for each
207  * possible kind of primitive type.
208  */
209 CPT(GeomPrimitive) GeomLinestrips::
210 decompose_impl() const {
211  PT(GeomLines) lines = new GeomLines(get_usage_hint());
212  lines->set_shade_model(get_shade_model());
213  CPTA_int ends = get_ends();
214 
215  int num_unused = get_num_unused_vertices_per_primitive();
216 
217  int vi = -num_unused;
218  int li = 0;
219  while (li < (int)ends.size()) {
220  // Skip unused vertices between tristrips.
221  vi += num_unused;
222  int end = ends[li];
223  nassertr(vi + 1 <= end, lines);
224  int v0 = get_vertex(vi);
225  ++vi;
226  while (vi < end) {
227  int v1 = get_vertex(vi);
228  ++vi;
229  lines->add_vertex(v0);
230  lines->add_vertex(v1);
231  v0 = v1;
232  lines->close_primitive();
233  }
234  ++li;
235  }
236  nassertr(vi == get_num_vertices(), nullptr);
237 
238  return lines;
239 }
240 
241 /**
242  * The virtual implementation of do_rotate().
243  */
244 CPT(GeomVertexArrayData) GeomLinestrips::
245 rotate_impl() const {
246  // To rotate a line strip, we just reverse the vertices.
247  CPTA_int ends = get_ends();
248  PT(GeomVertexArrayData) new_vertices = make_index_data();
249  new_vertices->set_num_rows(get_num_vertices());
250 
251  if (is_indexed()) {
252  CPT(GeomVertexArrayData) vertices = get_vertices();
253  GeomVertexReader from(vertices, 0);
254  GeomVertexWriter to(new_vertices, 0);
255 
256  int begin = 0;
257  CPTA_int::const_iterator ei;
258  for (ei = ends.begin(); ei != ends.end(); ++ei) {
259  int end = (*ei);
260  for (int vi = end - 1; vi >= begin; --vi) {
261  from.set_row_unsafe(vi);
262  to.set_data1i(from.get_data1i());
263  }
264  begin = end;
265  }
266 
267  nassertr(to.is_at_end(), nullptr);
268 
269  } else {
270  // Nonindexed case.
271  int first_vertex = get_first_vertex();
272  GeomVertexWriter to(new_vertices, 0);
273 
274  int begin = 0;
275  CPTA_int::const_iterator ei;
276  for (ei = ends.begin(); ei != ends.end(); ++ei) {
277  int end = (*ei);
278  for (int vi = end - 1; vi >= begin; --vi) {
279  to.set_data1i(vi + first_vertex);
280  }
281  begin = end;
282  }
283 
284  nassertr(to.is_at_end(), nullptr);
285  }
286  return new_vertices;
287 }
288 
289 /**
290  * Should be redefined to return true in any primitive that implements
291  * append_unused_vertices().
292  */
293 bool GeomLinestrips::
294 requires_unused_vertices() const {
295  return true;
296 }
297 
298 /**
299  * Called when a new primitive is begun (other than the first primitive), this
300  * should add some degenerate vertices between primitives, if the primitive
301  * type requires that. The second parameter is the first vertex that begins
302  * the new primitive.
303  */
304 void GeomLinestrips::
305 append_unused_vertices(GeomVertexArrayData *vertices, int vertex) {
306  GeomVertexWriter to(vertices, 0);
307  to.set_row_unsafe(vertices->get_num_rows());
308  to.add_data1i(get_strip_cut_index());
309 }
310 
311 /**
312  * Tells the BamReader how to create objects of type Geom.
313  */
314 void GeomLinestrips::
316  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
317 }
318 
319 /**
320  * This function is called by the BamReader's factory when a new object of
321  * type Geom is encountered in the Bam file. It should create the Geom and
322  * extract its information from the file.
323  */
324 TypedWritable *GeomLinestrips::
325 make_from_bam(const FactoryParams &params) {
326  GeomLinestrips *object = new GeomLinestrips(UH_unspecified);
327  DatagramIterator scan;
328  BamReader *manager;
329 
330  parse_params(params, scan, manager);
331  object->fillin(scan, manager);
332 
333  return object;
334 }
geomLinestripsAdjacency.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexArrayData
This is the data for one array of a GeomVertexData structure.
Definition: geomVertexArrayData.h:58
GeomPrimitive::get_first_vertex
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
Definition: geomPrimitive.I:98
DatagramIterator
A class to retrieve the individual data elements previously stored in a Datagram.
Definition: datagramIterator.h:27
BamReader
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
GeomPrimitive::get_strip_cut_index
get_strip_cut_index
Returns the index of the indicated type that is reserved for use as a strip cut index,...
Definition: geomPrimitive.h:176
pStatTimer.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
ConstPointerToArray
Similar to PointerToArray, except that its contents may not be modified.
Definition: pointerToArray.h:71
GeomVertexReader
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
Definition: geomVertexReader.h:47
BamReader::get_factory
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
geomLines.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
bamReader.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomLinestrips
Defines a series of line strips.
Definition: geomLinestrips.h:23
GeomPrimitive::get_vertex
get_vertex
Returns the ith vertex index in the table.
Definition: geomPrimitive.h:99
TypedWritable
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
GeomLinestripsAdjacency
Defines a series of line strips with adjacency information.
Definition: geomLinestripsAdjacency.h:25
Thread::get_current_thread
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
TypeHandle
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
FactoryParams
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
GeomVertexArrayData::get_num_rows
int get_num_rows() const
Returns the number of rows stored in the array, based on the number of bytes and the stride.
Definition: geomVertexArrayData.I:47
GeomPrimitive::get_num_vertices
get_num_vertices
Returns the number of indices used by all the primitives in this object.
Definition: geomPrimitive.h:99
GeomPrimitive::get_num_primitives
int get_num_primitives() const
Returns the number of individual primitives stored within this object.
Definition: geomPrimitive.I:126
geomVertexRewriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT
PT(GeomPrimitive) GeomLinestrips
Returns the fundamental rendering type of this primitive: whether it is points, lines,...
Definition: geomLinestrips.cxx:55
GeomPrimitive::get_shade_model
get_shade_model
Returns the ShadeModel hint for this primitive.
Definition: geomPrimitive.h:77
Factory::register_factory
void register_factory(TypeHandle handle, CreateFunc *func, void *user_data=nullptr)
Registers a new kind of thing the Factory will be able to create.
Definition: factory.I:73
GeomLines
Defines a series of disconnected line segments.
Definition: geomLines.h:23
geomLinestrips.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
GeomLinestrips::register_with_read_factory
static void register_with_read_factory()
Tells the BamReader how to create objects of type Geom.
Definition: geomLinestrips.cxx:315
GraphicsStateGuardianBase
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
Definition: graphicsStateGuardianBase.h:110
GeomPrimitive::get_ends
CPTA_int get_ends() const
Returns a const pointer to the primitive ends array so application code can read it directly.
Definition: geomPrimitive.I:314
GeomPrimitivePipelineReader
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
Definition: geomPrimitive.h:352
GeomPrimitive::is_indexed
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
Definition: geomPrimitive.I:86
bamWriter.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
graphicsStateGuardianBase.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Thread
A thread; that is, a lightweight process.
Definition: thread.h:46
GeomPrimitive::get_usage_hint
get_usage_hint
Returns the usage hint for this primitive.
Definition: geomPrimitive.h:81
parse_params
void parse_params(const FactoryParams &params, DatagramIterator &scan, BamReader *&manager)
Takes in a FactoryParams, passed from a WritableFactory into any TypedWritable's make function,...
Definition: bamReader.I:275
GeomPrimitive
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56