<commit_before>/*
 * File:   Composite.cpp
 * Author: Benedikt Vogler
 *
 * Created on 21. August 2014, 10:51
 */

#include "Composite.hpp"
#include "Intersection.hpp"
#include <algorithm>

void Composite::add_child(std::shared_ptr<RenderObject> const& child) {
    children.push_back(child);
}

Intersection Composite::intersect(Ray const& ray) const {
    Ray ray_t;
    if (isTransformed())
        ray_t = Ray(
            glm::vec3(getWorldTransfInv() * glm::vec4(ray.origin, 1)),
            glm::vec3(getWorldTransfInv() * glm::vec4(ray.direction, 0))
        );
    else
        ray_t = ray;

    std::vector<Intersection> intersections;

    //collect every intersection
    for(auto child = children.begin(); child != children.end(); ++child) {//every children
        auto intersection = (*child)->intersect(ray_t);
        if (intersection.hit && ray.mint<intersection.distance && ray.maxt>intersection.distance)
            intersections.push_back(intersection);
    }

    if (intersections.size()==0) return Intersection();//no intersection

    //return only intersection with nearest point
    return *std::min_element(
        intersections.begin(),
        intersections.end(),
        [](Intersection const& a, Intersection const& b)->bool { return a.distance < b.distance;}
    );

}<commit_msg>for each loop<commit_after>/*
 * File:   Composite.cpp
 * Author: Benedikt Vogler
 *
 * Created on 21. August 2014, 10:51
 */

#include "Composite.hpp"
#include "Intersection.hpp"
#include <algorithm>

void Composite::add_child(std::shared_ptr<RenderObject> const& child) {
    children.push_back(child);
}

Intersection Composite::intersect(Ray const& ray) const {
    Ray ray_t;
    if (isTransformed())
        ray_t = Ray(
            glm::vec3(getWorldTransfInv() * glm::vec4(ray.origin, 1)),
            glm::vec3(getWorldTransfInv() * glm::vec4(ray.direction, 0))
        );
    else
        ray_t = ray;

    std::vector<Intersection> intersections;

    //collect every intersection
    for(auto& child : children) {//every children
        auto intersection = child->intersect(ray_t);
        if (intersection.hit && ray.mint<intersection.distance && ray.maxt>intersection.distance)
            intersections.push_back(intersection);
    }

    if (intersections.size()==0) return Intersection();//no intersection

    //return only intersection with nearest point
    return *std::min_element(
        intersections.begin(),
        intersections.end(),
        [](Intersection const& a, Intersection const& b)->bool { return a.distance < b.distance;}
    );

}<|endoftext|>


<commit_before>#include "sdfloader.hpp"

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <glm/vec3.hpp>

#include "color.hpp"
#include "material.hpp"
#include "box.hpp"
#include "sphere.hpp"
#include "light.hpp"
#include "camera.hpp"
//#include "scene.hpp"

