Panda3D
Loading...
Searching...
No Matches
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
25using std::string;
26
27/**
28 *
29 */
30PtsToBam::
31PtsToBam() : 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 */
62void PtsToBam::
63run() {
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 */
112bool PtsToBam::
113handle_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 */
132void PtsToBam::
133process_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 */
175void PtsToBam::
176add_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 */
193void PtsToBam::
194open_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 */
206void PtsToBam::
207close_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
233int main(int argc, char *argv[]) {
234 PtsToBam prog;
235 prog.parse_command_line(argc, argv);
236 prog.run();
237 return 0;
238}
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
The principle public interface to reading and writing Bam disk files.
Definition bamFile.h:41
bool open_write(const Filename &bam_filename, bool report_errors=true)
Attempts to open the indicated file for writing.
Definition bamFile.cxx:190
bool write_object(const TypedWritable *object)
Writes the indicated object to the Bam file.
Definition bamFile.cxx:226
The name of a file, such as a texture file or an Egg file.
Definition filename.h:44
std::string get_basename() const
Returns the basename part of the filename.
Definition filename.I:367
bool open_read(std::ifstream &stream) const
Opens the indicated ifstream for reading the file, if possible.
bool make_dir() const
Creates all the directories in the path to the file specified in the filename, except for the basenam...
void set_text()
Indicates that the filename represents a text file.
Definition filename.I:424
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
A node that holds Geom objects, renderable pieces of geometry.
Definition geomNode.h:34
Defines a series of disconnected points.
Definition geomPoints.h:23
This is an abstract base class for a family of classes that represent the fundamental geometry primit...
This defines the actual numeric vertex data stored in a Geom, in the structure defined by a particula...
This class defines the physical layout of the vertex data stored within a Geom.
static const GeomVertexFormat * get_v3()
Returns a standard vertex format with just a 3-component vertex position.
This object provides a high-level interface for quickly writing a sequence of numeric values from a v...
void add_data3d(double x, double y, double z)
Sets the write row to a particular 3-component value, and advances the write row.
A container for geometry primitives.
Definition geom.h:54
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_...
This is the bare functionality (intended to be inherited from along with ProgramBase or some derivati...
Filename get_output_filename() const
If has_output_filename() returns true, this is the filename that the user specified.
bool has_output_filename() const
Returns true if the user specified an output filename, false otherwise (e.g.
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.
string trim(const string &str)
Returns a new string representing the contents of the given string with both leading and trailing whi...
double string_to_double(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
int string_to_int(const string &str, string &tail)
A string-interface wrapper around the C library strtol().
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.
PANDA 3D SOFTWARE Copyright (c) Carnegie Mellon University.