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 }
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
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
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
This is the fundamental interface for extracting binary objects from a Bam file, as generated by a Ba...
Definition: bamReader.h:110
static WritableFactory * get_factory()
Returns the global WritableFactory for generating TypedWritable objects.
Definition: bamReader.I:177
A class to retrieve the individual data elements previously stored in a Datagram.
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
Defines a series of disconnected line segments with adjacency information, for use with geometry shad...
Defines a series of disconnected line segments.
Definition: geomLines.h:23
Encapsulates the data from a GeomPrimitive, pre-fetched for one stage of the pipeline.
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56
get_usage_hint
Returns the usage hint for this primitive.
Definition: geomPrimitive.h:81
get_num_vertices
Returns the number of indices used by all the primitives in this object.
Definition: geomPrimitive.h:99
int get_first_vertex() const
Returns the first vertex number referenced by the primitive.
Definition: geomPrimitive.I:98
bool is_indexed() const
Returns true if the primitive is indexed, false otherwise.
Definition: geomPrimitive.I:86
This is the data for one array of a GeomVertexData structure.
This object provides a high-level interface for quickly reading a sequence of numeric values from a v...
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
This is a base class for the GraphicsStateGuardian class, which is itself a base class for the variou...
A thread; that is, a lightweight process.
Definition: thread.h:46
get_current_thread
Returns a pointer to the currently-executing Thread object.
Definition: thread.h:109
TypeHandle is the identifier used to differentiate C++ class types.
Definition: typeHandle.h:81
Base class for objects that can be written to and read from Bam files.
Definition: typedWritable.h:35
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PT(GeomPrimitive) GeomLines
Returns the fundamental rendering type of this primitive: whether it is points, lines,...
Definition: geomLines.cxx:55
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.