Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

panda/src/egg/eggNurbsSurface.cxx

Go to the documentation of this file.
00001 // Filename: eggNurbsSurface.cxx
00002 // Created by:  drose (15Feb00)
00003 //
00004 ////////////////////////////////////////////////////////////////////
00005 //
00006 // PANDA 3D SOFTWARE
00007 // Copyright (c) 2001, Disney Enterprises, Inc.  All rights reserved
00008 //
00009 // All use of this software is subject to the terms of the Panda 3d
00010 // Software license.  You should have received a copy of this license
00011 // along with this source code; you will also find a current copy of
00012 // the license at http://www.panda3d.org/license.txt .
00013 //
00014 // To contact the maintainers of this program write to
00015 // panda3d@yahoogroups.com .
00016 //
00017 ////////////////////////////////////////////////////////////////////
00018 
00019 #include "eggNurbsSurface.h"
00020 
00021 #include <indent.h>
00022 
00023 TypeHandle EggNurbsSurface::_type_handle;
00024 
00025 ////////////////////////////////////////////////////////////////////
00026 //     Function: EggNurbsSurface::setup
00027 //       Access: Public
00028 //  Description: Prepares a new surface definition with the indicated
00029 //               order and number of knots in each dimension.  This
00030 //               also implies a particular number of vertices in each
00031 //               dimension as well (the number of knots minus the
00032 //               order), but it is up to the user to add the correct
00033 //               number of vertices to the surface by repeatedly
00034 //               calling push_back().
00035 ////////////////////////////////////////////////////////////////////
00036 void EggNurbsSurface::
00037 setup(int u_order, int v_order,
00038       int num_u_knots, int num_v_knots) {
00039   _u_order = u_order;
00040   _v_order = v_order;
00041   _u_knots.clear();
00042   _v_knots.clear();
00043 
00044   int i;
00045   _u_knots.reserve(num_u_knots);
00046   for (i = 0; i < num_u_knots; i++) {
00047     _u_knots.push_back((double)i);
00048   }
00049   _v_knots.reserve(num_v_knots);
00050   for (i = 0; i < num_v_knots; i++) {
00051     _v_knots.push_back((double)i);
00052   }
00053 }
00054 
00055 ////////////////////////////////////////////////////////////////////
00056 //     Function: EggNurbsSurface::set_num_u_knots
00057 //       Access: Public
00058 //  Description: Directly changes the number of knots in the U
00059 //               direction.  This will either add zero-valued knots
00060 //               onto the end, or truncate knot values from the end,
00061 //               depending on whether the list is being increased or
00062 //               decreased.  If possible, it is preferable to use the
00063 //               setup() method instead of directly setting the number
00064 //               of knots, as this may result in an invalid surface.
00065 ////////////////////////////////////////////////////////////////////
00066 void EggNurbsSurface::
00067 set_num_u_knots(int num) {
00068   if ((int)_u_knots.size() >= num) {
00069     // Truncate knot values at the end.
00070     _u_knots.erase(_u_knots.begin() + num, _u_knots.end());
00071   } else {
00072     // Append knot values to the end.
00073     _u_knots.reserve(num);
00074     for (int i = _u_knots.size(); i < num; i++) {
00075       _u_knots.push_back(0.0);
00076     }
00077   }
00078 }
00079 
00080 ////////////////////////////////////////////////////////////////////
00081 //     Function: EggNurbsSurface::set_num_v_knots
00082 //       Access: Public
00083 //  Description: Directly changes the number of knots in the V
00084 //               direction.  This will either add zero-valued knots
00085 //               onto the end, or truncate knot values from the end,
00086 //               depending on whether the list is being increased or
00087 //               decreased.  If possible, it is preferable to use the
00088 //               setup() method instead of directly setting the number
00089 //               of knots, as this may result in an invalid surface.
00090 ////////////////////////////////////////////////////////////////////
00091 void EggNurbsSurface::
00092 set_num_v_knots(int num) {
00093   if ((int)_v_knots.size() >= num) {
00094     // Truncate knot values at the end.
00095     _v_knots.erase(_v_knots.begin() + num, _v_knots.end());
00096   } else {
00097     // Append knot values to the end.
00098     _v_knots.reserve(num);
00099     for (int i = _v_knots.size(); i < num; i++) {
00100       _v_knots.push_back(0.0);
00101     }
00102   }
00103 }
00104 
00105 ////////////////////////////////////////////////////////////////////
00106 //     Function: EggNurbsSurface::is_valid
00107 //       Access: Public
00108 //  Description: Returns true if the NURBS parameters are all
00109 //               internally consistent (e.g. it has the right number
00110 //               of vertices to match its number of knots and order in
00111 //               each dimension), or false otherwise.
00112 ////////////////////////////////////////////////////////////////////
00113 bool EggNurbsSurface::
00114 is_valid() const {
00115   if (_u_order < 1 || _u_order > 4 || _v_order < 1 || _v_order > 4) {
00116     // Invalid order.
00117     return false;
00118   }
00119 
00120   if (get_num_cvs() != (int)size()) {
00121     // Wrong number of CV's.
00122     return false;
00123   }
00124 
00125   // Do all the knot values monotonically increase?
00126   int i;
00127   for (i = 1; i < get_num_u_knots(); i++) {
00128     if (get_u_knot(i) < get_u_knot(i - 1)) {
00129       return false;
00130     }
00131   }
00132   for (i = 1; i < get_num_v_knots(); i++) {
00133     if (get_v_knot(i) < get_v_knot(i - 1)) {
00134       return false;
00135     }
00136   }
00137 
00138   // Everything's looking good!
00139   return true;
00140 }
00141 
00142 ////////////////////////////////////////////////////////////////////
00143 //     Function: EggNurbsSurface::is_closed_u
00144 //       Access: Public
00145 //  Description: Returns true if the surface appears to be closed in
00146 //               the U direction.  Since the Egg syntax does not
00147 //               provide a means for explicit indication of closure,
00148 //               this has to be guessed at by examining the surface
00149 //               itself.
00150 ////////////////////////////////////////////////////////////////////
00151 bool EggNurbsSurface::
00152 is_closed_u() const {
00153   // Technically, the surface is closed if the CV's at the end are
00154   // repeated from the beginning.  We'll do a cheesy test for
00155   // expediency's sake: the surface is closed if the first n knots are
00156   // not repeated.  I think this will catch all the normal surfaces
00157   // we're likely to see.
00158 
00159   int i;
00160   for (i = 1; i < get_u_order(); i++) {
00161     if (get_u_knot(i) != get_u_knot(i-1)) {
00162       return true;
00163     }
00164   }
00165   return false;
00166 }
00167 
00168 ////////////////////////////////////////////////////////////////////
00169 //     Function: EggNurbsSurface::is_closed_v
00170 //       Access: Public
00171 //  Description: Returns true if the surface appears to be closed in
00172 //               the V direction.  Since the Egg syntax does not
00173 //               provide a means for explicit indication of closure,
00174 //               this has to be guessed at by examining the surface
00175 //               itself.
00176 ////////////////////////////////////////////////////////////////////
00177 bool EggNurbsSurface::
00178 is_closed_v() const {
00179   int i;
00180   for (i = 1; i < get_v_order(); i++) {
00181     if (get_v_knot(i) != get_v_knot(i-1)) {
00182       return true;
00183     }
00184   }
00185   return false;
00186 }
00187 
00188 ////////////////////////////////////////////////////////////////////
00189 //     Function: EggNurbsSurface::write
00190 //       Access: Public, Virtual
00191 //  Description: Writes the nurbsSurface to the indicated output stream in
00192 //               Egg format.
00193 ////////////////////////////////////////////////////////////////////
00194 void EggNurbsSurface::
00195 write(ostream &out, int indent_level) const {
00196   write_header(out, indent_level, "<NurbsSurface>");
00197 
00198   Trims::const_iterator ti;
00199   for (ti = _trims.begin(); ti != _trims.end(); ++ti) {
00200     indent(out, indent_level + 2) << "<Trim> {\n";
00201     Loops::const_iterator li;
00202     for (li = (*ti).begin(); li != (*ti).end(); ++li) {
00203       indent(out, indent_level + 4) << "<Loop> {\n";
00204       Curves::const_iterator ci;
00205       for (ci = (*li).begin(); ci != (*li).end(); ++ci) {
00206         (*ci)->write(out, indent_level + 6);
00207       }
00208       indent(out, indent_level + 4) << "}\n";
00209     }
00210     indent(out, indent_level + 2) << "}\n";
00211   }
00212 
00213   if (get_u_subdiv() != 0) {
00214     indent(out, indent_level + 2)
00215       << "<Scalar> U-subdiv { " << get_u_subdiv() << " }\n";
00216   }
00217   if (get_v_subdiv() != 0) {
00218     indent(out, indent_level + 2)
00219       << "<Scalar> V-subdiv { " << get_v_subdiv() << " }\n";
00220   }
00221   indent(out, indent_level + 2)
00222     << "<Order> { " << get_u_order() << " " << get_v_order() << " }\n";
00223   indent(out, indent_level + 2)
00224     << "<U-Knots> {\n";
00225   write_long_list(out, indent_level+4, _u_knots.begin(), _u_knots.end(),
00226         "", "", 72);
00227   indent(out, indent_level + 2)
00228     << "}\n";
00229   indent(out, indent_level + 2)
00230     << "<V-Knots> {\n";
00231   write_long_list(out, indent_level+4, _v_knots.begin(), _v_knots.end(),
00232         "", "", 72);
00233   indent(out, indent_level + 2)
00234     << "}\n";
00235 
00236   write_body(out, indent_level+2);
00237 
00238   Curves::const_iterator ci;
00239   for (ci = _curves_on_surface.begin(); ci != _curves_on_surface.end(); ++ci) {
00240     (*ci)->write(out, indent_level + 2);
00241   }
00242 
00243   indent(out, indent_level) << "}\n";
00244 }
00245 
00246 ////////////////////////////////////////////////////////////////////
00247 //     Function: EggNurbsSurface::r_apply_texmats
00248 //       Access: Protected, Virtual
00249 //  Description: The recursive implementation of apply_texmats().
00250 ////////////////////////////////////////////////////////////////////
00251 void EggNurbsSurface::
00252 r_apply_texmats(EggTextureCollection &textures) {
00253   // A NURBS cannot safely apply texture matrices, so we leave it
00254   // alone.
00255 }

Generated on Fri May 2 00:37:47 2003 for Panda by doxygen1.3