Jelajahi Sumber

fix build circularity issue

David Rose 13 tahun lalu
induk
melakukan
8e3e89b5b3

+ 3 - 0
panda/src/grutil/Sources.pp

@@ -25,6 +25,7 @@
     lineSegs.I lineSegs.h \
     multitexReducer.I multitexReducer.h multitexReducer.cxx \
     nodeVertexTransform.I nodeVertexTransform.h \
+    pfmVizzer.I pfmVizzer.h \
     rigidBodyCombiner.I rigidBodyCombiner.h
     
   #define INCLUDED_SOURCES \
@@ -39,6 +40,7 @@
     sceneGraphAnalyzerMeter.cxx \
     heightfieldTesselator.cxx \
     nodeVertexTransform.cxx \    
+    pfmVizzer.cxx \
     pipeOcclusionCullTraverser.cxx \
     lineSegs.cxx \
     rigidBodyCombiner.cxx
@@ -56,6 +58,7 @@
     lineSegs.I lineSegs.h \
     multitexReducer.I multitexReducer.h \
     nodeVertexTransform.I nodeVertexTransform.h \
+    pfmVizzer.I pfmVizzer.h \
     rigidBodyCombiner.I rigidBodyCombiner.h
 
   #define IGATESCAN all

+ 12 - 0
panda/src/grutil/config_grutil.cxx

@@ -72,6 +72,18 @@ ConfigVariableBool movies_sync_pages
           "such as cube maps, 3-d textures, or stereo textures, or textures "
           "with separate color and alpha channel movie sources."));
 
+ConfigVariableInt pfm_vis_max_vertices
+("pfm-vis-max-vertices", 65535,
+ PRC_DESC("Specifies the maximum number of vertex entries that may appear in "
+          "a single generated mesh.  If the mesh would require more than that, "
+          "the mesh is subdivided into smaller pieces."));
+
+ConfigVariableInt pfm_vis_max_indices
+("pfm-vis-max-indices", 1048576,
+ PRC_DESC("Specifies the maximum number of vertex references that may appear in "
+          "a single generated mesh.  If the mesh would require more than that, "
+          "the mesh is subdivided into smaller pieces."));
+
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libgrutil
 //  Description: Initializes the library.  This must be called at

+ 3 - 0
panda/src/grutil/config_grutil.h

@@ -37,6 +37,9 @@ extern ConfigVariableDouble scene_graph_analyzer_meter_side_margins;
 
 extern ConfigVariableBool movies_sync_pages;
 
+extern ConfigVariableInt pfm_vis_max_vertices;
+extern ConfigVariableInt pfm_vis_max_indices;
+
 extern EXPCL_PANDA_GRUTIL void init_libgrutil();
 
 #endif

+ 4 - 2
panda/src/grutil/p3grutil_composite2.cxx

@@ -1,6 +1,8 @@
+#include "meshDrawer.cxx"
+#include "meshDrawer2D.cxx"
 #include "movieTexture.cxx"
 #include "nodeVertexTransform.cxx"
 #include "pipeOcclusionCullTraverser.cxx"
+#include "pfmVizzer.cxx"
 #include "rigidBodyCombiner.cxx"
-#include "meshDrawer.cxx"
-#include "meshDrawer2D.cxx"
+

+ 182 - 0
panda/src/grutil/pfmVizzer.I

