void buildAndRenderScene(Scene &scene, Camera &camera, RenderTarget &renderTarget) { // Build scene AmbientLight ambientLight(Color::white); PointLight light1(Vector3D(50.0, 70.0, 0.0)); PointLight light2(Vector3D(50.0, 70.0, 200.0)); Torus sphere1(10, 4, Vector3D(0.0, 20.0, 100.0)); PhongMaterial material1(Color::red); Sphere sphere2(10, Vector3D(0.0, 45.0, 100.0)); PhongMaterial material2(Color::green); Sphere sphere3(10, Vector3D(35.0, 20.0, 100.0)); PhongMaterial material3(Color::blue); Plane plane1(Vector3D(0, 0, 0), Vector3D(0.0, 1.0, 0.0)); PhongMaterial material4(Color(0.0, 1.0, 1.0)); Plane plane2(Vector3D(-100, 0, 0), Vector3D(1.0, 0.0, 0.0)); PhongMaterial material5(Color(1.0, 0.0, 1.0)); Plane plane3(Vector3D(0, 0, 500), Vector3D(0.0, 0.0, -1.0)); PhongMaterial material6(Color(1.0, 1.0, 0.0)); sphere1.setMaterial(&material1); sphere2.setMaterial(&material2); sphere3.setMaterial(&material3); plane1.setMaterial(&material4); plane2.setMaterial(&material5); plane3.setMaterial(&material6); scene.addObject(&sphere1); scene.addObject(&sphere2); scene.addObject(&sphere3); scene.addObject(&plane1); scene.addObject(&plane2); scene.addObject(&plane3); scene.addLight(&light1); scene.addLight(&light2); scene.setAmbientLight(&ambientLight); // Render scene camera.computeFrame(); camera.renderScene(scene, renderTarget); renderTarget.update(); }
void display(void) { // ****** declaracoes internas 'a funcao display() ****** float temp; GLUquadric* glQ; // nec. p/ criar sup. quadraticas (cilindros, esferas...) // ****** fim de todas as declaracoes da funcao display() ****** glQ = gluNewQuadric(); glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); camara_control(camera_select); /*// permissao de atribuicao directa de cores // para objectos que nao tem material atribuido, como // e' o caso dos eixos e da esfera que simboliza a fonte de luz... glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); // cilindro representativo do eixo X glColor3f(1.0,0.0,0.0); // vermelho glPushMatrix(); glRotated(90.0, 0.0,1.0,0.0 ); gluCylinder(glQ, axis_radius_begin, axis_radius_end, axis_lenght, axis_nslices, axis_nstacks); // nao tem bases glPopMatrix(); // cilindro representativo do eixo Y glColor3f(0.0,1.0,0.0); // verde glPushMatrix(); glRotated(-90.0, 1.0,0.0,0.0 ); gluCylinder(glQ, axis_radius_begin, axis_radius_end, axis_lenght, axis_nslices, axis_nstacks); // nao tem bases glPopMatrix(); // cilindro representativo do eixo Z glColor3f(0.0,0.0,1.0); // azul glPushMatrix(); // nao necessita rotacao... glRotated(...); gluCylinder(glQ, axis_radius_begin, axis_radius_end, axis_lenght, axis_nslices, axis_nstacks); // nao tem bases glPopMatrix();*/ // Actualizacao da posicao da fonte de luz... light0_position[0] = light0x; // por razoes de eficiencia, os restantes light0_position[1] = light0y; // parametros _invariaveis_ da LIGHT0 mantem os valores light0_position[2] = light0z; // definidos na funcao de inicializacao glLightfv(GL_LIGHT0, GL_POSITION, light0_position); glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, light0_direction); // ... e da esfera que a simboliza glColor3f(1.0,1.0,0.0); // cor amarela gluQuadricOrientation( glQ, GLU_INSIDE); glPushMatrix(); glTranslated(light0x,light0y,light0z); gluSphere(glQ, symb_light0_radius, symb_light0_slices, symb_light0_stacks); glPopMatrix(); gluQuadricOrientation( glQ, GLU_OUTSIDE); // SEGUEM-SE ALGUNS EXEMPLOS DE UTILIZACAO DE OPENGL (GL, GLU, GLUT) // GLU: funcoes para desenhar Quadraticas // Permitem desenhar alguns objectos: disco, cilindro/cone, esfera // O parametro do tipo GLUquadric (variavel glQ, declarada acima) passa, // em argumento da funcao de desenho respectiva, algumas propriedades // que esta tem em conta durante o desenho (estilo de desenho, calculo e // orientacao de normais, mapeamento de texturas... // Funcoes para definicao dessas propriedades em glQ gluQuadricDrawStyle(glQ, GLU_LINE); // GLU_FILL, GLU_LINE, GLU_SILHOUETTE, GLU_POINT gluQuadricNormals(glQ, GLU_SMOOTH); // GLU_NONE, GLU_FLAT, GLU_SMOOTH gluQuadricOrientation(glQ, GLU_OUTSIDE); // GLU_OUTSIDE, GLU_INSIDE gluQuadricTexture(glQ, GL_FALSE); // GL_TRUE, GL_FALSE //gluQuadricCallback(glQ, GLU_ERROR, <CallBackFunc>); // inibicao de atribuicao directa de cores; os objectos que se seguem DEVEM // possuir materiais associados glDisable(GL_COLOR_MATERIAL); // Definicao de material a usar daqui em diante (valores declarados em materias.h) material1(); //Terreno e árvores; glCallList(1); //Hospital (com telhado e letreiro incluídos); glCallList(2); //Heliporto (área de aterragem e holofotes). glCallList(3); hangar(); torre(); helicoptero(); // swapping the buffers causes the rendering above to be shown glutSwapBuffers(); glFlush(); }
//------------------------------------------------------------------------------ int main( int argc, char * argv[] ) { base::auxi::Timer total, detailed; //-------------------------------------------------------------------------- // User input if ( argc != 5 ) { std::cout << "Usage: " << argv[0] << " file.smf radius E1 E2 \n\n"; return -1; } // input mesh file const std::string smfFile = boost::lexical_cast<std::string>( argv[1] ); const std::string baseName = base::io::baseName( smfFile, ".smf" ); // problem parameter const double radius = boost::lexical_cast<double>( argv[2] ); const double E1 = boost::lexical_cast<double>( argv[3] ); const double E2 = boost::lexical_cast<double>( argv[4] ); const double penaltyFactor = 20.0; // material stuff const double nu = 0.3; const double lambda1 = mat::Lame::lambda( E1, nu ); const double lambda2 = mat::Lame::lambda( E2, nu ); const double mu1 = mat::Lame::mu( E1, nu ); const double mu2 = mat::Lame::mu( E2, nu ); //-------------------------------------------------------------------------- const unsigned geomDeg = 1; const unsigned dim = SPACEDIM; const base::Shape shape = base::SimplexShape<dim>::value; const bool isSigned = true; const unsigned fieldDeg = 1; const unsigned doFSize = dim; // use Nitsche const bool useNitscheTerms = true; //-------------------------------------------------------------------------- // Domain mesh typedef base::Unstructured<shape,geomDeg> Mesh; Mesh mesh; { std::ifstream smf( smfFile.c_str() ); base::io::smf::readMesh( smf, mesh ); } //-------------------------------------------------------------------------- // Compute the level set data typedef base::cut::LevelSet<dim> LevelSet; std::vector<LevelSet> levelSet; base::cut::AnalyticSurface<dim>::Type as = boost::bind( &interface<dim>, _1, radius, _2 ); base::cut::analyticLevelSet( mesh, as, isSigned, levelSet ); //-------------------------------------------------------------------------- // FE typedef base::fe::Basis<shape,fieldDeg> FEBasis; typedef base::cut::ScaledField<FEBasis,doFSize> Field; Field fieldIn, fieldOut; base::dof::generate<FEBasis>( mesh, fieldIn ); base::dof::generate<FEBasis>( mesh, fieldOut ); //-------------------------------------------------------------------------- // Cut typedef base::cut::Cell<shape> Cell; std::vector<Cell> cells; base::cut::generateCutCells( mesh, levelSet, cells ); //-------------------------------------------------------------------------- // surface meshes typedef base::cut::SurfaceMeshBinder<Mesh>::SurfaceMesh SurfaceMesh; SurfaceMesh boundaryMesh, interfaceMesh; // from boundary { // identify list of element boundary faces base::mesh::MeshBoundary meshBoundary; meshBoundary.create( mesh.elementsBegin(), mesh.elementsEnd() ); // generate a mesh from that list (with a filter) base::mesh::generateBoundaryMesh( meshBoundary.begin(), meshBoundary.end(), mesh, boundaryMesh, boost::bind( &dirichletBoundary<dim>, _1 ) ); } // from interface base::cut::generateSurfaceMesh<Mesh,Cell>( mesh, cells, interfaceMesh ); //-------------------------------------------------------------------------- // Quadratures const unsigned kernelDegEstimate = 5; // for domain typedef base::cut::Quadrature<kernelDegEstimate,shape> CutQuadrature; CutQuadrature cutQuadratureIn( cells, true ); CutQuadrature cutQuadratureOut( cells, false ); // for surface typedef base::SurfaceQuadrature<kernelDegEstimate,shape> SurfaceQuadrature; SurfaceQuadrature surfaceQuadrature; //-------------------------------------------------------------------------- // Bind fields // for domain fields typedef base::asmb::FieldBinder<Mesh,Field,Field> FieldBinder; typedef FieldBinder::TupleBinder<1,1>::Type FTB1; typedef FieldBinder::TupleBinder<2,2>::Type FTB2; FieldBinder fieldBinder( mesh, fieldIn, fieldOut ); // for surface fields typedef base::asmb::SurfaceFieldBinder<SurfaceMesh,Field,Field> SurfaceFieldBinder; typedef SurfaceFieldBinder::TupleBinder<1,1>::Type STB11; typedef SurfaceFieldBinder::TupleBinder<2,2>::Type STB22; typedef SurfaceFieldBinder::TupleBinder<1,2>::Type STB12; typedef SurfaceFieldBinder::TupleBinder<2,1>::Type STB21; SurfaceFieldBinder boundaryFieldBinder( boundaryMesh, fieldIn, fieldOut ); SurfaceFieldBinder interfaceFieldBinder( interfaceMesh, fieldIn, fieldOut ); // compute supports, scale basis const std::size_t numDoFs = std::distance( fieldIn.doFsBegin(), fieldIn.doFsEnd() ); std::vector<double> supportsIn, supportsOut; supportsIn.resize( numDoFs ); supportsOut.resize( numDoFs ); base::cut::supportComputation( mesh, fieldIn, cutQuadratureIn, supportsIn ); base::cut::supportComputation( mesh, fieldOut, cutQuadratureOut, supportsOut ); fieldIn.scaleAndTagBasis( supportsIn, 1.e-10 ); fieldOut.scaleAndTagBasis( supportsOut, 1.e-10 ); //fieldIn.tagBasis( supportsIn, 1.e-10 ); //fieldOut.tagBasis( supportsOut, 1.e-10 ); // number DoFs, create solver const std::size_t activeDoFsIn = base::dof::numberDoFsConsecutively( fieldIn.doFsBegin(), fieldIn.doFsEnd() ); const std::size_t activeDoFsOut = base::dof::numberDoFsConsecutively( fieldOut.doFsBegin(), fieldOut.doFsEnd(), activeDoFsIn ); typedef base::solver::Eigen3 Solver; Solver solver( activeDoFsIn + activeDoFsOut ); message( "Preprocessing time = " + detailed.print() ); detailed.reset(); //-------------------------------------------------------------------------- // Stiffness matrix typedef mat::hypel::StVenant Material; Material material1( lambda1, mu1 ); Material material2( lambda2, mu2 ); // matrix kernel typedef solid::HyperElastic<Material,FTB1::Tuple> HyperElastic1; HyperElastic1 hyperElastic1( material1 ); typedef solid::HyperElastic<Material,FTB2::Tuple> HyperElastic2; HyperElastic2 hyperElastic2( material2 ); message( "Stiffness" ); base::asmb::stiffnessMatrixComputation<FTB1>( cutQuadratureIn, solver, fieldBinder, hyperElastic1 ); base::asmb::stiffnessMatrixComputation<FTB2>( cutQuadratureOut, solver, fieldBinder, hyperElastic2 ); // boundary conditions #if 1 { message("Boundary Penalty"); base::nitsche::OuterBoundary ob1( E1); base::nitsche::OuterBoundary ob2( E2); base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver, boundaryFieldBinder, ob1, penaltyFactor ); base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver, boundaryFieldBinder, ob2, penaltyFactor ); base::nitsche::penaltyRHS<STB11>( surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1), ob1, penaltyFactor ); base::nitsche::penaltyRHS<STB22>( surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1), ob2, penaltyFactor ); if ( useNitscheTerms ) { message("Boundary Nitsche"); base::nitsche::energyLHS<STB11>( hyperElastic1, surfaceQuadrature, solver, boundaryFieldBinder, ob1 ); base::nitsche::energyLHS<STB22>( hyperElastic2, surfaceQuadrature, solver, boundaryFieldBinder, ob2 ); base::nitsche::energyRHS<STB11>( hyperElastic1, surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1), ob1 ); base::nitsche::energyRHS<STB22>( hyperElastic2, surfaceQuadrature, solver, boundaryFieldBinder, boost::bind( &dirichlet<dim>, _1), ob2 ); } } // interface conditions { message("Interface Penalty"); base::nitsche::ImmersedInterface<Cell> ip( E1, E2, cells ); base::nitsche::penaltyLHS<STB11>( surfaceQuadrature, solver, interfaceFieldBinder, ip, penaltyFactor ); base::nitsche::penaltyLHS<STB22>( surfaceQuadrature, solver, interfaceFieldBinder, ip, penaltyFactor ); base::nitsche::penaltyLHS<STB12>( surfaceQuadrature, solver, interfaceFieldBinder, ip, -penaltyFactor ); base::nitsche::penaltyLHS<STB21>( surfaceQuadrature, solver, interfaceFieldBinder, ip, -penaltyFactor ); if ( useNitscheTerms ) { message("Interface Nitsche"); base::nitsche::energyLHS<STB11>( hyperElastic1, surfaceQuadrature, solver, interfaceFieldBinder, ip, true, true ); // kappa1 base::nitsche::energyLHS<STB21>( hyperElastic1, surfaceQuadrature, solver, interfaceFieldBinder, ip, true, false ); // -kappa1 base::nitsche::energyLHS<STB12>( hyperElastic2, surfaceQuadrature, solver, interfaceFieldBinder, ip, false, true ); // kappa2 base::nitsche::energyLHS<STB22>( hyperElastic2, surfaceQuadrature, solver, interfaceFieldBinder, ip, false, false ); // -kappa2 } } #endif //-------------------------------------------------------------------------- // Solve and distribute solver.finishAssembly(); message( "Assembly time = " + detailed.print() ); detailed.reset(); #ifdef VERBOSE { solver.systemInfo( std::cout ); std::ofstream mat( "matrix" ); solver.debugLHS( mat ); std::ofstream vec( "vector" ); solver.debugRHS( vec ); } #endif #if 1 // decide to solve and post-process //solver.choleskySolve(); const unsigned numCGIter = solver.cgSolve(); //message( "Solve time = " + detailed.print() ); const double solveTime = detailed.seconds(); detailed.reset(); base::dof::setDoFsFromSolver( solver, fieldIn ); base::dof::setDoFsFromSolver( solver, fieldOut ); //-------------------------------------------------------------------------- // Extract distances, closestPoints and location flags from level set data { } //-------------------------------------------------------------------------- { const std::string vtkFile = baseName + ".vtk"; std::ofstream vtk( vtkFile.c_str() ); base::io::vtk::LegacyWriter vtkWriter( vtk ); vtkWriter.writeUnstructuredGrid( mesh ); { std::vector<double> distances; std::transform( levelSet.begin(), levelSet.end(), std::back_inserter( distances ), boost::bind( &LevelSet::getSignedDistance, _1 ) ); vtkWriter.writePointData( distances.begin(), distances.end(), "distances" ); } { std::vector<bool> location; std::transform( levelSet.begin(), levelSet.end(), std::back_inserter( location ), boost::bind( &LevelSet::isInterior, _1 ) ); vtkWriter.writePointData( location.begin(), location.end(), "location" ); } vtkWriter.writePointData( supportsIn.begin(), supportsIn.end(), "suppIn" ); vtkWriter.writePointData( supportsOut.begin(), supportsOut.end(), "suppOut" ); base::io::vtk::writePointData( vtkWriter, mesh, fieldIn, "fieldIn" ); base::io::vtk::writePointData( vtkWriter, mesh, fieldOut, "fieldOut" ); vtk.close(); } #ifdef VERBOSE // decide error verbosity // integrate double volumeIn = 0.; base::asmb::simplyIntegrate<FTB1>( cutQuadratureIn, volumeIn, fieldBinder, base::kernel::Measure<FTB1::Tuple>() ); double volumeOut = 0.; base::asmb::simplyIntegrate<FTB2>( cutQuadratureOut, volumeOut, fieldBinder, base::kernel::Measure<FTB2::Tuple>() ); std::cout << "Volume of mesh: " << volumeIn << " + " << volumeOut << " = " << volumeIn + volumeOut << '\n'; #else // for convergence analysis std::cout << solveTime << " " << numCGIter << "\n"; #endif #endif // decide to solve and write message( "Post-process time = " + detailed.print() ); message( "---------------------------------------" ); message( "Total time = " + total.print() ); return 0; }