void load_scene() {
  std::string line;
  std::ifstream myfile ("../../../scene/scene1.txt");
  std::map<std::string, std::shared_ptr<Material>> materials;
  std::vector<std::shared_ptr<Shape>> shapes;
  std::vector<std::shared_ptr<Light>> lights;
  int xres,yres;
  Color amblight, background;
  std::string filename;
  Camera cam;
//  Scene scene1;
  if (myfile.is_open())
  {
    while ( getline (myfile,line) )
     {
      //std::cout << line << '\n';
      std::stringstream ss;
  	  ss << line;

  	  std::string keyword;

  	  ss>>keyword;
      if(keyword == "#"){continue;}
      if(keyword == "define"){
     	    ss>>keyword;
          if(keyword == "material"){
            Material mat;
            ss>>mat.name;
     	      ss>>mat.ka.r;
     	      ss>>mat.ka.g;
            ss>>mat.ka.b;

            ss>>mat.ks.r;
        	  ss>>mat.ks.g;
            ss>>mat.ks.b;

            ss>>mat.kd.r;
        	  ss>>mat.kd.g;
            ss>>mat.kd.b;
       	    ss>>mat.m;

            std::shared_ptr<Material> temp_ptr = std::make_shared<Material>(mat);
            materials.insert({mat.name, temp_ptr});
            //materials[mat.name]= mat;
            std::cout << mat;
          }
          if(keyword == "shape"){
            ss>>keyword;

            if(keyword == "box"){
              std::string name;
              std::string mat_namebox;
              float minx,miny,minz,maxx,maxy,maxz;

              ss>>minx;
              ss>>miny;
              ss>>minz;
              ss>>maxx;
              ss>>maxy;
              ss>>maxz;

              glm::vec3 min{minx,miny,minz};
              glm::vec3 max{maxx,maxy,maxz};
              ss>>name;
              ss>>mat_namebox;
              //std::string mat_namebox;

              std::shared_ptr<Shape> temp_ptr = std::make_shared<Box>
              (
                Box{min,max,name,*materials[mat_namebox]}
              );
                std::cout << *temp_ptr;
                shapes.push_back(temp_ptr);

            }
            else if(keyword == "sphere"){
              std::string name;
              float x,y,z,r;
              ss>>name;
              ss>>x;
              ss>>y;
              ss>>z;
              glm::vec3 middle{x,y,z};
              ss>>r;
              std::string mat_name;
              ss>>mat_name;
              //alternative

            /*std::cout <<mat_name;
              ss>>sph.name_;
              ss>>sph.middle_.x;
              ss>>sph.middle_.y;
              ss>>sph.middle_.z;
              ss>>sph.r_;
              ss>>sph.mat_;
              std::cout << sph;sph.mat_=*materials(mat_name);*/
              std::shared_ptr<Shape> temp_ptr = std::make_shared<Sphere>
              (
                Sphere{middle,r,name,*materials[mat_name]}
              );
                std::cout << *temp_ptr;
                shapes.push_back(temp_ptr);
              // std::cout << sph;
            }

            }
          if(keyword == "light"){
              std::string name;
              std::string mat_namelight;
              float posx, posy, posz, ldr, ldg, ldb;
              ss>>name;
              ss>>posx;
              ss>>posy;
              ss>>posz;
              glm::vec3 pos{posx,posy,posz};
              ss>>ldr;
              ss>>ldg;
              ss>>ldb;
              Color ld{ldr,ldg,ldb};

              std::shared_ptr<Light> temp_ptr = std::make_shared<Light>
              (
                Light{name, pos, ld}
              );
                std::cout << *temp_ptr;
                lights.push_back(temp_ptr);

          }

          if(keyword == "camera"){
              std::string name;
              float angle, posx, posy, posz;
              ss>>name;
              ss>>posx;
              ss>>posy;
              ss>>posz;
              glm::vec3 pos{posx,posy,posz};
              ss>>angle;

              /*std::shared_ptr<Camera> cam_ptr = std::make_shared<Camera>
              (
                Camera{name,pos,angle}
              );*/
              Camera camera;
              //cam.name_=name;
              //cam.pos_=pos;
              //cam.angle_=angle;
              //Camera cam{name,pos,angle};
              std::cout << cam;
              cam=camera;

          }
          if(keyword == "amblight"){
              ss>>ambr;
              ss>>ambg;
              ss>>ambb;
              Color amb{ambr,ambg,ambb};
              amblight=amb;
        }
        if(keyword == "background"){
              ss>>backr;
              ss>>backg;
              ss>>backb;
              Color back{backr,backg,backb};
              background=back;
        }
        if(keyword == "renderer"){
          ss>>keyword;
          ss>>filename;
          ss>>xres;
          ss>>yres;
          std::shared_ptr<Scene> scene_ptr = std::make_shared<Scene>
            (
              Scene{filename, xres, yres, cam, amblight, background, materials, shapes, lights}
            );
        }
      }

      myfile.close();
    }

  else std::cout << "Unable to open file";
}
<commit_msg>tryin to find out da damn issuse, bad voodo that is ma friend...<commit_after>#include "sdfloader.hpp"

#include <iostream>
#include <fstream>
#include <sstream>
#include <string>
#include <map>
#include <vector>
#include <memory>
#include <glm/vec3.hpp>

#include "color.hpp"
#include "material.hpp"
#include "box.hpp"
#include "sphere.hpp"
#include "light.hpp"
#include "camera.hpp"
#include "scene.hpp"

void load_scene() {
  std::string line;
  std::ifstream myfile ("../../../scene/scene1.txt");
  std::map<std::string, std::shared_ptr<Material>> materials;
  std::vector<std::shared_ptr<Shape>> shapes;
  std::vector<std::shared_ptr<Light>> lights;
  int xres,yres;
  Color amblight, background;
  std::string filename;
  Camera cam;
//  Scene scene1;
  if (myfile.is_open())
  {
    while ( getline (myfile,line) )
     {
      //std::cout << line << '\n';
      std::stringstream ss;
  	  ss << line;

  	  std::string keyword;

  	  ss>>keyword;
      if(keyword == "#"){continue;}
      if(keyword == "define"){
     	    ss>>keyword;
          if(keyword == "material"){
            Material mat;
            ss>>mat.name;
     	      ss>>mat.ka.r;
     	      ss>>mat.ka.g;
            ss>>mat.ka.b;

            ss>>mat.ks.r;
        	  ss>>mat.ks.g;
            ss>>mat.ks.b;

            ss>>mat.kd.r;
        	  ss>>mat.kd.g;
            ss>>mat.kd.b;
       	    ss>>mat.m;

            std::shared_ptr<Material> temp_ptr = std::make_shared<Material>(mat);
            materials.insert({mat.name, temp_ptr});
            //materials[mat.name]= mat;
            std::cout << mat;
          }
          if(keyword == "shape"){
            ss>>keyword;

            if(keyword == "box"){
              std::string name;
              std::string mat_namebox;
              float minx,miny,minz,maxx,maxy,maxz;

              ss>>minx;
              ss>>miny;
              ss>>minz;
              ss>>maxx;
              ss>>maxy;
              ss>>maxz;

              glm::vec3 min{minx,miny,minz};
              glm::vec3 max{maxx,maxy,maxz};
              ss>>name;
              ss>>mat_namebox;
              //std::string mat_namebox;

              std::shared_ptr<Shape> temp_ptr = std::make_shared<Box>
              (
                Box{min,max,name,*materials[mat_namebox]}
              );
                std::cout << *temp_ptr;
                shapes.push_back(temp_ptr);

            }
            else if(keyword == "sphere"){
              std::string name;
              float x,y,z,r;
              ss>>name;
              ss>>x;
              ss>>y;
              ss>>z;
              glm::vec3 middle{x,y,z};
              ss>>r;
              std::string mat_name;
              ss>>mat_name;
              //alternative

            /*std::cout <<mat_name;
              ss>>sph.name_;
              ss>>sph.middle_.x;
              ss>>sph.middle_.y;
              ss>>sph.middle_.z;
              ss>>sph.r_;
              ss>>sph.mat_;
              std::cout << sph;sph.mat_=*materials(mat_name);*/
              std::shared_ptr<Shape> temp_ptr = std::make_shared<Sphere>
              (
                Sphere{middle,r,name,*materials[mat_name]}
              );
                std::cout << *temp_ptr;
                shapes.push_back(temp_ptr);
              // std::cout << sph;
            }

            }
          if(keyword == "light"){
              std::string name;
              std::string mat_namelight;
              float posx, posy, posz, ldr, ldg, ldb;
              ss>>name;
              ss>>posx;
              ss>>posy;
              ss>>posz;
              glm::vec3 pos{posx,posy,posz};
              ss>>ldr;
              ss>>ldg;
              ss>>ldb;
              Color ld{ldr,ldg,ldb};

              std::shared_ptr<Light> temp_ptr = std::make_shared<Light>
              (
                Light{name, pos, ld}
              );
                std::cout << *temp_ptr;
                lights.push_back(temp_ptr);

          }

          if(keyword == "camera"){
              std::string name;
              float angle, posx, posy, posz;
              ss>>name;
              ss>>posx;
              ss>>posy;
              ss>>posz;
              glm::vec3 pos{posx,posy,posz};
              ss>>angle;

              /*std::shared_ptr<Camera> cam_ptr = std::make_shared<Camera>
              (
                Camera{name,pos,angle}
              );*/
              Camera camera;
              //cam.name_=name;
              //cam.pos_=pos;
              //cam.angle_=angle;
              //Camera cam{name,pos,angle};
              std::cout << cam;
              cam=camera;

          }
          if(keyword == "amblight"){
              float ambr,ambg,ambb;
              ss>>ambr;
              ss>>ambg;
              ss>>ambb;
              Color amb{ambr,ambg,ambb};
              amblight=amb;
        }
        if(keyword == "background"){
              float backr, backg, backb;
              ss>>backr;
              ss>>backg;
              ss>>backb;
              Color back{backr,backg,backb};
              background=back;
        }
        if(keyword == "renderer"){
          ss>>keyword;
          ss>>filename;
          ss>>xres;
          ss>>yres;
          std::shared_ptr<Scene> scene_ptr = std::make_shared<Scene>
            (
              Scene{filename, xres, yres, cam, amblight, background, materials, shapes, lights}
            );
        }
      }

      myfile.close();
    }

  else std::cout << "Unable to open file";
}
<|endoftext|>


<commit_before>#include <Bull/Window/X11/WindowImplX11.hpp>

namespace Bull
{
    namespace prv
    {
        /*! \brief Constructor
         *
         * \param mode The VideoMode to use to create the window
         * \param title The title of the window
         * \param style The style to use to create the window
         *
         */
        WindowImplX11::WindowImplX11(const VideoMode& mode, const String& title, Uint32 style) :
            m_display(Display::get()),
            m_handler(0)
        {
            XSetWindowAttributes attribs;
            attribs.event_mask = KeyPressMask | KeyReleaseMask;

            m_handler = XCreateWindow(m_display->getHandler(),
                                      m_display->getRootWindow(),
                                      0, 0,
                                      mode.width, mode.height,
                                      0,
                                      CopyFromParent,
                                      InputOutput,
                                      nullptr,
                                      CWEventMask | CWBackPixel,
                                      &attribs);

            setTitle(title);

            XMapWindow(m_display->getHandler(), m_handler);
            m_display->flush();
        }

        /*! \brief Destructor
         *
         */
        WindowImplX11::~WindowImplX11()
        {
            XDestroyWindow(m_display->getHandler(), m_handler);
        }

        /*! \brief Start to process events to fill event queue
         *
         */
        void WindowImplX11::startProcessEvents()
        {
            XEvent e;
            while(XPending(m_display->getHandler()))
            {
                XNextEvent(m_display->getHandler(), &e);
                switch(e.type)
                {
                    case KeyPress:
                    {
                        Window::Event event;

                        event.type = Window::Event::KeyDown;

                        pushEvent(event);
                    }
                    break;

                    case KeyRelease:
                    {
                        Window::Event event;

                        event.type = Window::Event::KeyUp;

                        pushEvent(event);
                    }
                    break;
                }
            }
        }

        /*! \brief Minimize a window
         *
         */
        void WindowImplX11::minimize()
        {

        }

        /*! \brief Check if the window is minimized
         *
         * \return Return true if the window is minimized, false otherwise
         *
         */
        bool WindowImplX11::isMinimized() const
        {

        }

        /*! \brief Maximize a window
         *
         */
        void WindowImplX11::maximize()
        {

        }

        /*! \brief Check if the window is maximized
         *
         * \return Return true if the window is maximized, false otherwise
         *
         */
        bool WindowImplX11::isMaximized() const
        {

        }

        /*! \brief Enable or disable the capture of the cursor inside the window
         *
         * \param enable The state of the capture
         *
         */
        void WindowImplX11::enableCaptureCursor(bool capture)
        {

        }

        /*! \brief Hide or show the cursor
         *
         * \param enable The state of the cursor
         *
         */
        void WindowImplX11::showCursor(bool enable)
        {

        }

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void WindowImplX11::setPosition(const Vector2I& position)
        {

        }

        /*! \brief Set the size of the window
         *
         * \param x The new width of the window
         * \param y The new height of the window
         *
         */
        Vector2I WindowImplX11::getPosition() const
        {

        }

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void WindowImplX11::setSize(const Vector2UI& size)
        {

        }

        /*! \brief Get the size of the window
         *
         * \return Return the size of the window
         *
         */
        Vector2UI WindowImplX11::getSize() const
        {

        }

        /*! \brief Set the title of the window
         *
         * \param title The title to set to the window
         *
         */
        void WindowImplX11::setTitle(const String& title)
        {
            XStoreName(m_display->getHandler(), m_handler, title);
        }

        /*! \brief Get the title of the window
         *
         * \return Return the title of the window
         *
         */
        String WindowImplX11::getTitle() const
        {

        }

        /*! \brief Check if the window has the focus
         *
         * \param Return true if the window has the focus, false otherwise
         *
         */
        bool WindowImplX11::hasFocus() const
        {

        }

        /*! \brief Enter or leave the fullscreen mode
         *
         * \param mode The VideoMode to use
         * \param fullscreen False to leave the fullscreen mode, true to enter the fullscreen mode
         *
         * \return Return true if the switch was done successfully, false otherwise
         *
         */
        bool WindowImplX11::switchFullscreen(const VideoMode& mode, bool fullscreen)
        {

        }

        /*! \brief Show or hide the window
         *
         * \param visible True to show the window, false to hide the window
         *
         */
        void WindowImplX11::setVisible(bool visible)
        {

        }

        /*! \brief Get the window system handler
         *
         * \return Return the native window system handler
         *
         */
        WindowHandler WindowImplX11::getSystemHandler() const
        {
            return m_handler;
        }
    }
}
<commit_msg>[WIndow/Window/X11] Handle mouse events<commit_after>#include <Bull/Window/X11/WindowImplX11.hpp>

#ifndef Button6
    #define Button6 6
#endif // Button6

#ifndef Button7
    #define Button7 7
#endif // Button6

#ifndef Button8
    #define Button8 8
#endif // Button6

#ifndef Button9
    #define Button9 9
#endif // Button6

namespace Bull
{
    namespace prv
    {
        namespace
        {
            const long eventMasks = KeyPressMask      | KeyReleaseMask    | /// Keyboard events
                                    PointerMotionMask |                    /// Mouse move event
                                    ButtonPressMask   | ButtonReleaseMask;

        }
        /*! \brief Constructor
         *
         * \param mode The VideoMode to use to create the window
         * \param title The title of the window
         * \param style The style to use to create the window
         *
         */
        WindowImplX11::WindowImplX11(const VideoMode& mode, const String& title, Uint32 style) :
            m_display(Display::get()),
            m_handler(0)
        {
            XSetWindowAttributes attribs;
            attribs.event_mask = eventMasks;

            m_handler = XCreateWindow(m_display->getHandler(),
                                      m_display->getRootWindow(),
                                      0, 0,
                                      mode.width, mode.height,
                                      0,
                                      CopyFromParent,
                                      InputOutput,
                                      nullptr,
                                      CWEventMask | CWBackPixel,
                                      &attribs);

            setTitle(title);

            XMapWindow(m_display->getHandler(), m_handler);
            m_display->flush();
        }

        /*! \brief Destructor
         *
         */
        WindowImplX11::~WindowImplX11()
        {
            XDestroyWindow(m_display->getHandler(), m_handler);
        }

        /*! \brief Start to process events to fill event queue
         *
         */
        void WindowImplX11::startProcessEvents()
        {
            XEvent e;
            while(XPending(m_display->getHandler()))
            {
                XNextEvent(m_display->getHandler(), &e);
                switch(e.type)
                {
                    case KeyPress:
                    {
                        Window::Event event;

                        event.type = Window::Event::KeyDown;

                        pushEvent(event);
                    }
                    break;

                    case KeyRelease:
                    {
                        Window::Event event;

                        event.type = Window::Event::KeyUp;

                        pushEvent(event);
                    }
                    break;

                    case MotionNotify:
                    {
                        Window::Event event;

                        event.type        = Window::Event::MouseMoved;
                        event.mouseMove.x = e.xmotion.x;
                        event.mouseMove.y = e.xmotion.y;

                        pushEvent(event);
                    }
                    break;

                    case ButtonPress:
                    {
                        Window::Event event;

                        if(e.xbutton.button <= Button3 || e.xbutton.button >= Button8)
                        {
                            event.type          = Window::Event::MouseButtonDown;
                            event.mouseButton.x = e.xbutton.x;
                            event.mouseButton.y = e.xbutton.y;

                        }
                        else
                        {
                            event.type         = Window::Event::MouseWheel;
                            event.mouseWheel.x = e.xbutton.x;
                            event.mouseWheel.y = e.xbutton.y;
                        }

                        switch(e.xbutton.button)
                        {
                            case Button1:
                                event.mouseButton.button = Mouse::Left;
                            break;
                            case Button2:
                                event.mouseButton.button = Mouse::Middle;
                            break;
                            case Button3:
                                event.mouseButton.button = Mouse::Right;
                            break;
                            case Button4:
                                event.mouseWheel.up      = true;
                                event.mouseWheel.wheel   = Mouse::Vertical;
                            break;
                            case Button5:
                                event.mouseWheel.up      = false;
                                event.mouseWheel.wheel   = Mouse::Vertical;
                            break;
                            case Button6:
                                event.mouseWheel.up      = true;
                                event.mouseWheel.wheel   = Mouse::Horizontal;
                            break;
                            case Button7:
                                event.mouseWheel.up      = false;
                                event.mouseWheel.wheel   = Mouse::Horizontal;
                            break;
                            case Button8:
                                event.mouseButton.button = Mouse::Extra1;
                            break;
                            case Button9:
                                event.mouseButton.button = Mouse::Extra2;
                            break;
                        }

                        pushEvent(event);
                    }
                    break;

                    case ButtonRelease:
                    {
                        if(e.xbutton.button <= Button3 || e.xbutton.button >= Button8)
                        {
                            Window::Event event;
                            event.type = Window::Event::MouseButtonUp;

                            switch(e.xbutton.button)
                            {
                                case Button1:
                                    event.mouseButton.button = Mouse::Left;
                                break;
                                case Button2:
                                    event.mouseButton.button = Mouse::Middle;
                                break;
                                case Button3:
                                    event.mouseButton.button = Mouse::Right;
                                break;
                                case Button8:
                                    event.mouseButton.button = Mouse::Extra1;
                                break;
                                case Button9:
                                    event.mouseButton.button = Mouse::Extra2;
                                break;
                            }

                            event.mouseButton.x = e.xbutton.x;
                            event.mouseButton.y = e.xbutton.y;

                            pushEvent(event);
                        }
                    }
                    break;
                }
            }
        }

        /*! \brief Minimize a window
         *
         */
        void WindowImplX11::minimize()
        {

        }

        /*! \brief Check if the window is minimized
         *
         * \return Return true if the window is minimized, false otherwise
         *
         */
        bool WindowImplX11::isMinimized() const
        {

        }

        /*! \brief Maximize a window
         *
         */
        void WindowImplX11::maximize()
        {

        }

        /*! \brief Check if the window is maximized
         *
         * \return Return true if the window is maximized, false otherwise
         *
         */
        bool WindowImplX11::isMaximized() const
        {

        }

        /*! \brief Enable or disable the capture of the cursor inside the window
         *
         * \param enable The state of the capture
         *
         */
        void WindowImplX11::enableCaptureCursor(bool capture)
        {

        }

        /*! \brief Hide or show the cursor
         *
         * \param enable The state of the cursor
         *
         */
        void WindowImplX11::showCursor(bool enable)
        {

        }

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void WindowImplX11::setPosition(const Vector2I& position)
        {

        }

        /*! \brief Set the size of the window
         *
         * \param x The new width of the window
         * \param y The new height of the window
         *
         */
        Vector2I WindowImplX11::getPosition() const
        {

        }

        /*! \brief Set the size of the window
         *
         * \param size The new size of the window
         *
         */
        void WindowImplX11::setSize(const Vector2UI& size)
        {

        }

        /*! \brief Get the size of the window
         *
         * \return Return the size of the window
         *
         */
        Vector2UI WindowImplX11::getSize() const
        {

        }

        /*! \brief Set the title of the window
         *
         * \param title The title to set to the window
         *
         */
        void WindowImplX11::setTitle(const String& title)
        {
            XStoreName(m_display->getHandler(), m_handler, title);
        }

        /*! \brief Get the title of the window
         *
         * \return Return the title of the window
         *
         */
        String WindowImplX11::getTitle() const
        {

        }

        /*! \brief Check if the window has the focus
         *
         * \param Return true if the window has the focus, false otherwise
         *
         */
        bool WindowImplX11::hasFocus() const
        {

        }

        /*! \brief Enter or leave the fullscreen mode
         *
         * \param mode The VideoMode to use
         * \param fullscreen False to leave the fullscreen mode, true to enter the fullscreen mode
         *
         * \return Return true if the switch was done successfully, false otherwise
         *
         */
        bool WindowImplX11::switchFullscreen(const VideoMode& mode, bool fullscreen)
        {

        }

        /*! \brief Show or hide the window
         *
         * \param visible True to show the window, false to hide the window
         *
         */
        void WindowImplX11::setVisible(bool visible)
        {

        }

        /*! \brief Get the window system handler
         *
         * \return Return the native window system handler
         *
         */
        WindowHandler WindowImplX11::getSystemHandler() const
        {
            return m_handler;
        }
    }
}
<|endoftext|>


<commit_before>#include <iostream>
#include <math.h>
#include <cmath>
#include "CombFilterProject.h"
#include "FilterAudio.h"

//# define TEST_MODE

using namespace std;

//function
int testZeroInput();
float *sinOsc(float, float, float, unsigned);
int testFIRFeedforward();
int testIIRFeedforward();

// main function
int main(int argc, char* argv[])
{
    //decalare local variables
    CombFilterProject *pCombFilterProject;

    string sInputFilePath, sOutputFilePath, sInputFileName, sOutputFileName;

    float fFIRCoeff = 0.0;
    float fIIRCoeff = 0.0;
    float fDelayInMSec = 0.0;
    int iBlockSize = 2048; //default blockSize
    bool bOutputResultToTextFile = false; //default
    int iFileOpenStatus;

    // Parse command line arguments
    if( argc == 7 || argc == 8) {
        //File path and name
        sInputFilePath = argv[1];
        sInputFileName = argv[2];

        //Gain
        fFIRCoeff = atof(argv[3]);
        fIIRCoeff = atof(argv[4]);

        //Check for boundary conditions
        if (fFIRCoeff > 1 || fFIRCoeff < -1 || fIIRCoeff > 1 || fFIRCoeff < -1) {
            cout<<"\nFIR/IIR Co-efficient should be between -1 and 1.\n";
            return 0;
        }
        //Delay time
        fDelayInMSec = atof(argv[5]);

        //Check that delay time is positive
        if (fDelayInMSec < 0 ) {
            cout<<"\nDelay time must be positive.\n";
            return 0;
        }

        //enable write to Text file
        if (argv[6] != NULL) {
            int temp = atoi(argv[6]);
            if (temp == 1) {
                bOutputResultToTextFile = true;
            }
        }

        //Optional argument to set blockSize
        if (argv[7] != NULL) {
            iBlockSize = atoi(argv[7]);
        }
    }
    else if( argc > 8 ) {
        printf("Too many arguments supplied.\n");
        return 0;
    }
    else {
        printf("Please provide the following\n 1.file path\n 2.audio file name\n 3.FIR gain\n 4.IIR gain\n 5.delay time in milliseconds\n 6.write to text file (yes - 1, no - any value)\n 7.[OPTIONAL] block size\n ");
        return 0;
    }

    //Create Comb Filter
    CombFilterProject::create(pCombFilterProject, iBlockSize);

    //Print Information
    cout<<"CombFilter V"<<pCombFilterProject->getVersion(CombFilterProject::kMajor)
    <<"."<<pCombFilterProject->getVersion(CombFilterProject::kMinor)
    <<"."<<pCombFilterProject->getVersion(CombFilterProject::kPatch)<<endl;

    cout<<"Build date: "<<pCombFilterProject->getBuildDate()<<endl<<endl;

    cout<<"Reading audio file: "<<sInputFilePath<<sInputFileName<<"\n";
    cout<<"\nFIR Coefficient:"<<fFIRCoeff;
    cout<<"\nIIR Coefficient:"<<fIIRCoeff;
    cout<<"\nBlock size :"<<iBlockSize;
    cout<<"\nDelay in milliseconds :"<<fDelayInMSec;

    //Set defaults
    sOutputFilePath = sInputFilePath;
    sOutputFileName = "output.wav";

    //Initialize CombFilter
    iFileOpenStatus = pCombFilterProject->init(sInputFilePath, sInputFileName, sOutputFilePath, sOutputFileName, fFIRCoeff, fIIRCoeff, fDelayInMSec, bOutputResultToTextFile);

    if (iFileOpenStatus != 0) {
        /*File open error*/
        return 0;
    }

    cout<<"\nDelay in samples: "<<pCombFilterProject->getDelayinSamples()<<endl<<endl;

    pCombFilterProject->processAudio();

    pCombFilterProject->destroy(pCombFilterProject);

    cout<<"Success!\n";

    testZeroInput();
    testFIRFeedforward();
    testIIRFeedforward();

    return 0;
}

int testZeroInput() {
    FilterAudio *pFilter;
    float fFIRCoeff = 1.0;
    float fIIRCoeff = 0.0;
    int iDelayInSamples = 10;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks = 50; //Test for 10 blocks
    float **ppfAudioData = new float *[iNumChannels];

    for (int n=0; n<iNumChannels; n++) {
        ppfAudioData[n] = new float[iBlockSize];
        for (int m=0; m<iBlockSize; m++) {
            ppfAudioData[n][m] = 0;
        }
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    while (iNumBlocks > 0) {
        pFilter->combFilterBlock(ppfAudioData, iBlockSize, iNumChannels);

        for (int n=0; n<iNumChannels; n++) {
            for (int m=0; m<iBlockSize; m++) {
                if (ppfAudioData[n][m] > 0.001) {

                    cout<<"\nZero Input Test: failed!\n";
                    return -1;
                }
            }
        }
        iNumBlocks--;
    }

    cout<<"\nZero Input Test: Success!\n";
    return 0;
}

int testFIRFeedforward() {

    FilterAudio *pFilter;
    float fFIRCoeff = 1.0;
    float fIIRCoeff = 0.0;
    int iDelayInSamples = 50;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks;

    float fFreq = 441.0; //Hz
    float fTimeInSecs = 2.0;
    unsigned uSampleRate = 44100;

    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    float *sinWave = sinOsc(fFreq, 1.0, fTimeInSecs, uSampleRate);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

    for (int c=0; c<iNumChannels; c++) {

        int start = 0;

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            start = 0;
            if (n == 0){
                start = iDelayInSamples+1;
            }

            for (int m=start; m<iBlockSize; m++) {
                if (std::abs(buffer[c][m]) > 0.001) {
                    cout<<"\nFIR Feedforward Test: failed!\n";
                    return -1;
                }
            }

        }

        cout<<"\nFIR Feedforward Test: Success!\n";
    }

    return 0;
}

int testIIRFeedforward() {

    FilterAudio *pFilter;
    float fFIRCoeff = 0.0;
    float fIIRCoeff = 0.1;
    int iDelayInSamples = 100;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks;

    float fFreq = 441.0; //Hz
    float fTimeInSecs = 2.0;
    unsigned uSampleRate = 44100;

    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    float **origBuffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        origBuffer[i] = new float[iBlockSize];
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    float *sinWave = sinOsc(fFreq, 1.0, fTimeInSecs, uSampleRate);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

//    int iPeriodInSamples = (int)uSampleRate/fFreq;

    for (int c=0; c<iNumChannels; c++) {

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
                memcpy(origBuffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            float* temp = buffer[c];
            float* origTemp = origBuffer[c];
//            float* diff = new float[iBlockSize];

//            for (int m=iPeriodInSamples+iPeriodInSamples/4; m<iBlockSize; m=m+iPeriodInSamples) {
//
//                if (buffer[c][m] <= origBuffer[c][m]) {
//                    cout<<"\IIR Feedforward Test: failed!\n";
//                    return -1;
//                }
//
//
//            }

        }

        cout<<"\nIIR Feedforward Test: Success!\n";
    }

    return 0;
}

float *sinOsc(float fFreq, float fAmp, float fLengthInSec, unsigned uFs){

    float pi = 3.1415926535897932346;

    int lengthInSamples = ceil(fLengthInSec * uFs);
    float* fSineWave = new float[lengthInSamples];

    // Fill sine wave
    for(int i = 0; i<lengthInSamples; i++){
        fSineWave[i] = fAmp* sin((2.f*pi*fFreq)/(uFs) *i);
    }

    return fSineWave;
}

<commit_msg>All test functions updated<commit_after>#include <iostream>
#include <math.h>
#include <cmath>
#include "CombFilterProject.h"
#include "FilterAudio.h"

# define TEST_MODE

using namespace std;

//function declarations
float *sinOsc(float, float, float, unsigned);
int testZeroInput();
int testFIRFeedforward();
int testIIRDestructiveFeedforward();
int testIIRConstructiveFeedforward();
int testDifferntBlockSizes();
int testZeroDelay(int, float, float);
int testFIRImpulseResponse();
int testIIRImpulseResponse();

// main function
int main(int argc, char* argv[])
{
    //decalare local variables
    CombFilterProject *pCombFilterProject;

    string sInputFilePath, sOutputFilePath, sInputFileName, sOutputFileName;

    float fFIRCoeff = 0.0;
    float fIIRCoeff = 0.0;
    float fDelayInMSec = 0.0;
    int iBlockSize = 2048; //default blockSize
    bool bOutputResultToTextFile = false; //default
    int iFileOpenStatus;

    // Parse command line arguments
    if( argc == 7 || argc == 8) {
        //File path and name
        sInputFilePath = argv[1];
        sInputFileName = argv[2];

        //Gain
        fFIRCoeff = atof(argv[3]);
        fIIRCoeff = atof(argv[4]);

        //Check for boundary conditions
        if (fFIRCoeff > 1 || fFIRCoeff < -1 || fIIRCoeff > 1 || fFIRCoeff < -1) {
            cout<<"\nFIR/IIR Co-efficient should be between -1 and 1.\n";
            return 0;
        }
        //Delay time
        fDelayInMSec = atof(argv[5]);

        //Check that delay time is positive
        if (fDelayInMSec < 0 ) {
            cout<<"\nDelay time must be positive.\n";
            return 0;
        }

        //enable write to Text file
        if (argv[6] != NULL) {
            int temp = atoi(argv[6]);
            if (temp == 1) {
                bOutputResultToTextFile = true;
            }
        }

        //Optional argument to set blockSize
        if (argv[7] != NULL) {
            iBlockSize = atoi(argv[7]);
        }
    }
    else if( argc > 8 ) {
        printf("Too many arguments supplied.\n");
        return 0;
    }
    else {
        printf("Please provide the following\n 1.file path\n 2.audio file name\n 3.FIR gain\n 4.IIR gain\n 5.delay time in milliseconds\n 6.write to text file (yes - 1, no - any value)\n 7.[OPTIONAL] block size\n ");
        return 0;
    }

    //Create Comb Filter
    CombFilterProject::create(pCombFilterProject, iBlockSize);

    //Print Information
    cout<<"CombFilter V"<<pCombFilterProject->getVersion(CombFilterProject::kMajor)
    <<"."<<pCombFilterProject->getVersion(CombFilterProject::kMinor)
    <<"."<<pCombFilterProject->getVersion(CombFilterProject::kPatch)<<endl;

    cout<<"Build date: "<<pCombFilterProject->getBuildDate()<<endl<<endl;

    cout<<"Reading audio file: "<<sInputFilePath<<sInputFileName<<"\n";
    cout<<"\nFIR Coefficient:"<<fFIRCoeff;
    cout<<"\nIIR Coefficient:"<<fIIRCoeff;
    cout<<"\nBlock size :"<<iBlockSize;
    cout<<"\nDelay in milliseconds :"<<fDelayInMSec;

    //Set defaults
    sOutputFilePath = sInputFilePath;
    sOutputFileName = "output.wav";

    //Initialize CombFilter
    iFileOpenStatus = pCombFilterProject->init(sInputFilePath, sInputFileName, sOutputFilePath, sOutputFileName, fFIRCoeff, fIIRCoeff, fDelayInMSec, bOutputResultToTextFile);

    if (iFileOpenStatus != 0) {
        /*File open error*/
        return 0;
    }

    cout<<"\nDelay in samples: "<<pCombFilterProject->getDelayinSamples()<<endl<<endl;

    pCombFilterProject->processAudio();

    pCombFilterProject->destroy(pCombFilterProject);

    cout<<"Success!\n";

#ifdef TEST_MODE

    cout<<"\n====== Test Results ======\n";
    testFIRFeedforward();
    testIIRDestructiveFeedforward();
    testIIRConstructiveFeedforward();
    testDifferntBlockSizes();
    testZeroInput();

    //--- Some extra tests --- //
    if (testZeroDelay(1024, 1.0, 0)==0) {
        cout<<"\nZero Delay Test: Success!\n";
    }
    testFIRImpulseResponse();
    testIIRImpulseResponse();

#endif

    return 0;
}

int testZeroInput() {
    FilterAudio *pFilter;
    float fFIRCoeff = 1.0;
    float fIIRCoeff = 0.0;
    int iDelayInSamples = 10;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks = 50; //Length of sample is 50 blocks

    //Allocate memory
    float **ppfAudioData = new float *[iNumChannels];
    for (int n=0; n<iNumChannels; n++) {
        ppfAudioData[n] = new float[iBlockSize];
        for (int m=0; m<iBlockSize; m++) {
            ppfAudioData[n][m] = 0; //Initialize all samples to zero
        }
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    while (iNumBlocks > 0) {

        //Get filtered data
        ppfAudioData = pFilter->combFilterBlock(ppfAudioData, iBlockSize, iNumChannels);

        for (int n=0; n<iNumChannels; n++) {
            for (int m=0; m<iBlockSize; m++) {

                //Check if all the values are 0
                if (abs(ppfAudioData[n][m]) > 0.001) {
                    cout<<"\nZero Input Test: failed!\n";
                    return -1;
                }
            }
        }
        iNumBlocks--;
    }

    cout<<"\nZero Input Test: Success!\n";

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int n=0; n<iNumChannels; n++) {
        delete [] ppfAudioData[n];
    }
    delete ppfAudioData;

    return 0;
}

int testFIRFeedforward() {

    FilterAudio *pFilter;
    float fFIRCoeff = 1.0;

    float fIIRCoeff = 0.0;
    int iNumChannels = 1;
    int iBlockSize = 400;
    int iNumBlocks;

    float fFreq = 441.0; //in Hz - Test sine wave
    float fAmp = 1.0;
    float fTimeInSecs = 2.0; // 2 seconds long
    unsigned uSampleRate = 44100;
    int iPeriodInSamples = uSampleRate/fFreq; // 100 samples in this case

    int iDelayInSamples = iPeriodInSamples/2; //Delay = 50 samples to create destructive interference

    //Allocate memory
    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    //Create sine wave
    float *sinWave = sinOsc(fFreq, fAmp, fTimeInSecs, uSampleRate);

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    //To block the sine wave audio
    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

    for (int c=0; c<iNumChannels; c++) {

        int start = 0;

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            //Ignore first part of the first block
            start = 0;
            if (n == 0){
                start = iDelayInSamples+1;
            }

            for (int m=start; m<iBlockSize; m++) {
                //Check for Complete destructive interference - so all values are zero
                if (std::abs(buffer[c][m]) > 0.001) {
                    cout<<"\nFIR Feedforward Test: failed!\n";
                    return -1;
                }
            }

        }

        cout<<"\nFIR Feedforward Test: Success!\n";
    }

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] buffer[i];
    }
    delete buffer;

    delete [] sinWave;

    return 0;
}

