<commit_before>/*
 * DesktopSatelliteWindow.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "DesktopSatelliteWindow.hpp"

#include "DesktopGwtCallback.hpp"

namespace desktop {

SatelliteWindow::SatelliteWindow(MainWindow* pMainWindow) :
    BrowserWindow(false, true), gwtCallback_(pMainWindow, this)
{
   setAttribute(Qt::WA_QuitOnClose, false);
   setAttribute(Qt::WA_DeleteOnClose, true);
}

void SatelliteWindow::onJavaScriptWindowObjectCleared()
{
   webView()->page()->mainFrame()->addToJavaScriptWindowObject(
         QString::fromAscii("desktop"),
         &gwtCallback_,
         QScriptEngine::QtOwnership);

   connect(webView(), SIGNAL(onCloseWindowShortcut()),
           this, SLOT(onCloseWindowShortcut()));
}

void SatelliteWindow::onCloseWindowShortcut()
{
   close();
}

void SatelliteWindow::finishLoading(bool ok)
{
   BrowserWindow::finishLoading(ok);

   if (ok)
      avoidMoveCursorIfNecessary();
}

} // namespace desktop
<commit_msg>use rstudio icon for satellite windows<commit_after>/*
 * DesktopSatelliteWindow.cpp
 *
 * Copyright (C) 2009-11 by RStudio, Inc.
 *
 * This program is licensed to you under the terms of version 3 of the
 * GNU Affero General Public License. This program is distributed WITHOUT
 * ANY EXPRESS OR IMPLIED WARRANTY, INCLUDING THOSE OF NON-INFRINGEMENT,
 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. Please refer to the
 * AGPL (http://www.gnu.org/licenses/agpl-3.0.txt) for more details.
 *
 */

#include "DesktopSatelliteWindow.hpp"

#include "DesktopGwtCallback.hpp"

namespace desktop {

SatelliteWindow::SatelliteWindow(MainWindow* pMainWindow) :
    BrowserWindow(false, true), gwtCallback_(pMainWindow, this)
{
   setAttribute(Qt::WA_QuitOnClose, false);
   setAttribute(Qt::WA_DeleteOnClose, true);

   setWindowIcon(QIcon(QString::fromAscii(":/icons/RStudio.ico")));
}

void SatelliteWindow::onJavaScriptWindowObjectCleared()
{
   webView()->page()->mainFrame()->addToJavaScriptWindowObject(
         QString::fromAscii("desktop"),
         &gwtCallback_,
         QScriptEngine::QtOwnership);

   connect(webView(), SIGNAL(onCloseWindowShortcut()),
           this, SLOT(onCloseWindowShortcut()));
}

void SatelliteWindow::onCloseWindowShortcut()
{
   close();
}

void SatelliteWindow::finishLoading(bool ok)
{
   BrowserWindow::finishLoading(ok);

   if (ok)
      avoidMoveCursorIfNecessary();
}

} // namespace desktop
<|endoftext|>


<commit_before>//
// PROJECT CHRONO - http://projectchrono.org
//
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//
///////////////////////////////////////////////////
//
//  Summary: Test the DriveChain system.
//  Components: Gear, Powertrain, tensioned and passive Idler(s),
//
//  Throttle, gear, pin damping coef., etc. driven by the user with an Irrlicht GUI.
//  Alternatively, scripted driven simulations supported thru Track_FuncDriver.
//
//  Output I care about:
//    The reaction forces in the pins adjoining 5 or so track shoes.
//    I'm going to analyze the time history of pin tension forces, and also the
//    cumulative contact normal and friction forces between the pins and gear surface.
//    Changing Gear CollisionType from PRIMITIVES to CALLBACKFUNCTION with and without pin/gear
//    callback function enabled. So the gear collision shapes will be
//      a) two concentric cylinders, contact w/ flat shoe surface
//      b) two concentric cylinders, further laterally outwards. 10 boxes for the top gear tooth surface.
//      c) same as b), but add the collision callback function, which looks for contact between shoe pins and
//         concave gear tooth base surface.
//
//    Output to text files for Python plots, by uncommenting #define WRITE_OUTPUT
//	 Author: Justin Madsen, 2015
///////////////////////////////////////////////////

#include "physics/ChSystem.h"
// #include "particlefactory/ChParticleEmitter.h"

#include "core/ChFileutils.h"
#include "core/ChStream.h"
#include "core/ChRealtimeStep.h"
#include "physics/ChSystem.h"
#include "physics/ChLinkDistance.h"
#include "physics/ChBodyEasy.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"
#include "assets/ChTexture.h"
#include "assets/ChColorAsset.h"
/*
#if IRRLICHT_ENABLED
*/
#include "unit_IRRLICHT/ChIrrApp.h"
#include "subsys/driver/ChIrrGuiTrack.h"
// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;
 /*
 # define USE_IRRLICHT
#endif
 */

#include "subsys/trackVehicle/DriveChain.h"
#include "ModelDefs.h"
// Use the main namespace of Chrono
using namespace chrono;

// =============================================================================
// User Settings
// =============================================================================
// display the  system heirarchy, write output data, log constraint violations to console
//#define DEBUG_LOG
#define WRITE_OUTPUT
#define CONSOLE_CONSTRAINT_INFO

// Initial vehicle position and heading. Defines the REF frame for the hull body
ChVector<> initLoc(0, 1.0, 0);
//ChQuaternion<> initRot = Q_from_AngAxis(CH_C_PI_4, VECT_Y);
ChQuaternion<> initRot(QUNIT);

// Simulation step size
double step_size = 0.002;

size_t num_idlers = 2;

// Time interval between two render frames
int FPS = 40;
double render_step_size = 1.0 / FPS;   // FPS = 50
// Time interval between two output frames
double output_step_size = 1.0 / 1;    // once a second

// #ifdef USE_IRRLICHT
  // Point on chassis tracked by the camera, chassis c-sys
ChVector<> trackPoint(-1, 0, 0);
// if chase cam enabled:
double chaseDist = 1.8;
double chaseHeight = 0.0;
// set a static camera position, global c-sys
ChVector<> cameraPos(-1, 1.5, 2.5);
bool use_fixed_camera = true;
bool do_shadows = false; // shadow map is experimental

  /*
#else
  double tend = 20.0;

  const std::string out_dir = "../test_driveChain";
  const std::string pov_dir = out_dir + "/POVRAY";
#endif
  */

