瀏覽代碼

*** empty log message ***

David Rose 25 年之前
父節點
當前提交
8911e805e3

+ 20 - 0
dtool/src/dtoolutil/filename.I

@@ -386,6 +386,26 @@ is_local() const {
   return _filename.empty() || _filename[0] != '/';
   return _filename.empty() || _filename[0] != '/';
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: Filename::is_fully_qualified
+//       Access: Public
+//  Description: Returns true if the filename is fully qualified,
+//               e.g. begins with a slash.  This is almost, but not
+//               quite, the same thing as !is_local().  It's not
+//               exactly the same because a special case is made for
+//               filenames that begin with a single dot followed by a
+//               slash--these are considered to be fully qualified
+//               (they are explicitly relative to the current
+//               directory, and do not refer to a filename on a search
+//               path somewhere).
+////////////////////////////////////////////////////////////////////
+INLINE bool Filename::
+is_fully_qualified() const {
+  return 
+    (_filename.size() > 2 && _filename[0] == '.' && _filename[1] == '/') ||
+    (!_filename.empty() && _filename[0] == '/');
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: Filename::Equality operator
 //     Function: Filename::Equality operator
 //       Access: Public
 //       Access: Public

+ 1 - 1
dtool/src/dtoolutil/filename.cxx

@@ -827,7 +827,7 @@ resolve_filename(const DSearchPath &searchpath,
 		 const string &default_extension) {
 		 const string &default_extension) {
   string found;
   string found;
 
 
-  if (is_local()) {
+  if (!is_fully_qualified()) {
     found = searchpath.find_file(get_fullpath());
     found = searchpath.find_file(get_fullpath());
 
 
     if (found.empty()) {
     if (found.empty()) {

+ 1 - 0
dtool/src/dtoolutil/filename.h

@@ -119,6 +119,7 @@ PUBLISHED:
   // The following functions deal with the outside world.
   // The following functions deal with the outside world.
 
 
   INLINE bool is_local() const;
   INLINE bool is_local() const;
+  INLINE bool is_fully_qualified() const;
   void make_absolute();
   void make_absolute();
   void make_absolute(const Filename &start_directory);
   void make_absolute(const Filename &start_directory);
 
 

+ 1 - 1
panda/src/egg2sg/Sources.pp

@@ -4,7 +4,7 @@
 #begin lib_target
 #begin lib_target
   #define TARGET egg2sg
   #define TARGET egg2sg
   #define LOCAL_LIBS \
   #define LOCAL_LIBS \
-    cull collide egg builder loader chan char switchnode
+    parametrics cull collide egg builder loader chan char switchnode
 
 
   #define SOURCES \
   #define SOURCES \
     animBundleMaker.cxx animBundleMaker.h characterMaker.cxx \
     animBundleMaker.cxx animBundleMaker.h characterMaker.cxx \

+ 71 - 1
panda/src/egg2sg/eggLoader.cxx

@@ -26,8 +26,10 @@
 #include <eggPrimitive.h>
 #include <eggPrimitive.h>
 #include <eggPolygon.h>
 #include <eggPolygon.h>
 #include <eggPoint.h>
 #include <eggPoint.h>
+#include <eggNurbsCurve.h>
 #include <eggTextureCollection.h>
 #include <eggTextureCollection.h>
 #include <eggBin.h>
 #include <eggBin.h>
+#include <nurbsCurve.h>
 #include <builderBucket.h>
 #include <builderBucket.h>
 #include <builderPrim.h>
 #include <builderPrim.h>
 #include <builderVertex.h>
 #include <builderVertex.h>
@@ -1063,7 +1065,9 @@ setup_bucket(BuilderBucket &bucket, NamedNode *parent,
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 RenderRelation *EggLoader::
 RenderRelation *EggLoader::
 make_node(EggNode *egg_node, NamedNode *parent) {
 make_node(EggNode *egg_node, NamedNode *parent) {
-  if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
+  if (egg_node->is_of_type(EggNurbsCurve::get_class_type())) {
+    return make_node(DCAST(EggNurbsCurve, egg_node), parent);
+  } else if (egg_node->is_of_type(EggPrimitive::get_class_type())) {
     return make_node(DCAST(EggPrimitive, egg_node), parent);
     return make_node(DCAST(EggPrimitive, egg_node), parent);
   } else if (egg_node->is_of_type(EggBin::get_class_type())) {
   } else if (egg_node->is_of_type(EggBin::get_class_type())) {
     return make_node(DCAST(EggBin, egg_node), parent);
     return make_node(DCAST(EggBin, egg_node), parent);
@@ -1078,6 +1082,72 @@ make_node(EggNode *egg_node, NamedNode *parent) {
   return (RenderRelation *)NULL;
   return (RenderRelation *)NULL;
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: EggLoader::make_node (EggNurbsCurve)
+//       Access: Private
+//  Description: 
+////////////////////////////////////////////////////////////////////
+RenderRelation *EggLoader::
+make_node(EggNurbsCurve *egg_curve, NamedNode *parent) {
+  assert(parent != NULL);
+  assert(!parent->is_of_type(GeomNode::get_class_type()));
+
+  PT(NurbsCurve) curve = new NurbsCurve;
+
+  if (egg_curve->get_order() < 1 || egg_curve->get_order() > 4) {
+    egg2sg_cat.error()
+      << "Invalid NURBSCurve order for " << egg_curve->get_name() << ": "
+      << egg_curve->get_order() << "\n";
+    return (RenderRelation *)NULL;
+  }
+
+  curve->set_order(egg_curve->get_order());
+
+  EggPrimitive::const_iterator pi;
+  for (pi = egg_curve->begin(); pi != egg_curve->end(); ++pi) {
+    curve->append_cv(LCAST(float, (*pi)->get_pos4()));
+  }
+
+  int num_knots = egg_curve->get_num_knots();
+  if (num_knots != curve->get_num_knots()) {
+    egg2sg_cat.error()
+      << "Invalid NURBSCurve number of knots for "
+      << egg_curve->get_name() << ": got " << num_knots
+      << " knots, expected " << curve->get_num_knots() << "\n";
+    return (RenderRelation *)NULL;
+  }
+    
+  for (int i = 0; i < num_knots; i++) {
+    curve->set_knot(i, egg_curve->get_knot(i));
+  }
+
+  switch (egg_curve->get_curve_type()) {
+  case EggCurve::CT_xyz:
+    curve->set_curve_type(PCT_XYZ);
+    break;
+
+  case EggCurve::CT_hpr:
+    curve->set_curve_type(PCT_HPR);
+    break;
+
+  case EggCurve::CT_t:
+    curve->set_curve_type(PCT_T);
+    break;
+
+  default:
+    break;
+  }
+  curve->set_name(egg_curve->get_name());
+
+  if (!curve->recompute()) {
+    egg2sg_cat.error()
+      << "Invalid NURBSCurve " << egg_curve->get_name() << "\n";
+    return (RenderRelation *)NULL;
+  }
+
+  return new RenderRelation(parent, curve);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: EggLoader::make_node (EggPrimitive)
 //     Function: EggLoader::make_node (EggPrimitive)
 //       Access: Private
 //       Access: Private

+ 2 - 0
panda/src/egg2sg/eggLoader.h

@@ -26,6 +26,7 @@
 class EggNode;
 class EggNode;
 class EggBin;
 class EggBin;
 class EggTable;
 class EggTable;
+class EggNurbsCurve;
 class EggPrimitive;
 class EggPrimitive;
 class EggPolygon;
 class EggPolygon;
 class ComputedVerticesMaker;
 class ComputedVerticesMaker;
@@ -77,6 +78,7 @@ private:
 		    EggPrimitive *egg_prim);
 		    EggPrimitive *egg_prim);
 
 
   RenderRelation *make_node(EggNode *egg_node, NamedNode *parent);
   RenderRelation *make_node(EggNode *egg_node, NamedNode *parent);
+  RenderRelation *make_node(EggNurbsCurve *egg_curve, NamedNode *parent);
   RenderRelation *make_node(EggPrimitive *egg_prim, NamedNode *parent);
   RenderRelation *make_node(EggPrimitive *egg_prim, NamedNode *parent);
   RenderRelation *make_node(EggBin *egg_bin, NamedNode *parent);
   RenderRelation *make_node(EggBin *egg_bin, NamedNode *parent);
   RenderRelation *make_node(EggGroup *egg_group, NamedNode *parent);
   RenderRelation *make_node(EggGroup *egg_group, NamedNode *parent);

+ 4 - 8
panda/src/parametrics/curve.h

@@ -25,8 +25,7 @@
 #include <list>
 #include <list>
 #include <vector>
 #include <vector>
 
 
-#include "typedWriteableReferenceCount.h"
-#include "namable.h"
+#include "namedNode.h"
 #include "luse.h"
 #include "luse.h"
 
 
 
 
@@ -81,8 +80,7 @@ class NurbsCurve;
 //               This encapsulates all curves in 3-d space defined
 //               This encapsulates all curves in 3-d space defined
 //               for a single parameter t in the range [0,get_max_t()].
 //               for a single parameter t in the range [0,get_max_t()].
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-class EXPCL_PANDA ParametricCurve : public TypedWriteableReferenceCount,
-    public Namable {
+class EXPCL_PANDA ParametricCurve : public NamedNode {
 PUBLISHED:
 PUBLISHED:
   ParametricCurve();
   ParametricCurve();
   virtual ~ParametricCurve();
   virtual ~ParametricCurve();
@@ -153,11 +151,9 @@ public:
     return _type_handle;
     return _type_handle;
   }
   }
   static void init_type() {
   static void init_type() {
-    TypedWriteableReferenceCount::init_type();
-    Namable::init_type();
+    NamedNode::init_type();
     register_type(_type_handle, "ParametricCurve",
     register_type(_type_handle, "ParametricCurve",
-		  TypedWriteableReferenceCount::get_class_type(),
-		  Namable::get_class_type());
+		  NamedNode::get_class_type());
   }
   }
   virtual TypeHandle get_type() const {
   virtual TypeHandle get_type() const {
     return get_class_type();
     return get_class_type();

+ 8 - 8
panda/src/parametrics/curveDrawer.cxx

@@ -34,8 +34,8 @@ ParametricCurveDrawer(ParametricCurve *curve) {
   _lines.set_color(1.0, 1.0, 1.0);
   _lines.set_color(1.0, 1.0, 1.0);
   _ticks.set_color(1.0, 0.0, 0.0);
   _ticks.set_color(1.0, 0.0, 0.0);
   _tick_scale = 0.1;
   _tick_scale = 0.1;
-  _num_segs = 100;
-  _num_ticks = 0;
+  _num_segs = 100.0;
+  _num_ticks = 0.0;
   _frame_accurate = false;
   _frame_accurate = false;
   _geom_node = new GeomNode;
   _geom_node = new GeomNode;
   _drawn = false;
   _drawn = false;
@@ -168,7 +168,7 @@ detach_geom_node() {
 //               curve will be get_max_t() * get_num_segs().
 //               curve will be get_max_t() * get_num_segs().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ParametricCurveDrawer::
 void ParametricCurveDrawer::
-set_num_segs(int num_segs) {
+set_num_segs(double num_segs) {
   _num_segs = num_segs;
   _num_segs = num_segs;
   if (_drawn) {
   if (_drawn) {
     draw();
     draw();
@@ -184,7 +184,7 @@ set_num_segs(int num_segs) {
 //               is drawn.  The total number of segments drawn for the
 //               is drawn.  The total number of segments drawn for the
 //               curve will be get_max_t() * get_num_segs().
 //               curve will be get_max_t() * get_num_segs().
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-int ParametricCurveDrawer::
+double ParametricCurveDrawer::
 get_num_segs() const {
 get_num_segs() const {
   return _num_segs;
   return _num_segs;
 }
 }
@@ -202,7 +202,7 @@ get_num_segs() const {
 //               of tick marks.
 //               of tick marks.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void ParametricCurveDrawer::
 void ParametricCurveDrawer::
-set_num_ticks(int num_ticks) {
+set_num_ticks(double num_ticks) {
   _num_ticks = num_ticks;
   _num_ticks = num_ticks;
   if (_drawn) {
   if (_drawn) {
     draw();
     draw();
@@ -215,7 +215,7 @@ set_num_ticks(int num_ticks) {
 //  Description: Returns the number of time tick marks per unit of
 //  Description: Returns the number of time tick marks per unit of
 //               time drawn.
 //               time drawn.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-int ParametricCurveDrawer::
+double ParametricCurveDrawer::
 get_num_ticks() const {
 get_num_ticks() const {
   return _num_ticks;
   return _num_ticks;
 }
 }
@@ -330,7 +330,7 @@ draw() {
   _drawn = true;
   _drawn = true;
 
 
   // Now draw the time tick marks.
   // Now draw the time tick marks.
-  if (_num_ticks > 0) {
+  if (_num_ticks > 0.0) {
     LVecBase3f tangent2;
     LVecBase3f tangent2;
     int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5);
     int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5);
 
 
@@ -424,7 +424,7 @@ recompute(double t1, double t2, ParametricCurve *curve) {
     }
     }
   }
   }
     
     
-  if (_num_ticks > 0) {
+  if (_num_ticks > 0.0) {
     LVecBase3f tangent2;
     LVecBase3f tangent2;
     int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5);
     int total_ticks = (int)floor(_curve->get_max_t() * _num_ticks + 0.5);
 
 

+ 6 - 6
panda/src/parametrics/curveDrawer.h

@@ -71,11 +71,11 @@ PUBLISHED:
   GeomNode *get_geom_node();
   GeomNode *get_geom_node();
   GeomNode *detach_geom_node();
   GeomNode *detach_geom_node();
 
 
-  void set_num_segs(int num_segs);
-  int get_num_segs() const;
+  void set_num_segs(double num_segs);
+  double get_num_segs() const;
 
 
-  void set_num_ticks(int num_ticks);
-  int get_num_ticks() const;
+  void set_num_ticks(double num_ticks);
+  double get_num_ticks() const;
 
 
   void set_color(float r, float g, float b);
   void set_color(float r, float g, float b);
   void set_tick_color(float r, float g, float b);
   void set_tick_color(float r, float g, float b);
@@ -119,11 +119,11 @@ protected:
   static void get_tick_marks(const LVecBase3f &tangent, LVecBase3f &t1, LVecBase3f &t2);
   static void get_tick_marks(const LVecBase3f &tangent, LVecBase3f &t1, LVecBase3f &t2);
 
 
   PT(GeomNode) _geom_node;
   PT(GeomNode) _geom_node;
-  int _num_segs;
+  double _num_segs;
   ParametricCurve *_curve, *_time_curve;
   ParametricCurve *_curve, *_time_curve;
   LineSegs _lines, _ticks;
   LineSegs _lines, _ticks;
   bool _drawn;
   bool _drawn;
-  int _num_ticks;
+  double _num_ticks;
   double _tick_scale;
   double _tick_scale;
   bool _frame_accurate;
   bool _frame_accurate;
   LVecBase3fMapper *_mapper;
   LVecBase3fMapper *_mapper;

+ 75 - 7
panda/src/parametrics/curveFitter.cxx

@@ -65,6 +65,74 @@ add_point(double t, const LVecBase3f &point) {
   _data.push_back(dp);
   _data.push_back(dp);
 }
 }
 
 
+////////////////////////////////////////////////////////////////////
+//     Function: CurveFitter::get_num_samples
+//       Access: Public
+//  Description: Returns the number of sample points that have been
+//               added.
+////////////////////////////////////////////////////////////////////
+int CurveFitter::
+get_num_samples() const {
+  return _data.size();
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CurveFitter::get_sample_t
+//       Access: Public
+//  Description: Returns the parametric value of the nth sample added.
+////////////////////////////////////////////////////////////////////
+double CurveFitter::
+get_sample_t(int n) const {
+  nassertr(n >= 0 && n < (int)_data.size(), 0.0);
+  return _data[n]._t;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CurveFitter::get_sample_point
+//       Access: Public
+//  Description: Returns the point in space of the nth sample added.
+////////////////////////////////////////////////////////////////////
+const LVecBase3f &CurveFitter::
+get_sample_point(int n) const {
+#ifndef NDEBUG
+  static const LVecBase3f zero(0.0, 0.0, 0.0);
+  nassertr(n >= 0 && n < (int)_data.size(), zero);
+#endif
+  return _data[n]._point;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CurveFitter::get_sample_tangent
+//       Access: Public
+//  Description: Returns the tangent associated with the nth sample
+//               added.  This is only meaningful if compute_tangents()
+//               has already been called.
+////////////////////////////////////////////////////////////////////
+const LVecBase3f &CurveFitter::
+get_sample_tangent(int n) const {
+#ifndef NDEBUG
+  static const LVecBase3f zero(0.0, 0.0, 0.0);
+  nassertr(n >= 0 && n < (int)_data.size(), zero);
+#endif
+  return _data[n]._tangent;
+}
+
+////////////////////////////////////////////////////////////////////
+//     Function: CurveFitter::remove_samples
+//       Access: Public
+//  Description: Eliminates all samples from index begin, up to but not
+//               including index end, from the database.
+////////////////////////////////////////////////////////////////////
+void CurveFitter::
+remove_samples(int begin, int end) {
+  begin = max(0, min((int)_data.size(), begin));
+  end = max(0, min((int)_data.size(), end));
+
+  nassertv(begin <= end);
+
+  _data.erase(_data.begin() + begin, _data.begin() + end);
+}
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: CurveFitter::sample
 //     Function: CurveFitter::sample
 //       Access: Public
 //       Access: Public
@@ -452,26 +520,26 @@ make_nurbs() const {
 }
 }
   
   
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: CurveFitter::print
+//     Function: CurveFitter::output
 //       Access: Public
 //       Access: Public
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CurveFitter::
 void CurveFitter::
-print() const {
-  output(cerr);
+output(ostream &out) const {
+  out << "CurveFitter, " << _data.size() << " samples.\n";
 }
 }
   
   
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: CurveFitter::output
+//     Function: CurveFitter::write
 //       Access: Public
 //       Access: Public
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void CurveFitter::
 void CurveFitter::
-output(ostream &out) const {
+write(ostream &out) const {
+  out << "CurveFitter, " << _data.size() << " samples:\n";
   Data::const_iterator di;
   Data::const_iterator di;
-
   for (di = _data.begin(); di != _data.end(); ++di) {
   for (di = _data.begin(); di != _data.end(); ++di) {
-    out << (*di) << "\n";
+    out << "  " << (*di) << "\n";
   }
   }
 }
 }
 
 

+ 8 - 3
panda/src/parametrics/curveFitter.h

@@ -36,6 +36,12 @@ PUBLISHED:
   void reset();
   void reset();
   void add_point(double t, const LVecBase3f &point);
   void add_point(double t, const LVecBase3f &point);
 
 
+  int get_num_samples() const;
+  double get_sample_t(int n) const;
+  const LVecBase3f &get_sample_point(int n) const;
+  const LVecBase3f &get_sample_tangent(int n) const;
+  void remove_samples(int begin, int end);
+
   void sample(ParametricCurve *curve, int count, bool even);
   void sample(ParametricCurve *curve, int count, bool even);
   void generate_even(int count, double net_distance, double net_time);
   void generate_even(int count, double net_distance, double net_time);
 
 
@@ -48,11 +54,10 @@ PUBLISHED:
   PT(HermiteCurve) make_hermite() const;
   PT(HermiteCurve) make_hermite() const;
   PT(NurbsCurve) make_nurbs() const;
   PT(NurbsCurve) make_nurbs() const;
   
   
-  void print() const;
-
-public:
   void output(ostream &out) const;
   void output(ostream &out) const;
+  void write(ostream &out) const;
 
 
+public:
   class DataPoint {
   class DataPoint {
   public:
   public:
     DataPoint() : _t(0.0), _point(0.0, 0.0, 0.0), _tangent(0.0, 0.0, 0.0) { }
     DataPoint() : _t(0.0), _point(0.0, 0.0, 0.0), _tangent(0.0, 0.0, 0.0) { }

+ 75 - 54
panda/src/parametrics/nurbsCurve.cxx

@@ -15,6 +15,8 @@
 #include "nurbsCurve.h"
 #include "nurbsCurve.h"
 #include "config_parametrics.h"
 #include "config_parametrics.h"
 
 
+#include <indent.h>
+
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 // Statics
 // Statics
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -26,20 +28,6 @@ static const LVecBase3f zero = LVecBase3f(0.0, 0.0, 0.0);
 // used from time to time as an initializer.
 // used from time to time as an initializer.
 
 
 
 
-////////////////////////////////////////////////////////////////////
-//     Function: Indent
-//  Description: This function duplicates a similar function declared
-//               in eggBasics.C.  It prints a specified number of
-//               spaces to indent each line of output.
-////////////////////////////////////////////////////////////////////
-static ostream &
-Indent(ostream &out, int indent) {
-  for (int i=0; i<indent; i++) {
-    out << ' ';
-  }
-  return out;
-}
-
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 //     Function: NurbsCurve::Constructor
 //     Function: NurbsCurve::Constructor
 //       Access: Public, Scheme
 //       Access: Public, Scheme
@@ -355,61 +343,60 @@ get_knot(int n) const {
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: NurbsCurve::print
+//     Function: NurbsCurve::write
 //       Access: Public, Scheme
 //       Access: Public, Scheme
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void NurbsCurve::
 void NurbsCurve::
-print() const {
+write(ostream &out) const {
   switch (get_curve_type()) {
   switch (get_curve_type()) {
   case PCT_T:
   case PCT_T:
-    cout << "Time-warping ";
+    out << "Time-warping ";
     break;
     break;
 
 
   case PCT_XYZ:
   case PCT_XYZ:
-    cout << "XYZ ";
+    out << "XYZ ";
     break;
     break;
 
 
   case PCT_HPR:
   case PCT_HPR:
-    cout << "HPR ";
+    out << "HPR ";
     break;
     break;
 
 
   default:
   default:
     break;
     break;
   }
   }
 
 
-  cout << "NurbsCurve, order " << _order << ", " << get_num_cvs()
-       << " CV's.  t ranges from 0 to " << get_max_t() << ".\n";
+  out << "NurbsCurve, order " << _order << ", " << get_num_cvs()
+      << " CV's.  t ranges from 0 to " << get_max_t() << ".\n";
 
 
-  cout << "CV's:\n";
+  out << "CV's:\n";
   int i;
   int i;
   for (i = 0; i < (int)_cvs.size(); i++) {
   for (i = 0; i < (int)_cvs.size(); i++) {
     LVecBase3f p = (const LVecBase3f &)_cvs[i]._p / _cvs[i]._p[3];
     LVecBase3f p = (const LVecBase3f &)_cvs[i]._p / _cvs[i]._p[3];
-    cout << i << ") " << p << ", weight " << _cvs[i]._p[3] << "\n";
+    out << i << ") " << p << ", weight " << _cvs[i]._p[3] << "\n";
   }
   }
 
 
-  cout << "Knots: ";
+  out << "Knots: ";
   for (i = 0; i < (int)_cvs.size()+_order; i++) {
   for (i = 0; i < (int)_cvs.size()+_order; i++) {
-    cout << " " << GetKnot(i);
+    out << " " << GetKnot(i);
   }
   }
-  cout << "\n" << flush;
+  out << "\n";
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: NurbsCurve::print_cv
+//     Function: NurbsCurve::write_cv
 //       Access: Public, Scheme
 //       Access: Public, Scheme
 //  Description: 
 //  Description: 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void NurbsCurve::
 void NurbsCurve::
-print_cv(int n) const {
+write_cv(ostream &out, int n) const {
   if (n < 0 || n >= (int)_cvs.size()) {
   if (n < 0 || n >= (int)_cvs.size()) {
-    cout << "No such CV: " << n << "\n";
+    out << "No such CV: " << n << "\n";
   } else {
   } else {
     LVecBase3f p = (const LVecBase3f &)_cvs[n]._p / _cvs[n]._p[3];
     LVecBase3f p = (const LVecBase3f &)_cvs[n]._p / _cvs[n]._p[3];
-    cout << "CV " << n << ": " << p << ", weight " 
-	 << _cvs[n]._p[3] << "\n";
+    out << "CV " << n << ": " << p << ", weight " 
+	<< _cvs[n]._p[3] << "\n";
   }
   }
-  cout << flush;
 }
 }
 
 
 
 
@@ -692,12 +679,12 @@ rebuild_curveseg(int rtype0, double t0, const LVecBase4f &v0,
 //               Returns true if the file is successfully written.
 //               Returns true if the file is successfully written.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NurbsCurve::
 bool NurbsCurve::
-write_egg(const char *filename) {
+write_egg(const char *filename, CoordinateSystem cs) {
   const char *basename = strrchr(filename, '/');
   const char *basename = strrchr(filename, '/');
   basename = (basename==NULL) ? filename : basename+1;
   basename = (basename==NULL) ? filename : basename+1;
 
 
   ofstream out(filename, ios::app);
   ofstream out(filename, ios::app);
-  return write_egg(out, basename);
+  return write_egg(out, basename, cs);
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
@@ -708,7 +695,7 @@ write_egg(const char *filename) {
 //               successfully written.
 //               successfully written.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 bool NurbsCurve::
 bool NurbsCurve::
-write_egg(ostream &out, const char *basename) {
+write_egg(ostream &out, const char *basename, CoordinateSystem cs) {
   if (get_name().empty()) {
   if (get_name().empty()) {
     // If we don't have a name, come up with one.
     // If we don't have a name, come up with one.
     int len = strlen(basename);
     int len = strlen(basename);
@@ -738,7 +725,7 @@ write_egg(ostream &out, const char *basename) {
     set_name(name);
     set_name(name);
   }
   }
 
 
-  Output(out);
+  format_egg(out, cs, 0);
 
 
   if (out) {
   if (out) {
     return true;
     return true;
@@ -804,26 +791,59 @@ splice(double t, const NurbsCurve &other) {
 
 
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
-//     Function: NurbsCurve::Output
+//     Function: NurbsCurve::format_egg
 //       Access: Public
 //       Access: Public
 //  Description: Formats the Nurbs curve for output to an Egg file.
 //  Description: Formats the Nurbs curve for output to an Egg file.
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////
 void NurbsCurve::
 void NurbsCurve::
-Output(ostream &out, int indent) const {
-  Indent(out, indent)
+format_egg(ostream &out, CoordinateSystem cs, int indent_level) const {
+  if (cs == CS_default) {
+    cs = default_coordinate_system;
+  }
+
+  if (cs != CS_invalid) {
+    indent(out, indent_level)
+      << "<CoordinateSystem> { ";
+    switch (cs) {
+    case CS_zup_right:
+      out << "Z-Up";
+      break;
+      
+    case CS_yup_right:
+      out << "Y-Up";
+      break;
+      
+    case CS_zup_left:
+      out << "Z-Up-Left";
+      break;
+      
+    case CS_yup_left:
+      out << "Y-Up-Left";
+      break;
+
+    default:
+      break;
+    }
+    out << " }\n\n";
+  }
+
+  indent(out, indent_level)
     << "<VertexPool> " << get_name() << ".pool {\n";
     << "<VertexPool> " << get_name() << ".pool {\n";
 
 
   int cv;
   int cv;
   for (cv = 0; cv < (int)_cvs.size(); cv++) {
   for (cv = 0; cv < (int)_cvs.size(); cv++) {
-    Indent(out, indent+2) << "<Vertex> " << cv << " { " 
-			  << _cvs[cv]._p << " }\n";
+    indent(out, indent_level+2)
+      << "<Vertex> " << cv << " { " << _cvs[cv]._p << " }\n";
   }
   }
-  Indent(out, indent) << "}\n";
+  indent(out, indent_level)
+    << "}\n";
     
     
-  Indent(out, indent) << "<NURBSCurve> " << get_name() << " {\n";
+  indent(out, indent_level)
+    << "<NURBSCurve> " << get_name() << " {\n";
 
 
   if (_curve_type!=PCT_NONE) {
   if (_curve_type!=PCT_NONE) {
-    Indent(out, indent+2) << "<Char*> type { ";
+    indent(out, indent_level+2)
+      << "<Char*> type { ";
     switch (_curve_type) {
     switch (_curve_type) {
     case PCT_XYZ:
     case PCT_XYZ:
       out << "XYZ";
       out << "XYZ";
@@ -840,35 +860,36 @@ Output(ostream &out, int indent) const {
     out << " }\n";
     out << " }\n";
   }
   }
 
 
-  Indent(out, indent+2) << "<Order> { " << _order << " }\n";
+  indent(out, indent_level+2) << "<Order> { " << _order << " }\n";
   
   
-  Indent(out, indent+2) << "<Knots> {";
+  indent(out, indent_level+2) << "<Knots> {";
   int k;
   int k;
   int num_knots = _cvs.size() + _order;
   int num_knots = _cvs.size() + _order;
 
 
   for (k = 0; k < num_knots; k++) {
   for (k = 0; k < num_knots; k++) {
     if (k%6 == 0) {
     if (k%6 == 0) {
       out << "\n";
       out << "\n";
-      Indent(out, indent+4);
+      indent(out, indent_level+4);
     }
     }
     out << GetKnot(k) << " ";
     out << GetKnot(k) << " ";
   }
   }
   out << "\n";
   out << "\n";
-  Indent(out, indent+2) << "}\n";
+  indent(out, indent_level+2) << "}\n";
 
 
-  Indent(out, indent+2) << "<VertexRef> {";
+  indent(out, indent_level+2) << "<VertexRef> {";
   for (cv = 0; cv < (int)_cvs.size(); cv++) {
   for (cv = 0; cv < (int)_cvs.size(); cv++) {
-    if (cv%10 == 1) {
+    if (cv%10 == 0) {
       out << "\n";
       out << "\n";
-      Indent(out, indent+3);
+      indent(out, indent_level+3);
     }
     }
     out << " " << cv;
     out << " " << cv;
   }
   }
   out << "\n";
   out << "\n";
-  Indent(out, indent+4) << "<Ref> { " << get_name() << ".pool }\n";
-  Indent(out, indent+2) << "}\n";
+  indent(out, indent_level+4)
+    << "<Ref> { " << get_name() << ".pool }\n";
+  indent(out, indent_level+2) << "}\n";
 
 
-  Indent(out, indent) << "}\n";
+  indent(out, indent_level) << "}\n";
 }
 }
 
 
 ////////////////////////////////////////////////////////////////////
 ////////////////////////////////////////////////////////////////////

+ 5 - 5
panda/src/parametrics/nurbsCurve.h

@@ -87,15 +87,15 @@ PUBLISHED:
   bool set_knot(int n, double t);
   bool set_knot(int n, double t);
   double get_knot(int n) const;
   double get_knot(int n) const;
 
 
-  void print() const;
-  void print_cv(int n) const;
+  void write(ostream &out) const;
+  void write_cv(ostream &out, int n) const;
 
 
   bool recompute();
   bool recompute();
 
 
   void normalize_tlength();
   void normalize_tlength();
 
 
-  bool write_egg(const char *filename);
-  bool write_egg(ostream &out, const char *basename);
+  bool write_egg(const char *filename, CoordinateSystem cs = CS_default);
+  bool write_egg(ostream &out, const char *basename, CoordinateSystem cs);
 
 
   void splice(double t, const NurbsCurve &other);
   void splice(double t, const NurbsCurve &other);
   
   
@@ -124,7 +124,7 @@ public:
     }
     }
   }
   }
 
 
-  void Output(ostream &out, int indent=0) const;
+  void format_egg(ostream &out, CoordinateSystem cs, int indent_level) const;
 
 
 protected:
 protected:
   int FindCV(double t);
   int FindCV(double t);