int testIIRDestructiveFeedforward() {

    FilterAudio *pFilter;
    float fFIRCoeff = 0.0;
    float fIIRCoeff = 0.1;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks;

    float fFreq = 441.0; //Hz - Test sine wave
    float fAmp = 1.0;
    float fTimeInSecs = 2.0;
    unsigned uSampleRate = 44100;

    int iPeriodInSamples = uSampleRate/fFreq; //100 samples

    int iDelayInSamples = iPeriodInSamples/2; //50 samples - Causing Destructive interference by 0.1 margin

    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    float *sinWave = sinOsc(fFreq, fAmp, fTimeInSecs, uSampleRate);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

    for (int c=0; c<iNumChannels; c++) {

        int start = 0;
        float fMaxAmp = 0;

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            if (n == 0){
                start = iPeriodInSamples+1;
            }

            for (int m=0+start; m<iBlockSize; m++) {

                if (buffer[c][m] >= fMaxAmp) {
                    fMaxAmp = buffer[c][m];
                }
            }

            //Max amplitude of output should always be less than input
            if (fMaxAmp >= fAmp) {
                cout<<"\nIIR Desructive Feedforward Test: failed!\n";
                return -1;
            }

        }

        cout<<"\nIIR Destructive Feedforward Test: Success!\n";
    }

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] buffer[i];
    }
    delete buffer;

    delete [] sinWave;

    return 0;
}