@@ -0,0 +1,182 @@
+// Filename: pfmVizzer.I
+// Created by:  drose (30Sep12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_pfm
+//       Access: Published
+//  Description: Returns the reference to the PfmFile manipulated by
+//               thiz PfmVizzer.
+////////////////////////////////////////////////////////////////////
+INLINE PfmFile &PfmVizzer::
+get_pfm() {
+  return _pfm;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_pfm
+//       Access: Published
+//  Description: Returns the reference to the PfmFile manipulated by
+//               thiz PfmVizzer.
+////////////////////////////////////////////////////////////////////
+INLINE const PfmFile &PfmVizzer::
+get_pfm() const {
+  return _pfm;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::set_vis_inverse
+//       Access: Published
+//  Description: Sets the vis_inverse flag.  When this flag is true,
+//               vis meshes and point clouds are generated with the
+//               3-d depth value in the texture coordinates, and the
+//               2-d index value in the vertex position.  When it is
+//               false, meshes are generated normally, with the 3-d
+//               depth value in the vertex position and the 2-d index
+//               value in the texture coordinates.
+//
+//               This may be used in lieu of the lower-level
+//               add_vis_column().
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+set_vis_inverse(bool vis_inverse) {
+  _vis_inverse = vis_inverse;
+  clear_vis_columns();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_vis_inverse
+//       Access: Published
+//  Description: Returns the vis_inverse flag.  See set_vis_inverse().
+////////////////////////////////////////////////////////////////////
+INLINE bool PfmVizzer::
+get_vis_inverse() const {
+  return _vis_inverse;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::set_flat_texcoord_name
+//       Access: Published
+//  Description: If the flat_texcoord_name is specified, it is the
+//               name of an additional vertex column that will be
+//               created for the "flat" texture coordinates, i.e. the
+//               original 0..1 values that correspond to the 2-D index
+//               position of each point in the original pfm file.
+//
+//               These are the same values that will be assigned to
+//               the default texture coordinates if the vis_inverse
+//               flag is *not* true.
+//
+//               This may be used in lieu of the lower-level
+//               add_vis_column().
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+set_flat_texcoord_name(InternalName *flat_texcoord_name) {
+  _flat_texcoord_name = flat_texcoord_name;
+  clear_vis_columns();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::clear_flat_texcoord_name
+//       Access: Published
+//  Description: Resets the flat_texcoord_name to empty, so that
+//               additional texture coordinates are not created.
+//
+//               This may be used in lieu of the lower-level
+//               add_vis_column().
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+clear_flat_texcoord_name() {
+  _flat_texcoord_name = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_flat_texcoord_name
+//       Access: Published
+//  Description: Returns the flat_texcoord_name.  See set_flat_texcoord_name().
+////////////////////////////////////////////////////////////////////
+INLINE InternalName *PfmVizzer::
+get_flat_texcoord_name() const {
+  return _flat_texcoord_name;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::set_vis_2d
+//       Access: Published
+//  Description: Sets the vis_2d flag.  When this flag is true,
+//               only the first two (x, y) value of each depth point
+//               is considered meaningful; the z component is ignored.
+//               This is only relevant for generating visualizations.
+//
+//               This may be used in lieu of the lower-level
+//               add_vis_column().
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+set_vis_2d(bool vis_2d) {
+  _vis_2d = vis_2d;
+  clear_vis_columns();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_vis_2d
+//       Access: Published
+//  Description: Returns the vis_2d flag.  See set_vis_2d().
+////////////////////////////////////////////////////////////////////
+INLINE bool PfmVizzer::
+get_vis_2d() const {
+  return _vis_2d;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::set_vis_blend
+//       Access: Published
+//  Description: Specifies a blending map--a grayscale image--that
+//               will be applied to the vertex color during
+//               generate_vis_mesh() and generate_vis_points().  The
+//               image size must exactly match the mesh size of the
+//               PfmVizzer.
+//
+//               Ownership of the pointer is not kept by the PfmVizzer;
+//               it is your responsibility to ensure it does not
+//               destruct during the lifetime of the PfmVizzer (or at
+//               least not before your subsequent call to
+//               generate_vis_mesh()).
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+set_vis_blend(const PNMImage *vis_blend) {
+  _vis_blend = vis_blend;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::set_vis_blend
+//       Access: Published
+//  Description: Removes the blending map set by a prior call to
+//               set_vis_blend().
+////////////////////////////////////////////////////////////////////
+INLINE void PfmVizzer::
+clear_vis_blend() {
+  _vis_blend = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::get_vis_blend
+//       Access: Published
+//  Description: Returns the blending map set by the most recent call
+//               to set_vis_blend(), or NULL if there is no blending
+//               map in effect.
+////////////////////////////////////////////////////////////////////
+INLINE const PNMImage *PfmVizzer::
+get_vis_blend() const {
+  return _vis_blend;
+}

+ 743 - 0
panda/src/grutil/pfmVizzer.cxx

@@ -0,0 +1,743 @@
+// Filename: pfmVizzer.cxx
+// Created by:  drose (30Sep12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#include "pfmVizzer.h"
+#include "geomNode.h"
+#include "geom.h"
+#include "geomVertexData.h"
+#include "geomVertexFormat.h"
+#include "geomPoints.h"
+#include "geomTriangles.h"
+#include "geomVertexWriter.h"
+#include "lens.h"
+#include "config_grutil.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::Constructor
+//       Access: Published
+//  Description: The PfmVizzer constructor receives a reference to a
+//               PfmFile which it will operate on.  It does not keep
+//               ownership of this reference; it is your
+//               responsibility to ensure the PfmFile does not
+//               destruct during the lifetime of the PfmVizzer.
+////////////////////////////////////////////////////////////////////
+PfmVizzer::
+PfmVizzer(PfmFile &pfm) : _pfm(pfm) {
+  _vis_inverse = false;
+  _vis_2d = false;
+  _vis_blend = NULL;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::project
+//       Access: Published
+//  Description: Adjusts each (x, y, z) point of the Pfm file by
+//               projecting it through the indicated lens, converting
+//               each point to a (u, v, w) texture coordinate.  The
+//               resulting file can be generated to a mesh (with
+//               set_vis_inverse(true) and generate_vis_mesh())
+//               that will apply the lens distortion to an arbitrary
+//               texture image.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+project(const Lens *lens) {
+  nassertv(_pfm.is_valid());
+
+  static LMatrix4f to_uv(0.5f, 0.0f, 0.0f, 0.0f,
+                         0.0f, 0.5f, 0.0f, 0.0f, 
+                         0.0f, 0.0f, 0.5f, 0.0f, 
+                         0.5f, 0.5f, 0.5f, 1.0f);
+  
+  for (int yi = 0; yi < _pfm.get_y_size(); ++yi) {
+    for (int xi = 0; xi < _pfm.get_x_size(); ++xi) {
+      if (!_pfm.has_point(xi, yi)) {
+        continue;
+      }
+      LPoint3f &p = _pfm.modify_point(xi, yi);
+
+      LPoint3 film;
+      lens->project(LCAST(PN_stdfloat, p), film);
+      p = to_uv.xform_point(LCAST(PN_float32, film));
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::extrude
+//       Access: Published
+//  Description: Converts each (u, v, depth) point of the Pfm file to
+//               an (x, y, z) point, by reversing project().  If the
+//               original file is only a 1-d file, assumes that it is
+//               a depth map with implicit (u, v) coordinates.
+//
+//               This method is only valid for a linear lens (e.g. a
+//               PerspectiveLens or OrthographicLens).  Non-linear
+//               lenses don't necessarily compute a sensible depth
+//               coordinate.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+extrude(const Lens *lens) {
+  nassertv(_pfm.is_valid());
+  nassertv(lens->is_linear());
+
+  static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0,
+                          0.0, 2.0, 0.0, 0.0,
+                          0.0, 0.0, 2.0, 0.0,
+                          -1.0, -1.0, -1.0, 1.0);
+  const LMatrix4 &proj_mat_inv = lens->get_projection_mat_inv();
+
+  PfmFile result;
+  result.clear(_pfm.get_x_size(), _pfm.get_y_size(), 3);
+  result.set_zero_special(true);
+
+  if (_pfm.get_num_channels() == 1) {
+    // Create an implicit UV coordinate for each point.
+    LPoint2 uv_scale(1.0, 1.0);
+    if (_pfm.get_x_size() > 1) {
+      uv_scale[0] = 1.0 / PN_stdfloat(_pfm.get_x_size() - 1);
+    }
+    if (_pfm.get_y_size() > 1) {
+      uv_scale[1] = 1.0 / PN_stdfloat(_pfm.get_y_size() - 1);
+    }
+    for (int yi = 0; yi < _pfm.get_y_size(); ++yi) {
+      for (int xi = 0; xi < _pfm.get_x_size(); ++xi) {
+        if (!_pfm.has_point(xi, yi)) {
+          continue;
+        }
+        LPoint3 p;
+        p.set((PN_stdfloat)xi * uv_scale[0],
+              (PN_stdfloat)yi * uv_scale[1],
+              (PN_stdfloat)_pfm.get_point1(xi, yi));
+        
+        from_uv.xform_point_in_place(p);
+        proj_mat_inv.xform_point_general_in_place(p);
+        result.set_point(xi, yi, p);
+      }
+    }
+  } else {
+    // Use the existing UV coordinate for each point.
+    for (int yi = 0; yi < _pfm.get_y_size(); ++yi) {
+      for (int xi = 0; xi < _pfm.get_x_size(); ++xi) {
+        if (!_pfm.has_point(xi, yi)) {
+          continue;
+        }
+        LPoint3 p;
+        p = LCAST(PN_stdfloat, _pfm.get_point(xi, yi));
+        
+        from_uv.xform_point_in_place(p);
+        proj_mat_inv.xform_point_general_in_place(p);
+        result.set_point(xi, yi, p);
+      }
+    }
+  }
+
+  _pfm = result;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::clear_vis_columns
+//       Access: Published
+//  Description: Removes all of the previously-added vis columns in
+//               preparation for building a new list.  See
+//               add_vis_column().
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+clear_vis_columns() {
+  _vis_columns.clear();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::add_vis_column
+//       Access: Published
+//  Description: Adds a new vis column specification to the list of
+//               vertex data columns that will be generated at the
+//               next call to generate_vis_points() or
+//               generate_vis_mesh().  This advanced interface
+//               supercedes the higher-level set_vis_inverse(),
+//               set_flat_texcoord_name(), and set_vis_2d().
+//
+//               If you use this advanced interface, you must specify
+//               explicitly the complete list of data columns to be
+//               created in the resulting GeomVertexData, by calling
+//               add_vis_column() each time.  For each column, you
+//               specify the source of the column in the PFMFile, the
+//               target column and name in the GeomVertexData, and an
+//               optional transform matrix and/or lens to transform
+//               and project the point before generating it.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+add_vis_column(ColumnType source, ColumnType target,
+               InternalName *name, const TransformState *transform,
+               const Lens *lens) {
+  add_vis_column(_vis_columns, source, target, name, transform, lens);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::generate_vis_points
+//       Access: Published
+//  Description: Creates a point cloud with the points of the pfm as
+//               3-d coordinates in space, and texture coordinates
+//               ranging from 0 .. 1 based on the position within the
+//               pfm grid.
+////////////////////////////////////////////////////////////////////
+NodePath PfmVizzer::
+generate_vis_points() const {
+  nassertr(_pfm.is_valid(), NodePath());
+
+  CPT(GeomVertexFormat) format;
+  if (_vis_inverse) {
+    if (_vis_2d) {
+      format = GeomVertexFormat::get_v3t2();
+    } else {
+      // We need a 3-d texture coordinate if we're inverting the vis
+      // and it's 3-d.
+      GeomVertexArrayFormat *v3t3 = new GeomVertexArrayFormat
+        (InternalName::get_vertex(), 3, 
+         Geom::NT_stdfloat, Geom::C_point,
+         InternalName::get_texcoord(), 3, 
+         Geom::NT_stdfloat, Geom::C_texcoord);
+      format = GeomVertexFormat::register_format(v3t3);
+    }
+  } else {
+    format = GeomVertexFormat::get_v3t2();
+  }
+
+  PT(GeomVertexData) vdata = new GeomVertexData
+    ("points", format, Geom::UH_static);
+  vdata->set_num_rows(_pfm.get_x_size() * _pfm.get_y_size());
+  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
+  GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
+
+  LPoint2f uv_scale(1.0, 1.0);
+  if (_pfm.get_x_size() > 1) {
+    uv_scale[0] = 1.0f / PN_float32(_pfm.get_x_size() - 1);
+  }
+  if (_pfm.get_y_size() > 1) {
+    uv_scale[1] = 1.0f / PN_float32(_pfm.get_y_size() - 1);
+  }
+
+  int num_points = 0;
+  for (int yi = 0; yi < _pfm.get_y_size(); ++yi) {
+    for (int xi = 0; xi < _pfm.get_x_size(); ++xi) {
+      if (!_pfm.has_point(xi, yi)) {
+        continue;
+      }
+
+      const LPoint3f &point = _pfm.get_point(xi, yi);
+      LPoint2f uv(PN_float32(xi) * uv_scale[0],
+                  PN_float32(yi) * uv_scale[1]);
+      if (_vis_inverse) {
+        vertex.add_data2f(uv);
+        texcoord.add_data3f(point);
+      } else if (_vis_2d) {
+        vertex.add_data2f(point[0], point[1]);
+        texcoord.add_data2f(uv);
+      } else {
+        vertex.add_data3f(point);
+        texcoord.add_data2f(uv);
+      }
+      ++num_points;
+    }
+  }
+  
+  PT(Geom) geom = new Geom(vdata);
+  PT(GeomPoints) points = new GeomPoints(Geom::UH_static);
+  points->add_next_vertices(num_points);
+  geom->add_primitive(points);
+  
+  PT(GeomNode) gnode = new GeomNode("");
+  gnode->add_geom(geom);
+  return NodePath(gnode);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::generate_vis_mesh
+//       Access: Published
+//  Description: Creates a triangle mesh with the points of the pfm as
+//               3-d coordinates in space, and texture coordinates
+//               ranging from 0 .. 1 based on the position within the
+//               pfm grid.
+////////////////////////////////////////////////////////////////////
+NodePath PfmVizzer::
+generate_vis_mesh(MeshFace face) const {
+  nassertr(_pfm.is_valid(), NodePath());
+  nassertr(face != 0, NodePath());
+
+  if (_pfm.get_num_channels() == 1 && _vis_columns.empty()) {
+    // If we're generating a default mesh from a one-channel pfm file,
+    // expand it to a three-channel pfm file to make the visualization
+    // useful.
+    PfmFile expanded;
+    expanded.clear_to_texcoords(_pfm.get_x_size(), _pfm.get_y_size());
+    expanded.copy_channel(2, _pfm, 0);
+    PfmVizzer exvizzer(expanded);
+    return exvizzer.generate_vis_mesh(face);
+  }
+  
+  if (_pfm.get_x_size() == 1 || _pfm.get_y_size() == 1) {
+    // Can't generate a 1-d mesh, so generate points in this case.
+    return generate_vis_points();
+  }
+  
+  PT(GeomNode) gnode = new GeomNode("");
+
+  if (face & MF_front) {
+    make_vis_mesh_geom(gnode, false);
+  }
+
+  if (face & MF_back) {
+    make_vis_mesh_geom(gnode, true);
+  }
+
+  return NodePath(gnode);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::make_vis_mesh_geom
+//       Access: Private
+//  Description: Returns a triangle mesh for the pfm.  If inverted is
+//               true, the mesh is facing the opposite direction.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
+  int num_x_cells = 1;
+  int num_y_cells = 1;
+
+  int x_size = _pfm.get_x_size();
+  int y_size = _pfm.get_y_size();
+
+  // This is the number of independent vertices we will require.
+  int num_vertices = x_size * y_size;
+  if (num_vertices == 0) {
+    // Trivial no-op.
+    return;
+  }
+
+  bool reverse_normals = inverted;
+  bool reverse_faces = inverted;
+  if (!is_right_handed(get_default_coordinate_system())) {
+    reverse_faces = !reverse_faces;
+  }
+
+  // This is the max number of vertex indices we might add to the
+  // GeomTriangles.  (We might actually add fewer than this due to
+  // omitting the occasional missing data point.)
+  int max_indices = (x_size - 1) * (y_size - 1) * 6;
+
+  while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) {
+    // Too many vertices in one mesh.  Subdivide the mesh into smaller
+    // pieces.
+    if (num_x_cells > num_y_cells) {
+      ++num_y_cells;
+    } else {
+      ++num_x_cells;
+    }
+
+    x_size = (_pfm.get_x_size() + num_x_cells - 1) / num_x_cells + 1;
+    y_size = (_pfm.get_y_size() + num_y_cells - 1) / num_y_cells + 1;
+
+    num_vertices = x_size * y_size;
+    max_indices = (x_size - 1) * (y_size - 1) * 6;
+  }
+
+  // OK, now we know how many cells we need.
+  if (grutil_cat.is_debug()) {
+    grutil_cat.debug()
+      << "Generating mesh with " << num_x_cells << " x " << num_y_cells
+      << " pieces.\n";
+  }
+
+  VisColumns vis_columns = _vis_columns;
+  if (vis_columns.empty()) {
+    build_auto_vis_columns(vis_columns, true);
+  }
+
+  CPT(GeomVertexFormat) format = make_array_format(vis_columns);
+
+  for (int yci = 0; yci < num_y_cells; ++yci) {
+    int y_begin = (yci * _pfm.get_y_size()) / num_y_cells;
+    int y_end = ((yci + 1) * _pfm.get_y_size()) / num_y_cells;
+
+    // Include the first vertex from the next strip in this strip's
+    // vertices, so we are connected.
+    y_end = min(y_end + 1, _pfm.get_y_size());
+
+    y_size = y_end - y_begin;
+    if (y_size == 0) {
+      continue;
+    }
+
+    for (int xci = 0; xci < num_x_cells; ++xci) {
+      int x_begin = (xci * _pfm.get_x_size()) / num_x_cells;
+      int x_end = ((xci + 1) * _pfm.get_x_size()) / num_x_cells;
+      x_end = min(x_end + 1, _pfm.get_x_size());
+      x_size = x_end - x_begin;
+      if (x_size == 0) {
+        continue;
+      }
+
+      num_vertices = x_size * y_size;
+      max_indices = (x_size - 1) * (y_size - 1) * 6;
+
+      ostringstream mesh_name;
+      mesh_name << "mesh_" << xci << "_" << yci;
+      PT(GeomVertexData) vdata = new GeomVertexData
+        (mesh_name.str(), format, Geom::UH_static);
+
+      vdata->set_num_rows(num_vertices);
+
+      // Fill in all of the vertices.
+      for (VisColumns::const_iterator vci = vis_columns.begin();
+           vci != vis_columns.end();
+           ++vci) {
+        const VisColumn &column = *vci;
+        GeomVertexWriter vwriter(vdata, column._name);
+        vwriter.set_row(0);
+
+        for (int yi = y_begin; yi < y_end; ++yi) {
+          for (int xi = x_begin; xi < x_end; ++xi) {
+            column.add_data(*this, vwriter, xi, yi, reverse_normals);
+          }
+        }
+      }
+  
+      PT(Geom) geom = new Geom(vdata);
+      PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
+
+      tris->reserve_num_vertices(max_indices);
+
+      for (int yi = y_begin; yi < y_end - 1; ++yi) {
+        for (int xi = x_begin; xi < x_end - 1; ++xi) {
+
+          if (_pfm.has_no_data_value()) {
+            if (!_pfm.has_point(xi, yi) ||
+                !_pfm.has_point(xi, yi + 1) ||
+                !_pfm.has_point(xi + 1, yi + 1) ||
+                !_pfm.has_point(xi + 1, yi)) {
+              continue;
+            }
+          }
+
+          int xi0 = xi - x_begin;
+          int yi0 = yi - y_begin;
+
+          int vi0 = ((xi0) + (yi0) * x_size);
+          int vi1 = ((xi0) + (yi0 + 1) * x_size);
+          int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
+          int vi3 = ((xi0 + 1) + (yi0) * x_size);
+          
+          if (reverse_faces) {
+            tris->add_vertices(vi2, vi0, vi1);
+            tris->close_primitive();
+            
+            tris->add_vertices(vi3, vi0, vi2);
+            tris->close_primitive();
+          } else {
+            tris->add_vertices(vi2, vi1, vi0);
+            tris->close_primitive();
+            
+            tris->add_vertices(vi3, vi2, vi0);
+            tris->close_primitive();
+          }
+        }
+      }
+      geom->add_primitive(tris);
+      gnode->add_geom(geom);
+    }
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::add_vis_column
+//       Access: Private, Static
+//  Description: The private implementation of the public
+//               add_vis_column(), this adds the column to the
+//               indicated specific vector.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
+               InternalName *name, const TransformState *transform,
+               const Lens *lens) {
+  VisColumn column;
+  column._source = source;
+  column._target = target;
+  column._name = name;
+  column._transform = transform;
+  if (transform == NULL) {
+    column._transform = TransformState::make_identity();
+  }
+  column._lens = lens;
+  vis_columns.push_back(column);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::build_auto_vis_columns
+//       Access: Private
+//  Description: This function is called internally to construct the
+//               list of vis_columns automatically from the high-level
+//               interfaces such as set_vis_inverse(),
+//               set_flat_texcoord_name(), and set_vis_2d().  It's not
+//               called if the list has been build explicitly.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::
+build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const {
+  vis_columns.clear();
+
+  if (_vis_2d) {
+    // No normals needed if we're just generating a 2-d mesh.
+    if (_vis_inverse) {
+      add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex());
+      add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord());
+    } else {
+      add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex());
+      add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
+    }
+
+  } else {
+    if (_vis_inverse) {
+      // We need a 3-d texture coordinate if we're inverting the vis
+      // and it's 3-d.  But we still don't need normals in that case.
+      add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex());
+      add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord());
+    } else {
+      // Otherwise, we only need a 2-d texture coordinate, and we do
+      // want normals.
+      add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex());
+      add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal());
+      add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
+    }
+  }
+
+  if (_flat_texcoord_name != (InternalName *)NULL) {
+    // We need an additional texcoord column for the flat texcoords.
+    add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name);
+  }
+
+  if (_vis_blend != (PNMImage *)NULL) {
+    // The blend map, if specified, also gets applied to the vertices.
+    add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color());
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::make_array_format
+//       Access: Private
+//  Description: Constructs a GeomVertexFormat that corresponds to the
+//               vis_columns list.
+////////////////////////////////////////////////////////////////////
+CPT(GeomVertexFormat) PfmVizzer::
+make_array_format(const VisColumns &vis_columns) const {
+  PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat;
+
+  for (VisColumns::const_iterator vci = vis_columns.begin();
+       vci != vis_columns.end();
+       ++vci) {
+    const VisColumn &column = *vci;
+    InternalName *name = column._name;
+
+    int num_components = 0;
+    GeomEnums::NumericType numeric_type = GeomEnums::NT_float32;
+    GeomEnums::Contents contents = GeomEnums::C_point;
+    switch (column._target) {
+    case CT_texcoord2:
+      num_components = 2;
+      numeric_type = GeomEnums::NT_float32;
+      contents = GeomEnums::C_texcoord;
+      break;
+
+    case CT_texcoord3:
+      num_components = 3;
+      numeric_type = GeomEnums::NT_float32;
+      contents = GeomEnums::C_texcoord;
+      break;
+
+    case CT_vertex1:
+    case CT_vertex2:
+    case CT_vertex3:
+      num_components = 3;
+      numeric_type = GeomEnums::NT_float32;
+      contents = GeomEnums::C_point;
+      break;
+
+    case CT_normal3:
+      num_components = 3;
+      numeric_type = GeomEnums::NT_float32;
+      contents = GeomEnums::C_vector;
+      break;
+
+    case CT_blend1:
+      num_components = 4;
+      numeric_type = GeomEnums::NT_uint8;
+      contents = GeomEnums::C_color;
+      break;
+    }
+    nassertr(num_components != 0, NULL);
+    
+    array_format->add_column(name, num_components, numeric_type, contents);
+  }
+
+  return GeomVertexFormat::register_format(array_format);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::VisColumn::add_data
+//       Access: Public
+//  Description: Adds the data for this column to the appropriate
+//               column of the GeomVertexWriter.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::VisColumn::
+add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const {
+  const PfmFile &pfm = vizzer.get_pfm();
+
+  switch (_source) {
+  case CT_texcoord2:
+    { 
+      LPoint2f uv(PN_float32(xi) / PN_float32(pfm.get_x_size() - 1),
+                  PN_float32(yi) / PN_float32(pfm.get_y_size() - 1));
+      transform_point(uv);
+      vwriter.set_data2f(uv);
+    }
+    break;
+
+  case CT_texcoord3:
+    {
+      LPoint3f uv(PN_float32(xi) / PN_float32(pfm.get_x_size() - 1),
+                  PN_float32(yi) / PN_float32(pfm.get_y_size() - 1), 
+                  0.0f);
+      transform_point(uv);
+      vwriter.set_data3f(uv);
+    }
+    break;
+
+  case CT_vertex1:
+    {
+      PN_float32 p = pfm.get_point1(xi, yi);
+      LPoint2f point(p, 0.0);
+      transform_point(point);
+      vwriter.set_data2f(point);
+    }
+    break;
+
+  case CT_vertex2:
+    {
+      LPoint2f point = pfm.get_point2(xi, yi);
+      transform_point(point);
+      vwriter.set_data2f(point);
+    }
+    break;
+
+  case CT_vertex3:
+    {
+      LPoint3f point = pfm.get_point(xi, yi);
+      transform_point(point);
+      vwriter.set_data3f(point);
+    }
+    break;
+
+  case CT_normal3:
+    {
+      // Calculate the normal based on two neighboring vertices.
+      LPoint3f v[3];
+      v[0] = pfm.get_point(xi, yi);
+      if (xi + 1 < pfm.get_x_size()) {
+        v[1] = pfm.get_point(xi + 1, yi);
+      } else {
+        v[1] = v[0];
+        v[0] = pfm.get_point(xi - 1, yi);
+      }
+                
+      if (yi + 1 < pfm.get_y_size()) {
+        v[2] = pfm.get_point(xi, yi + 1);
+      } else {
+        v[2] = v[0];
+        v[0] = pfm.get_point(xi, yi - 1);
+      }
+                
+      LVector3f n = LVector3f::zero();
+      for (int i = 0; i < 3; ++i) {
+        const LPoint3f &v0 = v[i];
+        const LPoint3f &v1 = v[(i + 1) % 3];
+        n[0] += v0[1] * v1[2] - v0[2] * v1[1];
+        n[1] += v0[2] * v1[0] - v0[0] * v1[2];
+        n[2] += v0[0] * v1[1] - v0[1] * v1[0];
+      }
+      n.normalize();
+      nassertv(!n.is_nan());
+      if (reverse_normals) {
+        n = -n;
+      }
+      transform_vector(n);
+      vwriter.set_data3f(n);
+    }
+    break;
+
+  case CT_blend1:
+    {
+      const PNMImage *vis_blend = vizzer.get_vis_blend();
+      if (vis_blend != NULL) {
+        double gray = vis_blend->get_gray(xi, yi);
+        vwriter.set_data3d(gray, gray, gray);
+      }
+    }
+    break;
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::VisColumn::transform_point
+//       Access: Public
+//  Description: Transforms the indicated point as specified by the
+//               VisColumn.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::VisColumn::
+transform_point(LPoint2f &point) const {
+  if (!_transform->is_identity()) {
+    LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point);
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::VisColumn::transform_point
+//       Access: Public
+//  Description: Transforms the indicated point as specified by the
+//               VisColumn.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::VisColumn::
+transform_point(LPoint3f &point) const {
+  if (!_transform->is_identity()) {
+    LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point);
+  }
+  if (_lens != (Lens *)NULL) {
+    static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0,
+                           0.0, 0.5, 0.0, 0.0, 
+                           0.0, 0.0, 1.0, 0.0, 
+                           0.5, 0.5, 0.0, 1.0);
+    LPoint3 film;
+    _lens->project(LCAST(PN_stdfloat, point), film);
+    point = to_uv.xform_point(LCAST(PN_float32, film));
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: PfmVizzer::VisColumn::transform_vector
+//       Access: Public
+//  Description: Transforms the indicated vector as specified by the
+//               VisColumn.
+////////////////////////////////////////////////////////////////////
+void PfmVizzer::VisColumn::
+transform_vector(LVector3f &vec) const {
+  if (!_transform->is_identity()) {
+    LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec);
+  }
+}

+ 120 - 0
panda/src/grutil/pfmVizzer.h

@@ -0,0 +1,120 @@
+// Filename: pfmVizzer.h
+// Created by:  drose (30Sep12)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) Carnegie Mellon University.  All rights reserved.
+//
+// All use of this software is subject to the terms of the revised BSD
+// license.  You should have received a copy of this license along
+// with this source code in a file named "LICENSE."
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef PFMVIZZER_H
+#define PFMVIZZER_H
+
+#include "pandabase.h"
+#include "nodePath.h"
+#include "internalName.h"
+#include "lens.h"
+#include "pfmFile.h"
+
+class GeomNode;
+class Lens;
+class GeomVertexWriter;
+
+////////////////////////////////////////////////////////////////////
+//       Class : PfmVizzer
+// Description : This class aids in the visualization and manipulation
+//               of PfmFile objects.
+////////////////////////////////////////////////////////////////////
+class EXPCL_PANDA_GRUTIL PfmVizzer {
+PUBLISHED:
+  PfmVizzer(PfmFile &pfm);
+  INLINE PfmFile &get_pfm();
+  INLINE const PfmFile &get_pfm() const;
+
+  BLOCKING void project(const Lens *lens);
+  BLOCKING void extrude(const Lens *lens);
+
+  INLINE void set_vis_inverse(bool vis_inverse);
+  INLINE bool get_vis_inverse() const;
+  INLINE void set_flat_texcoord_name(InternalName *flat_texcoord_name);
+  INLINE void clear_flat_texcoord_name();
+  INLINE InternalName *get_flat_texcoord_name() const;
+  INLINE void set_vis_2d(bool vis_2d);
+  INLINE bool get_vis_2d() const;
+
+  INLINE void set_vis_blend(const PNMImage *vis_blend);
+  INLINE void clear_vis_blend();
+  INLINE const PNMImage *get_vis_blend() const;
+
+  enum ColumnType {
+    CT_texcoord2,
+    CT_texcoord3,
+    CT_vertex1,
+    CT_vertex2,
+    CT_vertex3,
+    CT_normal3,
+    CT_blend1,
+  };
+  void clear_vis_columns();
+  void add_vis_column(ColumnType source, ColumnType target,
+                      InternalName *name, 
+                      const TransformState *transform = NULL, const Lens *lens = NULL);
+
+  BLOCKING NodePath generate_vis_points() const;
+
+  enum MeshFace {
+    MF_front = 0x01,
+    MF_back  = 0x02,
+    MF_both  = 0x03,
+  };
+  BLOCKING NodePath generate_vis_mesh(MeshFace face = MF_front) const;
+
+private:
+  void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const;
+
+
+  class VisColumn {
+  public:
+    void add_data(const PfmVizzer &vizzer, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const;
+    void transform_point(LPoint2f &point) const;
+    void transform_point(LPoint3f &point) const;
+    void transform_vector(LVector3f &vec) const;
+
+  public:
+    ColumnType _source;
+    ColumnType _target;
+    PT(InternalName) _name;
+    CPT(TransformState) _transform;
+    CPT(Lens) _lens;
+  };
+  typedef pvector<VisColumn> VisColumns;
+
+  static void add_vis_column(VisColumns &vis_columns, 
+                             ColumnType source, ColumnType target,
+                             InternalName *name, 
+                             const TransformState *transform = NULL, const Lens *lens = NULL);
+  void build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const;
+  CPT(GeomVertexFormat) make_array_format(const VisColumns &vis_columns) const;
+
+private:
+  PfmFile &_pfm;
+
+  bool _vis_inverse;
+  PT(InternalName) _flat_texcoord_name;
+  bool _vis_2d;
+  const PNMImage *_vis_blend;
+
+  VisColumns _vis_columns;
+
+  friend class VisColumn;
+};
+
+#include "pfmVizzer.I"
+
+#endif
+

+ 0 - 12
panda/src/pnmimage/config_pnmimage.cxx

@@ -36,18 +36,6 @@ ConfigVariableBool pfm_reverse_dimensions
           "backwards, in the form height width instead of width height, "
           "on input.  Does not affect output, which is always written width height."));
 
-ConfigVariableInt pfm_vis_max_vertices
-("pfm-vis-max-vertices", 65535,
- PRC_DESC("Specifies the maximum number of vertex entries that may appear in "
-          "a single generated mesh.  If the mesh would require more than that, "
-          "the mesh is subdivided into smaller pieces."));
-
-ConfigVariableInt pfm_vis_max_indices
-("pfm-vis-max-indices", 1048576,
- PRC_DESC("Specifies the maximum number of vertex references that may appear in "
-          "a single generated mesh.  If the mesh would require more than that, "
-          "the mesh is subdivided into smaller pieces."));
-
 ////////////////////////////////////////////////////////////////////
 //     Function: init_libpnmimage
 //  Description: Initializes the library.  This must be called at

+ 0 - 2
panda/src/pnmimage/config_pnmimage.h

@@ -24,8 +24,6 @@ NotifyCategoryDecl(pnmimage, EXPCL_PANDA_PNMIMAGE, EXPTP_PANDA_PNMIMAGE);
 
 extern ConfigVariableBool pfm_force_littleendian;
 extern ConfigVariableBool pfm_reverse_dimensions;
-extern ConfigVariableInt pfm_vis_max_vertices;
-extern ConfigVariableInt pfm_vis_max_indices;
 
 extern EXPCL_PANDA_PNMIMAGE void init_libpnmimage();
 

+ 1 - 159
panda/src/pnmimage/pfmFile.I

@@ -442,19 +442,6 @@ get_no_data_value() const {
   return _no_data_value;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::xform
-//       Access: Published
-//  Description: Applies the indicated transform matrix to all points
-//               in-place.
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-xform(const TransformState *transform) {
-  if (!transform->is_identity()) {
-    xform(transform->get_mat());
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::xform
 //       Access: Published
@@ -465,6 +452,7 @@ INLINE void PfmFile::
 xform(const LMatrix4d &transform) {
   xform(LCAST(PN_float32, transform));
 }
+
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::compute_planar_bounds
 //       Access: Published
@@ -489,152 +477,6 @@ compute_planar_bounds(const LPoint2d &center, PN_float32 point_dist, PN_float32
   return compute_planar_bounds(LCAST(PN_float32, center), point_dist, sample_radius, points_only);
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::set_vis_inverse
-//       Access: Published
-//  Description: Sets the vis_inverse flag.  When this flag is true,
-//               vis meshes and point clouds are generated with the
-//               3-d depth value in the texture coordinates, and the
-//               2-d index value in the vertex position.  When it is
-//               false, meshes are generated normally, with the 3-d
-//               depth value in the vertex position and the 2-d index
-//               value in the texture coordinates.
-//
-//               This may be used in lieu of the lower-level
-//               add_vis_column().
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-set_vis_inverse(bool vis_inverse) {
-  _vis_inverse = vis_inverse;
-  clear_vis_columns();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::get_vis_inverse
-//       Access: Published
-//  Description: Returns the vis_inverse flag.  See set_vis_inverse().
-////////////////////////////////////////////////////////////////////
-INLINE bool PfmFile::
-get_vis_inverse() const {
-  return _vis_inverse;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::set_flat_texcoord_name
-//       Access: Published
-//  Description: If the flat_texcoord_name is specified, it is the
-//               name of an additional vertex column that will be
-//               created for the "flat" texture coordinates, i.e. the
-//               original 0..1 values that correspond to the 2-D index
-//               position of each point in the original pfm file.
-//
-//               These are the same values that will be assigned to
-//               the default texture coordinates if the vis_inverse
-//               flag is *not* true.
-//
-//               This may be used in lieu of the lower-level
-//               add_vis_column().
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-set_flat_texcoord_name(InternalName *flat_texcoord_name) {
-  _flat_texcoord_name = flat_texcoord_name;
-  clear_vis_columns();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::clear_flat_texcoord_name
-//       Access: Published
-//  Description: Resets the flat_texcoord_name to empty, so that
-//               additional texture coordinates are not created.
-//
-//               This may be used in lieu of the lower-level
-//               add_vis_column().
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-clear_flat_texcoord_name() {
-  _flat_texcoord_name = NULL;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::get_flat_texcoord_name
-//       Access: Published
-//  Description: Returns the flat_texcoord_name.  See set_flat_texcoord_name().
-////////////////////////////////////////////////////////////////////
-INLINE InternalName *PfmFile::
-get_flat_texcoord_name() const {
-  return _flat_texcoord_name;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::set_vis_2d
-//       Access: Published
-//  Description: Sets the vis_2d flag.  When this flag is true,
-//               only the first two (x, y) value of each depth point
-//               is considered meaningful; the z component is ignored.
-//               This is only relevant for generating visualizations.
-//
-//               This may be used in lieu of the lower-level
-//               add_vis_column().
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-set_vis_2d(bool vis_2d) {
-  _vis_2d = vis_2d;
-  clear_vis_columns();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::get_vis_2d
-//       Access: Published
-//  Description: Returns the vis_2d flag.  See set_vis_2d().
-////////////////////////////////////////////////////////////////////
-INLINE bool PfmFile::
-get_vis_2d() const {
-  return _vis_2d;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::set_vis_blend
-//       Access: Published
-//  Description: Specifies a blending map--a grayscale image--that
-//               will be applied to the vertex color during
-//               generate_vis_mesh() and generate_vis_points().  The
-//               image size must exactly match the mesh size of the
-//               PfmFile.
-//
-//               Ownership of the pointer is not kept by the PfmFile;
-//               it is your responsibility to ensure it does not
-//               destruct during the lifetime of the PfmFile (or at
-//               least not before your subsequent call to
-//               generate_vis_mesh()).
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-set_vis_blend(const PNMImage *vis_blend) {
-  _vis_blend = vis_blend;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::set_vis_blend
-//       Access: Published
-//  Description: Removes the blending map set by a prior call to
-//               set_vis_blend().
-////////////////////////////////////////////////////////////////////
-INLINE void PfmFile::
-clear_vis_blend() {
-  _vis_blend = NULL;
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::get_vis_blend
-//       Access: Published
-//  Description: Returns the blending map set by the most recent call
-//               to set_vis_blend(), or NULL if there is no blending
-//               map in effect.
-////////////////////////////////////////////////////////////////////
-INLINE const PNMImage *PfmFile::
-get_vis_blend() const {
-  return _vis_blend;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::get_table
 //       Access: Public

+ 1 - 720
panda/src/pnmimage/pfmFile.cxx

@@ -19,18 +19,10 @@
 #include "littleEndian.h"
 #include "bigEndian.h"
 #include "cmath.h"
-#include "geomNode.h"
-#include "geom.h"
-#include "geomVertexData.h"
-#include "geomVertexFormat.h"
-#include "geomPoints.h"
-#include "geomTriangles.h"
-#include "geomVertexWriter.h"
 #include "pnmImage.h"
 #include "pnmReader.h"
 #include "pnmWriter.h"
 #include "string_utils.h"
-#include "lens.h"
 #include "look_at.h"
 
 ////////////////////////////////////////////////////////////////////
@@ -43,9 +35,6 @@ PfmFile() {
   _has_no_data_value = false;
   _no_data_value = LPoint4f::zero();
   _has_point = has_point_noop;
-  _vis_inverse = false;
-  _vis_2d = false;
-  _vis_blend = NULL;
   clear();
 }
 
@@ -61,10 +50,7 @@ PfmFile(const PfmFile &copy) :
   _scale(copy._scale),
   _has_no_data_value(copy._has_no_data_value),
   _no_data_value(copy._no_data_value),
-  _has_point(copy._has_point),
-  _vis_inverse(copy._vis_inverse),
-  _vis_2d(copy._vis_2d),
-  _vis_blend(copy._vis_blend)
+  _has_point(copy._has_point)
 {
 }
 
@@ -81,9 +67,6 @@ operator = (const PfmFile &copy) {
   _has_no_data_value = copy._has_no_data_value;
   _no_data_value = copy._no_data_value;
   _has_point = copy._has_point;
-  _vis_inverse = copy._vis_inverse;
-  _vis_2d = copy._vis_2d;
-  _vis_blend = copy._vis_blend;
 }
 
 ////////////////////////////////////////////////////////////////////
@@ -97,7 +80,6 @@ clear() {
   _y_size = 0;
   _scale = 1.0;
   _num_channels = 3;
-  _vis_blend = NULL;
   _table.clear();
   clear_no_data_value();
 }
@@ -114,7 +96,6 @@ clear(int x_size, int y_size, int num_channels) {
   _y_size = y_size;
   _scale = 1.0;
   _num_channels = num_channels;
-  _vis_blend = NULL;
 
   _table.clear();
   int size = _x_size * _y_size * _num_channels;
@@ -948,112 +929,6 @@ xform(const LMatrix4f &transform) {
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::project
-//       Access: Published
-//  Description: Adjusts each (x, y, z) point of the Pfm file by
-//               projecting it through the indicated lens, converting
-//               each point to a (u, v, w) texture coordinate.  The
-//               resulting file can be generated to a mesh (with
-//               set_vis_inverse(true) and generate_vis_mesh())
-//               that will apply the lens distortion to an arbitrary
-//               texture image.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-project(const Lens *lens) {
-  nassertv(is_valid());
-
-  static LMatrix4f to_uv(0.5f, 0.0f, 0.0f, 0.0f,
-                         0.0f, 0.5f, 0.0f, 0.0f, 
-                         0.0f, 0.0f, 0.5f, 0.0f, 
-                         0.5f, 0.5f, 0.5f, 1.0f);
-  
-  for (int yi = 0; yi < _y_size; ++yi) {
-    for (int xi = 0; xi < _x_size; ++xi) {
-      if (!has_point(xi, yi)) {
-        continue;
-      }
-      LPoint3f &p = modify_point(xi, yi);
-
-      LPoint3 film;
-      lens->project(LCAST(PN_stdfloat, p), film);
-      p = to_uv.xform_point(LCAST(PN_float32, film));
-    }
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::extrude
-//       Access: Published
-//  Description: Converts each (u, v, depth) point of the Pfm file to
-//               an (x, y, z) point, by reversing project().  If the
-//               original file is only a 1-d file, assumes that it is
-//               a depth map with implicit (u, v) coordinates.
-//
-//               This method is only valid for a linear lens (e.g. a
-//               PerspectiveLens or OrthographicLens).  Non-linear
-//               lenses don't necessarily compute a sensible depth
-//               coordinate.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-extrude(const Lens *lens) {
-  nassertv(is_valid());
-  nassertv(lens->is_linear());
-
-  static LMatrix4 from_uv(2.0, 0.0, 0.0, 0.0,
-                          0.0, 2.0, 0.0, 0.0,
-                          0.0, 0.0, 2.0, 0.0,
-                          -1.0, -1.0, -1.0, 1.0);
-  const LMatrix4 &proj_mat_inv = lens->get_projection_mat_inv();
-
-  PfmFile result;
-  result.clear(_x_size, _y_size, 3);
-  result.set_zero_special(true);
-
-  if (_num_channels == 1) {
-    // Create an implicit UV coordinate for each point.
-    LPoint2 uv_scale(1.0, 1.0);
-    if (_x_size > 1) {
-      uv_scale[0] = 1.0 / PN_stdfloat(_x_size - 1);
-    }
-    if (_y_size > 1) {
-      uv_scale[1] = 1.0 / PN_stdfloat(_y_size - 1);
-    }
-    for (int yi = 0; yi < _y_size; ++yi) {
-      for (int xi = 0; xi < _x_size; ++xi) {
-        if (!has_point(xi, yi)) {
-          continue;
-        }
-        LPoint3 p;
-        p.set((PN_stdfloat)xi * uv_scale[0],
-              (PN_stdfloat)yi * uv_scale[1],
-              (PN_stdfloat)get_point1(xi, yi));
-        
-        from_uv.xform_point_in_place(p);
-        proj_mat_inv.xform_point_general_in_place(p);
-        result.set_point(xi, yi, p);
-      }
-    }
-  } else {
-    // Use the existing UV coordinate for each point.
-    for (int yi = 0; yi < _y_size; ++yi) {
-      for (int xi = 0; xi < _x_size; ++xi) {
-        if (!has_point(xi, yi)) {
-          continue;
-        }
-        LPoint3 p;
-        p = LCAST(PN_stdfloat, get_point(xi, yi));
-        
-        from_uv.xform_point_in_place(p);
-        proj_mat_inv.xform_point_general_in_place(p);
-        result.set_point(xi, yi, p);
-      }
-    }
-  }
-
-  (*this) = result;
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::forward_distort
 //       Access: Published
@@ -1490,163 +1365,6 @@ compute_sample_point(LPoint3f &result,
   }
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::clear_vis_columns
-//       Access: Published
-//  Description: Removes all of the previously-added vis columns in
-//               preparation for building a new list.  See
-//               add_vis_column().
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-clear_vis_columns() {
-  _vis_columns.clear();
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::add_vis_column
-//       Access: Published
-//  Description: Adds a new vis column specification to the list of
-//               vertex data columns that will be generated at the
-//               next call to generate_vis_points() or
-//               generate_vis_mesh().  This advanced interface
-//               supercedes the higher-level set_vis_inverse(),
-//               set_flat_texcoord_name(), and set_vis_2d().
-//
-//               If you use this advanced interface, you must specify
-//               explicitly the complete list of data columns to be
-//               created in the resulting GeomVertexData, by calling
-//               add_vis_column() each time.  For each column, you
-//               specify the source of the column in the PFMFile, the
-//               target column and name in the GeomVertexData, and an
-//               optional transform matrix and/or lens to transform
-//               and project the point before generating it.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-add_vis_column(ColumnType source, ColumnType target,
-               InternalName *name, const TransformState *transform,
-               const Lens *lens) {
-  add_vis_column(_vis_columns, source, target, name, transform, lens);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::generate_vis_points
-//       Access: Published
-//  Description: Creates a point cloud with the points of the pfm as
-//               3-d coordinates in space, and texture coordinates
-//               ranging from 0 .. 1 based on the position within the
-//               pfm grid.
-////////////////////////////////////////////////////////////////////
-NodePath PfmFile::
-generate_vis_points() const {
-  nassertr(is_valid(), NodePath());
-
-  CPT(GeomVertexFormat) format;
-  if (_vis_inverse) {
-    if (_vis_2d) {
-      format = GeomVertexFormat::get_v3t2();
-    } else {
-      // We need a 3-d texture coordinate if we're inverting the vis
-      // and it's 3-d.
-      GeomVertexArrayFormat *v3t3 = new GeomVertexArrayFormat
-        (InternalName::get_vertex(), 3, 
-         Geom::NT_stdfloat, Geom::C_point,
-         InternalName::get_texcoord(), 3, 
-         Geom::NT_stdfloat, Geom::C_texcoord);
-      format = GeomVertexFormat::register_format(v3t3);
-    }
-  } else {
-    format = GeomVertexFormat::get_v3t2();
-  }
-
-  PT(GeomVertexData) vdata = new GeomVertexData
-    ("points", format, Geom::UH_static);
-  vdata->set_num_rows(_x_size * _y_size);
-  GeomVertexWriter vertex(vdata, InternalName::get_vertex());
-  GeomVertexWriter texcoord(vdata, InternalName::get_texcoord());
-
-  LPoint2f uv_scale(1.0, 1.0);
-  if (_x_size > 1) {
-    uv_scale[0] = 1.0f / PN_float32(_x_size - 1);
-  }
-  if (_y_size > 1) {
-    uv_scale[1] = 1.0f / PN_float32(_y_size - 1);
-  }
-
-  int num_points = 0;
-  for (int yi = 0; yi < _y_size; ++yi) {
-    for (int xi = 0; xi < _x_size; ++xi) {
-      if (!has_point(xi, yi)) {
-        continue;
-      }
-
-      const LPoint3f &point = get_point(xi, yi);
-      LPoint2f uv(PN_float32(xi) * uv_scale[0],
-                  PN_float32(yi) * uv_scale[1]);
-      if (_vis_inverse) {
-        vertex.add_data2f(uv);
-        texcoord.add_data3f(point);
-      } else if (_vis_2d) {
-        vertex.add_data2f(point[0], point[1]);
-        texcoord.add_data2f(uv);
-      } else {
-        vertex.add_data3f(point);
-        texcoord.add_data2f(uv);
-      }
-      ++num_points;
-    }
-  }
-  
-  PT(Geom) geom = new Geom(vdata);
-  PT(GeomPoints) points = new GeomPoints(Geom::UH_static);
-  points->add_next_vertices(num_points);
-  geom->add_primitive(points);
-  
-  PT(GeomNode) gnode = new GeomNode("");
-  gnode->add_geom(geom);
-  return NodePath(gnode);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::generate_vis_mesh
-//       Access: Published
-//  Description: Creates a triangle mesh with the points of the pfm as
-//               3-d coordinates in space, and texture coordinates
-//               ranging from 0 .. 1 based on the position within the
-//               pfm grid.
-////////////////////////////////////////////////////////////////////
-NodePath PfmFile::
-generate_vis_mesh(MeshFace face) const {
-  nassertr(is_valid(), NodePath());
-  nassertr(face != 0, NodePath());
-
-  if (_num_channels == 1 && _vis_columns.empty()) {
-    // If we're generating a default mesh from a one-channel pfm file,
-    // expand it to a three-channel pfm file to make the visualization
-    // useful.
-    PfmFile expanded;
-    expanded.clear_to_texcoords(_x_size, _y_size);
-    expanded.copy_channel(2, *this, 0);
-    return expanded.generate_vis_mesh(face);
-  }
-  
-  if (_x_size == 1 || _y_size == 1) {
-    // Can't generate a 1-d mesh, so generate points in this case.
-    return generate_vis_points();
-  }
-  
-  PT(GeomNode) gnode = new GeomNode("");
-
-  if (face & MF_front) {
-    make_vis_mesh_geom(gnode, false);
-  }
-
-  if (face & MF_back) {
-    make_vis_mesh_geom(gnode, true);
-  }
-
-  return NodePath(gnode);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::output
 //       Access: Published
@@ -1658,161 +1376,6 @@ output(ostream &out) const {
       << _num_channels << " channels.";
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::make_vis_mesh_geom
-//       Access: Private
-//  Description: Returns a triangle mesh for the pfm.  If inverted is
-//               true, the mesh is facing the opposite direction.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-make_vis_mesh_geom(GeomNode *gnode, bool inverted) const {
-  int num_x_cells = 1;
-  int num_y_cells = 1;
-
-  int x_size = _x_size;
-  int y_size = _y_size;
-
-  // This is the number of independent vertices we will require.
-  int num_vertices = x_size * y_size;
-  if (num_vertices == 0) {
-    // Trivial no-op.
-    return;
-  }
-
-  bool reverse_normals = inverted;
-  bool reverse_faces = inverted;
-  if (!is_right_handed(get_default_coordinate_system())) {
-    reverse_faces = !reverse_faces;
-  }
-
-  // This is the max number of vertex indices we might add to the
-  // GeomTriangles.  (We might actually add fewer than this due to
-  // omitting the occasional missing data point.)
-  int max_indices = (x_size - 1) * (y_size - 1) * 6;
-
-  while (num_vertices > pfm_vis_max_vertices || max_indices > pfm_vis_max_indices) {
-    // Too many vertices in one mesh.  Subdivide the mesh into smaller
-    // pieces.
-    if (num_x_cells > num_y_cells) {
-      ++num_y_cells;
-    } else {
-      ++num_x_cells;
-    }
-
-    x_size = (_x_size + num_x_cells - 1) / num_x_cells + 1;
-    y_size = (_y_size + num_y_cells - 1) / num_y_cells + 1;
-
-    num_vertices = x_size * y_size;
-    max_indices = (x_size - 1) * (y_size - 1) * 6;
-  }
-
-  // OK, now we know how many cells we need.
-  if (pnmimage_cat.is_debug()) {
-    pnmimage_cat.debug()
-      << "Generating mesh with " << num_x_cells << " x " << num_y_cells
-      << " pieces.\n";
-  }
-
-  VisColumns vis_columns = _vis_columns;
-  if (vis_columns.empty()) {
-    build_auto_vis_columns(vis_columns, true);
-  }
-
-  CPT(GeomVertexFormat) format = make_array_format(vis_columns);
-
-  for (int yci = 0; yci < num_y_cells; ++yci) {
-    int y_begin = (yci * _y_size) / num_y_cells;
-    int y_end = ((yci + 1) * _y_size) / num_y_cells;
-
-    // Include the first vertex from the next strip in this strip's
-    // vertices, so we are connected.
-    y_end = min(y_end + 1, _y_size);
-
-    y_size = y_end - y_begin;
-    if (y_size == 0) {
-      continue;
-    }
-
-    for (int xci = 0; xci < num_x_cells; ++xci) {
-      int x_begin = (xci * _x_size) / num_x_cells;
-      int x_end = ((xci + 1) * _x_size) / num_x_cells;
-      x_end = min(x_end + 1, _x_size);
-      x_size = x_end - x_begin;
-      if (x_size == 0) {
-        continue;
-      }
-
-      num_vertices = x_size * y_size;
-      max_indices = (x_size - 1) * (y_size - 1) * 6;
-
-      ostringstream mesh_name;
-      mesh_name << "mesh_" << xci << "_" << yci;
-      PT(GeomVertexData) vdata = new GeomVertexData
-        (mesh_name.str(), format, Geom::UH_static);
-
-      vdata->set_num_rows(num_vertices);
-
-      // Fill in all of the vertices.
-      for (VisColumns::const_iterator vci = vis_columns.begin();
-           vci != vis_columns.end();
-           ++vci) {
-        const VisColumn &column = *vci;
-        GeomVertexWriter vwriter(vdata, column._name);
-        vwriter.set_row(0);
-
-        for (int yi = y_begin; yi < y_end; ++yi) {
-          for (int xi = x_begin; xi < x_end; ++xi) {
-            column.add_data(*this, vwriter, xi, yi, reverse_normals);
-          }
-        }
-      }
-  
-      PT(Geom) geom = new Geom(vdata);
-      PT(GeomTriangles) tris = new GeomTriangles(Geom::UH_static);
-
-      tris->reserve_num_vertices(max_indices);
-
-      for (int yi = y_begin; yi < y_end - 1; ++yi) {
-        for (int xi = x_begin; xi < x_end - 1; ++xi) {
-
-          if (_has_no_data_value) {
-            if (!has_point(xi, yi) ||
-                !has_point(xi, yi + 1) ||
-                !has_point(xi + 1, yi + 1) ||
-                !has_point(xi + 1, yi)) {
-              continue;
-            }
-          }
-
-          int xi0 = xi - x_begin;
-          int yi0 = yi - y_begin;
-
-          int vi0 = ((xi0) + (yi0) * x_size);
-          int vi1 = ((xi0) + (yi0 + 1) * x_size);
-          int vi2 = ((xi0 + 1) + (yi0 + 1) * x_size);
-          int vi3 = ((xi0 + 1) + (yi0) * x_size);
-          
-          if (reverse_faces) {
-            tris->add_vertices(vi2, vi0, vi1);
-            tris->close_primitive();
-            
-            tris->add_vertices(vi3, vi0, vi2);
-            tris->close_primitive();
-          } else {
-            tris->add_vertices(vi2, vi1, vi0);
-            tris->close_primitive();
-            
-            tris->add_vertices(vi3, vi2, vi0);
-            tris->close_primitive();
-          }
-        }
-      }
-      geom->add_primitive(tris);
-      gnode->add_geom(geom);
-    }
-  }
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::box_filter_region
 //       Access: Private
@@ -2089,138 +1652,6 @@ box_filter_point(LPoint4f &result, PN_float32 &coverage,
   coverage += contrib;
 }
 
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::add_vis_column
-//       Access: Private, Static
-//  Description: The private implementation of the public
-//               add_vis_column(), this adds the column to the
-//               indicated specific vector.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-add_vis_column(VisColumns &vis_columns, ColumnType source, ColumnType target,
-               InternalName *name, const TransformState *transform,
-               const Lens *lens) {
-  VisColumn column;
-  column._source = source;
-  column._target = target;
-  column._name = name;
-  column._transform = transform;
-  if (transform == NULL) {
-    column._transform = TransformState::make_identity();
-  }
-  column._lens = lens;
-  vis_columns.push_back(column);
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::build_auto_vis_columns
-//       Access: Private
-//  Description: This function is called internally to construct the
-//               list of vis_columns automatically from the high-level
-//               interfaces such as set_vis_inverse(),
-//               set_flat_texcoord_name(), and set_vis_2d().  It's not
-//               called if the list has been build explicitly.
-////////////////////////////////////////////////////////////////////
-void PfmFile::
-build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const {
-  vis_columns.clear();
-
-  if (_vis_2d) {
-    // No normals needed if we're just generating a 2-d mesh.
-    if (_vis_inverse) {
-      add_vis_column(vis_columns, CT_texcoord2, CT_vertex2, InternalName::get_vertex());
-      add_vis_column(vis_columns, CT_vertex2, CT_texcoord2, InternalName::get_texcoord());
-    } else {
-      add_vis_column(vis_columns, CT_vertex2, CT_vertex2, InternalName::get_vertex());
-      add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
-    }
-
-  } else {
-    if (_vis_inverse) {
-      // We need a 3-d texture coordinate if we're inverting the vis
-      // and it's 3-d.  But we still don't need normals in that case.
-      add_vis_column(vis_columns, CT_texcoord3, CT_vertex3, InternalName::get_vertex());
-      add_vis_column(vis_columns, CT_vertex3, CT_texcoord3, InternalName::get_texcoord());
-    } else {
-      // Otherwise, we only need a 2-d texture coordinate, and we do
-      // want normals.
-      add_vis_column(vis_columns, CT_vertex3, CT_vertex3, InternalName::get_vertex());
-      add_vis_column(vis_columns, CT_normal3, CT_normal3, InternalName::get_normal());
-      add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, InternalName::get_texcoord());
-    }
-  }
-
-  if (_flat_texcoord_name != (InternalName *)NULL) {
-    // We need an additional texcoord column for the flat texcoords.
-    add_vis_column(vis_columns, CT_texcoord2, CT_texcoord2, _flat_texcoord_name);
-  }
-
-  if (_vis_blend != (PNMImage *)NULL) {
-    // The blend map, if specified, also gets applied to the vertices.
-    add_vis_column(vis_columns, CT_blend1, CT_blend1, InternalName::get_color());
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::make_array_format
-//       Access: Private
-//  Description: Constructs a GeomVertexFormat that corresponds to the
-//               vis_columns list.
-////////////////////////////////////////////////////////////////////
-CPT(GeomVertexFormat) PfmFile::
-make_array_format(const VisColumns &vis_columns) const {
-  PT(GeomVertexArrayFormat) array_format = new GeomVertexArrayFormat;
-
-  for (VisColumns::const_iterator vci = vis_columns.begin();
-       vci != vis_columns.end();
-       ++vci) {
-    const VisColumn &column = *vci;
-    InternalName *name = column._name;
-
-    int num_components = 0;
-    GeomEnums::NumericType numeric_type = GeomEnums::NT_float32;
-    GeomEnums::Contents contents = GeomEnums::C_point;
-    switch (column._target) {
-    case CT_texcoord2:
-      num_components = 2;
-      numeric_type = GeomEnums::NT_float32;
-      contents = GeomEnums::C_texcoord;
-      break;
-
-    case CT_texcoord3:
-      num_components = 3;
-      numeric_type = GeomEnums::NT_float32;
-      contents = GeomEnums::C_texcoord;
-      break;
-
-    case CT_vertex1:
-    case CT_vertex2:
-    case CT_vertex3:
-      num_components = 3;
-      numeric_type = GeomEnums::NT_float32;
-      contents = GeomEnums::C_point;
-      break;
-
-    case CT_normal3:
-      num_components = 3;
-      numeric_type = GeomEnums::NT_float32;
-      contents = GeomEnums::C_vector;
-      break;
-
-    case CT_blend1:
-      num_components = 4;
-      numeric_type = GeomEnums::NT_uint8;
-      contents = GeomEnums::C_color;
-      break;
-    }
-    nassertr(num_components != 0, NULL);
-    
-    array_format->add_column(name, num_components, numeric_type, contents);
-  }
-
-  return GeomVertexFormat::register_format(array_format);
-}
-
 ////////////////////////////////////////////////////////////////////
 //     Function: PfmFile::fill_mini_grid
 //       Access: Private
@@ -2320,153 +1751,3 @@ has_point_chan4(const PfmFile *self, int x, int y) {
   }
   return false;
 }
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::VisColumn::add_data
-//       Access: Public
-//  Description: Adds the data for this column to the appropriate
-//               column of the GeomVertexWriter.
-////////////////////////////////////////////////////////////////////
-void PfmFile::VisColumn::
-add_data(const PfmFile &file, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const {
-  switch (_source) {
-  case CT_texcoord2:
-    { 
-      LPoint2f uv(PN_float32(xi) / PN_float32(file._x_size - 1),
-                  PN_float32(yi) / PN_float32(file._y_size - 1));
-      transform_point(uv);
-      vwriter.set_data2f(uv);
-    }
-    break;
-
-  case CT_texcoord3:
-    {
-      LPoint3f uv(PN_float32(xi) / PN_float32(file._x_size - 1),
-                  PN_float32(yi) / PN_float32(file._y_size - 1), 
-                  0.0f);
-      transform_point(uv);
-      vwriter.set_data3f(uv);
-    }
-    break;
-
-  case CT_vertex1:
-    {
-      PN_float32 p = file.get_point1(xi, yi);
-      LPoint2f point(p, 0.0);
-      transform_point(point);
-      vwriter.set_data2f(point);
-    }
-    break;
-
-  case CT_vertex2:
-    {
-      LPoint2f point = file.get_point2(xi, yi);
-      transform_point(point);
-      vwriter.set_data2f(point);
-    }
-    break;
-
-  case CT_vertex3:
-    {
-      LPoint3f point = file.get_point(xi, yi);
-      transform_point(point);
-      vwriter.set_data3f(point);
-    }
-    break;
-
-  case CT_normal3:
-    {
-      // Calculate the normal based on two neighboring vertices.
-      LPoint3f v[3];
-      v[0] = file.get_point(xi, yi);
-      if (xi + 1 < file._x_size) {
-        v[1] = file.get_point(xi + 1, yi);
-      } else {
-        v[1] = v[0];
-        v[0] = file.get_point(xi - 1, yi);
-      }
-                
-      if (yi + 1 < file._y_size) {
-        v[2] = file.get_point(xi, yi + 1);
-      } else {
-        v[2] = v[0];
-        v[0] = file.get_point(xi, yi - 1);
-      }
-                
-      LVector3f n = LVector3f::zero();
-      for (int i = 0; i < 3; ++i) {
-        const LPoint3f &v0 = v[i];
-        const LPoint3f &v1 = v[(i + 1) % 3];
-        n[0] += v0[1] * v1[2] - v0[2] * v1[1];
-        n[1] += v0[2] * v1[0] - v0[0] * v1[2];
-        n[2] += v0[0] * v1[1] - v0[1] * v1[0];
-      }
-      n.normalize();
-      nassertv(!n.is_nan());
-      if (reverse_normals) {
-        n = -n;
-      }
-      transform_vector(n);
-      vwriter.set_data3f(n);
-    }
-    break;
-
-  case CT_blend1:
-    {
-      const PNMImage *vis_blend = file.get_vis_blend();
-      if (vis_blend != NULL) {
-        double gray = vis_blend->get_gray(xi, yi);
-        vwriter.set_data3d(gray, gray, gray);
-      }
-    }
-    break;
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::VisColumn::transform_point
-//       Access: Public
-//  Description: Transforms the indicated point as specified by the
-//               VisColumn.
-////////////////////////////////////////////////////////////////////
-void PfmFile::VisColumn::
-transform_point(LPoint2f &point) const {
-  if (!_transform->is_identity()) {
-    LCAST(PN_float32, _transform->get_mat3()).xform_point_in_place(point);
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::VisColumn::transform_point
-//       Access: Public
-//  Description: Transforms the indicated point as specified by the
-//               VisColumn.
-////////////////////////////////////////////////////////////////////
-void PfmFile::VisColumn::
-transform_point(LPoint3f &point) const {
-  if (!_transform->is_identity()) {
-    LCAST(PN_float32, _transform->get_mat()).xform_point_in_place(point);
-  }
-  if (_lens != (Lens *)NULL) {
-    static LMatrix4f to_uv(0.5, 0.0, 0.0, 0.0,
-                           0.0, 0.5, 0.0, 0.0, 
-                           0.0, 0.0, 1.0, 0.0, 
-                           0.5, 0.5, 0.0, 1.0);
-    LPoint3 film;
-    _lens->project(LCAST(PN_stdfloat, point), film);
-    point = to_uv.xform_point(LCAST(PN_float32, film));
-  }
-}
-
-////////////////////////////////////////////////////////////////////
-//     Function: PfmFile::VisColumn::transform_vector
-//       Access: Public
-//  Description: Transforms the indicated vector as specified by the
-//               VisColumn.
-////////////////////////////////////////////////////////////////////
-void PfmFile::VisColumn::
-transform_vector(LVector3f &vec) const {
-  if (!_transform->is_identity()) {
-    LCAST(PN_float32, _transform->get_mat()).xform_vec_in_place(vec);
-  }
-}

+ 1 - 76
panda/src/pnmimage/pfmFile.h

@@ -18,17 +18,11 @@
 #include "pandabase.h"
 #include "pnmImageHeader.h"
 #include "luse.h"
-#include "nodePath.h"
 #include "boundingHexahedron.h"
-#include "internalName.h"
-#include "lens.h"
 
-class GeomNode;
-class Lens;
 class PNMImage;
 class PNMReader;
 class PNMWriter;
-class GeomVertexWriter;
 
 ////////////////////////////////////////////////////////////////////
 //       Class : PfmFile
@@ -98,11 +92,8 @@ PUBLISHED:
   BLOCKING void resize(int new_x_size, int new_y_size);
   BLOCKING void reverse_rows();
   BLOCKING void flip(bool flip_x, bool flip_y, bool transpose);
-  INLINE BLOCKING void xform(const TransformState *transform);
   BLOCKING void xform(const LMatrix4f &transform);
   INLINE BLOCKING void xform(const LMatrix4d &transform);
-  BLOCKING void project(const Lens *lens);
-  BLOCKING void extrude(const Lens *lens);
   BLOCKING void forward_distort(const PfmFile &dist);
   BLOCKING void reverse_distort(const PfmFile &dist);
   BLOCKING void merge(const PfmFile &other);
@@ -115,41 +106,6 @@ PUBLISHED:
   void compute_sample_point(LPoint3f &result,
                             PN_float32 x, PN_float32 y, PN_float32 sample_radius) const;
 
-  INLINE void set_vis_inverse(bool vis_inverse);
-  INLINE bool get_vis_inverse() const;
-  INLINE void set_flat_texcoord_name(InternalName *flat_texcoord_name);
-  INLINE void clear_flat_texcoord_name();
-  INLINE InternalName *get_flat_texcoord_name() const;
-  INLINE void set_vis_2d(bool vis_2d);
-  INLINE bool get_vis_2d() const;
-
-  INLINE void set_vis_blend(const PNMImage *vis_blend);
-  INLINE void clear_vis_blend();
-  INLINE const PNMImage *get_vis_blend() const;
-
-  enum ColumnType {
-    CT_texcoord2,
-    CT_texcoord3,
-    CT_vertex1,
-    CT_vertex2,
-    CT_vertex3,
-    CT_normal3,
-    CT_blend1,
-  };
-  void clear_vis_columns();
-  void add_vis_column(ColumnType source, ColumnType target,
-                      InternalName *name, 
-                      const TransformState *transform = NULL, const Lens *lens = NULL);
-
-  BLOCKING NodePath generate_vis_points() const;
-
-  enum MeshFace {
-    MF_front = 0x01,
-    MF_back  = 0x02,
-    MF_both  = 0x03,
-  };
-  BLOCKING NodePath generate_vis_mesh(MeshFace face = MF_front) const;
-
   void output(ostream &out) const;
 
 public:
@@ -157,8 +113,6 @@ public:
   INLINE void swap_table(pvector<PN_float32> &table);
 
 private:
-  void make_vis_mesh_geom(GeomNode *gnode, bool inverted) const;
-
   void box_filter_region(PN_float32 &result,
                          PN_float32 x0, PN_float32 y0, PN_float32 x1, PN_float32 y1) const;
   void box_filter_region(LPoint3f &result,
@@ -178,29 +132,6 @@ private:
   void box_filter_point(LPoint4f &result, PN_float32 &coverage,
                         int x, int y, PN_float32 x_contrib, PN_float32 y_contrib) const;
 
-  class VisColumn {
-  public:
-    void add_data(const PfmFile &file, GeomVertexWriter &vwriter, int xi, int yi, bool reverse_normals) const;
-    void transform_point(LPoint2f &point) const;
-    void transform_point(LPoint3f &point) const;
-    void transform_vector(LVector3f &vec) const;
-
-  public:
-    ColumnType _source;
-    ColumnType _target;
-    PT(InternalName) _name;
-    CPT(TransformState) _transform;
-    CPT(Lens) _lens;
-  };
-  typedef pvector<VisColumn> VisColumns;
-
-  static void add_vis_column(VisColumns &vis_columns, 
-                             ColumnType source, ColumnType target,
-                             InternalName *name, 
-                             const TransformState *transform = NULL, const Lens *lens = NULL);
-  void build_auto_vis_columns(VisColumns &vis_columns, bool for_points) const;
-  CPT(GeomVertexFormat) make_array_format(const VisColumns &vis_columns) const;
-
   class MiniGridCell {
   public:
     MiniGridCell() : _sxi(-1), _syi(-1), _dist(-1) { }
@@ -225,17 +156,11 @@ private:
 
   bool _has_no_data_value;
   LPoint4f _no_data_value;
-  bool _vis_inverse;
-  PT(InternalName) _flat_texcoord_name;
-  bool _vis_2d;
-  const PNMImage *_vis_blend;
-
-  VisColumns _vis_columns;
 
   typedef bool HasPointFunc(const PfmFile *file, int x, int y);
   HasPointFunc *_has_point;
 
-  friend class VisColumn;
+  friend class PfmVizzer;
 };
 
 #include "pfmFile.I"