// react to keys void keyboard(unsigned char k, int, int) { switch(k) { case 27: mgr = NULL; gpcl_defaultmat = NULL; gpcl_surface = NULL; exit(1); case 'y': case 'z': glPolygonMode( GL_FRONT_AND_BACK, GL_POINT); std::cerr << "PolygonMode: Point." << std::endl; break; case 'x': glPolygonMode( GL_FRONT_AND_BACK, GL_LINE); std::cerr << "PolygonMode: Line." << std::endl; break; case 'c': glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); std::cerr << "PolygonMode: Fill." << std::endl; break; case 'f': g_error *= 2; std::cerr << "Error: " << g_error << std::endl; gpcl_surface->setError( g_error ); break; case 'g': g_error /= 2; std::cerr << "Error: " << g_error << std::endl; gpcl_surface->setError( g_error ); break; default: std::cerr << "y,z = Polygon Point Mode\n" << "x = Polygon Line Mode\n" << "c = Polygon Fill Mode\n" << "f/g = +/- Error\n" << std::endl; break; } }
// react to keys void keyboard(unsigned char k, int, int) { switch(k) { case 27: mgr = NULL; gpcl_defaultmat = NULL; gpcl_surface = NULL; exit(1); case 'y': case 'z': glPolygonMode( GL_FRONT_AND_BACK, GL_POINT); std::cerr << "PolygonMode: Point." << std::endl; break; case 'x': glPolygonMode( GL_FRONT_AND_BACK, GL_LINE); std::cerr << "PolygonMode: Line." << std::endl; break; case 'c': glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); std::cerr << "PolygonMode: Fill." << std::endl; break; case 'f': g_error *= 2; std::cerr << "Error: " << g_error << std::endl; gpcl_surface->setError( g_error ); // See comments about OSGSurface::forceTessellate() below if(useForceTesselate) gpcl_surface->forceTessellate(); break; case 'g': g_error /= 2; std::cerr << "Error: " << g_error << std::endl; gpcl_surface->setError( g_error ); // See comments about OSGSurface::forceTessellate() below if(useForceTesselate) gpcl_surface->forceTessellate(); break; case 'd': gpcl_surface->setIsDelaunay(!gpcl_surface->getIsDelaunay()); std::cerr << "Delaunay: " << gpcl_surface->getIsDelaunay() << std::endl; // See comments about OSGSurface::forceTessellate() below if(useForceTesselate) gpcl_surface->forceTessellate(); break; default: std::cerr << "y,z = Polygon Point Mode\n" << "x = Polygon Line Mode\n" << "c = Polygon Fill Mode\n" << "f/g = +/- Error\n" << "d = Delaunay on/off\n" << std::endl; break; } }
// react to keys void keyboard(unsigned char k, int, int) { switch(k) { case 27: delete mgr; gpcl_defaultmat = NULL; gpcl_surface1 = NULL; gpcl_surface2 = NULL; gpcl_fb_chunk = NULL; exit(1); case 'y': case 'z': glPolygonMode( GL_FRONT_AND_BACK, GL_POINT); std::cerr << "PolygonMode: Point." << std::endl; break; case 'x': glPolygonMode( GL_FRONT_AND_BACK, GL_LINE); std::cerr << "PolygonMode: Line." << std::endl; break; case 'c': glPolygonMode( GL_FRONT_AND_BACK, GL_FILL); std::cerr << "PolygonMode: Fill." << std::endl; break; case 'f': g_error1 *= 2; if ( !gb_differenterrors ) { std::cerr << "Error: " << g_error1 << std::endl; } else { std::cerr << "Error1: " << g_error1 << std::endl; } gpcl_surface1->setError( g_error1 ); if ( !gb_differenterrors ) { g_error2 = g_error1; gpcl_surface2->setError( g_error2 ); } break; case 'g': g_error1 /= 2; if ( !gb_differenterrors ) { std::cerr << "Error: " << g_error1 << std::endl; } else { std::cerr << "Error1: " << g_error1 << std::endl; } gpcl_surface1->setError( g_error1 ); if ( !gb_differenterrors ) { g_error2 = g_error1; gpcl_surface2->setError( g_error2 ); } break; case 'h': g_error2 *= 2; if ( !gb_differenterrors ) { std::cerr << "Error: " << g_error2 << std::endl; } else { std::cerr << "Error2: " << g_error2 << std::endl; } gpcl_surface2->setError( g_error2 ); if ( !gb_differenterrors ) { g_error1 = g_error2; gpcl_surface1->setError( g_error1 ); } break; case 'j': g_error2 /= 2; if ( !gb_differenterrors ) { std::cerr << "Error: " << g_error2 << std::endl; } else { std::cerr << "Error2: " << g_error2 << std::endl; } gpcl_surface2->setError( g_error2 ); if ( !gb_differenterrors ) { g_error1 = g_error2; gpcl_surface1->setError( g_error1 ); } break; default: std::cerr << "y,z = Polygon Point Mode\n" << "x = Polygon Line Mode\n" << "c = Polygon Fill Mode\n" << "f/g = +/- Error1\n" << "h/j = +/- Error2\n" << std::endl; break; } }
OSG::NodeTransitPtr makeScene( void ) { setupDefaultMaterial(); OSG::NodeTransitPtr root = OSG::Node ::create(); OSG::SurfaceRefPtr surface = OSG::Surface ::create(); OSG::GeoPnt3fPropertyRefPtr cps = OSG::GeoPnt3fProperty::create(); // control points should always be 3D for the time being, // rational support will be added later cps->clear(); cps->push_back( OSG::Pnt3f( 1, 1, 2 )); cps->push_back( OSG::Pnt3f( 1, 0, 0 )); cps->push_back( OSG::Pnt3f( 1, 0, 1 )); cps->push_back( OSG::Pnt3f( 1, -1, -2 )); cps->push_back( OSG::Pnt3f( 0, 1, 0 )); cps->push_back( OSG::Pnt3f( 0, 0, 0 )); cps->push_back( OSG::Pnt3f( 0, 0, 1 )); cps->push_back( OSG::Pnt3f( 0, -1, 1 )); cps->push_back( OSG::Pnt3f( 0, 1, 1 )); cps->push_back( OSG::Pnt3f( 0, 0, 1 )); cps->push_back( OSG::Pnt3f( 0, 0, 0 )); cps->push_back( OSG::Pnt3f( 0, -1, 0 )); cps->push_back( OSG::Pnt3f( -1, 1, 1 )); cps->push_back( OSG::Pnt3f( -1, 0, 1 )); cps->push_back( OSG::Pnt3f( -1, 0, 0 )); cps->push_back( OSG::Pnt3f( -1, -1, 0 )); // let's clear the trimming surface->removeCurves(); // set up dimensions and knot vectors: surface->setDimU( 3 ); surface->setDimV( 3 ); surface->editMFKnotsU()->clear(); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsV()->clear(); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); // set control points and texture control points surface->setControlPoints( cps ); // set error surface->setError( g_error ); // and finally set the material surface->setMaterial( gpcl_defaultmat ); root->setCore( surface ); gpcl_surface = surface; // Usually when the endEditCP() is called for an OSGSurface object // the need for (re)tessellation is flagged, and when the object // would be drawn on screen it gets tessellated. This might cause // problems in a cluster environment as surfaces may get tessellated // more than once (e.g. on the server and on each client) which can // be _very_ slow and annoying. // // The solution is "forcing" the tessellation by calling // OSGSurface::forceTessellate(). This will perform the tessellation // immediately, and setup flags so that automatic tessellation will // not be called again. This means that even if you change some or // all of the surface descriptiong FieldContainersin your OSGSurface // object it will _not_ be retessellated. You will have to "force" // tessellation again by calling OSGSurface::forceTessellate() whenever // you change something. See the calls in the keyboard() function // above. // // If you don't do clustering, you can probably just forget about all // this OSGSurface::forceTessellate() stuff (just like in the other // Surface examples), it will just work automagically and tessellate // your surface when needed (provided you don't forget the proper // beginEditCP()/endEditCP() calls. if(useForceTesselate) gpcl_surface->forceTessellate(); return root; }
OSG::NodeTransitPtr makeScene( void ) { setupDefaultMaterial(); OSG::NodeTransitPtr root = OSG::Node ::create(); OSG::SurfaceRefPtr surface = OSG::Surface ::create(); OSG::GeoPnt3fPropertyRefPtr cps = OSG::GeoPnt3fProperty::create(); // control points should always be 3D for the time being, // rational support will be added later cps->clear(); cps->push_back( OSG::Pnt3f( 1, 1, 0 )); cps->push_back( OSG::Pnt3f( 1, 0, 0 )); cps->push_back( OSG::Pnt3f( 1, 0, 1 )); cps->push_back( OSG::Pnt3f( 1, -1, 1 )); cps->push_back( OSG::Pnt3f( 0, 1, 0 )); cps->push_back( OSG::Pnt3f( 0, 0, 0 )); cps->push_back( OSG::Pnt3f( 0, 0, 1 )); cps->push_back( OSG::Pnt3f( 0, -1, 1 )); cps->push_back( OSG::Pnt3f( 0, 1, 1 )); cps->push_back( OSG::Pnt3f( 0, 0, 1 )); cps->push_back( OSG::Pnt3f( 0, 0, 0 )); cps->push_back( OSG::Pnt3f( 0, -1, 0 )); cps->push_back( OSG::Pnt3f( -1, 1, 1 )); cps->push_back( OSG::Pnt3f( -1, 0, 1 )); cps->push_back( OSG::Pnt3f( -1, 0, 0 )); cps->push_back( OSG::Pnt3f( -1, -1, 0 )); std::vector<OSG::Real64> knots1; std::vector<OSG::Real64> knots2; std::vector<OSG::Pnt2f> points; knots1.clear(); knots1.push_back(0); knots1.push_back(0); knots1.push_back(1); knots1.push_back(1); knots2.clear(); knots2.push_back(0); knots2.push_back(0); knots2.push_back(0); knots2.push_back(1); knots2.push_back(1); knots2.push_back(1); // first, let's clear the trimming surface->removeCurves(); // add the outer trimming around the domain points.clear(); points.push_back( OSG::Pnt2f(0,0) ); points.push_back( OSG::Pnt2f(1,0) ); surface->addCurve( 1, knots1, points, true ); points.clear(); points.push_back( OSG::Pnt2f(1,0) ); points.push_back( OSG::Pnt2f(1,1) ); surface->addCurve( 1, knots1, points, false ); points.clear(); points.push_back( OSG::Pnt2f(1,1) ); points.push_back( OSG::Pnt2f(0,1) ); surface->addCurve( 1, knots1, points, false ); points.clear(); points.push_back( OSG::Pnt2f(0,1) ); points.push_back( OSG::Pnt2f(0,0) ); surface->addCurve( 1, knots1, points, false ); // add inner trimming loop 1 points.clear(); points.push_back( OSG::Pnt2f(0.3f,0.5f) ); points.push_back( OSG::Pnt2f(0.1f,0.9f) ); points.push_back( OSG::Pnt2f(0.5f,0.7f) ); surface->addCurve( 2, knots2, points, true ); points.clear(); points.push_back( OSG::Pnt2f(0.5f,0.7f) ); points.push_back( OSG::Pnt2f(0.9f,0.9f) ); points.push_back( OSG::Pnt2f(0.7f,0.5f) ); surface->addCurve( 2, knots2, points, false ); points.clear(); points.push_back( OSG::Pnt2f(0.7f,0.5f) ); points.push_back( OSG::Pnt2f(0.9f,0.1f) ); points.push_back( OSG::Pnt2f(0.5f,0.3f) ); surface->addCurve( 2, knots2, points, false ); points.clear(); points.push_back( OSG::Pnt2f(0.5f,0.3f) ); points.push_back( OSG::Pnt2f(0.1f,0.1f) ); points.push_back( OSG::Pnt2f(0.3f,0.5f) ); surface->addCurve( 2, knots2, points, false ); // add inner trimming loop 2 points.clear(); points.push_back( OSG::Pnt2f(0.4f,0.5f) ); points.push_back( OSG::Pnt2f(0.4f,0.4f) ); points.push_back( OSG::Pnt2f(0.5f,0.4f) ); surface->addCurve( 2, knots2, points, true ); points.clear(); points.push_back( OSG::Pnt2f(0.5f,0.4f) ); points.push_back( OSG::Pnt2f(0.6f,0.4f) ); points.push_back( OSG::Pnt2f(0.6f,0.5f) ); surface->addCurve( 2, knots2, points, false ); points.clear(); points.push_back( OSG::Pnt2f(0.6f,0.5f) ); points.push_back( OSG::Pnt2f(0.6f,0.6f) ); points.push_back( OSG::Pnt2f(0.5f,0.6f) ); surface->addCurve( 2, knots2, points, false ); points.clear(); points.push_back( OSG::Pnt2f(0.5f,0.6f) ); points.push_back( OSG::Pnt2f(0.4f,0.6f) ); points.push_back( OSG::Pnt2f(0.4f,0.5f) ); surface->addCurve( 2, knots2, points, false ); // set up dimensions and knot vectors: surface->setDimU( 3 ); surface->setDimV( 3 ); surface->editMFKnotsU()->clear(); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 0 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsU()->push_back( 1 ); surface->editMFKnotsV()->clear(); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 0 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); surface->editMFKnotsV()->push_back( 1 ); // set control points and texture control points surface->setControlPoints( cps ); // set error surface->setError( g_error ); // and finally set the material surface->setMaterial( gpcl_defaultmat ); root->setCore( surface ); gpcl_surface = surface; return root; }