int testIIRConstructiveFeedforward() {

    FilterAudio *pFilter;
    float fFIRCoeff = 0.0;
    float fIIRCoeff = 0.1;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks;

    float fFreq = 441.0; //Hz
    float fAmp = 1.0;
    float fTimeInSecs = 2.0;
    unsigned uSampleRate = 44100;

    int iPeriodInSamples = uSampleRate/fFreq; //100 samples

    int iDelayInSamples = iPeriodInSamples; //100 samples - Constructive interference

    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    float *sinWave = sinOsc(fFreq, fAmp, fTimeInSecs, uSampleRate);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

    for (int c=0; c<iNumChannels; c++) {

        int start = 0;
        float fMaxAmp = 0;

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            if (n == 0){
                start = iPeriodInSamples+1;
            }

            for (int m=0+start; m<iBlockSize; m++) {

                if (buffer[c][m] >= fMaxAmp) {
                    fMaxAmp = buffer[c][m];
                }
            }

            //Max amplitude of output should always be greater than input
            if (fMaxAmp <= fAmp) {
                cout<<"\nIIR Constructive Feedforward Test: failed!\n";
                return -1;
            }
        }
        cout<<"\nIIR Constructive Feedforward Test: Success!\n";
    }

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] buffer[i];
    }
    delete buffer;

    delete [] sinWave;

    return 0;
}

