Panda3D
|
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 }