int main(int argc, char* argv[])
{
  // NOTE: utils library built with this sets this statically
  // SetChronoDataPath(CHRONO_DATA_DIR);

  // --------------------------
  // Create the Chain system (drive gear, idler, chain)

  // The drive chain inherits ChSystem. Specify the
  // collision type used by the gear here.
  DriveChain chainSystem("Justins driveChain system",
    // VisualizationType::MESH,
    VisualizationType::COMPOUNDPRIMITIVES,
    CollisionType::CALLBACKFUNCTION,
    num_idlers);

  // set the chassis REF at the specified initial config.
  chainSystem.Initialize(ChCoordsys<>(initLoc, initRot));

  // if writing an output file, setup what debugInformation we want added each step data is saved.
#ifdef WRITE_OUTPUT
  chainSystem.Save_DebugLog(DBG_FIRSTSHOE || DBG_GEAR || DBG_IDLER || DBG_PTRAIN || DBG_CONSTRAINTS,
    "test_driveChain_all.csv");
#endif

/*
#ifdef USE_IRRLICHT
*/

  // --------------------------
  // Setup the Irrlicht GUI

  // Create the Irrlicht visualization applicaiton
  ChIrrApp application(chainSystem.GetSystem(),
                      L"test driveChain demo",
                      dimension2d<u32>(1200, 800),
                      false,
                      do_shadows);
  // assumes Y-up
  application.AddTypicalSky();

  irr::scene::ILightSceneNode* mlight = 0;

  if (do_shadows)
  {
    mlight = application.AddLightWithShadow(
      irr::core::vector3df(10.f, 60.f, 30.f),
      irr::core::vector3df(0.f, 0.f, 0.f),
      150, 60, 80, 15, 512, irr::video::SColorf(1, 1, 1), false, false);
  }
  else
  {
    application.AddTypicalLights(
      irr::core::vector3df(50.f, -25.f, 30.f),
      irr::core::vector3df(-30.f, 80.f, -50.f),
      150, 125);
  }

  application.SetTimestep(step_size);

  // the GUI driver
  ChIrrGuiTrack driver(application, chainSystem, trackPoint, chaseDist, chaseHeight);
  // even though using a chase camera, set the initial camera position laterally
  if(use_fixed_camera)
    driver.SetCameraPos(cameraPos);

  // Set the time response for steering and throttle keyboard inputs.
  // NOTE: this is not exact, since we do not render quite at the specified FPS.
  double throttle_time = 2.0;  // time to go from 0 to +1
  double braking_time = 0.5;	// time to go from 0 to +1
  // driver.SetSteeringDelta(render_step_size / 1);
  driver.SetThrottleDelta(render_step_size / throttle_time);
  driver.SetBrakingDelta(render_step_size / braking_time);
  driver.SetDampingDelta(render_step_size / 3.0);

  // Set up the assets for rendering
  application.AssetBindAll();
  application.AssetUpdateAll();
  if (do_shadows)
  {
    application.AddShadowAll();
  }
/*
#else
  Track_FuncDriver driver;
#endif
*/

  // ---------------------
  // GUI and render settings

  // GUI driver inputs
  std::vector<double> throttle_input;
  std::vector<double> braking_input;

  // Number of simulation steps between two 3D view render frames
  int render_steps = (int)std::ceil(render_step_size / step_size);

  // Number of simulation steps between two output frames
  int output_steps = (int)std::ceil(output_step_size / step_size);

  // ---------------------
  // Simulation loop
#ifdef DEBUG_LOG
  GetLog() << "\n\n============ System Configuration ============\n";
  chainSystem.GetSystem()->ShowHierarchy(GetLog() );
#endif

  // Initialize simulation frame counter and simulation time
  int step_number = 0;
  double time = 0;
/*
#ifdef USE_IRRLICHT
*/

  ChRealtimeStepTimer realtime_timer;
  while (application.GetDevice()->run())
	{
		// keep track of the time spent calculating each sim step
    ChTimer<double> step_time;
    step_time.start();

    // Render scene
    if (step_number % render_steps == 0) {
      application.GetVideoDriver()->beginScene(true, true,irr::video::SColor(255, 140, 161, 192));
      driver.DrawAll();
      application.GetVideoDriver()->endScene();
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    braking_input = driver.GetBraking();

    // Update
    time = chainSystem.GetSystem()->GetChTime();

    driver.Update(time);

    chainSystem.Update(time, throttle_input[0], braking_input[0]);

    // Advance simulation for one timestep for all modules
    // step_size = realtime_timer.SuggestSimulationStep(step_size);
    use_fixed_camera ? driver.Advance(step_size, cameraPos): driver.Advance(step_size);

    // Settlings phase has hardcoded solver settings, for the first few timesteps
    // application.SetPaused(true);
    if( !application.GetPaused() )
      chainSystem.Advance(step_size);

    // log desired output to console?
#ifdef CONSOLE_CONSTRAINT_INFO
    chainSystem.LogConstraintViolations();
#endif

    // write data to file?
#ifdef WRITE_OUTPUT
    chainSystem.SaveLog();  // needs to already be setup before sim loop calls it
#endif

    step_number++;

  }

  application.GetDevice()->drop();

/*
#else

  int render_frame = 0;

  if(ChFileutils::MakeDirectory(out_dir.c_str()) < 0) {
    std::cout << "Error creating directory " << out_dir << std::endl;
    return 1;
  }
  if(ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) {
    std::cout << "Error creating directory " << pov_dir << std::endl;
    return 1;
  }

  chainSystem.ExportMeshPovray(out_dir);

  char filename[100];

  while (time < tend)
  {
    if (step_number % render_steps == 0) {
      // Output render data
      sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), render_frame + 1);
      utils::WriteShapesPovray(chainSystem.GetSystem(), filename);
      std::cout << "Output frame:   " << render_frame << std::endl;
      std::cout << "Sim frame:      " << step_number << std::endl;
      std::cout << "Time:           " << time << std::endl;
      std::cout << " throttle: " << driver.GetThrottle() << " braking: " << driver.GetBraking() << std::endl;
      std::cout << std::endl;
      render_frame++;
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    braking_input = driver.GetBraking();

    // Update modules (process inputs from other modules)
    time = chainSystem.GetSystem()->GetChTime();

    driver.Update(time);

    chainSystem.Update(time, throttle_input, braking_input);

    // Advance simulation for one timestep for all modules
    driver.Advance(step_size);

    chainSystem.Advance(step_size);

    // Increment frame number
    step_number++;
  }

#endif

*/

	return 0;
}

<commit_msg>rename the console log of system info<commit_after>//
// PROJECT CHRONO - http://projectchrono.org
//
// All rights reserved.
//
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file at the top level of the distribution
// and at http://projectchrono.org/license-chrono.txt.
//
///////////////////////////////////////////////////
//
//  Summary: Test the DriveChain system.
//  Components: Gear, Powertrain, tensioned and passive Idler(s),
//
//  Throttle, gear, pin damping coef., etc. driven by the user with an Irrlicht GUI.
//  Alternatively, scripted driven simulations supported thru Track_FuncDriver.
//
//  Output I care about:
//    The reaction forces in the pins adjoining 5 or so track shoes.
//    I'm going to analyze the time history of pin tension forces, and also the
//    cumulative contact normal and friction forces between the pins and gear surface.
//    Changing Gear CollisionType from PRIMITIVES to CALLBACKFUNCTION with and without pin/gear
//    callback function enabled. So the gear collision shapes will be
//      a) two concentric cylinders, contact w/ flat shoe surface
//      b) two concentric cylinders, further laterally outwards. 10 boxes for the top gear tooth surface.
//      c) same as b), but add the collision callback function, which looks for contact between shoe pins and
//         concave gear tooth base surface.
//
//    Output to text files for Python plots, by uncommenting #define WRITE_OUTPUT
//	 Author: Justin Madsen, 2015
///////////////////////////////////////////////////

#include "physics/ChSystem.h"
// #include "particlefactory/ChParticleEmitter.h"

#include "core/ChFileutils.h"
#include "core/ChStream.h"
#include "core/ChRealtimeStep.h"
#include "physics/ChSystem.h"
#include "physics/ChLinkDistance.h"
#include "physics/ChBodyEasy.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"
#include "assets/ChTexture.h"
#include "assets/ChColorAsset.h"
/*
#if IRRLICHT_ENABLED
*/
#include "unit_IRRLICHT/ChIrrApp.h"
#include "subsys/driver/ChIrrGuiTrack.h"
// Use the main namespaces of Irrlicht
using namespace irr;
using namespace core;
 /*
 # define USE_IRRLICHT
#endif
 */

#include "subsys/trackVehicle/DriveChain.h"
#include "ModelDefs.h"
// Use the main namespace of Chrono
using namespace chrono;

// =============================================================================
// User Settings
// =============================================================================
// display the  system heirarchy, write output data, log constraint violations to console
//#define CONSOLE_SYSTEM_INFO
#define WRITE_OUTPUT
#define CONSOLE_CONSTRAINT_INFO

// Initial vehicle position and heading. Defines the REF frame for the hull body
ChVector<> initLoc(0, 1.0, 0);
//ChQuaternion<> initRot = Q_from_AngAxis(CH_C_PI_4, VECT_Y);
ChQuaternion<> initRot(QUNIT);

// Simulation step size
double step_size = 0.002;

size_t num_idlers = 2;

// Time interval between two render frames
int FPS = 40;
double render_step_size = 1.0 / FPS;   // FPS = 50
// Time interval between two output frames
double output_step_size = 1.0 / 1;    // once a second

// #ifdef USE_IRRLICHT
  // Point on chassis tracked by the camera, chassis c-sys
ChVector<> trackPoint(-1, 0, 0);
// if chase cam enabled:
double chaseDist = 1.8;
double chaseHeight = 0.0;
// set a static camera position, global c-sys
ChVector<> cameraPos(-1, 1.5, 2.5);
bool use_fixed_camera = true;
bool do_shadows = false; // shadow map is experimental

  /*
#else
  double tend = 20.0;

  const std::string out_dir = "../test_driveChain";
  const std::string pov_dir = out_dir + "/POVRAY";
#endif
  */

int main(int argc, char* argv[])
{
  // NOTE: utils library built with this sets this statically
  // SetChronoDataPath(CHRONO_DATA_DIR);

  // --------------------------
  // Create the Chain system (drive gear, idler, chain)

  // The drive chain inherits ChSystem. Specify the
  // collision type used by the gear here.
  DriveChain chainSystem("Justins driveChain system",
    // VisualizationType::MESH,
    VisualizationType::COMPOUNDPRIMITIVES,
    CollisionType::CALLBACKFUNCTION,
    num_idlers);

  // set the chassis REF at the specified initial config.
  chainSystem.Initialize(ChCoordsys<>(initLoc, initRot));

  // if writing an output file, setup what debugInformation we want added each step data is saved.
#ifdef WRITE_OUTPUT
  chainSystem.Save_DebugLog(DBG_FIRSTSHOE || DBG_GEAR || DBG_IDLER || DBG_PTRAIN || DBG_CONSTRAINTS,
    "test_driveChain_all.csv");
#endif

/*
#ifdef USE_IRRLICHT
*/

  // --------------------------
  // Setup the Irrlicht GUI

  // Create the Irrlicht visualization applicaiton
  ChIrrApp application(chainSystem.GetSystem(),
                      L"test driveChain demo",
                      dimension2d<u32>(1200, 800),
                      false,
                      do_shadows);
  // assumes Y-up
  application.AddTypicalSky();

  irr::scene::ILightSceneNode* mlight = 0;

  if (do_shadows)
  {
    mlight = application.AddLightWithShadow(
      irr::core::vector3df(10.f, 60.f, 30.f),
      irr::core::vector3df(0.f, 0.f, 0.f),
      150, 60, 80, 15, 512, irr::video::SColorf(1, 1, 1), false, false);
  }
  else
  {
    application.AddTypicalLights(
      irr::core::vector3df(50.f, -25.f, 30.f),
      irr::core::vector3df(-30.f, 80.f, -50.f),
      150, 125);
  }

  application.SetTimestep(step_size);

  // the GUI driver
  ChIrrGuiTrack driver(application, chainSystem, trackPoint, chaseDist, chaseHeight);
  // even though using a chase camera, set the initial camera position laterally
  if(use_fixed_camera)
    driver.SetCameraPos(cameraPos);

  // Set the time response for steering and throttle keyboard inputs.
  // NOTE: this is not exact, since we do not render quite at the specified FPS.
  double throttle_time = 2.0;  // time to go from 0 to +1
  double braking_time = 0.5;	// time to go from 0 to +1
  // driver.SetSteeringDelta(render_step_size / 1);
  driver.SetThrottleDelta(render_step_size / throttle_time);
  driver.SetBrakingDelta(render_step_size / braking_time);
  driver.SetDampingDelta(render_step_size / 3.0);

  // Set up the assets for rendering
  application.AssetBindAll();
  application.AssetUpdateAll();
  if (do_shadows)
  {
    application.AddShadowAll();
  }
/*
#else
  Track_FuncDriver driver;
#endif
*/

  // ---------------------
  // GUI and render settings

  // GUI driver inputs
  std::vector<double> throttle_input;
  std::vector<double> braking_input;

  // Number of simulation steps between two 3D view render frames
  int render_steps = (int)std::ceil(render_step_size / step_size);

  // Number of simulation steps between two output frames
  int output_steps = (int)std::ceil(output_step_size / step_size);

  // ---------------------
  // Simulation loop
#ifdef CONSOLE_SYSTEM_INFO
  GetLog() << "\n\n============ System Configuration ============\n";
  chainSystem.GetSystem()->ShowHierarchy(GetLog() );
#endif

  // Initialize simulation frame counter and simulation time
  int step_number = 0;
  double time = 0;
/*
#ifdef USE_IRRLICHT
*/

  ChRealtimeStepTimer realtime_timer;
  while (application.GetDevice()->run())
	{
		// keep track of the time spent calculating each sim step
    ChTimer<double> step_time;
    step_time.start();

    // Render scene
    if (step_number % render_steps == 0) {
      application.GetVideoDriver()->beginScene(true, true,irr::video::SColor(255, 140, 161, 192));
      driver.DrawAll();
      application.GetVideoDriver()->endScene();
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    braking_input = driver.GetBraking();

    // Update
    time = chainSystem.GetSystem()->GetChTime();

    driver.Update(time);

    chainSystem.Update(time, throttle_input[0], braking_input[0]);

    // Advance simulation for one timestep for all modules
    // step_size = realtime_timer.SuggestSimulationStep(step_size);
    use_fixed_camera ? driver.Advance(step_size, cameraPos): driver.Advance(step_size);

    // Settlings phase has hardcoded solver settings, for the first few timesteps
    // application.SetPaused(true);
    if( !application.GetPaused() )
      chainSystem.Advance(step_size);

    // log desired output to console?
#ifdef CONSOLE_CONSTRAINT_INFO
    chainSystem.LogConstraintViolations();
#endif

    // write data to file?
#ifdef WRITE_OUTPUT
    chainSystem.SaveLog();  // needs to already be setup before sim loop calls it
#endif

    step_number++;

  }

  application.GetDevice()->drop();

/*
#else

  int render_frame = 0;

  if(ChFileutils::MakeDirectory(out_dir.c_str()) < 0) {
    std::cout << "Error creating directory " << out_dir << std::endl;
    return 1;
  }
  if(ChFileutils::MakeDirectory(pov_dir.c_str()) < 0) {
    std::cout << "Error creating directory " << pov_dir << std::endl;
    return 1;
  }

  chainSystem.ExportMeshPovray(out_dir);

  char filename[100];

  while (time < tend)
  {
    if (step_number % render_steps == 0) {
      // Output render data
      sprintf(filename, "%s/data_%03d.dat", pov_dir.c_str(), render_frame + 1);
      utils::WriteShapesPovray(chainSystem.GetSystem(), filename);
      std::cout << "Output frame:   " << render_frame << std::endl;
      std::cout << "Sim frame:      " << step_number << std::endl;
      std::cout << "Time:           " << time << std::endl;
      std::cout << " throttle: " << driver.GetThrottle() << " braking: " << driver.GetBraking() << std::endl;
      std::cout << std::endl;
      render_frame++;
    }

    // Collect output data from modules (for inter-module communication)
    throttle_input = driver.GetThrottle();
    braking_input = driver.GetBraking();

    // Update modules (process inputs from other modules)
    time = chainSystem.GetSystem()->GetChTime();

    driver.Update(time);

    chainSystem.Update(time, throttle_input, braking_input);

    // Advance simulation for one timestep for all modules
    driver.Advance(step_size);

    chainSystem.Advance(step_size);

    // Increment frame number
    step_number++;
  }

#endif

*/

	return 0;
}

<|endoftext|>


<commit_before>#include <libmesh/libmesh.h>
#include <libmesh/distributed_mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_tools.h>
#include <libmesh/replicated_mesh.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

class MeshGenerationTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify proper operation of
   * MeshGeneration functions, as well as to indirectly verify the
   * MeshBase functions they rely on.
   */
public:
  CPPUNIT_TEST_SUITE( MeshGenerationTest );

  CPPUNIT_TEST( buildLineEdge2 );
  CPPUNIT_TEST( buildLineEdge3 );
  CPPUNIT_TEST( buildLineEdge4 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereEdge2 );
  CPPUNIT_TEST( buildSphereEdge3 );
// CPPUNIT_TEST( buildSphereEdge4 ); Doesn't work with AMR yet
#  endif

#if LIBMESH_DIM > 1
  CPPUNIT_TEST( buildSquareTri3 );
  CPPUNIT_TEST( buildSquareTri6 );
  CPPUNIT_TEST( buildSquareQuad4 );
  CPPUNIT_TEST( buildSquareQuad8 );
  CPPUNIT_TEST( buildSquareQuad9 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereTri3 );
  CPPUNIT_TEST( buildSphereQuad4 );
#  endif
#endif
#if LIBMESH_DIM > 2
  CPPUNIT_TEST( buildCubeTet4 );
  CPPUNIT_TEST( buildCubeTet10 );
  CPPUNIT_TEST( buildCubeHex8 );
  CPPUNIT_TEST( buildCubeHex20 );
  CPPUNIT_TEST( buildCubeHex27 );
  CPPUNIT_TEST( buildCubePrism6 );
  CPPUNIT_TEST( buildCubePrism15 );
  CPPUNIT_TEST( buildCubePrism18 );
  CPPUNIT_TEST( buildCubePyramid5 );
  CPPUNIT_TEST( buildCubePyramid13 );
  CPPUNIT_TEST( buildCubePyramid14 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereHex8 );
//  CPPUNIT_TEST( buildSphereHex27 );
#  endif
#endif

  CPPUNIT_TEST_SUITE_END();

protected:
  std::unique_ptr<UnstructuredMesh> new_mesh (bool is_replicated)
  {
    if (is_replicated)
      return libmesh_make_unique<ReplicatedMesh>(*TestCommWorld);
    return libmesh_make_unique<DistributedMesh>(*TestCommWorld);
  }

public:
  void setUp() {}

  void tearDown() {}

  void testBuildLine(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_line (mesh, n, -1.0, 2.0, type);
    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n));
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                         cast_int<dof_id_type>((Elem::type_to_n_nodes_map[type]-1)*n + 1));

    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT_EQUAL(bbox.min()(0), Real(-1.0));
    CPPUNIT_ASSERT_EQUAL(bbox.max()(0), Real(2.0));
  }

  void testBuildSquare(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_square (mesh, n, n, -2.0, 3.0, -4.0, 5.0, type);
    if (Elem::type_to_n_sides_map[type] == 4)
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n));
    else
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*2));

    const unsigned int n_nodes = Elem::type_to_n_nodes_map[type];

    switch (n_nodes)
      {
      case 3: // First-order elements
      case 4:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)));
        break;
      case 6: // Second-order elements
      case 9:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)));
        break;
      default: // QUAD8
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1) - n*n));
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
  }

  void testBuildCube(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_cube (mesh, n, n, n, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, type);
    switch (Elem::type_to_n_sides_map[type])
      {
      case 4: // tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*24));
        break;
      case 5: // prisms, pyramids
        if (type == PRISM6 || type == PRISM15 || type == PRISM18)
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*2));
        else
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*6));
        break;
      case 6: // hexes
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
        break;
      default:
        libmesh_error();
      }

    switch (Elem::type_to_n_nodes_map[type])
      {
      case 4: // First-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n + 3*(n+1)*n*n));
        break;
      case 6: // First-order prisms and hexes use the same nodes
      case 8:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1)));
        break;
      case 10: // Second-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n));
        break;
      case 18: // Second-order prisms and hexes use the same nodes
      case 27:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1)));
        break;
      case 20:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 3*(n+1)*n*n));
        break;
      case 15: // weird partial order prism
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 2*(n+1)*n*n));
        break;
      case 5: // pyramids
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n));
        break;
      case 13:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n - 3*(n+1)*n*n));
        break;
      case 14:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n));
        break;
      default:
        libmesh_error();
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
    CPPUNIT_ASSERT(bbox.min()(2) <= Real(-6.0));
    CPPUNIT_ASSERT(bbox.max()(2) >= Real(7.0));
  }

  void testBuildSphere(unsigned int n_ref, ElemType type)
  {
    ReplicatedMesh rmesh(*TestCommWorld);
    MeshTools::Generation::build_sphere (rmesh, 2.0, n_ref, type);

    DistributedMesh dmesh(*TestCommWorld);
    dmesh.allow_renumbering(false);
    MeshTools::Generation::build_sphere (dmesh, 2.0, n_ref, type);
  }

  typedef void (MeshGenerationTest::*Builder)(UnstructuredMesh&, unsigned int, ElemType);

  void tester(Builder f, unsigned int n, ElemType type)
  {
    for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
      {
        for (int skip_renumber = 0 ; skip_renumber != 2; ++skip_renumber)
          {
            std::unique_ptr<UnstructuredMesh> mesh =
              new_mesh(is_replicated);
            mesh->allow_renumbering(!skip_renumber);
            (this->*f)(*mesh, n, type);
          }
      }
  }

  void buildLineEdge2 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE2); }
  void buildLineEdge3 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE3); }
  void buildLineEdge4 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE4); }

  void buildSphereEdge2 ()     { testBuildSphere(2, EDGE2); }
  void buildSphereEdge3 ()     { testBuildSphere(2, EDGE3); }
  void buildSphereEdge4 ()     { testBuildSphere(2, EDGE4); }

  void buildSquareTri3 ()    { tester(&MeshGenerationTest::testBuildSquare, 3, TRI3); }
  void buildSquareTri6 ()    { tester(&MeshGenerationTest::testBuildSquare, 4, TRI6); }
  void buildSquareQuad4 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD4); }
  void buildSquareQuad8 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD8); }
  void buildSquareQuad9 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD9); }

  void buildSphereTri3 ()     { testBuildSphere(2, TRI3); }
  void buildSphereQuad4 ()     { testBuildSphere(2, QUAD4); }

  void buildCubeTet4 ()      { tester(&MeshGenerationTest::testBuildCube, 2, TET4); }
  void buildCubeTet10 ()     { tester(&MeshGenerationTest::testBuildCube, 2, TET10); }
  void buildCubeHex8 ()      { tester(&MeshGenerationTest::testBuildCube, 2, HEX8); }
  void buildCubeHex20 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX20); }
  void buildCubeHex27 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX27); }
  void buildCubePrism6 ()    { tester(&MeshGenerationTest::testBuildCube, 2, PRISM6); }
  void buildCubePrism15 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM15); }
  void buildCubePrism18 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM18); }
  void buildCubePyramid5 ()  { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID5); }
  void buildCubePyramid13 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID13); }
  void buildCubePyramid14 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID14); }

  void buildSphereHex8 ()     { testBuildSphere(2, HEX8); }
  void buildSphereHex27 ()     { testBuildSphere(2, HEX27); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshGenerationTest );
<commit_msg>Enable build_sphere HEX27 unit test<commit_after>#include <libmesh/libmesh.h>
#include <libmesh/distributed_mesh.h>
#include <libmesh/elem.h>
#include <libmesh/mesh_generation.h>
#include <libmesh/mesh_tools.h>
#include <libmesh/replicated_mesh.h>

#include "test_comm.h"
#include "libmesh_cppunit.h"

using namespace libMesh;

class MeshGenerationTest : public CppUnit::TestCase
{
  /**
   * The goal of this test is to verify proper operation of
   * MeshGeneration functions, as well as to indirectly verify the
   * MeshBase functions they rely on.
   */
public:
  CPPUNIT_TEST_SUITE( MeshGenerationTest );

  CPPUNIT_TEST( buildLineEdge2 );
  CPPUNIT_TEST( buildLineEdge3 );
  CPPUNIT_TEST( buildLineEdge4 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereEdge2 );
  CPPUNIT_TEST( buildSphereEdge3 );
// CPPUNIT_TEST( buildSphereEdge4 ); Doesn't work with AMR yet
#  endif

#if LIBMESH_DIM > 1
  CPPUNIT_TEST( buildSquareTri3 );
  CPPUNIT_TEST( buildSquareTri6 );
  CPPUNIT_TEST( buildSquareQuad4 );
  CPPUNIT_TEST( buildSquareQuad8 );
  CPPUNIT_TEST( buildSquareQuad9 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereTri3 );
  CPPUNIT_TEST( buildSphereQuad4 );
#  endif
#endif
#if LIBMESH_DIM > 2
  CPPUNIT_TEST( buildCubeTet4 );
  CPPUNIT_TEST( buildCubeTet10 );
  CPPUNIT_TEST( buildCubeHex8 );
  CPPUNIT_TEST( buildCubeHex20 );
  CPPUNIT_TEST( buildCubeHex27 );
  CPPUNIT_TEST( buildCubePrism6 );
  CPPUNIT_TEST( buildCubePrism15 );
  CPPUNIT_TEST( buildCubePrism18 );
  CPPUNIT_TEST( buildCubePyramid5 );
  CPPUNIT_TEST( buildCubePyramid13 );
  CPPUNIT_TEST( buildCubePyramid14 );
#  ifdef LIBMESH_ENABLE_AMR
  CPPUNIT_TEST( buildSphereHex8 );
  CPPUNIT_TEST( buildSphereHex27 );
#  endif
#endif