int testDifferntBlockSizes() {

    if(testZeroDelay(1024, 1.0, 0)!=0) {
        cout<<"\nVarying block size test @ 1024 : failed!\n";
        return -1;
    }
    if(testZeroDelay(256, 0.5, 0.5)!=0) {
        cout<<"\nVarying block size test @ 1024 : failed!\n";
        return -1;
    }
    if(testZeroDelay(2048, 0.5, 1.0)!=0) {
        cout<<"\nVarying block size test @ 1024 : failed!\n";
        return -1;
    }
    if(testZeroDelay(4096, 0, 1.0)!=0) {
        cout<<"\nVarying block size test @ 1024 : failed!\n";
        return -1;
    }

    cout<<"\nVarying block size test : Success!\n";
    return 0;
}

int testZeroDelay(int iBlockSize, float fFIRCoeff, float fIIRCoeff) {

    FilterAudio *pFilter;
    int iNumChannels = 1;
    int iNumBlocks;

    float fFreq = 441.0; //Hz -  Test sine wave
    float fAmp = 1.0;
    float fTimeInSecs = 2.0;
    unsigned uSampleRate = 44100;

    int iDelayInSamples = 0; //No delay

    float **buffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        buffer[i] = new float[iBlockSize];
    }

    float **origBuffer = new float *[iNumChannels];
    for (int i=0;i<iNumChannels ;i++) {
        origBuffer[i] = new float[iBlockSize];
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    float *sinWave = sinOsc(fFreq, fAmp, fTimeInSecs, uSampleRate);

    int iLengthInSamples = ceil(fTimeInSecs * uSampleRate);

    iNumBlocks = ceil((float)iLengthInSamples/(float)iBlockSize);

    for (int c=0; c<iNumChannels; c++) {

        for (int n=0; n<iNumBlocks-1; n++) {

            if (n*iBlockSize >  iLengthInSamples) {
                memcpy(buffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
                memcpy(origBuffer[c], &sinWave[n*iBlockSize], (iLengthInSamples-n*iBlockSize)*sizeof(float));
            }
            else {
                memcpy(buffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
                memcpy(origBuffer[c], &sinWave[n*iBlockSize], iBlockSize*sizeof(float));
            }

            buffer = pFilter->combFilterBlock(buffer, iBlockSize, iNumChannels);

            for (int m=0; m<iBlockSize; m++) {
                //Output should be same as input
                if (buffer[c][m] != origBuffer[c][m]) {
                    cout<<"\nZero Delay Test: failure!\n";
                    return -1;
                }
            }

        }
    }

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] buffer[i];
    }
    delete buffer;

    for (int i=0;i<iNumChannels ;i++) {
        delete [] origBuffer[i];
    }
    delete origBuffer;

    delete [] sinWave;

    return 0;
}

int testFIRImpulseResponse() {
    FilterAudio *pFilter;
    float fFIRCoeff = 1.0;
    float fIIRCoeff = 0.0;
    int iDelayInSamples = 5;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks = 1; //Do this test only for 1 block
    float **ppfAudioData = new float *[iNumChannels];

    for (int n=0; n<iNumChannels; n++) {
        ppfAudioData[n] = new float[iBlockSize];
        for (int m=0; m<iBlockSize; m++) {
            ppfAudioData[n][m] = 0;
        }
        ppfAudioData[n][0]=1.0;
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    for (int n=0; n<iNumBlocks; n++)  {

        ppfAudioData = pFilter->combFilterBlock(ppfAudioData, iBlockSize, iNumChannels);

        for (int n=0; n<iNumChannels; n++) {

            for (int m=0; m<iBlockSize; m++) {

                //Check for peak at the m=delaylength
                if (m==0 || m==iDelayInSamples) {
                    if (ppfAudioData[n][m] != 1.0F) {
                        cout<<"\nFIR Impulse Response Test: failed!\n";
                        return -1;
                    }
                }
                else {
                    if (ppfAudioData[n][m] > 0.001) {
                        cout<<"\nFIR Impulse Response Test: failed!\n";
                        return -1;
                    }

                }
            }
        }
    }

    cout<<"\nFIR Impulse Response Test: Success!\n";

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] ppfAudioData[i];
    }
    delete ppfAudioData;

    return 0;
}

int testIIRImpulseResponse() {
    FilterAudio *pFilter;
    float fFIRCoeff = 0.0;
    float fIIRCoeff = 1.0;
    int iDelayInSamples = 5;
    int iNumChannels = 1;
    int iBlockSize = 1024;
    int iNumBlocks = 1; //Do this test only for 1 block
    float **ppfAudioData = new float *[iNumChannels];

    for (int n=0; n<iNumChannels; n++) {
        ppfAudioData[n] = new float[iBlockSize];
        for (int m=0; m<iBlockSize; m++) {
            ppfAudioData[n][m] = 0;
        }
        ppfAudioData[n][0]=1.0;
    }

    pFilter = new FilterAudio(fFIRCoeff, fIIRCoeff, iDelayInSamples, iNumChannels);

    for (int n=0; n<iNumBlocks; n++)  {

        ppfAudioData = pFilter->combFilterBlock(ppfAudioData, iBlockSize, iNumChannels);

        for (int n=0; n<iNumChannels; n++) {

            for (int m=0; m<iBlockSize; m++) {

                if (m%5==0) {
                    //Check for peaks at multiples of delay length
                    if (ppfAudioData[n][m] != 1.0F) {
                        cout<<"\nIIR Impulse Response Test: failed!\n";
                        return -1;
                    }
                }
                else {
                    if (ppfAudioData[n][m] > 0.001) {
                        cout<<"\nIIR Impulse Response Test: failed!\n";
                        return -1;
                    }

                }
            }
        }
    }

    cout<<"\nIIR Impulse Response Test: Success!\n";

    //Free memory
    delete pFilter;
    pFilter = 0;
    for (int i=0;i<iNumChannels ;i++) {
        delete [] ppfAudioData[i];
    }
    delete ppfAudioData;

    return 0;
}

float *sinOsc(float fFreq, float fAmp, float fLengthInSec, unsigned uFs){

    float pi = 3.1415926535897932346;

    int lengthInSamples = ceil(fLengthInSec * uFs);
    float* fSineWave = new float[lengthInSamples];

    // Fill sine wave
    for(int i = 0; i<lengthInSamples; i++){
        fSineWave[i] = fAmp* sin((2.f*pi*fFreq)/(uFs) *i);
    }

    return fSineWave;
}

<|endoftext|>


<commit_before>#include "PhysicsManager.hpp"

#include <btBulletDynamicsCommon.h>
#include <glm/gtx/quaternion.hpp>
#include "../Component/RigidBody.hpp"
#include "../Component/Shape.hpp"
#include "../Entity/Entity.hpp"
#include "../Physics/GlmConversion.hpp"
#include "../Physics/Shape.hpp"
#include "../Physics/Trigger.hpp"
#include "../Physics/TriggerObserver.hpp"
#include "../Util/Json.hpp"

PhysicsManager::PhysicsManager() {
    // The broadphase is used to quickly cull bodies that will not collide with
    // each other, normally by leveraging some simpler (and rough) test such as
    // bounding boxes.
    broadphase = new btDbvtBroadphase;

    // With the collision configuration one can configure collision detection
    // algorithms.
    collisionConfiguration = new btDefaultCollisionConfiguration;
    dispatcher = new btCollisionDispatcher(collisionConfiguration);

    // The solver makes objects interact by making use of gravity, collisions,
    // game logic supplied forces, and constraints.
    solver = new btSequentialImpulseConstraintSolver;

    // The dynamics world encompasses objects included in the simulation.
    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

    // Y axis up
    dynamicsWorld->setGravity(btVector3(0, -9.82, 0));

    // Set the lockbox key we will use for lockboxes created in here.
    triggerLockBoxKey.reset(new Utility::LockBox<Physics::Trigger>::Key());
}

PhysicsManager::~PhysicsManager() {
    delete dynamicsWorld;
    delete solver;
    delete dispatcher;
    delete collisionConfiguration;
    delete broadphase;

    for (auto t : triggers) {
        delete t;
    }
}

void PhysicsManager::Update(float deltaTime) {
    for (auto rigidBodyComp : rigidBodyComponents.GetAll()) {
        if (rigidBodyComp->IsKilled() || !rigidBodyComp->entity->enabled) {
            continue;
        }

        rigidBodyComp->Position(rigidBodyComp->entity->position);
        dynamicsWorld->removeRigidBody(rigidBodyComp->GetBulletRigidBody());
        dynamicsWorld->addRigidBody(rigidBodyComp->GetBulletRigidBody());
        rigidBodyComp->GetBulletRigidBody()->setGravity(btVector3(0, 0, 0));
    }

    dynamicsWorld->stepSimulation(deltaTime, 10);

    for (auto trigger : triggers) {
        trigger->Process(*dynamicsWorld);
    }
}

void PhysicsManager::UpdateEntityTransforms() {
    for (auto rigidBodyComp : rigidBodyComponents.GetAll()) {
        if (rigidBodyComp->IsKilled() || !rigidBodyComp->entity->enabled)
            continue;

        Entity* entity = rigidBodyComp->entity;

        auto trans = rigidBodyComp->GetBulletRigidBody()->getWorldTransform();
        entity->position = Physics::btToGlm(trans.getOrigin());
        entity->SetLocalOrientation(Physics::btToGlm(trans.getRotation()));
    }
}

void PhysicsManager::OnTriggerEnter(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](Physics::TriggerObserver& observer) {
            observer.OnEnter(callback);
        });
    });
}

void PhysicsManager::OnTriggerRetain(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](::Physics::TriggerObserver& observer) {
            observer.OnRetain(callback);
        });
    });
}

void PhysicsManager::OnTriggerLeave(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](::Physics::TriggerObserver& observer) {
            observer.OnLeave(callback);
        });
    });
}

Component::RigidBody* PhysicsManager::CreateRigidBody(Entity* owner) {
    auto comp = rigidBodyComponents.Create();
    comp->entity = owner;

    comp->NewBulletRigidBody(1.0f);

    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp) {
        comp->GetBulletRigidBody()->setCollisionShape(shapeComp->GetShape()->GetShape());
    }

    return comp;
}

