Example #1
0
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();
}
Example #2
0
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();
}
Example #3
0
//------------------------------------------------------------------------------
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;
}