Panda3D
 All Classes Functions Variables Enumerations
eggNurbsCurve.cxx
00001 // Filename: eggNurbsCurve.cxx
00002 // Created by:  drose (15Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) Carnegie Mellon University.  All rights reserved.
00008 //
00009 // All use of this software is subject to the terms of the revised BSD
00010 // license.  You should have received a copy of this license along
00011 // with this source code in a file named "LICENSE."
00012 //
00013 ////////////////////////////////////////////////////////////////////
00014 
00015 #include "eggNurbsCurve.h"
00016 
00017 #include "indent.h"
00018 
00019 TypeHandle EggNurbsCurve::_type_handle;
00020 
00021 ////////////////////////////////////////////////////////////////////
00022 //     Function: EggNurbsCurve::setup
00023 //       Access: Public
00024 //  Description: Prepares a new curve definition with the indicated
00025 //               order and number of knots.  This also implies a
00026 //               particular number of vertices as well (the number of
00027 //               knots minus the order), but it is up to the user to
00028 //               add the correct number of vertices to the curve by
00029 //               repeatedly calling push_back().
00030 ////////////////////////////////////////////////////////////////////
00031 void EggNurbsCurve::
00032 setup(int order, int num_knots) {
00033   _order = order;
00034   _knots.clear();
00035 
00036   int i;
00037   _knots.reserve(num_knots);
00038   for (i = 0; i < num_knots; i++) {
00039     _knots.push_back((double)i);
00040   }
00041 }
00042 
00043 ////////////////////////////////////////////////////////////////////
00044 //     Function: EggNurbsCurve::set_num_knots
00045 //       Access: Public
00046 //  Description: Directly changes the number of knots.  This will
00047 //               either add zero-valued knots onto the end, or
00048 //               truncate knot values from the end, depending on
00049 //               whether the list is being increased or decreased.  If
00050 //               possible, it is preferable to use the setup() method
00051 //               instead of directly setting the number of knots, as
00052 //               this may result in an invalid curve.
00053 ////////////////////////////////////////////////////////////////////
00054 void EggNurbsCurve::
00055 set_num_knots(int num) {
00056   if ((int)_knots.size() >= num) {
00057     // Truncate knot values at the end.
00058     _knots.erase(_knots.begin() + num, _knots.end());
00059   } else {
00060     // Append knot values to the end.
00061     _knots.reserve(num);
00062     for (int i = _knots.size(); i < num; i++) {
00063       _knots.push_back(0.0);
00064     }
00065   }
00066 }
00067 
00068 ////////////////////////////////////////////////////////////////////
00069 //     Function: EggNurbsCurve::is_valid
00070 //       Access: Public
00071 //  Description: Returns true if the NURBS parameters are all
00072 //               internally consistent (e.g. it has the right number
00073 //               of vertices to match its number of knots and order in
00074 //               each dimension), or false otherwise.
00075 ////////////////////////////////////////////////////////////////////
00076 bool EggNurbsCurve::
00077 is_valid() const {
00078   if (_order < 1 || _order > 4) {
00079     // Invalid order.
00080     return false;
00081   }
00082 
00083   if (get_num_cvs() != (int)size()) {
00084     // Wrong number of CV's.
00085     return false;
00086   }
00087 
00088   // Do all the knot values monotonically increase?
00089   int i;
00090   for (i = 1; i < get_num_knots(); i++) {
00091     if (get_knot(i) < get_knot(i - 1)) {
00092       return false;
00093     }
00094   }
00095 
00096   // Everything's looking good!
00097   return true;
00098 }
00099 
00100 ////////////////////////////////////////////////////////////////////
00101 //     Function: EggNurbsCurve::is_closed
00102 //       Access: Public
00103 //  Description: Returns true if the curve appears to be closed.
00104 //               Since the Egg syntax does not provide a means for
00105 //               explicit indication of closure, this has to be
00106 //               guessed at by examining the curve itself.
00107 ////////////////////////////////////////////////////////////////////
00108 bool EggNurbsCurve::
00109 is_closed() const {
00110   // Technically, the curve is closed if the CV's at the end are
00111   // repeated from the beginning.  We'll do a cheesy test for
00112   // expediency's sake: the curve is closed if the first n knots are
00113   // not repeated.  I think this will catch all the normal curves
00114   // we're likely to see.
00115 
00116   int i;
00117   for (i = 1; i < get_order(); i++) {
00118     if (get_knot(i) != get_knot(i-1)) {
00119       return true;
00120     }
00121   }
00122   return false;
00123 }
00124 
00125 ////////////////////////////////////////////////////////////////////
00126 //     Function: EggNurbsCurve::write
00127 //       Access: Public, Virtual
00128 //  Description: Writes the nurbsCurve to the indicated output stream in
00129 //               Egg format.
00130 ////////////////////////////////////////////////////////////////////
00131 void EggNurbsCurve::
00132 write(ostream &out, int indent_level) const {
00133   write_header(out, indent_level, "<NurbsCurve>");
00134 
00135   if (get_curve_type() != CT_none) {
00136     indent(out, indent_level + 2)
00137       << "<Char*> type { " << get_curve_type() << " }\n";
00138   }
00139   if (get_subdiv() != 0) {
00140     indent(out, indent_level + 2)
00141       << "<Scalar> subdiv { " << get_subdiv() << " }\n";
00142   }
00143   indent(out, indent_level + 2)
00144     << "<Order> { " << get_order() << " }\n";
00145   indent(out, indent_level + 2)
00146     << "<Knots> {\n";
00147   write_long_list(out, indent_level+4, _knots.begin(), _knots.end(), "",
00148         "", 72);
00149   indent(out, indent_level + 2)
00150     << "}\n";
00151 
00152   write_body(out, indent_level+2);
00153   indent(out, indent_level) << "}\n";
00154 }
 All Classes Functions Variables Enumerations