Component::RigidBody* PhysicsManager::CreateRigidBody(Entity* owner, const Json::Value& node) {
    auto comp = rigidBodyComponents.Create();
    comp->entity = owner;

    auto mass = node.get("mass", 1.0f).asFloat();
    comp->NewBulletRigidBody(mass);

    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp) {
        comp->GetBulletRigidBody()->setCollisionShape(shapeComp->GetShape()->GetShape());
    }

    return comp;
}

Component::Shape* PhysicsManager::CreateShape(Entity* owner) {
    auto comp = shapeComponents.Create();
    comp->entity = owner;

    auto shape = std::shared_ptr<Physics::Shape>(new Physics::Shape(Physics::Shape::Sphere(1.0f)));
    comp->SetShape(shape);

    auto rigidBodyComp = comp->entity->GetComponent<Component::RigidBody>();
    if (rigidBodyComp) {
        rigidBodyComp->GetBulletRigidBody()->setCollisionShape(comp->GetShape()->GetShape());
    }

    return comp;
}

Component::Shape* PhysicsManager::CreateShape(Entity* owner, const Json::Value& node) {
    auto comp = shapeComponents.Create();
    comp->entity = owner;

    if (node.isMember("sphere")) {
        auto sphere = node.get("sphere", {});
        auto radius = sphere.get("radius", 1.0f).asFloat();
        auto shape = std::shared_ptr<::Physics::Shape>(new ::Physics::Shape(::Physics::Shape::Sphere(radius)));
        comp->SetShape(shape);
    }
    else if (node.isMember("plane")) {
        auto plane = node.get("plane", {});
        auto normal = Json::LoadVec3(plane.get("normal", {}));
        auto planeCoeff = plane.get("planeCoeff", 0.0f).asFloat();
        auto shape = std::shared_ptr<::Physics::Shape>(new ::Physics::Shape(::Physics::Shape::Plane(normal, planeCoeff)));
        comp->SetShape(shape);
    }

    auto rigidBodyComp = comp->entity->GetComponent<Component::RigidBody>();
    if (rigidBodyComp) {
        rigidBodyComp->GetBulletRigidBody()->setCollisionShape(comp->GetShape()->GetShape());
    }

    return comp;
}

Utility::LockBox<Physics::Trigger> PhysicsManager::CreateTrigger(Component::RigidBody* comp) {
    btTransform trans(btQuaternion(0, 0, 0, 1), ::Physics::glmToBt(comp->entity->position));
    Physics::Trigger* trigger = new Physics::Trigger(trans);
    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    trigger->SetCollisionShape(shapeComp ? shapeComp->GetShape() : nullptr);
    triggers.push_back(trigger);
    return Utility::LockBox<Physics::Trigger>(triggerLockBoxKey, trigger);
}

void PhysicsManager::SetShape(Component::Shape* comp, std::shared_ptr<::Physics::Shape> shape) {
    comp->SetShape(shape);
}

void PhysicsManager::SetMass(Component::RigidBody* comp, float mass) {
    // Setting mass is only valid with a shape because it also sets inertia.
    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp)
        comp->Mass(mass);
}

const std::vector<Component::Shape*>& PhysicsManager::GetShapeComponents() const {
    return shapeComponents.GetAll();
}

void PhysicsManager::ClearKilledComponents() {
    rigidBodyComponents.ClearKilled(
        [this](Component::RigidBody* body) {
            dynamicsWorld->removeRigidBody(body->GetBulletRigidBody());
        });
    shapeComponents.ClearKilled();
}
<commit_msg>Remove braces around single statement for.<commit_after>#include "PhysicsManager.hpp"

#include <btBulletDynamicsCommon.h>
#include <glm/gtx/quaternion.hpp>
#include "../Component/RigidBody.hpp"
#include "../Component/Shape.hpp"
#include "../Entity/Entity.hpp"
#include "../Physics/GlmConversion.hpp"
#include "../Physics/Shape.hpp"
#include "../Physics/Trigger.hpp"
#include "../Physics/TriggerObserver.hpp"
#include "../Util/Json.hpp"

PhysicsManager::PhysicsManager() {
    // The broadphase is used to quickly cull bodies that will not collide with
    // each other, normally by leveraging some simpler (and rough) test such as
    // bounding boxes.
    broadphase = new btDbvtBroadphase;

    // With the collision configuration one can configure collision detection
    // algorithms.
    collisionConfiguration = new btDefaultCollisionConfiguration;
    dispatcher = new btCollisionDispatcher(collisionConfiguration);

    // The solver makes objects interact by making use of gravity, collisions,
    // game logic supplied forces, and constraints.
    solver = new btSequentialImpulseConstraintSolver;

    // The dynamics world encompasses objects included in the simulation.
    dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);

    // Y axis up
    dynamicsWorld->setGravity(btVector3(0, -9.82, 0));

    // Set the lockbox key we will use for lockboxes created in here.
    triggerLockBoxKey.reset(new Utility::LockBox<Physics::Trigger>::Key());
}

PhysicsManager::~PhysicsManager() {
    delete dynamicsWorld;
    delete solver;
    delete dispatcher;
    delete collisionConfiguration;
    delete broadphase;

    for (auto t : triggers)
        delete t;
}

void PhysicsManager::Update(float deltaTime) {
    for (auto rigidBodyComp : rigidBodyComponents.GetAll()) {
        if (rigidBodyComp->IsKilled() || !rigidBodyComp->entity->enabled) {
            continue;
        }

        rigidBodyComp->Position(rigidBodyComp->entity->position);
        dynamicsWorld->removeRigidBody(rigidBodyComp->GetBulletRigidBody());
        dynamicsWorld->addRigidBody(rigidBodyComp->GetBulletRigidBody());
        rigidBodyComp->GetBulletRigidBody()->setGravity(btVector3(0, 0, 0));
    }

    dynamicsWorld->stepSimulation(deltaTime, 10);

    for (auto trigger : triggers) {
        trigger->Process(*dynamicsWorld);
    }
}

void PhysicsManager::UpdateEntityTransforms() {
    for (auto rigidBodyComp : rigidBodyComponents.GetAll()) {
        if (rigidBodyComp->IsKilled() || !rigidBodyComp->entity->enabled)
            continue;

        Entity* entity = rigidBodyComp->entity;

        auto trans = rigidBodyComp->GetBulletRigidBody()->getWorldTransform();
        entity->position = Physics::btToGlm(trans.getOrigin());
        entity->SetLocalOrientation(Physics::btToGlm(trans.getRotation()));
    }
}

void PhysicsManager::OnTriggerEnter(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](Physics::TriggerObserver& observer) {
            observer.OnEnter(callback);
        });
    });
}

void PhysicsManager::OnTriggerRetain(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](::Physics::TriggerObserver& observer) {
            observer.OnRetain(callback);
        });
    });
}

void PhysicsManager::OnTriggerLeave(Component::RigidBody* trigger, Component::RigidBody* object, std::function<void()> callback) {
    auto t = CreateTrigger(trigger);
    // Add the callback to the trigger observer
    t.Open(triggerLockBoxKey, [object, &callback](Physics::Trigger& trigger) {
        trigger.ForObserver(object->GetBulletRigidBody(), [&callback](::Physics::TriggerObserver& observer) {
            observer.OnLeave(callback);
        });
    });
}

Component::RigidBody* PhysicsManager::CreateRigidBody(Entity* owner) {
    auto comp = rigidBodyComponents.Create();
    comp->entity = owner;

    comp->NewBulletRigidBody(1.0f);

    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp) {
        comp->GetBulletRigidBody()->setCollisionShape(shapeComp->GetShape()->GetShape());
    }

    return comp;
}

Component::RigidBody* PhysicsManager::CreateRigidBody(Entity* owner, const Json::Value& node) {
    auto comp = rigidBodyComponents.Create();
    comp->entity = owner;

    auto mass = node.get("mass", 1.0f).asFloat();
    comp->NewBulletRigidBody(mass);

    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp) {
        comp->GetBulletRigidBody()->setCollisionShape(shapeComp->GetShape()->GetShape());
    }

    return comp;
}

Component::Shape* PhysicsManager::CreateShape(Entity* owner) {
    auto comp = shapeComponents.Create();
    comp->entity = owner;

    auto shape = std::shared_ptr<Physics::Shape>(new Physics::Shape(Physics::Shape::Sphere(1.0f)));
    comp->SetShape(shape);

    auto rigidBodyComp = comp->entity->GetComponent<Component::RigidBody>();
    if (rigidBodyComp) {
        rigidBodyComp->GetBulletRigidBody()->setCollisionShape(comp->GetShape()->GetShape());
    }

    return comp;
}

Component::Shape* PhysicsManager::CreateShape(Entity* owner, const Json::Value& node) {
    auto comp = shapeComponents.Create();
    comp->entity = owner;

    if (node.isMember("sphere")) {
        auto sphere = node.get("sphere", {});
        auto radius = sphere.get("radius", 1.0f).asFloat();
        auto shape = std::shared_ptr<::Physics::Shape>(new ::Physics::Shape(::Physics::Shape::Sphere(radius)));
        comp->SetShape(shape);
    }
    else if (node.isMember("plane")) {
        auto plane = node.get("plane", {});
        auto normal = Json::LoadVec3(plane.get("normal", {}));
        auto planeCoeff = plane.get("planeCoeff", 0.0f).asFloat();
        auto shape = std::shared_ptr<::Physics::Shape>(new ::Physics::Shape(::Physics::Shape::Plane(normal, planeCoeff)));
        comp->SetShape(shape);
    }

    auto rigidBodyComp = comp->entity->GetComponent<Component::RigidBody>();
    if (rigidBodyComp) {
        rigidBodyComp->GetBulletRigidBody()->setCollisionShape(comp->GetShape()->GetShape());
    }

    return comp;
}

Utility::LockBox<Physics::Trigger> PhysicsManager::CreateTrigger(Component::RigidBody* comp) {
    btTransform trans(btQuaternion(0, 0, 0, 1), ::Physics::glmToBt(comp->entity->position));
    Physics::Trigger* trigger = new Physics::Trigger(trans);
    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    trigger->SetCollisionShape(shapeComp ? shapeComp->GetShape() : nullptr);
    triggers.push_back(trigger);
    return Utility::LockBox<Physics::Trigger>(triggerLockBoxKey, trigger);
}

void PhysicsManager::SetShape(Component::Shape* comp, std::shared_ptr<::Physics::Shape> shape) {
    comp->SetShape(shape);
}

