Browse Source

dxf reader

David Rose 21 years ago
parent
commit
63d2fad3dd

+ 17 - 0
pandatool/src/dxf/Sources.pp

@@ -0,0 +1,17 @@
+#begin ss_lib_target
+  #define TARGET dxf
+  #define LOCAL_LIBS pandatoolbase
+
+  #define OTHER_LIBS \
+    mathutil:c linmath:c panda:m \
+    dtoolbase:c dtool:m
+  #define UNIX_SYS_LIBS m
+  
+  #define SOURCES \
+    dxfFile.cxx dxfFile.h dxfLayer.h dxfLayerMap.cxx dxfLayerMap.h \
+    dxfVertex.cxx dxfVertex.h dxfVertexMap.cxx dxfVertexMap.h
+
+  #define INSTALL_HEADERS \
+    dxfFile.h dxfLayer.h dxfLayerMap.h dxfVertex.h dxfVertexMap.h
+
+#end ss_lib_target

+ 979 - 0
pandatool/src/dxf/dxfFile.cxx

@@ -0,0 +1,979 @@
+// Filename: dxfFile.cxx
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxfFile.h"
+#include "string_utils.h"
+
+DXFFile::Color DXFFile::_colors[DXF_num_colors] = {
+  { 1, 1, 1 },        // Color 0 is not used.
+  { 1, 0, 0 },        // Color 1 = Red
+  { 1, 1, 0 },        // Color 2 = Yellow
+  { 0, 1, 0 },        // Color 3 = Green
+  { 0, 1, 1 },        // Color 4 = Cyan
+  { 0, 0, 1 },        // Color 5 = Blue
+  { 1, 0, 1 },        // Color 6 = Magenta
+  { 1, 1, 1 },        // Color 7 = Black/White
+  { 0.3, 0.3, 0.3 },  // Color 8 = Gray
+  { 0.7, 0.7, 0.7 },  // Color 9 = Gray
+  { 1, 0, 0 },        // Remaining colors are from the fancy palette.
+  { 1, 0.5, 0.5 },
+  { 0.65, 0, 0 },
+  { 0.65, 0.325, 0.325 },
+  { 0.5, 0, 0 },
+  { 0.5, 0.25, 0.25 },
+  { 0.3, 0, 0 },
+  { 0.3, 0.15, 0.15 },
+  { 0.15, 0, 0 },
+  { 0.15, 0.075, 0.075 },
+  { 1, 0.25, 0 },
+  { 1, 0.625, 0.5 },
+  { 0.65, 0.1625, 0 },
+  { 0.65, 0.4063, 0.325 },
+  { 0.5, 0.125, 0 },
+  { 0.5, 0.3125, 0.25 },
+  { 0.3, 0.075, 0 },
+  { 0.3, 0.1875, 0.15 },
+  { 0.15, 0.0375, 0 },
+  { 0.15, 0.0938, 0.075 },
+  { 1, 0.5, 0 },
+  { 1, 0.75, 0.5 },
+  { 0.65, 0.325, 0 },
+  { 0.65, 0.4875, 0.325 },
+  { 0.5, 0.25, 0 },
+  { 0.5, 0.375, 0.25 },
+  { 0.3, 0.15, 0 },
+  { 0.3, 0.225, 0.15 },
+  { 0.15, 0.075, 0 },
+  { 0.15, 0.1125, 0.075 },
+  { 1, 0.75, 0 },
+  { 1, 0.875, 0.5 },
+  { 0.65, 0.4875, 0 },
+  { 0.65, 0.5688, 0.325 },
+  { 0.5, 0.375, 0 },
+  { 0.5, 0.4375, 0.25 },
+  { 0.3, 0.225, 0 },
+  { 0.3, 0.2625, 0.15 },
+  { 0.15, 0.1125, 0 },
+  { 0.15, 0.1313, 0.075 },
+  { 1, 1, 0 },
+  { 1, 1, 0.5 },
+  { 0.65, 0.65, 0 },
+  { 0.65, 0.65, 0.325 },
+  { 0.5, 0.5, 0 },
+  { 0.5, 0.5, 0.25 },
+  { 0.3, 0.3, 0 },
+  { 0.3, 0.3, 0.15 },
+  { 0.15, 0.15, 0 },
+  { 0.15, 0.15, 0.075 },
+  { 0.75, 1, 0 },
+  { 0.875, 1, 0.5 },
+  { 0.4875, 0.65, 0 },
+  { 0.5688, 0.65, 0.325 },
+  { 0.375, 0.5, 0 },
+  { 0.4375, 0.5, 0.25 },
+  { 0.225, 0.3, 0 },
+  { 0.2625, 0.3, 0.15 },
+  { 0.1125, 0.15, 0 },
+  { 0.1313, 0.15, 0.075 },
+  { 0.5, 1, 0 },
+  { 0.75, 1, 0.5 },
+  { 0.325, 0.65, 0 },
+  { 0.4875, 0.65, 0.325 },
+  { 0.25, 0.5, 0 },
+  { 0.375, 0.5, 0.25 },
+  { 0.15, 0.3, 0 },
+  { 0.225, 0.3, 0.15 },
+  { 0.075, 0.15, 0 },
+  { 0.1125, 0.15, 0.075 },
+  { 0.25, 1, 0 },
+  { 0.625, 1, 0.5 },
+  { 0.1625, 0.65, 0 },
+  { 0.4063, 0.65, 0.325 },
+  { 0.125, 0.5, 0 },
+  { 0.3125, 0.5, 0.25 },
+  { 0.075, 0.3, 0 },
+  { 0.1875, 0.3, 0.15 },
+  { 0.0375, 0.15, 0 },
+  { 0.0938, 0.15, 0.075 },
+  { 0, 1, 0 },
+  { 0.5, 1, 0.5 },
+  { 0, 0.65, 0 },
+  { 0.325, 0.65, 0.325 },
+  { 0, 0.5, 0 },
+  { 0.25, 0.5, 0.25 },
+  { 0, 0.3, 0 },
+  { 0.15, 0.3, 0.15 },
+  { 0, 0.15, 0 },
+  { 0.075, 0.15, 0.075 },
+  { 0, 1, 0.25 },
+  { 0.5, 1, 0.625 },
+  { 0, 0.65, 0.1625 },
+  { 0.325, 0.65, 0.4063 },
+  { 0, 0.5, 0.125 },
+  { 0.25, 0.5, 0.3125 },
+  { 0, 0.3, 0.075 },
+  { 0.15, 0.3, 0.1875 },
+  { 0, 0.15, 0.0375 },
+  { 0.075, 0.15, 0.0938 },
+  { 0, 1, 0.5 },
+  { 0.5, 1, 0.75 },
+  { 0, 0.65, 0.325 },
+  { 0.325, 0.65, 0.4875 },
+  { 0, 0.5, 0.25 },
+  { 0.25, 0.5, 0.375 },
+  { 0, 0.3, 0.15 },
+  { 0.15, 0.3, 0.225 },
+  { 0, 0.15, 0.075 },
+  { 0.075, 0.15, 0.1125 },
+  { 0, 1, 0.75 },
+  { 0.5, 1, 0.875 },
+  { 0, 0.65, 0.4875 },
+  { 0.325, 0.65, 0.5688 },
+  { 0, 0.5, 0.375 },
+  { 0.25, 0.5, 0.4375 },
+  { 0, 0.3, 0.225 },
+  { 0.15, 0.3, 0.2625 },
+  { 0, 0.15, 0.1125 },
+  { 0.075, 0.15, 0.1313 },
+  { 0, 1, 1 },
+  { 0.5, 1, 1 },
+  { 0, 0.65, 0.65 },
+  { 0.325, 0.65, 0.65 },
+  { 0, 0.5, 0.5 },
+  { 0.25, 0.5, 0.5 },
+  { 0, 0.3, 0.3 },
+  { 0.15, 0.3, 0.3 },
+  { 0, 0.15, 0.15 },
+  { 0.075, 0.15, 0.15 },
+  { 0, 0.75, 1 },
+  { 0.5, 0.875, 1 },
+  { 0, 0.4875, 0.65 },
+  { 0.325, 0.5688, 0.65 },
+  { 0, 0.375, 0.5 },
+  { 0.25, 0.4375, 0.5 },
+  { 0, 0.225, 0.3 },
+  { 0.15, 0.2625, 0.3 },
+  { 0, 0.1125, 0.15 },
+  { 0.075, 0.1313, 0.15 },
+  { 0, 0.5, 1 },
+  { 0.5, 0.75, 1 },
+  { 0, 0.325, 0.65 },
+  { 0.325, 0.4875, 0.65 },
+  { 0, 0.25, 0.5 },
+  { 0.25, 0.375, 0.5 },
+  { 0, 0.15, 0.3 },
+  { 0.15, 0.225, 0.3 },
+  { 0, 0.075, 0.15 },
+  { 0.075, 0.1125, 0.15 },
+  { 0, 0.25, 1 },
+  { 0.5, 0.625, 1 },
+  { 0, 0.1625, 0.65 },
+  { 0.325, 0.4063, 0.65 },
+  { 0, 0.125, 0.5 },
+  { 0.25, 0.3125, 0.5 },
+  { 0, 0.075, 0.3 },
+  { 0.15, 0.1875, 0.3 },
+  { 0, 0.0375, 0.15 },
+  { 0.075, 0.0938, 0.15 },
+  { 0, 0, 1 },
+  { 0.5, 0.5, 1 },
+  { 0, 0, 0.65 },
+  { 0.325, 0.325, 0.65 },
+  { 0, 0, 0.5 },
+  { 0.25, 0.25, 0.5 },
+  { 0, 0, 0.3 },
+  { 0.15, 0.15, 0.3 },
+  { 0, 0, 0.15 },
+  { 0.075, 0.075, 0.15 },
+  { 0.25, 0, 1 },
+  { 0.625, 0.5, 1 },
+  { 0.1625, 0, 0.65 },
+  { 0.4063, 0.325, 0.65 },
+  { 0.125, 0, 0.5 },
+  { 0.3125, 0.25, 0.5 },
+  { 0.075, 0, 0.3 },
+  { 0.1875, 0.15, 0.3 },
+  { 0.0375, 0, 0.15 },
+  { 0.0938, 0.075, 0.15 },
+  { 0.5, 0, 1 },
+  { 0.75, 0.5, 1 },
+  { 0.325, 0, 0.65 },
+  { 0.4875, 0.325, 0.65 },
+  { 0.25, 0, 0.5 },
+  { 0.375, 0.25, 0.5 },
+  { 0.15, 0, 0.3 },
+  { 0.225, 0.15, 0.3 },
+  { 0.075, 0, 0.15 },
+  { 0.1125, 0.075, 0.15 },
+  { 0.75, 0, 1 },
+  { 0.875, 0.5, 1 },
+  { 0.4875, 0, 0.65 },
+  { 0.5688, 0.325, 0.65 },
+  { 0.375, 0, 0.5 },
+  { 0.4375, 0.25, 0.5 },
+  { 0.225, 0, 0.3 },
+  { 0.2625, 0.15, 0.3 },
+  { 0.1125, 0, 0.15 },
+  { 0.1313, 0.075, 0.15 },
+  { 1, 0, 1 },
+  { 1, 0.5, 1 },
+  { 0.65, 0, 0.65 },
+  { 0.65, 0.325, 0.65 },
+  { 0.5, 0, 0.5 },
+  { 0.5, 0.25, 0.5 },
+  { 0.3, 0, 0.3 },
+  { 0.3, 0.15, 0.3 },
+  { 0.15, 0, 0.15 },
+  { 0.15, 0.075, 0.15 },
+  { 1, 0, 0.75 },
+  { 1, 0.5, 0.875 },
+  { 0.65, 0, 0.4875 },
+  { 0.65, 0.325, 0.5688 },
+  { 0.5, 0, 0.375 },
+  { 0.5, 0.25, 0.4375 },
+  { 0.3, 0, 0.225 },
+  { 0.3, 0.15, 0.2625 },
+  { 0.15, 0, 0.1125 },
+  { 0.15, 0.075, 0.1313 },
+  { 1, 0, 0.5 },
+  { 1, 0.5, 0.75 },
+  { 0.65, 0, 0.325 },
+  { 0.65, 0.325, 0.4875 },
+  { 0.5, 0, 0.25 },
+  { 0.5, 0.25, 0.375 },
+  { 0.3, 0, 0.15 },
+  { 0.3, 0.15, 0.225 },
+  { 0.15, 0, 0.075 },
+  { 0.15, 0.075, 0.1125 },
+  { 1, 0, 0.25 },
+  { 1, 0.5, 0.625 },
+  { 0.65, 0, 0.1625 },
+  { 0.65, 0.325, 0.4063 },
+  { 0.5, 0, 0.125 },
+  { 0.5, 0.25, 0.3125 },
+  { 0.3, 0, 0.075 },
+  { 0.3, 0.15, 0.1875 },
+  { 0.15, 0, 0.0375 },
+  { 0.15, 0.075, 0.0938 },
+  { 0.33, 0.33, 0.33 },
+  { 0.464, 0.464, 0.464 },
+  { 0.598, 0.598, 0.598 },
+  { 0.732, 0.732, 0.732 },
+  { 0.866, 0.866, 0.866 },
+  { 1, 1, 1 },
+};
+      
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXFFile::
+DXFFile() {
+  _layer = NULL;
+  reset_entity();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::Destructor
+//       Access: Public, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXFFile::
+~DXFFile() {
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::process
+//       Access: Public
+//  Description: Opens the indicated filename and reads it as a DXF
+//               file.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+process(Filename filename) {
+  filename.set_text();
+  filename.open_read(_in_file);
+  process(_in_file);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::process
+//       Access: Public
+//  Description: Reads the indicated stream as a DXF file.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+process(istream &in) {
+  _in = ∈
+  _state = ST_top;
+
+  begin_file();
+  while (_state != ST_done && _state != ST_error) {
+    if (get_group()) {
+      switch (_state) {
+      case ST_top:
+	state_top();
+	break;
+
+      case ST_section:
+	state_section();
+	break;
+
+      case ST_entity:
+	state_entity();
+	break;
+
+      case ST_verts:
+	state_verts();
+	break;
+
+      default:
+	break;
+      }
+    }
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::Begin File
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called whenever processing begins on the DXF file.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+begin_file() {
+}
+      
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::begin_section
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called whenever a new section in the DXF file is
+//               encountered.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+begin_section() {
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::done_vertex
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called whenever a vertex is read from the DXF file.
+//               This function has the default behavior of adding the
+//               vertex to the _verts list, so that when done_entity()
+//               is called later, it will have the complete list of
+//               vertices available to it.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+done_vertex() {
+  DXFVertex v;
+  v._p = _p;
+  _verts.push_back(v);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::done_entity
+//       Access: Public, Virtual
+//  Description: This is the primary hook for user code.  This
+//               function is called when an entity is read from the
+//               DXF file.  This may be something like a polygon,
+//               point, or a polygon mesh: any geometry.  It is up to
+//               the user code to override this function and do
+//               something interesting with each piece of geometry
+//               that is read.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+done_entity() {
+}
+      
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::end_section
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called as each section in the DXF file is finished.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+end_section() {
+}
+      
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::end_file
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called when the DXF processing is complete.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+end_file() {
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::Error
+//       Access: Public, Virtual
+//  Description: A hook for user code, if desired.  This function is
+//               called when some unexpected error occurs while
+//               reading the DXF file.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+error() {
+  nout << "Error!\n";
+}
+
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::find_color
+//       Access: Public, Static
+//  Description: Returns the index of the closest matching AutoCAD
+//               color to the indicated r, g, b.
+////////////////////////////////////////////////////////////////////
+int DXFFile::
+find_color(double r, double g, double b) {
+  double best_diff = 4.0;   // 4 is greater than our expected max, 3.
+  int best_index = 7;
+
+  for (int i = 0; i < 255; i++) {
+    double diff = ((r - _colors[i].r) * (r - _colors[i].r) +
+		   (g - _colors[i].g) * (g - _colors[i].g) +
+		   (b - _colors[i].b) * (b - _colors[i].b));
+    if (diff < best_diff) {
+      best_diff = diff;
+      best_index = i;
+    }
+  }
+
+  return best_index;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::get_color
+//       Access: Public
+//  Description: This is a convenience function to return the r,g,b
+//               color of the current entity (at the time of
+//               done_entity()).  It's based on the _color_index value
+//               that was read from the DXF file.
+////////////////////////////////////////////////////////////////////
+const DXFFile::Color &DXFFile::
+get_color() const {
+  if (_color_index >= 0 && _color_index <= 255) {
+    return _colors[_color_index];
+  }
+  return _colors[0];
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::ocs_2_wcs
+//       Access: Public
+//  Description: Assuming the current entity is a planar-based entity,
+//               for instance, a 2-d polygon (as opposed to a 3-d
+//               polygon), this converts the coordinates from the
+//               funny planar coordinate system to the world
+//               coordinates.  It converts the _p value of the entity,
+//               as well as all vertices in the _verts list.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+ocs_2_wcs() {
+  compute_ocs();
+
+  // Convert the entity's position.
+  _p = _p * _ocs2wcs;
+
+  // Maybe we have these coordinates too.
+  _q = _q * _ocs2wcs;
+  _r = _r * _ocs2wcs;
+  _s = _s * _ocs2wcs;
+
+  // If there are any vertices, convert them too.
+  DXFVertices::iterator vi;
+  for (vi = _verts.begin(); vi != _verts.end(); ++vi) {
+    (*vi)._p = (*vi)._p * _ocs2wcs;
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::compute_ocs
+//       Access: Protected
+//  Description: Computes the matrix used to convert from the planar
+//               coordinate system to world coordinates.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+compute_ocs() {
+  // A 2-d entity's vertices might be defined in an "Object Coordinate
+  // System" which has a funny definition.  Its Z axis is defined by
+  // _z, and its X and Y axes are inferred from that.  The origin is
+  // the same as the world coordinate system's origin.
+
+  // The Z axis is _z.  Determine the x and y axes.
+  LVector3d x, y;
+
+  if (fabs(_z[0]) < 1.0/64.0 && fabs(_z[1]) < 1.0/64.0) {
+    x = cross(LVector3d(0.0, 1.0, 0.0), _z);
+  } else {
+    x = cross(LVector3d(0.0, 0.0, 1.0), _z);
+  }
+  x.normalize();
+  y = cross(x, _z);
+  y.normalize();
+
+  // Now build a rotate matrix from these vectors.
+  LMatrix4d
+    ocs( x[0],  x[1],  x[2],    0,
+	 y[0],  y[1],  y[2],    0,
+	_z[0], _z[1], _z[2],    0,
+	    0,     0,     0,    1);
+
+  _ocs2wcs.invert_from(ocs);
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::get_group
+//       Access: Protected
+//  Description: Reads the next code, string pair from the DXF file.
+//               This is the basic unit of data in a DXF file.
+////////////////////////////////////////////////////////////////////
+bool DXFFile::
+get_group() {
+  istream &in = *_in;
+  do {
+    in >> _code;
+    if (!in) {
+      change_state(ST_error);
+      return false;
+    }
+    
+    // Now skip past exactly one newline character and any number of
+    // other whitespace characters.
+    while (in!=0 && in.peek() != '\n') {
+      in.get();
+    }
+    in.get();
+    while (in!=0 && isspace(in.peek()) && in.peek() != '\n') {
+      in.get();
+    }
+
+    getline(in, _string);
+    _string = trim_right(_string);
+    
+    if (!in) {
+      change_state(ST_error);
+      return false;
+    }
+
+    // If we just read a comment, go back and get another one.
+  } while (_code == 999);
+
+  return true;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::change_state
+//       Access: Protected
+//  Description: Called as new nodes are read to update the internal
+//               state correctly.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+change_state(State new_state) {
+  if (_state == ST_verts) {
+    done_vertex();
+    _p.set(0.0, 0.0, 0.0);
+    _q.set(0.0, 0.0, 0.0);
+    _r.set(0.0, 0.0, 0.0);
+    _s.set(0.0, 0.0, 0.0);
+  }
+  if ((_state == ST_entity || _state == ST_verts) &&
+      new_state != ST_verts) {
+    // We finish an entity when we read a new entity, or when we've
+    // read the last vertex (if we were scanning the vertices after an
+    // entity).
+    done_entity();
+    reset_entity();
+  }
+  switch (new_state) {
+  case ST_top:
+    end_section();
+    break;
+
+  case ST_done:
+    end_file();
+    break;
+
+  default:
+    break;
+  }
+  _state = new_state;
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::change_section
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+change_section(Section new_section) {
+  change_state(ST_section);
+  _section = new_section;
+  begin_section();
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::change_layer
+//       Access: Protected
+//  Description: Given a newly read layer name, sets the _layer
+//               pointer to point to the associate layer.  If the
+//               layer name has not been encountered before, creates a
+//               new layer definition.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+change_layer(const string &layer_name) {
+  if (_layer == NULL || _layer->_name != layer_name) {
+    _layer = _layers.get_layer(layer_name, this);
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::change_entity
+//       Access: Protected
+//  Description:
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+change_entity(Entity new_entity) {
+  if (new_entity == EN_vertex && _vertices_follow) {
+    // If we read a new vertex and we're still scanning the vertices
+    // that follow an entity, keep scanning it--we haven't finished
+    // the entity yet.
+    change_state(ST_verts);
+
+  } else {
+    // Otherwise, begin a new entity.
+    change_state(ST_entity);
+    _entity = new_entity;
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::reset_entity
+//       Access: Protected
+//  Description: Resets the current entity to its initial, default
+//               state prior to reading a new entity.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+reset_entity() {
+  _p.set(0.0, 0.0, 0.0);
+  _q.set(0.0, 0.0, 0.0);
+  _r.set(0.0, 0.0, 0.0);
+  _s.set(0.0, 0.0, 0.0);
+  _z.set(0.0, 0.0, 1.0);
+  _vertices_follow = false;
+  _color_index = -1;
+
+  _verts.erase(_verts.begin(), _verts.end());
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::state_top
+//       Access: Protected
+//  Description: Does the DXF processing when we are at the top of the
+//               file, outside of any section.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+state_top() {
+  if (_code != 0) {
+    nout << "Group code 0 not found at top level; found code " << _code
+	 << " instead.\n";
+    change_state(ST_error);
+  } else {
+    if (_string == "SECTION") {
+      if (get_group()) {
+	if (_code != 2) {
+	  nout << "Group code 0 not immediately followed by code 2; found code " 
+	       << _code << " instead.\n";
+	} else {
+	  if (_string == "HEADER") {
+	    change_section(SE_header);
+	  } else if (_string == "TABLES") {
+	    change_section(SE_tables);
+	  } else if (_string == "BLOCKS") {
+	    change_section(SE_blocks);
+	  } else if (_string == "ENTITIES") {
+	    change_section(SE_entities);
+	  } else if (_string == "OBJECTS") {
+	    change_section(SE_objects);
+	  } else {
+	    change_section(SE_unknown);
+	  }
+	}
+      }
+    } else if (_string == "EOF") {
+      change_state(ST_done);
+    } else {
+      nout << "Unexpected section at top level: '" << _string << "'\n";
+      change_state(ST_error);
+    }
+  }
+}
+
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::state_section
+//       Access: Protected
+//  Description: Does the DXF processing when we are within some
+//               section.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+state_section() {
+  switch (_code) {
+  case 0:
+    if (_string == "ENDSEC") {
+      change_state(ST_top);
+    } else {
+      if (_section == SE_entities) {
+	if (_string == "3DFACE") {
+	  change_entity(EN_3dface);
+	} else if (_string == "POINT") {
+	  change_entity(EN_point);
+	} else if (_string == "INSERT") {
+	  change_entity(EN_insert);
+	} else if (_string == "VERTEX") {
+	  change_entity(EN_vertex);
+	} else if (_string == "POLYLINE") {
+	  change_entity(EN_polyline);
+	} else {
+	  change_entity(EN_unknown);
+	}
+      }
+    }
+    break;
+
+  case 8:
+    change_layer(_string);
+    break;
+
+  default:
+    break;
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::state_entity
+//       Access: Protected
+//  Description: Does the DXF processing when we are reading an
+//               entity.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+state_entity() {
+  string tail;
+
+  switch (_code) {
+  case 0:
+    state_section();
+    break;
+
+  case 8:
+    change_layer(_string);
+    break;
+
+  case 10:
+    _p[0] = string_to_double(_string, tail);
+    break;
+
+  case 11:
+    _q[0] = string_to_double(_string, tail);
+    break;
+
+  case 12:
+    _r[0] = string_to_double(_string, tail);
+    break;
+
+  case 13:
+    _s[0] = string_to_double(_string, tail);
+    break;
+
+  case 20:
+    _p[1] = string_to_double(_string, tail);
+    break;
+
+  case 21:
+    _q[1] = string_to_double(_string, tail);
+    break;
+
+  case 22:
+    _r[1] = string_to_double(_string, tail);
+    break;
+
+  case 23:
+    _s[1] = string_to_double(_string, tail);
+    break;
+
+  case 30:
+    _p[2] = string_to_double(_string, tail);
+    break;
+
+  case 31:
+    _q[2] = string_to_double(_string, tail);
+    break;
+
+  case 32:
+    _r[2] = string_to_double(_string, tail);
+    break;
+
+  case 33:
+    _s[2] = string_to_double(_string, tail);
+    break;
+
+  case 62:  // Color.
+    _color_index = string_to_int(_string, tail);
+    break;
+
+  case 66:  // Vertices-follow.
+    _vertices_follow = string_to_int(_string, tail);
+    break;
+
+  case 70:  // Polyline flags.
+    _flags = string_to_int(_string, tail);
+    break;
+
+  case 210:
+    _z[0] = string_to_double(_string, tail);
+    break;
+
+  case 220:
+    _z[1] = string_to_double(_string, tail);
+    break;
+
+  case 230:
+    _z[2] = string_to_double(_string, tail);
+    break;
+
+  default:
+    break;
+  }
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFFile::state_verts
+//       Access: Protected
+//  Description: Does the DXF processing when we are reading the list
+//               of vertices that might follow an entity.
+////////////////////////////////////////////////////////////////////
+void DXFFile::
+state_verts() {
+  string tail;
+
+  switch (_code) {
+  case 0:
+    state_section();
+    break;
+
+  case 8:
+    change_layer(_string);
+    break;
+
+  case 10:
+    _p[0] = string_to_double(_string, tail);
+    break;
+
+  case 20:
+    _p[1] = string_to_double(_string, tail);
+    break;
+
+  case 30:
+    _p[2] = string_to_double(_string, tail);
+    break;
+
+  default:
+    break;
+  }
+}
+
+
+ostream &operator << (ostream &out, const DXFFile::State &state) {
+  switch (state) {
+  case DXFFile::ST_top:
+    return out << "ST_top";
+  case DXFFile::ST_section:
+    return out << "ST_section";
+  case DXFFile::ST_entity:
+    return out << "ST_entity";
+  case DXFFile::ST_verts:
+    return out << "ST_verts";
+  case DXFFile::ST_error:
+    return out << "ST_error";
+  case DXFFile::ST_done:
+    return out << "ST_done";
+  }
+  return out << "Unknown state";
+}
+
+ostream &operator << (ostream &out, const DXFFile::Section &section) {
+  switch (section) {
+  case DXFFile::SE_unknown:
+    return out << "SE_unknown";
+  case DXFFile::SE_header:
+    return out << "SE_header";
+  case DXFFile::SE_tables:
+    return out << "SE_tables";
+  case DXFFile::SE_blocks:
+    return out << "SE_blocks";
+  case DXFFile::SE_entities:
+    return out << "SE_entities";
+  case DXFFile::SE_objects:
+    return out << "SE_objects";
+  }
+  return out << "Unknown section";
+}
+
+ostream &operator << (ostream &out, const DXFFile::Entity &entity) {
+  switch (entity) {
+  case DXFFile::EN_unknown:
+    return out << "EN_unknown";
+  case DXFFile::EN_3dface:
+    return out << "EN_3dface";
+  case DXFFile::EN_point:
+    return out << "EN_point";
+  case DXFFile::EN_insert:
+    return out << "EN_insert";
+  case DXFFile::EN_vertex:
+    return out << "EN_vertex";
+  case DXFFile::EN_polyline:
+    return out << "EN_polyline";
+  }
+  return out << "Unknown entity";
+}
+

+ 178 - 0
pandatool/src/dxf/dxfFile.h

@@ -0,0 +1,178 @@
+// Filename: dxfFile.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFFILE_H
+#define DXFFILE_H
+
+#include "pandatoolbase.h"
+
+#include "dxfLayer.h"
+#include "dxfLayerMap.h"
+#include "dxfVertex.h"
+
+#include "luse.h"
+#include "filename.h"
+
+
+static const int DXF_max_line = 256;
+static const int DXF_num_colors = 256;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : DXFFile
+// Description : A generic DXF-reading class.  This class can read a
+//               DXF file but doesn't actually do anything with the
+//               data; it's intended to be inherited from and the
+//               appropriate functions overridden (particularly
+//               DoneEntity()).
+////////////////////////////////////////////////////////////////////
+class DXFFile {
+public:
+  DXFFile();
+  virtual ~DXFFile();
+
+  void process(Filename filename);
+  void process(istream &in);
+
+  // These functions are called as the file is processed.  These are
+  // the main hooks for redefining how the class should dispense its
+  // data.  As each function is called, the state stored in the
+  // DXFFile class reflects the data that was most recently read.
+
+  virtual void begin_file();
+  virtual void begin_section();
+  virtual void done_vertex();
+  virtual void done_entity();
+  virtual void end_section();
+  virtual void end_file();
+  virtual void error();
+
+  // new_layer() is called whenever the DXFFile class encounters a new
+  // Layer definition, and must allocate a DXFLayer instance.  This
+  // function is provided so that user code may force allocate of a
+  // specialized DXFLayer instance instead.
+  virtual DXFLayer *new_layer(const string &name) {
+    return new DXFLayer(name);
+  }
+
+  enum State {
+    ST_top,
+    ST_section,
+    ST_entity,
+    ST_verts,
+    ST_error,
+    ST_done,
+  };
+  enum Section {
+    SE_unknown,
+    SE_header,
+    SE_tables,
+    SE_blocks,
+    SE_entities,
+    SE_objects,
+  };
+  enum Entity {
+    EN_unknown,
+    EN_3dface,
+    EN_point,
+    EN_insert,
+    EN_vertex,
+    EN_polyline,
+  };
+  enum PolylineFlags {
+    PF_closed              = 0x01,
+    PF_curve_fit           = 0x02,
+    PF_spline_fit          = 0x04,
+    PF_3d                  = 0x08,
+    PF_3d_mesh             = 0x10,
+    PF_closed_n            = 0x20,
+    PF_polyface            = 0x40,
+    PF_continuous_linetype = 0x80,
+  };
+
+  // This is a table of standard Autocad colors.  DXF files can store
+  // only a limited range of colors; specifically, the 255 colors
+  // defined by Autocad.
+  struct Color {
+    double r, g, b;
+  };
+  static Color _colors[DXF_num_colors];
+
+  // find_color() returns the index of the closest matching AutoCAD
+  // color to the indicated r, g, b.
+  static int find_color(double r, double g, double b);
+
+  // get_color() returns the r,g,b of the current entity.  It is valid
+  // at the time done_entity() is called.
+  const Color &get_color() const;
+
+  // Some entities are defined in world coordinates, in 3-d space;
+  // other entities are inherently 2-d in nature and are defined in
+  // planar coordinates and must be converted to 3-d space.  Call this
+  // function from done_entity() to convert a 2-d entity to 3-d world
+  // coordinates.
+  void ocs_2_wcs();
+
+  // These members indicate the current state and describe properties
+  // of the current thing being processed.  They are valid at
+  // done_entity(), and at other times.
+  int _flags;
+  Section _section;
+  Entity _entity;
+  LPoint3d _p, _q, _r, _s;
+  LVector3d _z;
+  int _color_index;
+  DXFLayer *_layer;
+
+  // _verts is the list of vertices associated with the current
+  // entity.  It is valid at the time done_entity() is called.
+  DXFVertices _verts;
+
+  // This is the set of layers encountered within the DXF file.
+  DXFLayerMap _layers;
+
+protected:
+  State _state;
+  bool _vertices_follow;
+  LMatrix4d _ocs2wcs;
+
+  istream *_in;
+  ifstream _in_file;
+
+  int _code;
+  string _string;
+
+  void compute_ocs();
+
+  bool get_group();
+  void change_state(State new_state);
+  void change_section(Section new_section);
+  void change_layer(const string &layer_name);
+  void change_entity(Entity new_entity);
+  void reset_entity();
+
+  void state_top();
+  void state_section();
+  void state_entity();
+  void state_verts();
+};
+
+ostream &operator << (ostream &out, const DXFFile::State &state);
+ostream &operator << (ostream &out, const DXFFile::Section &section);
+ostream &operator << (ostream &out, const DXFFile::Entity &entity);
+
+#endif

+ 49 - 0
pandatool/src/dxf/dxfLayer.h

@@ -0,0 +1,49 @@
+// Filename: dxfLayer.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFLAYER_H
+#define DXFLAYER_H
+
+#include "pandatoolbase.h"
+#include "dxfVertexMap.h"
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : DXFLayer
+// Description : This represents a "layer" as read from the DXF file.
+//               A layer may be defined by reading the header part of
+//               the file, or it may be implicitly defined by an
+//               entity's having referenced it.
+//
+//               The DXFLayer class provides a facility for collapsing
+//               identical vertices, via the _vmap member; however,
+//               this is not automatic and must be done explicitly by
+//               user code.
+//
+//               User code may derive from DXFLayer to associate
+//               private data with each layer, if desired.
+////////////////////////////////////////////////////////////////////
+class DXFLayer {
+public:
+  DXFLayer(const string &name) : _name(name) { }
+  virtual ~DXFLayer() { }
+  
+  string _name;
+  DXFVertexMap _vmap;
+};
+
+#endif

+ 48 - 0
pandatool/src/dxf/dxfLayerMap.cxx

@@ -0,0 +1,48 @@
+// Filename: dxfLayerMap.cxx
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxfLayerMap.h"
+#include "dxfFile.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFLayerMap::get_layer
+//       Access: Public
+//  Description: Looks up the layer name in the map, and returns a
+//               pointer to the associated DXFLayer.  If this is the
+//               first time this layer name has been used, creates a
+//               new DXFLayer by the given name.  In this case, it
+//               calls dxffile->new_layer() to create the layer,
+//               allowing user code to override this function to
+//               create a specialized time, if desired.
+////////////////////////////////////////////////////////////////////
+DXFLayer *DXFLayerMap::
+get_layer(const string &name, DXFFile *dxffile) {
+  iterator lmi;
+  lmi = find(name);
+  if (lmi != end()) {
+    // The layer was already here.
+    return (*lmi).second;
+  }
+
+  // Need a new layer.
+  DXFLayer *layer = dxffile->new_layer(name);
+  (*this)[name] = layer;
+
+  return layer;
+}
+

+ 40 - 0
pandatool/src/dxf/dxfLayerMap.h

@@ -0,0 +1,40 @@
+// Filename: dxfLayerMap.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFLAYERMAP_H
+#define DXFLAYERMAP_H
+
+#include "pandatoolbase.h"
+#include "pmap.h"
+
+class DXFLayer;
+class DXFFile;
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : DXFLayerMap
+// Description : A map of string (layer name) to DXFLayer: that is,
+//               the layers of a file ordered by name.  This is used
+//               as a lookup within DXFFile to locate the layer
+//               associated with a particular entity.
+////////////////////////////////////////////////////////////////////
+class DXFLayerMap : public pmap<string, DXFLayer *> {
+public:
+  DXFLayer *get_layer(const string &name, DXFFile *dxffile);
+};
+
+#endif

+ 40 - 0
pandatool/src/dxf/dxfVertex.cxx

@@ -0,0 +1,40 @@
+// Filename: dxfVertex.cxx
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxfVertex.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFVertex::Ordering operator
+//       Access: Public
+//  Description: This defines a unique ordering for vertices so that
+//               the DXFVertexMap can group identical vertices
+//               together.
+////////////////////////////////////////////////////////////////////
+int DXFVertex::
+operator < (const DXFVertex &other) const {
+  if (fabs(_p[0] - other._p[0]) > 0.0001) {
+    return _p[0] < other._p[0];
+  } else if (fabs(_p[1] - other._p[1]) > 0.0001) {
+    return _p[1] < other._p[1];
+  } else if (fabs(_p[2] - other._p[2]) > 0.0001) {
+    return _p[2] < other._p[2];
+  }
+
+  return false;
+}
+

+ 46 - 0
pandatool/src/dxf/dxfVertex.h

@@ -0,0 +1,46 @@
+// Filename: dxfVertex.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFVERTEX_H
+#define DXFVERTEX_H
+
+#include "pandatoolbase.h"
+#include "pvector.h"
+#include "luse.h"
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : DXFVertex
+// Description : Stored within DXFFile, this is the basic Vertex data
+//               of a DXF file.  When DXFFile::DoneEntity() is called,
+//               if the entity is a type to have vertices, then
+//               DXFFile::_verts contains a list of all the vertices
+//               that belong to the entity.
+////////////////////////////////////////////////////////////////////
+class DXFVertex {
+public:
+  DXFVertex() { }
+  DXFVertex(const LPoint3d &p) : _p(p) { }
+  int operator < (const DXFVertex &other) const;
+  
+  LPoint3d _p;
+};
+
+typedef pvector<DXFVertex> DXFVertices;
+
+#endif
+

+ 48 - 0
pandatool/src/dxf/dxfVertexMap.cxx

@@ -0,0 +1,48 @@
+// Filename: dxfVertexMap.cxx
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxfVertexMap.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFVertexMap::get_vertex_index
+//       Access: Public
+//  Description: Looks up the vertex in the map, and returns an index
+//               unique to that vertex.  If the vertex has been used
+//               before, returns the index used previously; otherwise,
+//               assigns a new, unique index to the vertex and returns
+//               that.
+////////////////////////////////////////////////////////////////////
+int DXFVertexMap::
+get_vertex_index(const DXFVertex &vert) {
+  iterator vmi;
+  vmi = find(vert);
+  if (vmi != end()) {
+    // The vertex was already here.
+    return (*vmi).second;
+  }
+
+  // Nope, need a new vertex.
+  int index = size();
+  (*this)[vert] = index;
+
+  // That should have added one to the map.
+  nassertr((int)size() == index+1, index);
+
+  return index;
+}
+

+ 39 - 0
pandatool/src/dxf/dxfVertexMap.h

@@ -0,0 +1,39 @@
+// Filename: dxfVertexMap.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFVERTEXMAP_H
+#define DXFVERTEXMAP_H
+
+#include "pandatoolbase.h"
+
+#include "dxfVertex.h"
+#include "pmap.h"
+
+////////////////////////////////////////////////////////////////////
+// 	 Class : DXFVertexMap
+// Description : This is a map of DXFVertex to an integer index
+//               number.  It is intended to be used to collapse
+//               together identical vertices, since the DXF file has
+//               no inherent notion of shared vertices.
+////////////////////////////////////////////////////////////////////
+class DXFVertexMap : public pmap<DXFVertex, int> {
+public:
+  int get_vertex_index(const DXFVertex &vert);
+};
+
+#endif

+ 11 - 0
pandatool/src/dxfprogs/Sources.pp

@@ -0,0 +1,11 @@
+#define UNIX_SYS_LIBS m
+
+#begin bin_target
+  #define TARGET dxf-points
+  #define LOCAL_LIBS \
+    progbase dxf
+
+  #define SOURCES \
+    dxfPoints.cxx dxfPoints.h
+
+#end bin_target

+ 102 - 0
pandatool/src/dxfprogs/dxfPoints.cxx

@@ -0,0 +1,102 @@
+// Filename: dxfPoints.cxx
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#include "dxfPoints.h"
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFPoints::Constructor
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+DXFPoints::
+DXFPoints() :
+  WithOutputFile(true, true, false)
+{
+  // Indicate the extension name we expect the user to supply for
+  // output files.
+  _preferred_extension = ".txt";
+
+  set_program_description
+    ("This program reads an AutoCAD .dxf file and generates a simple "
+     "list of all the points contained within it, one per line, to a "
+     "text file, or to standard output.");
+
+  clear_runlines();
+  add_runline("[opts] input.dxf > output.txt");
+  add_runline("[opts] -o output.txt input.dxf");
+  add_runline("[opts] input.dxf output.txt");
+}
+
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFPoints::run
+//       Access: Public
+//  Description:
+////////////////////////////////////////////////////////////////////
+void DXFPoints::
+run() {
+  // Invoke the DXFFile base class to process the input file.
+  process(_input_filename);
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFPoints::done_entity
+//       Access: Public, Virtual
+//  Description: This is inherited from DXFFile, and gets called as
+//               each entity (face, line, whatever) has finished
+//               processing.
+////////////////////////////////////////////////////////////////////
+void DXFPoints::
+done_entity() {
+  if (_entity == EN_point) {
+    get_output() << _p << "\n";
+
+  } else if (_entity == EN_insert) {
+    ocs_2_wcs();
+    get_output() << _p << "\n";
+  }
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: DXFPoints::handle_args
+//       Access: Protected, Virtual
+//  Description:
+////////////////////////////////////////////////////////////////////
+bool DXFPoints::
+handle_args(ProgramBase::Args &args) {
+  if (args.empty()) {
+    nout << "You must specify the .dxf file to read on the command line.\n";
+    return false;
+
+  } else if (args.size() != 1) {
+    nout << "You must specify only one .dxf file to read on the command line.\n";
+    return false;
+  }
+
+  _input_filename = args[0];
+
+  return true;
+}
+
+
+int main(int argc, char *argv[]) {
+  DXFPoints prog;
+  prog.parse_command_line(argc, argv);
+  prog.run();
+  return 0;
+}

+ 48 - 0
pandatool/src/dxfprogs/dxfPoints.h

@@ -0,0 +1,48 @@
+// Filename: dxfPoints.h
+// Created by:  drose (04May04)
+//
+////////////////////////////////////////////////////////////////////
+//
+// PANDA 3D SOFTWARE
+// Copyright (c) 2001 - 2004, Disney Enterprises, Inc.  All rights reserved
+//
+// All use of this software is subject to the terms of the Panda 3d
+// Software license.  You should have received a copy of this license
+// along with this source code; you will also find a current copy of
+// the license at http://etc.cmu.edu/panda3d/docs/license/ .
+//
+// To contact the maintainers of this program write to
+// [email protected] .
+//
+////////////////////////////////////////////////////////////////////
+
+#ifndef DXFPOINTS_H
+#define DXFPOINTS_H
+
+#include "pandatoolbase.h"
+#include "programBase.h"
+#include "withOutputFile.h"
+
+#include "dxfFile.h"
+
+////////////////////////////////////////////////////////////////////
+//       Class : DXFPoints
+// Description : A simple program to read a dxf file and list the
+//               points contained within it to a text file.
+////////////////////////////////////////////////////////////////////
+class DXFPoints : public ProgramBase, public WithOutputFile, public DXFFile {
+public:
+  DXFPoints();
+
+  void run();
+
+  virtual void done_entity();
+
+protected:
+  virtual bool handle_args(Args &args);
+
+  Filename _input_filename;
+};
+
+#endif
+