Panda3D
ptsToBam.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 ptsToBam.cxx
10  * @author drose
11  * @date 2000-06-28
12  */
13 
14 #include "ptsToBam.h"
15 
16 #include "config_putil.h"
17 #include "geomPoints.h"
18 #include "bamFile.h"
19 #include "pandaNode.h"
20 #include "geomNode.h"
21 #include "dcast.h"
22 #include "string_utils.h"
23 #include "config_egg2pg.h"
24 
25 using std::string;
26 
27 /**
28  *
29  */
30 PtsToBam::
31 PtsToBam() : WithOutputFile(true, false, true)
32 {
33  set_program_brief("convert point cloud data into a .bam file");
34  set_program_description
35  ("This program reads a point clound in a pts file and outputs a bam files, "
36  "suitable for viewing in Panda.");
37 
38  clear_runlines();
39  add_runline("[opts] input.pts output.bam");
40  add_runline("[opts] -o output.bam input.pts");
41 
42  add_option
43  ("o", "filename", 0,
44  "Specify the filename to which the resulting .bam file will be written. "
45  "If this option is omitted, the last parameter name is taken to be the "
46  "name of the output file.",
47  &PtsToBam::dispatch_filename, &_got_output_filename, &_output_filename);
48 
49  add_option
50  ("d", "divisor", 0,
51  "Decimates the point cloud by the indicated divisor. The number of points\n"
52  "added is 1/divisor; numbers larger than 1.0 mean correspondingly fewer\n"
53  "points.",
54  &PtsToBam::dispatch_double, nullptr, &_decimate_divisor);
55 
56  _decimate_divisor = 1.0;
57 }
58 
59 /**
60  *
61  */
62 void PtsToBam::
63 run() {
64  pifstream pts;
65  _pts_filename.set_text();
66  if (!_pts_filename.open_read(pts)) {
67  nout << "Cannot open " << _pts_filename << "\n";
68  exit(1);
69  }
70 
71  _gnode = new GeomNode(_pts_filename.get_basename());
72 
73  _num_points_expected = 0;
74  _num_points_found = 0;
75  _num_points_added = 0;
76  _decimate_factor = 1.0 / std::max(1.0, _decimate_divisor);
77  _line_number = 0;
78  _point_number = 0;
79  _decimated_point_number = 0.0;
80  _num_vdatas = 0;
81  string line;
82  while (std::getline(pts, line)) {
83  process_line(line);
84  }
85  close_vertex_data();
86 
87  nout << "\nFound " << _num_points_found << " points of " << _num_points_expected << " expected.\n";
88  nout << "Generated " << _num_points_added << " points to bam file.\n";
89 
90  // This should be guaranteed because we pass false to the constructor,
91  // above.
92  nassertv(has_output_filename());
93 
94  Filename filename = get_output_filename();
95  filename.make_dir();
96  nout << "Writing " << filename << "\n";
97  BamFile bam_file;
98  if (!bam_file.open_write(filename)) {
99  nout << "Error in writing.\n";
100  exit(1);
101  }
102 
103  if (!bam_file.write_object(_gnode.p())) {
104  nout << "Error in writing.\n";
105  exit(1);
106  }
107 }
108 
109 /**
110  *
111  */
112 bool PtsToBam::
113 handle_args(ProgramBase::Args &args) {
114  if (args.empty()) {
115  nout << "You must specify the pts file to read on the command line.\n";
116  return false;
117  }
118 
119  if (args.size() > 1) {
120  nout << "Specify only one pts on the command line.\n";
121  return false;
122  }
123 
124  _pts_filename = Filename::from_os_specific(args[0]);
125 
126  return true;
127 }
128 
129 /**
130  * Reads a single line from the pts file.
131  */
132 void PtsToBam::
133 process_line(const string &line) {
134  _line_number++;
135 
136  if (_line_number % 1000000 == 0) {
137  std::cerr << "." << std::flush;
138  }
139 
140  if (line.empty() || !isdigit(line[0])) {
141  return;
142  }
143 
144  if (_line_number == 1) {
145  // The first line might be just the number of points.
146  vector_string words;
147  tokenize(trim(line), words, " \t", true);
148  if (words.size() == 1) {
149  string tail;
150  _num_points_expected = string_to_int(words[0], tail);
151  nout << "Expecting " << _num_points_expected << " points, will generate "
152  << (int)(_num_points_expected * _decimate_factor) << "\n";
153  return;
154  }
155  }
156 
157  // Here we might have a point.
158  _num_points_found++;
159  _decimated_point_number += _decimate_factor;
160  int point_number = int(_decimated_point_number);
161  if (point_number > _point_number) {
162  _point_number = point_number;
163 
164  vector_string words;
165  tokenize(trim(line), words, " \t", true);
166  if (words.size() >= 3) {
167  add_point(words);
168  }
169  }
170 }
171 
172 /**
173  * Adds a point from the pts file.
174  */
175 void PtsToBam::
176 add_point(const vector_string &words) {
177  if (_data == nullptr || _data->get_num_rows() >= egg_max_vertices) {
178  open_vertex_data();
179  }
180 
181  string tail;
182  double x, y, z;
183  x = string_to_double(words[0], tail);
184  y = string_to_double(words[1], tail);
185  z = string_to_double(words[2], tail);
186  _vertex.add_data3d(x, y, z);
187  _num_points_added++;
188 }
189 
190 /**
191  * Creates a new GeomVertexData.
192  */
193 void PtsToBam::
194 open_vertex_data() {
195  if (_data != nullptr) {
196  close_vertex_data();
197  }
199  _data = new GeomVertexData("pts", format, GeomEnums::UH_static);
200  _vertex = GeomVertexWriter(_data, "vertex");
201 }
202 
203 /**
204  * Closes a previous GeomVertexData and adds it to the scene graph.
205  */
206 void PtsToBam::
207 close_vertex_data() {
208  if (_data == nullptr) {
209  return;
210  }
211 
212  _num_vdatas++;
213  nout << "\nGenerating " << _num_points_added << " points in " << _num_vdatas << " GeomVertexDatas\n";
214 
215  PT(Geom) geom = new Geom(_data);
216 
217  int num_vertices = _data->get_num_rows();
218  int vertices_so_far = 0;
219  while (num_vertices > 0) {
220  int this_num_vertices = std::min(num_vertices, (int)egg_max_indices);
221  PT(GeomPrimitive) points = new GeomPoints(GeomEnums::UH_static);
222  points->add_consecutive_vertices(vertices_so_far, this_num_vertices);
223  geom->add_primitive(points);
224  vertices_so_far += this_num_vertices;
225  num_vertices -= this_num_vertices;
226  }
227 
228  _gnode->add_geom(geom);
229 
230  _data = nullptr;
231 }
232 
233 int main(int argc, char *argv[]) {
234  PtsToBam prog;
235  prog.parse_command_line(argc, argv);
236  prog.run();
237  return 0;
238 }
Geom
A container for geometry primitives.
Definition: geom.h:54
Filename::set_text
void set_text()
Indicates that the filename represents a text file.
Definition: filename.I:424
WithOutputFile
This is the bare functionality (intended to be inherited from along with ProgramBase or some derivati...
Definition: withOutputFile.h:29
pandaNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_putil.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Filename::open_read
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
Definition: filename.cxx:1863
GeomVertexWriter::add_data3d
void add_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row.
Definition: geomVertexWriter.I:986
tokenize
void tokenize(const string &str, vector_string &words, const string &delimiters, bool discard_repeated_delimiters)
Chops the source string up into pieces delimited by any of the characters specified in delimiters.
Definition: string_utils.cxx:170
Filename::from_os_specific
static Filename from_os_specific(const std::string &os_specific, Type type=T_general)
This named constructor returns a Panda-style filename (that is, using forward slashes,...
Definition: filename.cxx:328
GeomVertexData
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
Definition: geomVertexData.h:68
string_utils.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
BamFile::open_write
bool open_write(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated file for writing.
Definition: bamFile.cxx:190
dcast.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
WithOutputFile::get_output_filename
Filename get_output_filename() const
If has_output_filename() returns true, this is the filename that the user specified.
Definition: withOutputFile.cxx:131
GeomPoints
Defines a series of disconnected points.
Definition: geomPoints.h:23
GeomVertexWriter
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
Definition: geomVertexWriter.h:55
ptsToBam.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
config_egg2pg.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
WithOutputFile::has_output_filename
bool has_output_filename() const
Returns true if the user specified an output filename, false otherwise (e.g.
Definition: withOutputFile.cxx:122
bamFile.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
ProgramBase::parse_command_line
virtual void parse_command_line(int argc, char **argv)
Dispatches on each of the options on the command line, and passes the remaining parameters to handle_...
Definition: programBase.cxx:274
GeomNode
A node that holds Geom objects, renderable pieces of geometry.
Definition: geomNode.h:34
pdeque< std::string >
BamFile::write_object
bool write_object(const TypedWritable *object)
Writes the indicated object to the Bam file.
Definition: bamFile.cxx:226
GeomVertexFormat::get_v3
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
Definition: geomVertexFormat.I:251
string_to_int
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
Definition: string_utils.cxx:324
GeomVertexFormat
This class defines the physical layout of the vertex data stored within a Geom.
Definition: geomVertexFormat.h:55
string_to_double
double string_to_double(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
Definition: string_utils.cxx:354
BamFile
The principle public interface to reading and writing Bam disk files.
Definition: bamFile.h:41
PtsToBam
Definition: ptsToBam.h:30
geomPoints.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
trim
string trim(const string &str)
Returns a new string representing the contents of the given string with both leading and trailing whi...
Definition: string_utils.cxx:281
geomNode.h
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
Filename::make_dir
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
Definition: filename.cxx:2484
Filename::get_basename
std::string get_basename() const
Returns the basename part of the filename.
Definition: filename.I:367
Filename
The name of a file, such as a texture file or an Egg file.
Definition: filename.h:39
GeomPrimitive
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
Definition: geomPrimitive.h:56