Panda3D
geomLines.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 geomLines.cxx
10  * @author drose
11  * @date 2005-03-22
12  */
13 
14 #include "geomLines.h"
15 #include "pStatTimer.h"
16 #include "bamReader.h"
17 #include "bamWriter.h"
19 #include "geomVertexReader.h"
20 #include "geomVertexWriter.h"
21 #include "geomLinesAdjacency.h"
22 
23 using std::map;
24 
25 TypeHandle GeomLines::_type_handle;
26 
27 /**
28  *
29  */
30 GeomLines::
31 GeomLines(GeomLines::UsageHint usage_hint) :
32  GeomPrimitive(usage_hint)
33 {
34 }
35 
36 /**
37  *
38  */
39 GeomLines::
40 GeomLines(const GeomLines &copy) :
41  GeomPrimitive(copy)
42 {
43 }
44 
45 /**
46  *
47  */
48 GeomLines::
49 ~GeomLines() {
50 }
51 
52 /**
53  *
54  */
55 PT(GeomPrimitive) GeomLines::
56 make_copy() const {
57  return new GeomLines(*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 GeomLines::
69 get_primitive_type() const {
70  return PT_lines;
71 }
72 
73 /**
74  * Adds adjacency information to this primitive. May return null if this type
75  * of geometry does not support adjacency information.
76  */
77 CPT(GeomPrimitive) GeomLines::
78 make_adjacency() const {
79  Thread *current_thread = Thread::get_current_thread();
81 
82  GeomPrimitivePipelineReader from(this, current_thread);
83  int num_vertices = from.get_num_vertices();
84 
85  PT(GeomVertexArrayData) new_vertices = adj->make_index_data();
86  new_vertices->set_num_rows(num_vertices * 2);
87 
88  // First, build a map of each vertex to its next vertex, and another map
89  // doing the exact reverse. Note that this only considers lines that are
90  // ordered the same way as being connected; we may need to change this.
91  map<int, int> forward_map, reverse_map;
92  for (int i = 0; i < num_vertices; i += 2) {
93  int v0 = from.get_vertex(i);
94  int v1 = from.get_vertex(i + 1);
95  forward_map[v0] = v1;
96  reverse_map[v1] = v0;
97  }
98 
99  // Now build up the new vertex data. For each line, we insert the
100  // appropriate connecting vertex.
101  {
102  GeomVertexWriter to(new_vertices, 0);
103  for (int i = 0; i < num_vertices; i += 2) {
104  int v0 = from.get_vertex(i);
105  int v1 = from.get_vertex(i + 1);
106 
107  auto it = reverse_map.find(v0);
108  if (it != reverse_map.end()) {
109  to.set_data1i(it->second);
110  } else {
111  // Um, no adjoining line segment? Just repeat the vertex, I guess.
112  to.set_data1i(v0);
113  }
114 
115  to.set_data1i(v0);
116  to.set_data1i(v1);
117 
118  // Do the same for the second vertex in the line.
119  it = forward_map.find(v1);
120  if (it != forward_map.end()) {
121  to.set_data1i(it->second);
122  } else {
123  to.set_data1i(v1);
124  }
125  }
126 
127  nassertr(to.is_at_end(), nullptr);
128  }
129 
130  adj->set_vertices(std::move(new_vertices));
131  return adj;
132 }
133 
134 /**
135  * If the primitive type is a simple type in which all primitives have the
136  * same number of vertices, like lines, returns the number of vertices per
137  * primitive. If the primitive type is a more complex type in which different
138  * primitives might have different numbers of vertices, for instance a line
139  * strip, returns 0.
140  */
141 int GeomLines::
142 get_num_vertices_per_primitive() const {
143  return 2;
144 }
145 
146 /**
147  * Returns the minimum number of vertices that must be added before
148  * close_primitive() may legally be called.
149  */
150 int GeomLines::
151 get_min_num_vertices_per_primitive() const {
152  return 2;
153 }
154 
155 /**
156  * Calls the appropriate method on the GSG to draw the primitive.
157  */
158 bool GeomLines::
160  bool force) const {
161  return gsg->draw_lines(reader, force);
162 }
163 
164 /**
165  * The virtual implementation of do_rotate().
166  */
167 CPT(GeomVertexArrayData) GeomLines::
168 rotate_impl() const {
169  // To rotate lines, we just move reverse the pairs of vertices.
170  int num_vertices = get_num_vertices();
171 
172  PT(GeomVertexArrayData) new_vertices = make_index_data();
173  new_vertices->set_num_rows(num_vertices);
174 
175  if (is_indexed()) {
176  CPT(GeomVertexArrayData) vertices = get_vertices();
177  GeomVertexReader from(vertices, 0);
178  GeomVertexWriter to(new_vertices, 0);
179 
180  for (int begin = 0; begin < num_vertices; begin += 2) {
181  from.set_row_unsafe(begin + 1);
182  to.set_data1i(from.get_data1i());
183  from.set_row_unsafe(begin);
184  to.set_data1i(from.get_data1i());
185  }
186 
187  nassertr(to.is_at_end(), nullptr);
188 
189  } else {
190  // Nonindexed case.
191  int first_vertex = get_first_vertex();
192  GeomVertexWriter to(new_vertices, 0);
193 
194  for (int begin = 0; begin < num_vertices; begin += 2) {
195  to.set_data1i(begin + 1 + first_vertex);
196  to.set_data1i(begin + first_vertex);
197  }
198 
199  nassertr(to.is_at_end(), nullptr);
200  }
201 
202  return new_vertices;
203 }
204 
205 /**
206  * Tells the BamReader how to create objects of type Geom.
207  */
208 void GeomLines::
209 register_with_read_factory() {
210  BamReader::get_factory()->register_factory(get_class_type(), make_from_bam);
211 }
212 
213 /**
214  * This function is called by the BamReader's factory when a new object of
215  * type Geom is encountered in the Bam file. It should create the Geom and
216  * extract its information from the file.
217  */
218 TypedWritable *GeomLines::
219 make_from_bam(const FactoryParams &params) {
220  GeomLines *object = new GeomLines(UH_unspecified);
221  DatagramIterator scan;
222  BamReader *manager;
223 
224  parse_params(params, scan, manager);
225  object->fillin(scan, manager);
226 
227  return object;
228 }
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Defines a series of disconnected line segments with adjacency information, for use with geometry shad...
get_usage_hint
Returns the usage hint for this primitive.
Definition: geomPrimitive.h:81
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
PT(GeomPrimitive) GeomLines
Returns the fundamental rendering type of this primitive: whether it is points, lines,...
Definition: geomLines.cxx:55
get_num_vertices
Returns the number of indices used by all the primitives in this object.
Definition: geomPrimitive.h:99
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
Definition: geomPrimitive.I:98
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
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
An instance of this class is passed to the Factory when requesting it to do its business and construc...
Definition: factoryParams.h:36
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Defines a series of disconnected line segments.
Definition: geomLines.h:23
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
A thread; that is, a lightweight process.
Definition: thread.h:46
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
A class to retrieve the individual data elements previously stored in a Datagram.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
Definition: geomPrimitive.I:86
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the data for one array of a GeomVertexData structure.