  CPPUNIT_TEST_SUITE_END();

protected:
  std::unique_ptr<UnstructuredMesh> new_mesh (bool is_replicated)
  {
    if (is_replicated)
      return libmesh_make_unique<ReplicatedMesh>(*TestCommWorld);
    return libmesh_make_unique<DistributedMesh>(*TestCommWorld);
  }

public:
  void setUp() {}

  void tearDown() {}

  void testBuildLine(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_line (mesh, n, -1.0, 2.0, type);
    CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n));
    CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                         cast_int<dof_id_type>((Elem::type_to_n_nodes_map[type]-1)*n + 1));

    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT_EQUAL(bbox.min()(0), Real(-1.0));
    CPPUNIT_ASSERT_EQUAL(bbox.max()(0), Real(2.0));
  }

  void testBuildSquare(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_square (mesh, n, n, -2.0, 3.0, -4.0, 5.0, type);
    if (Elem::type_to_n_sides_map[type] == 4)
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n));
    else
      CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*2));

    const unsigned int n_nodes = Elem::type_to_n_nodes_map[type];

    switch (n_nodes)
      {
      case 3: // First-order elements
      case 4:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)));
        break;
      case 6: // Second-order elements
      case 9:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)));
        break;
      default: // QUAD8
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1) - n*n));
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
  }

  void testBuildCube(UnstructuredMesh & mesh, unsigned int n, ElemType type)
  {
    MeshTools::Generation::build_cube (mesh, n, n, n, -2.0, 3.0, -4.0, 5.0, -6.0, 7.0, type);
    switch (Elem::type_to_n_sides_map[type])
      {
      case 4: // tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*24));
        break;
      case 5: // prisms, pyramids
        if (type == PRISM6 || type == PRISM15 || type == PRISM18)
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*2));
        else
          CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n*6));
        break;
      case 6: // hexes
        CPPUNIT_ASSERT_EQUAL(mesh.n_elem(), cast_int<dof_id_type>(n*n*n));
        break;
      default:
        libmesh_error();
      }

    switch (Elem::type_to_n_nodes_map[type])
      {
      case 4: // First-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n + 3*(n+1)*n*n));
        break;
      case 6: // First-order prisms and hexes use the same nodes
      case 8:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1)));
        break;
      case 10: // Second-order tets
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 14*n*n*n + 4*3*(n+1)*n*n));
        break;
      case 18: // Second-order prisms and hexes use the same nodes
      case 27:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1)));
        break;
      case 20:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 3*(n+1)*n*n));
        break;
      case 15: // weird partial order prism
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) - n*n*n - 2*(n+1)*n*n));
        break;
      case 5: // pyramids
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((n+1)*(n+1)*(n+1) + n*n*n));
        break;
      case 13:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n - 3*(n+1)*n*n));
        break;
      case 14:
        CPPUNIT_ASSERT_EQUAL(mesh.n_nodes(),
                             cast_int<dof_id_type>((2*n+1)*(2*n+1)*(2*n+1) + 8*n*n*n));
        break;
      default:
        libmesh_error();
      }

    // Our bounding boxes can be loose on higher order elements, but
    // we can at least assert that they're not too tight
    BoundingBox bbox = MeshTools::create_bounding_box(mesh);
    CPPUNIT_ASSERT(bbox.min()(0) <= Real(-2.0));
    CPPUNIT_ASSERT(bbox.max()(0) >= Real(3.0));
    CPPUNIT_ASSERT(bbox.min()(1) <= Real(-4.0));
    CPPUNIT_ASSERT(bbox.max()(1) >= Real(5.0));
    CPPUNIT_ASSERT(bbox.min()(2) <= Real(-6.0));
    CPPUNIT_ASSERT(bbox.max()(2) >= Real(7.0));
  }

  void testBuildSphere(unsigned int n_ref, ElemType type)
  {
    ReplicatedMesh rmesh(*TestCommWorld);
    MeshTools::Generation::build_sphere (rmesh, 2.0, n_ref, type);

    DistributedMesh dmesh(*TestCommWorld);
    dmesh.allow_renumbering(false);
    MeshTools::Generation::build_sphere (dmesh, 2.0, n_ref, type);
  }

  typedef void (MeshGenerationTest::*Builder)(UnstructuredMesh&, unsigned int, ElemType);

  void tester(Builder f, unsigned int n, ElemType type)
  {
    for (int is_replicated = 0; is_replicated != 2; ++is_replicated)
      {
        for (int skip_renumber = 0 ; skip_renumber != 2; ++skip_renumber)
          {
            std::unique_ptr<UnstructuredMesh> mesh =
              new_mesh(is_replicated);
            mesh->allow_renumbering(!skip_renumber);
            (this->*f)(*mesh, n, type);
          }
      }
  }

  void buildLineEdge2 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE2); }
  void buildLineEdge3 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE3); }
  void buildLineEdge4 ()     { tester(&MeshGenerationTest::testBuildLine, 5, EDGE4); }

  void buildSphereEdge2 ()     { testBuildSphere(2, EDGE2); }
  void buildSphereEdge3 ()     { testBuildSphere(2, EDGE3); }
  void buildSphereEdge4 ()     { testBuildSphere(2, EDGE4); }

  void buildSquareTri3 ()    { tester(&MeshGenerationTest::testBuildSquare, 3, TRI3); }
  void buildSquareTri6 ()    { tester(&MeshGenerationTest::testBuildSquare, 4, TRI6); }
  void buildSquareQuad4 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD4); }
  void buildSquareQuad8 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD8); }
  void buildSquareQuad9 ()   { tester(&MeshGenerationTest::testBuildSquare, 4, QUAD9); }

  void buildSphereTri3 ()     { testBuildSphere(2, TRI3); }
  void buildSphereQuad4 ()     { testBuildSphere(2, QUAD4); }

  void buildCubeTet4 ()      { tester(&MeshGenerationTest::testBuildCube, 2, TET4); }
  void buildCubeTet10 ()     { tester(&MeshGenerationTest::testBuildCube, 2, TET10); }
  void buildCubeHex8 ()      { tester(&MeshGenerationTest::testBuildCube, 2, HEX8); }
  void buildCubeHex20 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX20); }
  void buildCubeHex27 ()     { tester(&MeshGenerationTest::testBuildCube, 2, HEX27); }
  void buildCubePrism6 ()    { tester(&MeshGenerationTest::testBuildCube, 2, PRISM6); }
  void buildCubePrism15 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM15); }
  void buildCubePrism18 ()   { tester(&MeshGenerationTest::testBuildCube, 2, PRISM18); }
  void buildCubePyramid5 ()  { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID5); }
  void buildCubePyramid13 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID13); }
  void buildCubePyramid14 () { tester(&MeshGenerationTest::testBuildCube, 2, PYRAMID14); }

  void buildSphereHex8 ()     { testBuildSphere(2, HEX8); }
  void buildSphereHex27 ()     { testBuildSphere(2, HEX27); }
};

CPPUNIT_TEST_SUITE_REGISTRATION( MeshGenerationTest );
<|endoftext|>


<commit_before>/*************************************************************************
 *
 *  OpenOffice.org - a multi-platform office productivity suite
 *
 *  $RCSfile: svdoattr.hxx,v $
 *
 *  $Revision: 1.2 $
 *
 *  last change: $Author: vg $ $Date: 2007-04-11 16:22:44 $
 *
 *  The Contents of this file are made available subject to
 *  the terms of GNU Lesser General Public License Version 2.1.
 *
 *
 *    GNU Lesser General Public License Version 2.1
 *    =============================================
 *    Copyright 2005 by Sun Microsystems, Inc.
 *    901 San Antonio Road, Palo Alto, CA 94303, USA
 *
 *    This library is free software; you can redistribute it and/or
 *    modify it under the terms of the GNU Lesser General Public
 *    License version 2.1, as published by the Free Software Foundation.
 *
 *    This library is distributed in the hope that it will be useful,
 *    but WITHOUT ANY WARRANTY; without even the implied warranty of
 *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 *    Lesser General Public License for more details.
 *
 *    You should have received a copy of the GNU Lesser General Public
 *    License along with this library; if not, write to the Free Software
 *    Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 *    MA  02111-1307  USA
 *
 ************************************************************************/