void PhysicsManager::SetMass(Component::RigidBody* comp, float mass) {
    // Setting mass is only valid with a shape because it also sets inertia.
    auto shapeComp = comp->entity->GetComponent<Component::Shape>();
    if (shapeComp)
        comp->Mass(mass);
}

const std::vector<Component::Shape*>& PhysicsManager::GetShapeComponents() const {
    return shapeComponents.GetAll();
}

void PhysicsManager::ClearKilledComponents() {
    rigidBodyComponents.ClearKilled(
        [this](Component::RigidBody* body) {
            dynamicsWorld->removeRigidBody(body->GetBulletRigidBody());
        });
    shapeComponents.ClearKilled();
}
<|endoftext|>


<commit_before>
using namespace std;
#include "GEOMImpl_ShapeDriver.hxx"
#include "GEOMImpl_IShapes.hxx"
#include "GEOMImpl_IShapesOperations.hxx"
#include "GEOMImpl_Types.hxx"
#include "GEOM_Function.hxx"

#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepAlgo_FaceRestrictor.hxx>
#include <BRepAlgo_Sewing.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepTools_Quilt.hxx>
#include <BRepCheck.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>

#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>

#include <Precision.hxx>
#include <Standard_NullObject.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_ConstructionError.hxx>

//=======================================================================
//function : GetID
//purpose  :
//=======================================================================
const Standard_GUID& GEOMImpl_ShapeDriver::GetID()
{
  static Standard_GUID aShapeDriver("FF1BBB54-5D14-4df2-980B-3A668264EA16");
  return aShapeDriver;
}

//=======================================================================
//function : GEOMImpl_ShapeDriver
//purpose  :
//=======================================================================
GEOMImpl_ShapeDriver::GEOMImpl_ShapeDriver()
{
}

//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IShapes aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;
  BRep_Builder B;

  if (aType == WIRE_EDGES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add edges
    BRepBuilderAPI_MakeWire MW;
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Shape for wire construction is null");
      }
      if (aShape_i.ShapeType() == TopAbs_EDGE)
	MW.Add(TopoDS::Edge(aShape_i));
      else if (aShape_i.ShapeType() == TopAbs_WIRE)
	MW.Add(TopoDS::Wire(aShape_i));
      else
        Standard_TypeMismatch::Raise
          ("Shape for wire construction is neither an edge nor a wire");
    }

    if (!MW.IsDone()) {
      Standard_ConstructionError::Raise("Wire construction failed");
    }
    aShape = MW;

  } else if (aType == FACE_WIRE) {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull() || aShapeBase.ShapeType() != TopAbs_WIRE) {
      Standard_NullObject::Raise
        ("Shape for face construction is null or not a wire");
    }
    TopoDS_Wire W = TopoDS::Wire(aShapeBase);
    BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar());
    if (!MF.IsDone()) {
      Standard_ConstructionError::Raise("Face construction failed");
    }
    aShape = MF.Shape();

  } else if (aType == FACE_WIRES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();

    // first wire
    Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1));
    TopoDS_Shape aWire = aRefWire->GetValue();
    if (aWire.IsNull() || aWire.ShapeType() != TopAbs_WIRE) {
      Standard_NullObject::Raise("Shape for face construction is null or not a wire");
    }
    TopoDS_Wire W = TopoDS::Wire(aWire);

    // basic face
    BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar());
    if (!MF.IsDone()) {
      Standard_ConstructionError::Raise("Face construction failed");
    }
    TopoDS_Shape FFace = MF.Shape();
    if (!FFace.IsNull()) {
      unsigned int ind, nbshapes = aShapes->Length();
      if (nbshapes == 1) {
	aShape = FFace;

      } else if (nbshapes >= 2) {
	TopoDS_Compound C;
	BRep_Builder aBuilder;
	aBuilder.MakeCompound(C);
	BRepAlgo_FaceRestrictor FR;

	TopAbs_Orientation OriF = FFace.Orientation();
	TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD);
	FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True);

	for (ind = 1; ind <= nbshapes; ind++) {
          Handle(GEOM_Function) aRefWire_i =
            Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
          TopoDS_Shape aWire_i = aRefWire_i->GetValue();
          if (aWire_i.IsNull() || aWire_i.ShapeType() != TopAbs_WIRE) {
            Standard_NullObject::Raise("Shape for face construction is null or not a wire");
          }

	  FR.Add(TopoDS::Wire(aWire_i));
	}

	FR.Perform();

	if (FR.IsDone()) {
	  int k = 0;
	  TopoDS_Shape aFace;
	  for (; FR.More(); FR.Next()) {
	    aFace = FR.Current().Oriented(OriF);
	    aBuilder.Add(C, aFace);
	    k++;
	  }
	  if (k == 1) {
	    aShape = aFace;
	  } else {
	    aShape = C;
	  }
	}
      }
    }
  } else if (aType == SHELL_FACES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add faces
    BRepAlgo_Sewing aSewing(Precision::Confusion()*10.0);
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Face for shell construction is null");
      }
      aSewing.Add(aShape_i);
    }

    aSewing.Perform();

    TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL);
    Standard_Integer ish = 0;
    for (; exp.More(); exp.Next()) {
      aShape = exp.Current();
      ish++;
    }

    if (ish != 1)
      aShape = aSewing.SewedShape();

  } else if (aType == SOLID_SHELL) {
    Handle(GEOM_Function) aRefShell = aCI.GetBase();
    TopoDS_Shape aShapeShell = aRefShell->GetValue();
    if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) {
      Standard_NullObject::Raise("Shape for solid construction is null or not a shell");
    }

    BRepCheck_Shell chkShell(TopoDS::Shell(aShapeShell));
    if(chkShell.Closed() == BRepCheck_NotClosed) return 0;

    TopoDS_Solid Sol;
    B.MakeSolid(Sol);
    B.Add(Sol, aShapeShell);
    BRepClass3d_SolidClassifier SC (Sol);
    SC.PerformInfinitePoint(Precision::Confusion());
    if (SC.State() == TopAbs_IN) {
      B.MakeSolid(Sol);
      B.Add(Sol, aShapeShell.Reversed());
    }

    aShape = Sol;

  } else if (aType == SOLID_SHELLS) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();
    Standard_Integer ish = 0;
    TopoDS_Solid Sol;
    TopoDS_Compound Res;
    B.MakeCompound(Res);

    // add shapes
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShapeShell = aRefShape->GetValue();
      if (aShapeShell.IsNull()) {
        Standard_NullObject::Raise("Shell for solid construction is null");
      }
      if (aShapeShell.ShapeType() == TopAbs_SHELL) {
        B.MakeSolid(Sol);
        B.Add(Sol, aShapeShell);
        BRepClass3d_SolidClassifier SC (Sol);
        SC.PerformInfinitePoint(Precision::Confusion());
        if (SC.State() == TopAbs_IN) {
          B.MakeSolid(Sol);
          B.Add(Sol, aShapeShell.Reversed());
        }
        B.Add(Res, Sol);
        ish++;
      }
    }
    if (ish == 1) aShape = Sol;
    else          aShape = Res;

  } else if (aType == COMPOUND_SHAPES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add shapes
    TopoDS_Compound C;
    B.MakeCompound(C);
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Shape for compound construction is null");
      }
      B.Add(C, aShape_i);
    }

    aShape = C;

  } else if (aType == REVERSE_ORIENTATION) {
    Handle(GEOM_Function) aRefShape = aCI.GetBase();
    TopoDS_Shape aShape_i = aRefShape->GetValue();
    if (aShape_i.IsNull()) {
       Standard_NullObject::Raise("Shape for reverse is null");
    }

    BRepBuilderAPI_Copy Copy(aShape_i);
    if( Copy.IsDone() ) {
      TopoDS_Shape tds = Copy.Shape();
      if( tds.IsNull() ) {
	Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape");
      }

      if( tds.Orientation() == TopAbs_FORWARD)
	tds.Orientation(TopAbs_REVERSED) ;
      else
	tds.Orientation(TopAbs_FORWARD) ;

      aShape = tds;
    }
  }

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
    Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
  }

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}

//=======================================================================
//function :  GEOMImpl_ShapeDriver_Type_
//purpose  :
//=======================================================================
Standard_EXPORT Handle_Standard_Type& GEOMImpl_ShapeDriver_Type_()
{

  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);

  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ShapeDriver",
			                                 sizeof(GEOMImpl_ShapeDriver),
			                                 1,
			                                 (Standard_Address)_Ancestors,
			                                 (Standard_Address)NULL);

  return _aType;
}

//=======================================================================
//function : DownCast
//purpose  :
//=======================================================================
const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
{
  Handle(GEOMImpl_ShapeDriver) _anOtherObject;

  if (!AnObject.IsNull()) {
     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_ShapeDriver))) {
       _anOtherObject = Handle(GEOMImpl_ShapeDriver)((Handle(GEOMImpl_ShapeDriver)&)AnObject);
     }
  }

  return _anOtherObject ;
}
<commit_msg>PAL9074. Now MakeSolidShells() makes one solid of all given shells like OCC MakeSolid() does<commit_after>
using namespace std;
#include "GEOMImpl_ShapeDriver.hxx"
#include "GEOMImpl_IShapes.hxx"
#include "GEOMImpl_IShapesOperations.hxx"
#include "GEOMImpl_Types.hxx"
#include "GEOM_Function.hxx"

#include <BRep_Tool.hxx>
#include <BRep_Builder.hxx>
#include <BRepAlgo_FaceRestrictor.hxx>
#include <BRepAlgo_Sewing.hxx>
#include <BRepBuilderAPI_Copy.hxx>
#include <BRepTools_Quilt.hxx>
#include <BRepCheck.hxx>
#include <BRepCheck_Analyzer.hxx>
#include <BRepCheck_Shell.hxx>
#include <BRepClass3d_SolidClassifier.hxx>
#include <BRepBuilderAPI_MakeWire.hxx>
#include <BRepBuilderAPI_MakeFace.hxx>

#include <TopAbs.hxx>
#include <TopoDS.hxx>
#include <TopoDS_Shape.hxx>
#include <TopoDS_Edge.hxx>
#include <TopoDS_Wire.hxx>
#include <TopoDS_Solid.hxx>
#include <TopoDS_Compound.hxx>
#include <TopoDS_Iterator.hxx>
#include <TopExp_Explorer.hxx>
#include <TopTools_MapOfShape.hxx>
#include <TopTools_SequenceOfShape.hxx>
#include <TopTools_ListIteratorOfListOfShape.hxx>

#include <Precision.hxx>
#include <Standard_NullObject.hxx>
#include <Standard_TypeMismatch.hxx>
#include <Standard_ConstructionError.hxx>

//=======================================================================
//function : GetID
//purpose  :
//=======================================================================
const Standard_GUID& GEOMImpl_ShapeDriver::GetID()
{
  static Standard_GUID aShapeDriver("FF1BBB54-5D14-4df2-980B-3A668264EA16");
  return aShapeDriver;
}

//=======================================================================
//function : GEOMImpl_ShapeDriver
//purpose  :
//=======================================================================
GEOMImpl_ShapeDriver::GEOMImpl_ShapeDriver()
{
}

//=======================================================================
//function : Execute
//purpose  :
//=======================================================================
Standard_Integer GEOMImpl_ShapeDriver::Execute(TFunction_Logbook& log) const
{
  if (Label().IsNull()) return 0;
  Handle(GEOM_Function) aFunction = GEOM_Function::GetFunction(Label());

  GEOMImpl_IShapes aCI (aFunction);
  Standard_Integer aType = aFunction->GetType();

  TopoDS_Shape aShape;
  BRep_Builder B;

  if (aType == WIRE_EDGES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add edges
    BRepBuilderAPI_MakeWire MW;
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Shape for wire construction is null");
      }
      if (aShape_i.ShapeType() == TopAbs_EDGE)
	MW.Add(TopoDS::Edge(aShape_i));
      else if (aShape_i.ShapeType() == TopAbs_WIRE)
	MW.Add(TopoDS::Wire(aShape_i));
      else
        Standard_TypeMismatch::Raise
          ("Shape for wire construction is neither an edge nor a wire");
    }

    if (!MW.IsDone()) {
      Standard_ConstructionError::Raise("Wire construction failed");
    }
    aShape = MW;

  } else if (aType == FACE_WIRE) {
    Handle(GEOM_Function) aRefBase = aCI.GetBase();
    TopoDS_Shape aShapeBase = aRefBase->GetValue();
    if (aShapeBase.IsNull() || aShapeBase.ShapeType() != TopAbs_WIRE) {
      Standard_NullObject::Raise
        ("Shape for face construction is null or not a wire");
    }
    TopoDS_Wire W = TopoDS::Wire(aShapeBase);
    BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar());
    if (!MF.IsDone()) {
      Standard_ConstructionError::Raise("Face construction failed");
    }
    aShape = MF.Shape();

  } else if (aType == FACE_WIRES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();

    // first wire
    Handle(GEOM_Function) aRefWire = Handle(GEOM_Function)::DownCast(aShapes->Value(1));
    TopoDS_Shape aWire = aRefWire->GetValue();
    if (aWire.IsNull() || aWire.ShapeType() != TopAbs_WIRE) {
      Standard_NullObject::Raise("Shape for face construction is null or not a wire");
    }
    TopoDS_Wire W = TopoDS::Wire(aWire);

    // basic face
    BRepBuilderAPI_MakeFace MF (W, aCI.GetIsPlanar());
    if (!MF.IsDone()) {
      Standard_ConstructionError::Raise("Face construction failed");
    }
    TopoDS_Shape FFace = MF.Shape();
    if (!FFace.IsNull()) {
      unsigned int ind, nbshapes = aShapes->Length();
      if (nbshapes == 1) {
	aShape = FFace;

      } else if (nbshapes >= 2) {
	TopoDS_Compound C;
	BRep_Builder aBuilder;
	aBuilder.MakeCompound(C);
	BRepAlgo_FaceRestrictor FR;

	TopAbs_Orientation OriF = FFace.Orientation();
	TopoDS_Shape aLocalS = FFace.Oriented(TopAbs_FORWARD);
	FR.Init(TopoDS::Face(aLocalS), Standard_False, Standard_True);

	for (ind = 1; ind <= nbshapes; ind++) {
          Handle(GEOM_Function) aRefWire_i =
            Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
          TopoDS_Shape aWire_i = aRefWire_i->GetValue();
          if (aWire_i.IsNull() || aWire_i.ShapeType() != TopAbs_WIRE) {
            Standard_NullObject::Raise("Shape for face construction is null or not a wire");
          }

	  FR.Add(TopoDS::Wire(aWire_i));
	}

	FR.Perform();

	if (FR.IsDone()) {
	  int k = 0;
	  TopoDS_Shape aFace;
	  for (; FR.More(); FR.Next()) {
	    aFace = FR.Current().Oriented(OriF);
	    aBuilder.Add(C, aFace);
	    k++;
	  }
	  if (k == 1) {
	    aShape = aFace;
	  } else {
	    aShape = C;
	  }
	}
      }
    }
  } else if (aType == SHELL_FACES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add faces
    BRepAlgo_Sewing aSewing(Precision::Confusion()*10.0);
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Face for shell construction is null");
      }
      aSewing.Add(aShape_i);
    }

    aSewing.Perform();

    TopExp_Explorer exp (aSewing.SewedShape(), TopAbs_SHELL);
    Standard_Integer ish = 0;
    for (; exp.More(); exp.Next()) {
      aShape = exp.Current();
      ish++;
    }

    if (ish != 1)
      aShape = aSewing.SewedShape();

  } else if (aType == SOLID_SHELL) {
    Handle(GEOM_Function) aRefShell = aCI.GetBase();
    TopoDS_Shape aShapeShell = aRefShell->GetValue();
    if (aShapeShell.IsNull() || aShapeShell.ShapeType() != TopAbs_SHELL) {
      Standard_NullObject::Raise("Shape for solid construction is null or not a shell");
    }

    BRepCheck_Shell chkShell(TopoDS::Shell(aShapeShell));
    if(chkShell.Closed() == BRepCheck_NotClosed) return 0;

    TopoDS_Solid Sol;
    B.MakeSolid(Sol);
    B.Add(Sol, aShapeShell);
    BRepClass3d_SolidClassifier SC (Sol);
    SC.PerformInfinitePoint(Precision::Confusion());
    if (SC.State() == TopAbs_IN) {
      B.MakeSolid(Sol);
      B.Add(Sol, aShapeShell.Reversed());
    }

    aShape = Sol;

  } else if (aType == SOLID_SHELLS) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();
    Standard_Integer ish = 0;
    TopoDS_Solid Sol;
    B.MakeSolid(Sol);

    // add shapes
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShapeShell = aRefShape->GetValue();
      if (aShapeShell.IsNull()) {
        Standard_NullObject::Raise("Shell for solid construction is null");
      }
      if (aShapeShell.ShapeType() == TopAbs_SHELL) {
        B.Add(Sol, aShapeShell);
        ish++;
      }
    }
    if ( ish == 0 ) return 0;
    BRepClass3d_SolidClassifier SC (Sol);
    SC.PerformInfinitePoint(Precision::Confusion());
    switch (SC.State()) {
    case TopAbs_IN:
      aShape = Sol.Reversed(); break;
    case TopAbs_OUT:
      aShape = Sol; break;
    default: // not closed shell?
      return 0;
    }

  } else if (aType == COMPOUND_SHAPES) {
    Handle(TColStd_HSequenceOfTransient) aShapes = aCI.GetShapes();
    unsigned int ind, nbshapes = aShapes->Length();

    // add shapes
    TopoDS_Compound C;
    B.MakeCompound(C);
    for (ind = 1; ind <= nbshapes; ind++) {
      Handle(GEOM_Function) aRefShape = Handle(GEOM_Function)::DownCast(aShapes->Value(ind));
      TopoDS_Shape aShape_i = aRefShape->GetValue();
      if (aShape_i.IsNull()) {
        Standard_NullObject::Raise("Shape for compound construction is null");
      }
      B.Add(C, aShape_i);
    }

    aShape = C;

  } else if (aType == REVERSE_ORIENTATION) {
    Handle(GEOM_Function) aRefShape = aCI.GetBase();
    TopoDS_Shape aShape_i = aRefShape->GetValue();
    if (aShape_i.IsNull()) {
       Standard_NullObject::Raise("Shape for reverse is null");
    }

    BRepBuilderAPI_Copy Copy(aShape_i);
    if( Copy.IsDone() ) {
      TopoDS_Shape tds = Copy.Shape();
      if( tds.IsNull() ) {
	Standard_ConstructionError::Raise("Orientation aborted : Can not reverse the shape");
      }

      if( tds.Orientation() == TopAbs_FORWARD)
	tds.Orientation(TopAbs_REVERSED) ;
      else
	tds.Orientation(TopAbs_FORWARD) ;

      aShape = tds;
    }
  }

  if (aShape.IsNull()) return 0;

  // Check shape validity
  BRepCheck_Analyzer ana (aShape, false);
  if (!ana.IsValid()) {
    Standard_ConstructionError::Raise("Algorithm have produced an invalid shape result");
  }

  aFunction->SetValue(aShape);

  log.SetTouched(Label());

  return 1;
}

//=======================================================================
//function :  GEOMImpl_ShapeDriver_Type_
//purpose  :
//=======================================================================
Standard_EXPORT Handle_Standard_Type& GEOMImpl_ShapeDriver_Type_()
{

  static Handle_Standard_Type aType1 = STANDARD_TYPE(TFunction_Driver);
  if ( aType1.IsNull()) aType1 = STANDARD_TYPE(TFunction_Driver);
  static Handle_Standard_Type aType2 = STANDARD_TYPE(MMgt_TShared);
  if ( aType2.IsNull()) aType2 = STANDARD_TYPE(MMgt_TShared);
  static Handle_Standard_Type aType3 = STANDARD_TYPE(Standard_Transient);
  if ( aType3.IsNull()) aType3 = STANDARD_TYPE(Standard_Transient);

  static Handle_Standard_Transient _Ancestors[]= {aType1,aType2,aType3,NULL};
  static Handle_Standard_Type _aType = new Standard_Type("GEOMImpl_ShapeDriver",
			                                 sizeof(GEOMImpl_ShapeDriver),
			                                 1,
			                                 (Standard_Address)_Ancestors,
			                                 (Standard_Address)NULL);

  return _aType;
}

//=======================================================================
//function : DownCast
//purpose  :
//=======================================================================
const Handle(GEOMImpl_ShapeDriver) Handle(GEOMImpl_ShapeDriver)::DownCast(const Handle(Standard_Transient)& AnObject)
{
  Handle(GEOMImpl_ShapeDriver) _anOtherObject;

  if (!AnObject.IsNull()) {
     if (AnObject->IsKind(STANDARD_TYPE(GEOMImpl_ShapeDriver))) {
       _anOtherObject = Handle(GEOMImpl_ShapeDriver)((Handle(GEOMImpl_ShapeDriver)&)AnObject);
     }
  }

  return _anOtherObject ;
}
<|endoftext|>


<commit_before><commit_msg>Sketcher: Ellipse trim, handle multiple intersection<commit_after><|endoftext|>