#ifndef _SVDOATTR_HXX
#define _SVDOATTR_HXX

#ifndef SVX_XFILLIT0_HXX //autogen
#include <svx/xfillit0.hxx>
#endif

#ifndef _SVX_XFLASIT_HXX //autogen
#include <svx/xflasit.hxx>
#endif

#ifndef _SVX_XLINEIT0_HXX //autogen
#include <svx/xlineit0.hxx>
#endif

#ifndef _SVX_XLNASIT_HXX //autogen
#include <svx/xlnasit.hxx>
#endif

#ifndef _SVDOBJ_HXX
#include <svx/svdobj.hxx>
#endif

#ifndef _SVDATTR_HXX
#include <svx/svdattr.hxx>
#endif

#ifndef INCLUDED_SVXDLLAPI_H
#include "svx/svxdllapi.h"
#endif

//************************************************************
//   Vorausdeklarationen
//************************************************************

class SfxPoolItem;
class SfxSetItem;
class SdrOutliner;
class SfxItemSet;
class SfxItemPool;

//************************************************************
//   SdrAttrObj
//************************************************************

class SVX_DLLPUBLIC SdrAttrObj : public SdrObject
{
    virtual sdr::properties::BaseProperties* CreateObjectSpecificProperties();

    friend class                SdrOutliner;

protected:
    Rectangle                   maSnapRect;

protected:
    // Strichstaerke ermitteln. Keine Linie -> 0.
    sal_Int32 ImpGetLineWdt() const;

    // Feststellen, wieviel wegen der Linienenden auf's BoundRect draufaddiert werden muss.
    INT32 ImpGetLineEndAdd() const;

    // Schattenabstand ermitteln. FALSE=Kein Schatten.
    FASTBOOL ImpGetShadowDist(sal_Int32& nXDist, sal_Int32& nYDist) const;

    // ggf. Schattenversatz zum BoundRect draufaddieren
    void ImpAddShadowToBoundRect();

    // Line und Fill Attribute fuer Schatten setzen.
    // Return=FALSE: kein Schatten attributiert.
    FASTBOOL ImpSetShadowAttributes( const SfxItemSet& rSet, SfxItemSet& rShadowSet ) const;

    // Zuhoeren, ob sich ein StyleSheet aendert
    virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType, const SfxHint& rHint, const TypeId& rHintType);

    SdrAttrObj();
    virtual ~SdrAttrObj();

public:
    TYPEINFO();

    // Feststellen, ob bFilledObj && Fuellung!=FillNone
    BOOL HasFill() const;

    // Feststellen, ob Linie!=LineNone
    BOOL HasLine() const;

    virtual const Rectangle& GetSnapRect() const;

    virtual void SetModel(SdrModel* pNewModel);
};

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //_SVDOATTR_HXX

<commit_msg>INTEGRATION: CWS changefileheader (1.2.466); FILE MERGED 2008/04/01 12:46:54 thb 1.2.466.2: #i85898# Stripping all external header guards 2008/03/31 14:18:17 rt 1.2.466.1: #i87441# Change license header to LPGL v3.<commit_after>/*************************************************************************
 *
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * Copyright 2008 by Sun Microsystems, Inc.
 *
 * OpenOffice.org - a multi-platform office productivity suite
 *
 * $RCSfile: svdoattr.hxx,v $
 * $Revision: 1.3 $
 *
 * This file is part of OpenOffice.org.
 *
 * OpenOffice.org is free software: you can redistribute it and/or modify
 * it under the terms of the GNU Lesser General Public License version 3
 * only, as published by the Free Software Foundation.
 *
 * OpenOffice.org is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Lesser General Public License version 3 for more details
 * (a copy is included in the LICENSE file that accompanied this code).
 *
 * You should have received a copy of the GNU Lesser General Public License
 * version 3 along with OpenOffice.org.  If not, see
 * <http://www.openoffice.org/license.html>
 * for a copy of the LGPLv3 License.
 *
 ************************************************************************/

#ifndef _SVDOATTR_HXX
#define _SVDOATTR_HXX

#include <svx/xfillit0.hxx>
#include <svx/xflasit.hxx>
#include <svx/xlineit0.hxx>
#include <svx/xlnasit.hxx>
#include <svx/svdobj.hxx>
#include <svx/svdattr.hxx>
#include "svx/svxdllapi.h"

//************************************************************
//   Vorausdeklarationen
//************************************************************

class SfxPoolItem;
class SfxSetItem;
class SdrOutliner;
class SfxItemSet;
class SfxItemPool;

//************************************************************
//   SdrAttrObj
//************************************************************

class SVX_DLLPUBLIC SdrAttrObj : public SdrObject
{
    virtual sdr::properties::BaseProperties* CreateObjectSpecificProperties();

    friend class                SdrOutliner;

protected:
    Rectangle                   maSnapRect;

protected:
    // Strichstaerke ermitteln. Keine Linie -> 0.
    sal_Int32 ImpGetLineWdt() const;

    // Feststellen, wieviel wegen der Linienenden auf's BoundRect draufaddiert werden muss.
    INT32 ImpGetLineEndAdd() const;

    // Schattenabstand ermitteln. FALSE=Kein Schatten.
    FASTBOOL ImpGetShadowDist(sal_Int32& nXDist, sal_Int32& nYDist) const;

    // ggf. Schattenversatz zum BoundRect draufaddieren
    void ImpAddShadowToBoundRect();

    // Line und Fill Attribute fuer Schatten setzen.
    // Return=FALSE: kein Schatten attributiert.
    FASTBOOL ImpSetShadowAttributes( const SfxItemSet& rSet, SfxItemSet& rShadowSet ) const;

    // Zuhoeren, ob sich ein StyleSheet aendert
    virtual void SFX_NOTIFY(SfxBroadcaster& rBC, const TypeId& rBCType, const SfxHint& rHint, const TypeId& rHintType);

    SdrAttrObj();
    virtual ~SdrAttrObj();

public:
    TYPEINFO();

    // Feststellen, ob bFilledObj && Fuellung!=FillNone
    BOOL HasFill() const;

    // Feststellen, ob Linie!=LineNone
    BOOL HasLine() const;

    virtual const Rectangle& GetSnapRect() const;

    virtual void SetModel(SdrModel* pNewModel);
};

////////////////////////////////////////////////////////////////////////////////////////////////////

#endif //_SVDOATTR_HXX

<|endoftext|>


<commit_before>#ifndef QUERY_GRAMMAR_TEST_CASE
#define QUERY_GRAMMAR_TEST_CASE

#include <glog/logging.h>
#include <driver.h>
#include <expression.h>
#include <iostream>

TEST(query_grammar_true_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(true)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  ASSERT_TRUE(eval_fn(e));
}

TEST(query_grammar_tagged_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(tagged = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  // Check empty tags do not match anything
  ASSERT_FALSE(eval_fn(e));

  // Check foo matches
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  query = "(tagged = \"foo\" and tagged = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that a missing "bar" tag doesn't match
  ASSERT_FALSE(eval_fn(e));

  //Check foo and bar match
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  query = "(tagged = \"foo\" or tagged = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that only foo matches
  e.clear_tags();
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  //Check only bar matches
  e.clear_tags();
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo and bar match
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  query = "((tagged = \"foo\" or tagged = \"bar\") and (tagged = \"baz\"))";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing baz doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  ASSERT_FALSE(eval_fn(e));

  // Check that only foo and baz match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

 // Check that only bar and baz match
  e.clear_tags();
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo, bar and baz match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

  query = "(not tagged = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing foo matches
  e.clear_tags();
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  ASSERT_FALSE(eval_fn(e));

  query = "((tagged = \"foo\" or tagged = \"bar\") and not (tagged = \"baz\"))";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing baz matches
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check thatbaz doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_FALSE(eval_fn(e));
}

TEST(query_grammar_fields_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(service = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  ASSERT_FALSE(eval_fn(e));

  e.set_service("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(host = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_service();
  e.set_host("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(state = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_host();
  e.set_state("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(description = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_state();
  e.set_description("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(time = 7)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_description();
  e.set_time(7);
  ASSERT_TRUE(eval_fn(e));

  query = "(ttl = 7)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_time();
  e.set_ttl(7);
  ASSERT_TRUE(eval_fn(e));

  query = "(metric = 7.1)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_ttl();
  e.set_metric_d(7.1);
  ASSERT_TRUE(eval_fn(e));

  query = "(foo = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_metric_d();
  auto att = e.add_attributes();
  att->set_key("foo");
  att->set_value("bar");
  ASSERT_TRUE(eval_fn(e));

  std::cout << "aura co" << std::endl;
  query = "(foo = 7.1)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_attributes();
  att = e.add_attributes();
  att->set_key("foo");
  att->set_value("7.1");
  ASSERT_TRUE(eval_fn(e));
}

#endif
<commit_msg>Remove debug line<commit_after>#ifndef QUERY_GRAMMAR_TEST_CASE
#define QUERY_GRAMMAR_TEST_CASE

#include <glog/logging.h>
#include <driver.h>
#include <expression.h>
#include <iostream>

TEST(query_grammar_true_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(true)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  ASSERT_TRUE(eval_fn(e));
}

TEST(query_grammar_tagged_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(tagged = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  // Check empty tags do not match anything
  ASSERT_FALSE(eval_fn(e));

  // Check foo matches
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  query = "(tagged = \"foo\" and tagged = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that a missing "bar" tag doesn't match
  ASSERT_FALSE(eval_fn(e));

  //Check foo and bar match
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  query = "(tagged = \"foo\" or tagged = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that only foo matches
  e.clear_tags();
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  //Check only bar matches
  e.clear_tags();
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo and bar match
  *(e.add_tags()) = "foo";
  ASSERT_TRUE(eval_fn(e));

  query = "((tagged = \"foo\" or tagged = \"bar\") and (tagged = \"baz\"))";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing baz doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  ASSERT_FALSE(eval_fn(e));

  // Check that only foo and baz match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

 // Check that only bar and baz match
  e.clear_tags();
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo, bar and baz match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_TRUE(eval_fn(e));

  query = "(not tagged = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing foo matches
  e.clear_tags();
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check that foo doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  ASSERT_FALSE(eval_fn(e));

  query = "((tagged = \"foo\" or tagged = \"bar\") and not (tagged = \"baz\"))";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  // Check that missing baz matches
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  ASSERT_TRUE(eval_fn(e));

  // Check thatbaz doesn't match
  e.clear_tags();
  *(e.add_tags()) = "foo";
  *(e.add_tags()) = "bar";
  *(e.add_tags()) = "baz";
  ASSERT_FALSE(eval_fn(e));
}

TEST(query_grammar_fields_test_case, test)
{
  QueryContext query_ctx;
  queryparser::Driver driver(query_ctx);

  std::string query = "(service = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  auto eval_fn = query_ctx.expression->evaluate();

  Event e;
  ASSERT_FALSE(eval_fn(e));

  e.set_service("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(host = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_service();
  e.set_host("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(state = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_host();
  e.set_state("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(description = \"foo\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_state();
  e.set_description("foo");
  ASSERT_TRUE(eval_fn(e));

  query = "(time = 7)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_description();
  e.set_time(7);
  ASSERT_TRUE(eval_fn(e));

  query = "(ttl = 7)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_time();
  e.set_ttl(7);
  ASSERT_TRUE(eval_fn(e));

  query = "(metric = 7.1)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_ttl();
  e.set_metric_d(7.1);
  ASSERT_TRUE(eval_fn(e));

  query = "(foo = \"bar\")";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_metric_d();
  auto att = e.add_attributes();
  att->set_key("foo");
  att->set_value("bar");
  ASSERT_TRUE(eval_fn(e));

  query = "(foo = 7.1)";
  ASSERT_TRUE(driver.parse_string(query, "query"));

  eval_fn = query_ctx.expression->evaluate();

  ASSERT_FALSE(eval_fn(e));

  e.clear_attributes();
  att = e.add_attributes();
  att->set_key("foo");
  att->set_value("7.1");
  ASSERT_TRUE(eval_fn(e));
}

#endif
<|endoftext|>


<commit_before>#include "view/SceneView.h"

#include "DotSceneLoader.h"

#include "util/BulletDebugDrawer.h"

#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreConfigFile.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>

#include <sstream>
#include <string>

#include <btBulletDynamicsCommon.h>

SceneView::SceneView(Rally::Model::World& world) :
        world(world),
        camera(NULL),
        sceneManager(NULL),
        renderWindow(NULL) {
}

SceneView::~SceneView() {
    //delete bulletDebugDrawer;

    Ogre::Root* root = Ogre::Root::getSingletonPtr();
    delete root;
}

void SceneView::initialize(std::string resourceConfigPath, std::string pluginConfigPath) {
    Ogre::Root* root = new Ogre::Root(pluginConfigPath);

    this->loadResourceConfig(resourceConfigPath);
    // (The actual precaching is done below, once there is a render context)

    if(!root->restoreConfig() && !root->showConfigDialog()) {
        throw std::runtime_error("Could neither restore Ogre config, nor read it from the user.");
    }

    renderWindow = root->initialise(
        true, // auto-create the render window now
        "Rally Sport Racing Game");

    sceneManager = root->createSceneManager("OctreeSceneManager"); // Todo: Research a good scene manager

    // This should be done after creating a scene manager, so that there is a render context (GL/D3D)
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    camera = this->addCamera("MainCamera");
    Ogre::Viewport* viewport = this->addViewport(camera);
    camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));

    Ogre::SceneNode* sceneNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    sceneNode->setPosition(Ogre::Vector3(0, 110.0f, 0));

	sceneManager->setAmbientLight(Ogre::ColourValue(1, 1, 1));
	Ogre::Light* light = sceneManager->createLight("MainLight");

	// Load the scene.
	DotSceneLoader loader;
	loader.parseDotScene("world.scene", "General", sceneManager, sceneNode);

	// Todo: Move to appropriate view
	Ogre::Entity* playerCarEntity = sceneManager->createEntity("PlayerCar", "car.mesh");
	playerCarNode = sceneManager->getRootSceneNode()->createChildSceneNode();
	playerCarNode->attachObject(playerCarEntity);
    playerCarNode->scale(Ogre::Vector3(2.0f, 1.0f, 4.0f) / playerCarEntity->getBoundingBox().getSize()); // Force scale to 2, 1, 4. Might be buggy...

    // Debug draw Bullet
    //bulletDebugDrawer = new Rally::Util::BulletDebugDrawer(sceneManager);
    //world.getPhysicsWorld().getDynamicsWorld()->setDebugDrawer(bulletDebugDrawer);

	// Sky dome
	//sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8, 1000, true);
	sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);
}

Ogre::Viewport* SceneView::addViewport(Ogre::Camera* followedCamera) {
    Ogre::Viewport* viewport = renderWindow->addViewport(camera);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    return viewport;
}

Ogre::Camera* SceneView::addCamera(Ogre::String cameraName) {
    // Setup camera to match viewport
    Ogre::Camera* camera = sceneManager->createCamera(cameraName);
	camera->setNearClipDistance(Ogre::Real(0.1));

    return camera;
}

void SceneView::loadResourceConfig(Ogre::String resourceConfigPath) {
    Ogre::ResourceGroupManager& resourceGroupManager = Ogre::ResourceGroupManager::getSingleton();

    Ogre::ConfigFile resourceConfig;
    resourceConfig.load(resourceConfigPath);

    for(Ogre::ConfigFile::SectionIterator sectionIterator = resourceConfig.getSectionIterator();
            sectionIterator.hasMoreElements();
            sectionIterator.moveNext()) {
        Ogre::ConfigFile::SettingsMultiMap* settings = sectionIterator.peekNextValue();

        // Now load all the resources for this resource group
        for(Ogre::ConfigFile::SettingsMultiMap::iterator resource = settings->begin();
                resource != settings->end();
                ++resource) {
            resourceGroupManager.addResourceLocation(
                resource->second, // filename of directory
                resource->first, // resource type
                sectionIterator.peekNextKey()); // resource group
        }
    }
}

bool SceneView::renderFrame(float deltaTime) {
    Ogre::WindowEventUtilities::messagePump();

    if(renderWindow->isClosed())  {
        return false;
    } else {
        updatePlayerCar(deltaTime);
		world.getPhysicsWorld().getDynamicsWorld()->debugDrawWorld();

        Ogre::Root& root = Ogre::Root::getSingleton();
        if(!root.renderOneFrame()) {
            return false;
        }
    }
    return true;
}

void SceneView::updatePlayerCar(float deltaTime) {
    // Todo: Move to separate view
    Rally::Model::Car& playerCar = world.getPlayerCar();
    Rally::Vector3 position = playerCar.getPosition();
    playerCarNode->setPosition(position);
    playerCarNode->setOrientation(playerCar.getOrientation());

	Rally::Vector3 currentCameraPosition = camera->getPosition();

	Rally::Vector3 displacementBase = playerCar.getOrientation() * Ogre::Vector3::UNIT_Z;

	// TOOD: Fix so that the camera looks backwards when going backwards
	displacementBase *= -1;

	Rally::Vector3 displacement(10.0f * displacementBase.x, 10.0f, 10.0f * displacementBase.z);
    Rally::Vector3 endPosition = position + displacement;

	float lerpAdjust = (playerCar.getVelocity().length())/5;
	//std::cout << lerpAdjust << std::endl;

	// Lerp towards the new camera position to get a smoother pan
	float lerpX = Ogre::Math::lerp(currentCameraPosition.x, endPosition.x, lerpAdjust*deltaTime);
	float lerpY = Ogre::Math::lerp(currentCameraPosition.y, endPosition.y, lerpAdjust*deltaTime);
	float lerpZ = Ogre::Math::lerp(currentCameraPosition.z, endPosition.z, lerpAdjust*deltaTime);

	Rally::Vector3 newPos(lerpX, lerpY, lerpZ);
	Rally::Vector3 cameraPosition = newPos;

	/*
	Shoot a ray from the car (with an offset to prevent collision with itself) to the camera.
	If anyting is intersected the camera is adjusted to prevent that the camera is blocked.
	*/
	btVector3 start(position.x, position.y + 2.0f, position.z);
	btVector3 end(newPos.x, newPos.y, newPos.z);

	btCollisionWorld::ClosestRayResultCallback ClosestRayResultCallBack(start, end);

	// Perform raycast
	world.getPhysicsWorld().getDynamicsWorld()->getCollisionWorld()->rayTest(start, end, ClosestRayResultCallBack);

	if(ClosestRayResultCallBack.hasHit()) {
		btVector3 hitLoc = ClosestRayResultCallBack.m_hitPointWorld;

		//If the camera is blocked, the new camera is set to where the collison
		//happened with a tiny offset.
		cameraPosition = Rally::Vector3(hitLoc.getX(), hitLoc.getY(), hitLoc.getZ());

		float camOffset = 0.5f;

		//Adjust for X
		if(hitLoc.getX() > cameraPosition.x)
			cameraPosition += Rally::Vector3(-camOffset, 0.0f, 0.0f);
		else if(hitLoc.getX() < cameraPosition.x)
			cameraPosition += Rally::Vector3(camOffset, 0.0f, 0.0f);

		//Adjust for Y
		if(hitLoc.getY() > cameraPosition.y)
			cameraPosition += Rally::Vector3(0.0f, -camOffset, 0.0f);

		//Adjust for Z
		if(hitLoc.getZ() > cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, -camOffset);
		else if(hitLoc.getZ() < cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, camOffset);

	}

    camera->setPosition(cameraPosition);
    sceneManager->getLight("MainLight")->setPosition(cameraPosition);
	camera->lookAt(position);
}

void SceneView::remoteCarUpdated(int carId, const Rally::Model::RemoteCar& remoteCar) {
    // Todo: Move to separate view
    std::ostringstream baseNameStream;
    baseNameStream << "RemoteCar_" << carId;
    std::string baseString = baseNameStream.str();
    std::string nodeName = baseString + "_Node";

    Ogre::SceneNode* remoteCarNode;
    if(sceneManager->hasSceneNode(nodeName)) {
        remoteCarNode = sceneManager->getSceneNode(nodeName);// Throws if nodeName not found.
    } else {
        // Lazily construct if not found
        Ogre::Entity* remoteCarEntity = sceneManager->createEntity(baseString + "_Entity", "car.mesh");
        remoteCarNode = sceneManager->getRootSceneNode()->createChildSceneNode(nodeName);
        remoteCarNode->attachObject(remoteCarEntity);
        remoteCarNode->scale(Ogre::Vector3(2.0f, 1.0f, 4.0f) / remoteCarEntity->getBoundingBox().getSize()); // Force scale to 2, 1, 4. Might be buggy...
    }

    remoteCarNode->setPosition(remoteCar.getPosition());
    remoteCarNode->setOrientation(remoteCar.getOrientation());

    /*std::map<const Rally::Model::RemoteCar&, TheViewType::iterator found = remoteCarViews.find(remoteCar);

    // Lazily construct if not found
    if(found == remoteCarViews.end()) {
        found = remoteCarViews.insert(std::map<const Rally::Model::RemoteCar&, TheViewType>::value_type(remoteCar,
            TheViewType(remoteCar))).first;
    }*/
}

void SceneView::remoteCarRemoved(int carId, const Rally::Model::RemoteCar& remoteCar) {
    // Todo: Move to separate view
    std::ostringstream baseNameStream;
    baseNameStream << "RemoteCar_" << carId;
    std::string baseString = baseNameStream.str();

    sceneManager->destroySceneNode(baseString + "_Node");
    sceneManager->destroyEntity(baseString + "_Entity");
}
<commit_msg>Slightly changed the camera height<commit_after>#include "view/SceneView.h"

#include "DotSceneLoader.h"

#include "util/BulletDebugDrawer.h"

#include <OgreRoot.h>
#include <OgreViewport.h>
#include <OgreConfigFile.h>
#include <OgreEntity.h>
#include <OgreWindowEventUtilities.h>

#include <sstream>
#include <string>

#include <btBulletDynamicsCommon.h>

SceneView::SceneView(Rally::Model::World& world) :
        world(world),
        camera(NULL),
        sceneManager(NULL),
        renderWindow(NULL) {
}

SceneView::~SceneView() {
    //delete bulletDebugDrawer;

    Ogre::Root* root = Ogre::Root::getSingletonPtr();
    delete root;
}

void SceneView::initialize(std::string resourceConfigPath, std::string pluginConfigPath) {
    Ogre::Root* root = new Ogre::Root(pluginConfigPath);

    this->loadResourceConfig(resourceConfigPath);
    // (The actual precaching is done below, once there is a render context)

    if(!root->restoreConfig() && !root->showConfigDialog()) {
        throw std::runtime_error("Could neither restore Ogre config, nor read it from the user.");
    }

    renderWindow = root->initialise(
        true, // auto-create the render window now
        "Rally Sport Racing Game");

    sceneManager = root->createSceneManager("OctreeSceneManager"); // Todo: Research a good scene manager

    // This should be done after creating a scene manager, so that there is a render context (GL/D3D)
    Ogre::ResourceGroupManager::getSingleton().initialiseAllResourceGroups();

    camera = this->addCamera("MainCamera");
    Ogre::Viewport* viewport = this->addViewport(camera);
    camera->setAspectRatio(Ogre::Real(viewport->getActualWidth()) / Ogre::Real(viewport->getActualHeight()));

    Ogre::SceneNode* sceneNode = sceneManager->getRootSceneNode()->createChildSceneNode();
    sceneNode->setPosition(Ogre::Vector3(0, 110.0f, 0));

	sceneManager->setAmbientLight(Ogre::ColourValue(1, 1, 1));
	Ogre::Light* light = sceneManager->createLight("MainLight");

	// Load the scene.
	DotSceneLoader loader;
	loader.parseDotScene("world.scene", "General", sceneManager, sceneNode);

	// Todo: Move to appropriate view
	Ogre::Entity* playerCarEntity = sceneManager->createEntity("PlayerCar", "car.mesh");
	playerCarNode = sceneManager->getRootSceneNode()->createChildSceneNode();
	playerCarNode->attachObject(playerCarEntity);
    playerCarNode->scale(Ogre::Vector3(2.0f, 1.0f, 4.0f) / playerCarEntity->getBoundingBox().getSize()); // Force scale to 2, 1, 4. Might be buggy...

    // Debug draw Bullet
    //bulletDebugDrawer = new Rally::Util::BulletDebugDrawer(sceneManager);
    //world.getPhysicsWorld().getDynamicsWorld()->setDebugDrawer(bulletDebugDrawer);

	// Sky dome
	//sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8, 1000, true);
	sceneManager->setSkyDome(true, "Rally/CloudySky", 5, 8);
}

Ogre::Viewport* SceneView::addViewport(Ogre::Camera* followedCamera) {
    Ogre::Viewport* viewport = renderWindow->addViewport(camera);
    viewport->setBackgroundColour(Ogre::ColourValue(0, 0, 0));

    return viewport;
}

Ogre::Camera* SceneView::addCamera(Ogre::String cameraName) {
    // Setup camera to match viewport
    Ogre::Camera* camera = sceneManager->createCamera(cameraName);
	camera->setNearClipDistance(Ogre::Real(0.1));

    return camera;
}

void SceneView::loadResourceConfig(Ogre::String resourceConfigPath) {
    Ogre::ResourceGroupManager& resourceGroupManager = Ogre::ResourceGroupManager::getSingleton();

    Ogre::ConfigFile resourceConfig;
    resourceConfig.load(resourceConfigPath);

    for(Ogre::ConfigFile::SectionIterator sectionIterator = resourceConfig.getSectionIterator();
            sectionIterator.hasMoreElements();
            sectionIterator.moveNext()) {
        Ogre::ConfigFile::SettingsMultiMap* settings = sectionIterator.peekNextValue();

        // Now load all the resources for this resource group
        for(Ogre::ConfigFile::SettingsMultiMap::iterator resource = settings->begin();
                resource != settings->end();
                ++resource) {
            resourceGroupManager.addResourceLocation(
                resource->second, // filename of directory
                resource->first, // resource type
                sectionIterator.peekNextKey()); // resource group
        }
    }
}

bool SceneView::renderFrame(float deltaTime) {
    Ogre::WindowEventUtilities::messagePump();

    if(renderWindow->isClosed())  {
        return false;
    } else {
        updatePlayerCar(deltaTime);
		world.getPhysicsWorld().getDynamicsWorld()->debugDrawWorld();

        Ogre::Root& root = Ogre::Root::getSingleton();
        if(!root.renderOneFrame()) {
            return false;
        }
    }
    return true;
}

void SceneView::updatePlayerCar(float deltaTime) {
    // Todo: Move to separate view
    Rally::Model::Car& playerCar = world.getPlayerCar();
    Rally::Vector3 position = playerCar.getPosition();
    playerCarNode->setPosition(position);
    playerCarNode->setOrientation(playerCar.getOrientation());

	Rally::Vector3 currentCameraPosition = camera->getPosition();

	Rally::Vector3 displacementBase = playerCar.getOrientation() * Ogre::Vector3::UNIT_Z;
	displacementBase *= -1;

	Rally::Vector3 displacement(12.0f * displacementBase.x, 6.0f, 12.0f * displacementBase.z);
    Rally::Vector3 endPosition = position + displacement;

	float lerpAdjust = (playerCar.getVelocity().length())/5;
	//std::cout << lerpAdjust << std::endl;

	// Lerp towards the new camera position to get a smoother pan
	float lerpX = Ogre::Math::lerp(currentCameraPosition.x, endPosition.x, lerpAdjust*deltaTime);
	float lerpY = Ogre::Math::lerp(currentCameraPosition.y, endPosition.y, lerpAdjust*deltaTime);
	float lerpZ = Ogre::Math::lerp(currentCameraPosition.z, endPosition.z, lerpAdjust*deltaTime);

	Rally::Vector3 newPos(lerpX, lerpY, lerpZ);
	Rally::Vector3 cameraPosition = newPos;

	/*
	Shoot a ray from the car (with an offset to prevent collision with itself) to the camera.
	If anyting is intersected the camera is adjusted to prevent that the camera is blocked.
	*/
	btVector3 start(position.x, position.y + 2.0f, position.z);
	btVector3 end(newPos.x, newPos.y, newPos.z);

	btCollisionWorld::ClosestRayResultCallback ClosestRayResultCallBack(start, end);

	// Perform raycast
	world.getPhysicsWorld().getDynamicsWorld()->getCollisionWorld()->rayTest(start, end, ClosestRayResultCallBack);

	if(ClosestRayResultCallBack.hasHit()) {
		btVector3 hitLoc = ClosestRayResultCallBack.m_hitPointWorld;

		//If the camera is blocked, the new camera is set to where the collison
		//happened with a tiny offset.
		cameraPosition = Rally::Vector3(hitLoc.getX(), hitLoc.getY(), hitLoc.getZ());

		float camOffset = 0.5f;

		//Adjust for X
		if(hitLoc.getX() > cameraPosition.x)
			cameraPosition += Rally::Vector3(-camOffset, 0.0f, 0.0f);
		else if(hitLoc.getX() < cameraPosition.x)
			cameraPosition += Rally::Vector3(camOffset, 0.0f, 0.0f);

		//Adjust for Y
		if(hitLoc.getY() > cameraPosition.y)
			cameraPosition += Rally::Vector3(0.0f, -camOffset, 0.0f);

		//Adjust for Z
		if(hitLoc.getZ() > cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, -camOffset);
		else if(hitLoc.getZ() < cameraPosition.z)
			cameraPosition += Rally::Vector3(0.0f, 0.0f, camOffset);

	}

    camera->setPosition(cameraPosition);
    sceneManager->getLight("MainLight")->setPosition(cameraPosition);
	camera->lookAt(position);
}

void SceneView::remoteCarUpdated(int carId, const Rally::Model::RemoteCar& remoteCar) {
    // Todo: Move to separate view
    std::ostringstream baseNameStream;
    baseNameStream << "RemoteCar_" << carId;
    std::string baseString = baseNameStream.str();
    std::string nodeName = baseString + "_Node";

    Ogre::SceneNode* remoteCarNode;
    if(sceneManager->hasSceneNode(nodeName)) {
        remoteCarNode = sceneManager->getSceneNode(nodeName);// Throws if nodeName not found.
    } else {
        // Lazily construct if not found
        Ogre::Entity* remoteCarEntity = sceneManager->createEntity(baseString + "_Entity", "car.mesh");
        remoteCarNode = sceneManager->getRootSceneNode()->createChildSceneNode(nodeName);
        remoteCarNode->attachObject(remoteCarEntity);
        remoteCarNode->scale(Ogre::Vector3(2.0f, 1.0f, 4.0f) / remoteCarEntity->getBoundingBox().getSize()); // Force scale to 2, 1, 4. Might be buggy...
    }

    remoteCarNode->setPosition(remoteCar.getPosition());
    remoteCarNode->setOrientation(remoteCar.getOrientation());

    /*std::map<const Rally::Model::RemoteCar&, TheViewType::iterator found = remoteCarViews.find(remoteCar);

    // Lazily construct if not found
    if(found == remoteCarViews.end()) {
        found = remoteCarViews.insert(std::map<const Rally::Model::RemoteCar&, TheViewType>::value_type(remoteCar,
            TheViewType(remoteCar))).first;
    }*/
}

void SceneView::remoteCarRemoved(int carId, const Rally::Model::RemoteCar& remoteCar) {
    // Todo: Move to separate view
    std::ostringstream baseNameStream;
    baseNameStream << "RemoteCar_" << carId;
    std::string baseString = baseNameStream.str();

    sceneManager->destroySceneNode(baseString + "_Node");
    sceneManager->destroyEntity(baseString + "_Entity");
}
<|endoftext|>


<commit_before>/* Copyright (c) 2018 Francis James Franklin
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
 *    the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *    the following disclaimer in the documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __Window_hh__
#define __Window_hh__

class Window;

static unsigned s_id_counter = 0;
static unsigned s_id_next () {
  return ++s_id_counter;
}

static Window * s_root = 0;

class Window {
private:
  Window * m_parent;

  Window * m_child_bottom;
  Window * m_child_top;
  Window * m_sibling_lower;
  Window * m_sibling_upper;

  int m_abs_x;
  int m_abs_y;
  int m_rel_x;
  int m_rel_y;

  unsigned m_W;
  unsigned m_H;

  unsigned m_id;

  bool m_bDirty;
protected:
  bool m_bTouchable;
private:
  void add_child (Window * child) {
  }

  Window (unsigned width, unsigned height) :
    m_parent(0),
    m_child_bottom(0),
    m_child_top(0),
    m_sibling_lower(0),
    m_sibling_upper(0),
    m_abs_x(0),
    m_abs_y(0),
    m_rel_x(0),
    m_rel_y(0),
    m_W(width),
    m_H(height),
    m_id(0),
    m_bDirty(true),
    m_bTouchable(true)
  {
    // TODO: set root window properties
    // ui_window_bbox (m_id, m_abs_x, m_abs_y, m_W, m_H);
  }

protected:
  Window (Window & parent, int rel_x, int rel_y, unsigned width, unsigned height) :
    m_parent(&parent),
    m_child_bottom(0),
    m_child_top(0),
    m_sibling_lower(0),
    m_sibling_upper(0),
    m_abs_x(parent.abs_x + rel_x),
    m_abs_y(parent.abs_y + rel_y),
    m_rel_x(rel_x),
    m_rel_y(rel_y),
    m_W(width),
    m_H(height),
    m_id(s_id_next ()),
    m_bDirty(true),
    m_bTouchable(false)
  {
    parent->add_child (this);
    // TODO: set default window properties
    // ui_window_bbox (m_id, m_abs_x, m_abs_y, m_W, m_H);
  }

public:
  ~Window () {
    // ...
  }

  static Window & root () {
    return *s_root;
  }
  static Window * root (unsigned width, unsigned height) {
    if (!s_root && width && height) {
      try {
	s_root = new Window(width, height);
      } catch (...) {
	s_root = 0;
      }
    }
    return s_root;
  }

  inline unsigned id () const {
    return m_id;
  }

  inline void set_dirty (bool bDirty) {
    m_bDirty = bDirty;
  }
  inline bool dirty () const {
    return m_bDirty;
  }

  bool touch_in_bounds (int x, int y) {
    if ((x < m_abs_x) || (y < m_abs_y)) {
      return false;
    }
    if ((x >= m_abs_x + m_W) || (y >= m_abs_y + m_H)) {
      return false;
    }
    return true;
  }
protected:
  virtual void handle_touch (TouchInput::TouchEvent te, int rel_x, int rel_y) {
    // catch & ignore...
  }
public:
  void touch_event (TouchInput::TouchEvent te, int x, int y) {
    if (m_bTouchable) {
      handle_touch (te, x - m_abs_x, y - m_abs_y);
    } else {
      m_parent->touch_event (te, x, y); // propagate event to parent
    }
  }

  virtual void redraw () {
    // TODO: request redraw by window ID
    // ui_window_redraw (m_id);
    set_dirty (false);
  }
};

#endif /* ! __Window_hh__ */
<commit_msg>Hierarchical window management.<commit_after>/* Copyright (c) 2018 Francis James Franklin
 *
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without modification, are permitted provided
 * that the following conditions are met:
 *
 * 1. Redistributions of source code must retain the above copyright notice, this list of conditions and
 *    the following disclaimer.
 * 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and
 *    the following disclaimer in the documentation and/or other materials provided with the distribution.
 * 3. The name of the author may not be used to endorse or promote products derived from this software
 *    without specific prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
 * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
 * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 */

#ifndef __Window_hh__
#define __Window_hh__

class Window;

static unsigned s_id_counter = 0;
static unsigned s_id_next () {
  return ++s_id_counter;
}

static Window * s_root = 0;

class Window {
private:
  Window * m_parent;

  Window * m_child_bottom;
  Window * m_child_top;
  Window * m_sibling_lower;
  Window * m_sibling_upper;

  int m_abs_x;
  int m_abs_y;
  int m_rel_x;
  int m_rel_y;

  unsigned m_W;
  unsigned m_H;

  unsigned m_id;

  bool m_bDirty;
  bool m_bVisible;
protected:
  bool m_bTouchable;
private:
  void add_child (Window * child) {
    if (m_child_top) {
      child->m_sibling_lower = m_child_top;
      child->m_sibling_upper = 0;
      m_child_top->m_sibling_upper = child;
      m_child_top    = child;
    } else {
      child->m_sibling_lower = 0;
      child->m_sibling_upper = 0;
      m_child_bottom = child;
      m_child_top    = child;
    }
  }

  Window (unsigned width, unsigned height) :
    m_parent(0),
    m_child_bottom(0),
    m_child_top(0),
    m_sibling_lower(0),
    m_sibling_upper(0),
    m_abs_x(0),
    m_abs_y(0),
    m_rel_x(0),
    m_rel_y(0),
    m_W(width),
    m_H(height),
    m_id(0),
    m_bDirty(true),
    m_bVisible(true),
    m_bTouchable(true)
  {
    // TODO: set root window properties
    // ui_window_bbox (m_id, m_abs_x, m_abs_y, m_W, m_H);
  }

protected:
  Window (Window & parent, int rel_x, int rel_y, unsigned width, unsigned height) :
    m_parent(&parent),
    m_child_bottom(0),
    m_child_top(0),
    m_sibling_lower(0),
    m_sibling_upper(0),
    m_abs_x(parent.abs_x + rel_x),
    m_abs_y(parent.abs_y + rel_y),
    m_rel_x(rel_x),
    m_rel_y(rel_y),
    m_W(width),
    m_H(height),
    m_id(s_id_next ()),
    m_bDirty(true),
    m_bVisible(false),
    m_bTouchable(false)
  {
    parent->add_child (this);
    // TODO: set default window properties
    // ui_window_bbox (m_id, m_abs_x, m_abs_y, m_W, m_H);
  }

public:
  ~Window () {
    // ...
  }

  static Window & root () {
    return *s_root;
  }
  static Window * root (unsigned width, unsigned height) {
    if (!s_root && width && height) {
      try {
	s_root = new Window(width, height);
      } catch (...) {
	s_root = 0;
      }
    }
    return s_root;
  }

  inline unsigned id () const {
    return m_id;
  }

  inline void set_dirty (bool bDirty) {
    m_bDirty = bDirty;
  }
  inline bool dirty () const {
    return m_bDirty;
  }

  inline void set_visible (bool bVisible) {
    if (m_id)
      m_bVisible = bVisible;
  }
  inline bool visible () const {
    return m_bVisible;
  }

  bool touch_in_bounds (int x, int y) {
    if ((x < m_abs_x) || (y < m_abs_y)) {
      return false;
    }
    if ((x >= m_abs_x + m_W) || (y >= m_abs_y + m_H)) {
      return false;
    }
    return true;
  }
protected:
  virtual bool handle_touch (TouchInput::TouchEvent te, int rel_x, int rel_y) {
    return true; // catch & ignore...
  }
public:
  bool touch_event (TouchInput::TouchEvent te, int x, int y) {
    bool bHandled = false;

    /* Check children first, top to bottom
     */
    Window * child = m_child_top;

    while (child && !bHandled) {
      if (child->visible ()) {
	if (child->touch_in_bounds (x, y)) {
	  bHandled = child->touch_event (te, x, y);
	}
      }
      child = child->m_sibling_lower;
    }

    /* If not handled by a child, handle it ourselves
     */
    if (!bHandled && m_bTouchable) {
      bHandled = handle_touch (te, x - m_abs_x, y - m_abs_y);
    }

    return bHandled;
  }

  virtual void redraw () {
    /* Draw self first
     */
    // TODO: request redraw by window ID
    // ui_window_redraw (m_id);
    set_dirty (false);

    /* Draw children, bottom to top
     */
    Window * child = m_child_bottom;

    while (child) {
      if (child->visible ()) {
	child->redraw ();
      }
      child = child->m_sibling_upper;
    }
  }
};

#endif /* ! __Window_hh__ */
<|endoftext|>