<commit_before>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right 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.
//
// =============================================================================
// Authors: Justin Madsen
// =============================================================================
//
// A Simple Idler system that keeps track chain tension by pre-loading a
//  spring/damper elemnt
//
// =============================================================================

#include <cstdio>

#include "IdlerSimple.h"

#include "assets/ChAsset.h"
#include "assets/ChCylinderShape.h"
#include "assets/ChTriangleMeshShape.h"
#include "assets/ChColorAsset.h"
// collision mesh
#include "geometry/ChCTriangleMeshSoup.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"

namespace chrono {

// Static variables
const double IdlerSimple::m_mass = 429.6;
const ChVector<> IdlerSimple::m_inertia = ChVector<>(14.7, 12.55, 12.55);

const std::string IdlerSimple::m_meshName = "idler_mesh";
const std::string IdlerSimple::m_meshFile = utils::GetModelDataFile("data/idlerMesh.obj");

// guessing at these values
const double IdlerSimple::m_radius = 0.5;
const double IdlerSimple::m_width = 0.35;
const double IdlerSimple::m_springK = 100000;
const double IdlerSimple::m_springC = 1000;
const double IdlerSimple::m_springRestLength = 1.0;

/*
// -----------------------------------------------------------------------------
// Default shock and spring functors (used for linear elements)
// -----------------------------------------------------------------------------
class LinearSpringForce : public ChSpringForceCallback
{
public:
  LinearSpringForce(double k) : m_k(k) {}

  virtual double operator()(double time,         // current time
                            double rest_length,  // undeformed length
                            double length,       // current length
                            double vel)          // current velocity (positive when extending)
  {
    return -m_k * (length - rest_length);
  }

private:
  double  m_k;
};

class LinearShockForce : public ChSpringForceCallback
{
public:
  LinearShockForce(double c) : m_c(c) {}

  virtual double operator()(double time,         // current time
                            double rest_length,  // undeformed length
                            double length,       // current length
                            double vel)          // current velocity (positive when extending)
  {
    return -m_c * vel;
  }

private:
  double  m_c;
};
*/

IdlerSimple::IdlerSimple(const std::string& name,
                         VisualizationType vis,
                         CollisionType collide)
  : m_vis(vis), m_collide(collide)
//  , m_shockCB(NULL), m_springCB(NULL)
{
  // create the body, set the basic info
  m_idler = ChSharedPtr<ChBody>(new ChBody);
  m_idler->SetNameString(name + "_body");
  m_idler->SetMass(m_mass);
  m_idler->SetInertiaXX(m_inertia);

  // create the idler joint
  m_idler_joint = ChSharedPtr<ChLinkLockRevolutePrismatic>(new ChLinkLockRevolutePrismatic);
  m_idler_joint->SetNameString(name + "_idler_joint");

  // create the tensioning linear spring-shock
  m_shock = ChSharedPtr<ChLinkSpring>(new ChLinkSpring);
  m_shock->SetNameString(name + "_shock");
  m_shock->Set_SpringK(m_springK);
  m_shock->Set_SpringR(m_springC);
  m_shock->Set_SpringRestLength(m_springRestLength);

  AddVisualization();

}

IdlerSimple::~IdlerSimple()
{
  // delete m_springCB;
  // delete m_shockCB;
}

void IdlerSimple::Initialize(ChSharedPtr<ChBodyAuxRef> chassis,
                             const ChCoordsys<>& local_Csys)
{
  // add collision geometry
  AddCollisionGeometry();

  // Express the steering reference frame in the absolute coordinate system.
  ChFrame<> idler_to_abs(local_Csys);
  idler_to_abs.ConcatenatePreTransformation(chassis->GetFrame_REF_to_abs());

  // transform the idler body, add to system
  m_idler->SetPos(idler_to_abs.GetPos());
  m_idler->SetRot(idler_to_abs.GetRot());
  chassis->GetSystem()->Add(m_idler);

  // init joint, add to system
  // body 1 should rotate about z-axis, translate about x-axis of body2
  m_idler_joint->Initialize(m_idler, chassis, local_Csys);
  chassis->GetSystem()->AddLink(m_idler_joint);

  // init shock, add to system
  ChVector<> marker2(local_Csys.pos);
  // put the second marker some length behind (-x) marker1, based on desired preload
  double preLoad = 10000; // [N]
  marker2.x -= m_springRestLength + (preLoad / m_springK);
  m_shock->Initialize(m_idler, chassis, false, local_Csys.pos, ChVector<>() );
  chassis->GetSystem()->AddLink(m_shock);
}

void IdlerSimple::AddVisualization()
{
  // add visualization asset
  switch (m_vis) {
  case VisualizationType::PRIMITIVES:
  {
    ChSharedPtr<ChCylinderShape> cyl(new ChCylinderShape);
    // define the cylinder shape with the two end points of the cylinder
    ChVector<> p1(0, 0, m_width/2.0);
    ChVector<> p2(0, 0, -m_width/2.0);
    cyl->GetCylinderGeometry().p1 = p1;
    cyl->GetCylinderGeometry().p2 = p2;
    cyl->GetCylinderGeometry().rad = m_radius;
    m_idler->AddAsset(cyl);

    // add a color asset
    ChSharedPtr<ChColorAsset> mcolor(new ChColorAsset(0.5f, 0.1f, 0.4f));
    m_idler->AddAsset(mcolor);

    break;
  }
   case VisualizationType::MESH:
  {
    geometry::ChTriangleMeshConnected trimesh;
    trimesh.LoadWavefrontMesh(getMeshFile(), false, false);

    ChSharedPtr<ChTriangleMeshShape> trimesh_shape(new ChTriangleMeshShape);
    trimesh_shape->SetMesh(trimesh);
    trimesh_shape->SetName(getMeshName());
    m_idler->AddAsset(trimesh_shape);

    // add a color asset
    ChSharedPtr<ChColorAsset> mcolor(new ChColorAsset(0.5f, 0.1f, 0.4f));
    m_idler->AddAsset(mcolor);

    break;
  }
  } // end switch
}

void IdlerSimple::AddCollisionGeometry()
{
  // add collision geometrey to the chassis, if enabled
  m_idler->SetCollide(true);
  m_idler->GetCollisionModel()->ClearModel();

  switch (m_collide) {
  case CollisionType::NONE:
    {
      m_idler->SetCollide(false);
    }
  case CollisionType::PRIMITIVES:
  {
    // use a simple cylinder
    m_idler->GetCollisionModel()->AddCylinder(m_radius, m_radius, m_width,
      ChVector<>(),Q_from_AngAxis(CH_C_PI_2,VECT_X));

    break;
  }
  case CollisionType::MESH:
  {
    // use a triangle mesh

		geometry::ChTriangleMeshSoup temp_trianglemesh;

    // TODO: fill the triangleMesh here with some track shoe geometry

		m_idler->GetCollisionModel()->SetSafeMargin(0.004);	// inward safe margin
		m_idler->GetCollisionModel()->SetEnvelope(0.010);		// distance of the outward "collision envelope"
		m_idler->GetCollisionModel()->ClearModel();

    // is there an offset??
    double shoelength = 0.2;
    ChVector<> mesh_displacement(shoelength*0.5,0,0);  // since mesh origin is not in body center of mass
    m_idler->GetCollisionModel()->AddTriangleMesh(temp_trianglemesh, false, false, mesh_displacement);

    break;
  }
  case CollisionType::CONVEXHULL:
  {
    // use convex hulls, loaded from file
    ChStreamInAsciiFile chull_file(GetChronoDataFile("idler.chulls").c_str());
    // transform the collision geometry as needed
    double mangle = 45.0; // guess
    ChQuaternion<>rot;
    rot.Q_from_AngAxis(mangle*(CH_C_PI/180.),VECT_X);
    ChMatrix33<> rot_offset(rot);
    ChVector<> disp_offset(0,0,0);  // no displacement offset
    m_idler->GetCollisionModel()->AddConvexHullsFromFile(chull_file, disp_offset, rot_offset);
    break;
  }
  } // end switch

  // setup collision family
  m_idler->GetCollisionModel()->SetFamily( (int)CollisionFam::GEARS );
  // don't collide with other roling elements or the ground
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::HULL );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::GEARS );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::WHEELS );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::GROUND );

  m_idler->GetCollisionModel()->BuildModel();
}

} // end namespace chrono
<commit_msg>fixes for Idler initialize()<commit_after>// =============================================================================
// PROJECT CHRONO - http://projectchrono.org
//
// Copyright (c) 2014 projectchrono.org
// All right 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.
//
// =============================================================================
// Authors: Justin Madsen
// =============================================================================
//
// A Simple Idler system that keeps track chain tension by pre-loading a
//  spring/damper elemnt
//
// =============================================================================

#include <cstdio>

#include "IdlerSimple.h"

#include "assets/ChAsset.h"
#include "assets/ChCylinderShape.h"
#include "assets/ChTriangleMeshShape.h"
#include "assets/ChColorAsset.h"
// collision mesh
#include "geometry/ChCTriangleMeshSoup.h"

#include "utils/ChUtilsInputOutput.h"
#include "utils/ChUtilsData.h"

namespace chrono {

// Static variables
const double IdlerSimple::m_mass = 429.6;
const ChVector<> IdlerSimple::m_inertia = ChVector<>(14.7, 12.55, 12.55);

const std::string IdlerSimple::m_meshName = "idler_mesh";
const std::string IdlerSimple::m_meshFile = utils::GetModelDataFile("data/idlerMesh.obj");

// guessing at these values
const double IdlerSimple::m_radius = 0.5;
const double IdlerSimple::m_width = 0.35;
const double IdlerSimple::m_springK = 100000;
const double IdlerSimple::m_springC = 1000;
const double IdlerSimple::m_springRestLength = 1.0;

/*
// -----------------------------------------------------------------------------
// Default shock and spring functors (used for linear elements)
// -----------------------------------------------------------------------------
class LinearSpringForce : public ChSpringForceCallback
{
public:
  LinearSpringForce(double k) : m_k(k) {}

  virtual double operator()(double time,         // current time
                            double rest_length,  // undeformed length
                            double length,       // current length
                            double vel)          // current velocity (positive when extending)
  {
    return -m_k * (length - rest_length);
  }

private:
  double  m_k;
};

class LinearShockForce : public ChSpringForceCallback
{
public:
  LinearShockForce(double c) : m_c(c) {}

  virtual double operator()(double time,         // current time
                            double rest_length,  // undeformed length
                            double length,       // current length
                            double vel)          // current velocity (positive when extending)
  {
    return -m_c * vel;
  }

private:
  double  m_c;
};
*/

IdlerSimple::IdlerSimple(const std::string& name,
                         VisualizationType vis,
                         CollisionType collide)
  : m_vis(vis), m_collide(collide)
//  , m_shockCB(NULL), m_springCB(NULL)
{
  // create the body, set the basic info
  m_idler = ChSharedPtr<ChBody>(new ChBody);
  m_idler->SetNameString(name + "_body");
  m_idler->SetMass(m_mass);
  m_idler->SetInertiaXX(m_inertia);

  // create the idler joint
  m_idler_joint = ChSharedPtr<ChLinkLockRevolutePrismatic>(new ChLinkLockRevolutePrismatic);
  m_idler_joint->SetNameString(name + "_idler_joint");

  // create the tensioning linear spring-shock
  m_shock = ChSharedPtr<ChLinkSpring>(new ChLinkSpring);
  m_shock->SetNameString(name + "_shock");
  m_shock->Set_SpringK(m_springK);
  m_shock->Set_SpringR(m_springC);
  m_shock->Set_SpringRestLength(m_springRestLength);

  AddVisualization();

}

IdlerSimple::~IdlerSimple()
{
  // delete m_springCB;
  // delete m_shockCB;
}

void IdlerSimple::Initialize(ChSharedPtr<ChBodyAuxRef> chassis,
                             const ChCoordsys<>& local_Csys)
{
  // add collision geometry
  AddCollisionGeometry();

  // Express the steering reference frame in the absolute coordinate system.
  ChFrame<> idler_to_abs(local_Csys);
  idler_to_abs.ConcatenatePreTransformation(chassis->GetFrame_REF_to_abs());

  // transform the idler body, add to system
  m_idler->SetPos(idler_to_abs.GetPos());
  m_idler->SetRot(idler_to_abs.GetRot());
  chassis->GetSystem()->Add(m_idler);

  // init joint, add to system
  // body 1 should rotate about z-axis, translate about x-axis of body2
  // TODO: (check) idler joint translates, rotates in correct direction.
  // NOTE: I created the idler to translate x-dir, rotate about z-dir, according
  //      to how the chassis is rotated by default.
  m_idler_joint->Initialize(m_idler, chassis, m_idler->GetCoord() );
  chassis->GetSystem()->AddLink(m_idler_joint);

  // init shock, add to system
  // put the second marker some length behind (-x) marker1, based on desired preload
  double preLoad = 10000; // [N]
  // chassis spring attachment point in -x dir w.r.t. chassis c-sys
  ChVector<> pos_chassis_abs = local_Csys.pos;
  pos_chassis_abs.x -= m_springRestLength - (preLoad / m_springK);
  // transform 2nd attachment point to abs coords
  pos_chassis_abs = chassis->GetCoord().TransformPointLocalToParent(pos_chassis_abs);

  // init. points based on desired preload and free lengths
  m_shock->Initialize(m_idler, chassis, false, m_idler->GetPos(), pos_chassis_abs );
  // setting rest length should yield desired preload at time = 0
  m_shock->Set_SpringRestLength(m_springRestLength);

  chassis->GetSystem()->AddLink(m_shock);
}

void IdlerSimple::AddVisualization()
{
  // add visualization asset
  switch (m_vis) {
  case VisualizationType::PRIMITIVES:
  {
    ChSharedPtr<ChCylinderShape> cyl(new ChCylinderShape);
    // define the cylinder shape with the two end points of the cylinder
    ChVector<> p1(0, 0, m_width/2.0);
    ChVector<> p2(0, 0, -m_width/2.0);
    cyl->GetCylinderGeometry().p1 = p1;
    cyl->GetCylinderGeometry().p2 = p2;
    cyl->GetCylinderGeometry().rad = m_radius;
    m_idler->AddAsset(cyl);

    // add a color asset
    ChSharedPtr<ChColorAsset> mcolor(new ChColorAsset(0.5f, 0.1f, 0.4f));
    m_idler->AddAsset(mcolor);

    break;
  }
   case VisualizationType::MESH:
  {
    geometry::ChTriangleMeshConnected trimesh;
    trimesh.LoadWavefrontMesh(getMeshFile(), false, false);

    ChSharedPtr<ChTriangleMeshShape> trimesh_shape(new ChTriangleMeshShape);
    trimesh_shape->SetMesh(trimesh);
    trimesh_shape->SetName(getMeshName());
    m_idler->AddAsset(trimesh_shape);

    // add a color asset
    ChSharedPtr<ChColorAsset> mcolor(new ChColorAsset(0.5f, 0.1f, 0.4f));
    m_idler->AddAsset(mcolor);

    break;
  }
  } // end switch
}

void IdlerSimple::AddCollisionGeometry()
{
  // add collision geometrey to the chassis, if enabled
  m_idler->SetCollide(true);
  m_idler->GetCollisionModel()->ClearModel();

  switch (m_collide) {
  case CollisionType::NONE:
    {
      m_idler->SetCollide(false);
    }
  case CollisionType::PRIMITIVES:
  {
    // use a simple cylinder
    m_idler->GetCollisionModel()->AddCylinder(m_radius, m_radius, m_width,
      ChVector<>(),Q_from_AngAxis(CH_C_PI_2,VECT_X));

    break;
  }
  case CollisionType::MESH:
  {
    // use a triangle mesh

		geometry::ChTriangleMeshSoup temp_trianglemesh;

    // TODO: fill the triangleMesh here with some track shoe geometry

		m_idler->GetCollisionModel()->SetSafeMargin(0.004);	// inward safe margin
		m_idler->GetCollisionModel()->SetEnvelope(0.010);		// distance of the outward "collision envelope"
		m_idler->GetCollisionModel()->ClearModel();

    // is there an offset??
    double shoelength = 0.2;
    ChVector<> mesh_displacement(shoelength*0.5,0,0);  // since mesh origin is not in body center of mass
    m_idler->GetCollisionModel()->AddTriangleMesh(temp_trianglemesh, false, false, mesh_displacement);

    break;
  }
  case CollisionType::CONVEXHULL:
  {
    // use convex hulls, loaded from file
    ChStreamInAsciiFile chull_file(GetChronoDataFile("idler.chulls").c_str());
    // transform the collision geometry as needed
    double mangle = 45.0; // guess
    ChQuaternion<>rot;
    rot.Q_from_AngAxis(mangle*(CH_C_PI/180.),VECT_X);
    ChMatrix33<> rot_offset(rot);
    ChVector<> disp_offset(0,0,0);  // no displacement offset
    m_idler->GetCollisionModel()->AddConvexHullsFromFile(chull_file, disp_offset, rot_offset);
    break;
  }
  } // end switch

  // setup collision family
  m_idler->GetCollisionModel()->SetFamily( (int)CollisionFam::GEARS );
  // don't collide with other roling elements or the ground
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::HULL );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::GEARS );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::WHEELS );
  m_idler->GetCollisionModel()->SetFamilyMaskNoCollisionWithFamily( (int)CollisionFam::GROUND );

  m_idler->GetCollisionModel()->BuildModel();
}

} // end namespace chrono
<|endoftext|>


<commit_before>// @(#)root/eve:$Id$
// Author: Matevz Tadel

// Complex example showing ALICE VSD visualization.

/*
  alice_vsd.C - a simple event-display for ALICE

  ------------------------------------------------------------------------
  ------------------------------------------------------------------------

  Only standard ROOT is used to process the ALICE VSD files.

  No ALICE code is needed -- the VSD file is exported from AliRoot into
  VSD format -- see TEveVSDStructs.h and TEveVSD.h.

  A simple geometry of 10KB, extracted from the full TGeo-geometry, is
  used to outline the central detectors of ALICE.

  All files are access from the web by using the "CACHEREAD" option.

*/

#if defined(__CINT__) && !defined(__MAKECINT__)
{
   Info("alice_vsd.C", "Has to be run in compiled mode ... doing this for you.");
   gSystem->CompileMacro("alice_vsd.C");
   alice_vsd();
}
#else

#include <TEveManager.h>
#include <TEveEventManager.h>
#include <TEveVSD.h>
#include <TEveVSDStructs.h>

#include <TEveTrack.h>
#include <TEveTrackPropagator.h>
#include <TEveGeoShape.h>

#include <TGTab.h>
#include <TGButton.h>

#include <TFile.h>
#include <TKey.h>
#include <TSystem.h>
#include <TPRegexp.h>

// Include componets -- compile time link :)

#include "MultiView.C"
MultiView* gMultiView = 0;

class TVSDReader
{
public:
   // ----------------------------------------------------------
   // File / Event Data
   // ----------------------------------------------------------

   TFile      *fFile;
   TDirectory *fDirectory;

   TObjArray  *fEvDirKeys;

   TEveVSD    *fVSD;

   Int_t       fMaxEv, fCurEv;

   // ----------------------------------------------------------
   // Event visualization structures
   // ----------------------------------------------------------

   TEveTrackList *fTrackList;
   TEvePointSet  *fITSClusters;
   TEvePointSet  *fTPCClusters;
   TEvePointSet  *fTRDClusters;
   TEvePointSet  *fTOFClusters;

public:
   TVSDReader(const char* file_name) :
      fFile(0), fDirectory(0), fEvDirKeys(0),
      fVSD(0),

      fMaxEv(-1), fCurEv(-1),

      fTrackList(0),
      fITSClusters(0), fTPCClusters(0), fTRDClusters(0), fTOFClusters(0)
   {
      fFile = TFile::Open(file_name);
      if (!fFile)
      {
         Error("VSD_Reader", "Can not open file '%s' ... terminating.", file_name);
         gSystem->Exit(1);
      }

      fEvDirKeys = new TObjArray;
      TPMERegexp name_re("Event\\d+");
      TObjLink* lnk = fFile->GetListOfKeys()->FirstLink();
      while (lnk)
      {
         if (name_re.Match(lnk->GetObject()->GetName()))
         {
            fEvDirKeys->Add(lnk->GetObject());
         }
         lnk = lnk->Next();
      }

      fMaxEv = fEvDirKeys->GetEntriesFast();
      if (fMaxEv == 0)
      {
         Error("VSD_Reader", "No events to show ... terminating.");
         gSystem->Exit(1);
      }

      fVSD = new TEveVSD;
   }

   ~TVSDReader()
   {
      // Destructor.

      DropEvent();

      delete fVSD;
      delete fEvDirKeys;

      fFile->Close();
      delete fFile;
   }

   void AttachEvent()
   {
      // Attach event data from current directory.

      fVSD->LoadTrees();
      fVSD->SetBranchAddresses();
   }

   void DropEvent()
   {
      // Drup currently held event data, release current directory.

      // Drop old visualization structures.

      gEve->GetViewers()->DeleteAnnotations();
      gEve->GetCurrentEvent()->DestroyElements();

      // Drop old event-data.

      fVSD->DeleteTrees();
      delete fDirectory;
      fDirectory = 0;
   }

   //---------------------------------------------------------------------------
   // Event navigation
   //---------------------------------------------------------------------------

   void NextEvent()
   {
      GotoEvent(fCurEv + 1);
   }

   void PrevEvent()
   {
      GotoEvent(fCurEv - 1);
   }

   Bool_t GotoEvent(Int_t ev)
   {
      if (ev < 0 || ev >= fMaxEv)
      {
         Warning("GotoEvent", "Invalid event id %d.", ev);
         return kFALSE;
      }

      DropEvent();

      // Connect to new event-data.

      fCurEv = ev;
      fDirectory = (TDirectory*) ((TKey*) fEvDirKeys->At(fCurEv))->ReadObj();
      fVSD->SetDirectory(fDirectory);

      AttachEvent();

      // Load event data into visualization structures.

      LoadClusters(fITSClusters, "ITS", 0);
      LoadClusters(fTPCClusters, "TPC", 1);
      LoadClusters(fTRDClusters, "TRD", 2);
      LoadClusters(fTOFClusters, "TOF", 3);

      LoadEsdTracks();

      // Fill projected views.

      TEveElement* top = gEve->GetCurrentEvent();

      gMultiView->DestroyEventRPhi();
      gMultiView->ImportEventRPhi(top);

      gMultiView->DestroyEventRhoZ();
      gMultiView->ImportEventRhoZ(top);

      gEve->Redraw3D(kFALSE, kTRUE);

      return kTRUE;
   }

   //---------------------------------------------------------------------------
   // Cluster loading
   //---------------------------------------------------------------------------

   void LoadClusters(TEvePointSet*& ps, const TString& det_name, Int_t det_id)
   {
      if (ps == 0)
      {
         ps = new TEvePointSet(det_name);
         ps->SetMainColor((Color_t)(det_id + 2));
         ps->SetMarkerSize(0.5);
         ps->SetMarkerStyle(2);
         ps->IncDenyDestroy();
      }
      else
      {
         ps->Reset();
      }

      TEvePointSelector ss(fVSD->fTreeC, ps, "fV.fX:fV.fY:fV.fZ",
                           TString::Format("fDetId==%d", det_id));
      ss.Select();
      ps->SetTitle(TString::Format("N=%d", ps->Size()));

      gEve->AddElement(ps);
   }

   //---------------------------------------------------------------------------
   // Track loading
   //---------------------------------------------------------------------------

   enum ESDTrackFlags
   {
      kITSin=0x0001,kITSout=0x0002,kITSrefit=0x0004,kITSpid=0x0008,
      kTPCin=0x0010,kTPCout=0x0020,kTPCrefit=0x0040,kTPCpid=0x0080,
      kTRDin=0x0100,kTRDout=0x0200,kTRDrefit=0x0400,kTRDpid=0x0800,
      kTOFin=0x1000,kTOFout=0x2000,kTOFrefit=0x4000,kTOFpid=0x8000,
      kHMPIDpid=0x20000,
      kEMCALmatch=0x40000,
      kTRDbackup=0x80000,
      kTRDStop=0x20000000,
      kESDpid=0x40000000,
      kTIME=0x80000000
   };

   Bool_t trackIsOn(TEveTrack* t, Int_t mask)
   {
      // Check is track-flag specified by mask are set.

      return (t->fStatus & mask) > 0;
   }

   void LoadEsdTracks()
   {
      // Read reconstructed tracks from current event.

      if (fTrackList == 0)
      {
         fTrackList = new TEveTrackList("ESD Tracks");
         fTrackList->SetMainColor(6);
         fTrackList->SetMarkerColor(kYellow);
         fTrackList->SetMarkerStyle(4);
         fTrackList->SetMarkerSize(0.5);

         fTrackList->IncDenyDestroy();
      }
      else
      {
         fTrackList->DestroyElements();
      }

      TEveTrackPropagator* trkProp = fTrackList->GetPropagator();
      // !!!! Need to store field on file !!!!
      // Can store TEveMagField ?
      trkProp->SetMagField(0.5);

      Int_t nTracks = fVSD->fTreeR->GetEntries();
      for (Int_t n = 0; n < nTracks; ++n)
      {
         fVSD->fTreeR->GetEntry(n);

         TEveTrack* track = new TEveTrack(&fVSD->fR, trkProp);
         track->SetName(Form("ESD Track %d", fVSD->fR.fIndex));
         track->SetStdTitle();
         track->SetAttLineAttMarker(fTrackList);
         fTrackList->AddElement(track);
      }

      fTrackList->MakeTracks();

      gEve->AddElement(fTrackList);
   }

   ClassDef(TVSDReader, 0);
};

TVSDReader* gVSDReader = 0;

// Forward declaration.
void make_gui();

//______________________________________________________________________________
void alice_vsd(const char* vsd_file_name = "http://mtadel.home.cern.ch/mtadel/root/AliVSD.root")
{
   // Main function, initializes the application.
   //
   // 1. Load the auto-generated library holding ESD classes and ESD dictionaries.
   // 2. Open ESD data-files.
   // 3. Load cartoon geometry.
   // 4. Spawn simple GUI.
   // 5. Load first event.

   TFile::SetCacheFileDir(".");

   TEveVSD::DisableTObjectStreamersForVSDStruct();

   gVSDReader = new TVSDReader(vsd_file_name);

   TEveManager::Create();

   TEveGeoShape *gentle_geom = 0;

   { // Simple geometry
      TFile* geom = TFile::Open("http://mtadel.home.cern.ch/mtadel/root/alice_mini_geom.root", "CACHEREAD");
      if (!geom)
         return;
      TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle");
      gentle_geom = TEveGeoShape::ImportShapeExtract(gse, 0);
      geom->Close();
      delete geom;
      gEve->AddGlobalElement(gentle_geom);
   }

   // Standard multi-view
   //=====================

   gMultiView = new MultiView;
   gMultiView->f3DView->GetGLViewer()->SetStyle(TGLRnrCtx::kOutline);

   gMultiView->SetDepth(-10);
   gMultiView->ImportGeomRPhi(gentle_geom);
   gMultiView->ImportGeomRhoZ(gentle_geom);
   gMultiView->SetDepth(0);

   // Final stuff
   //=============

   gEve->GetViewers()->SwitchColorSet();
   gEve->GetDefaultGLViewer()->SetStyle(TGLRnrCtx::kOutline);

   gEve->GetBrowser()->GetTabRight()->SetTab(1);

   make_gui();

   gEve->AddEvent(new TEveEventManager("Event", "ALICE VSD Event"));

   gVSDReader->GotoEvent(0);

   gEve->Redraw3D(kTRUE); // Reset camera after the first event has been shown.
}

//______________________________________________________________________________
void make_gui()
{
   // Create minimal GUI for event navigation.

   TEveBrowser* browser = gEve->GetBrowser();
   browser->StartEmbedding(TRootBrowser::kLeft);

   TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
   frmMain->SetWindowName("XX GUI");
   frmMain->SetCleanup(kDeepCleanup);

   TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain);
   {
      TString icondir(TString::Format("%s/icons/", gSystem->Getenv("ROOTSYS")) );
      TGPictureButton* b = 0;

      b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoBack.gif"));
      hf->AddFrame(b);
      b->Connect("Clicked()", "TVSDReader", gVSDReader, "PrevEvent()");

      b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoForward.gif"));
      hf->AddFrame(b);
      b->Connect("Clicked()", "TVSDReader", gVSDReader, "NextEvent()");
   }
   frmMain->AddFrame(hf);

   frmMain->MapSubwindows();
   frmMain->Resize();
   frmMain->MapWindow();

   browser->StopEmbedding();
   browser->SetTabTitle("Event Control", 0);
}

#endif
<commit_msg>Actually forgot to make destructor virtual :)<commit_after>// @(#)root/eve:$Id$
// Author: Matevz Tadel

// Complex example showing ALICE VSD visualization.

/*
  alice_vsd.C - a simple event-display for ALICE

  ------------------------------------------------------------------------
  ------------------------------------------------------------------------

  Only standard ROOT is used to process the ALICE VSD files.

  No ALICE code is needed -- the VSD file is exported from AliRoot into
  VSD format -- see TEveVSDStructs.h and TEveVSD.h.

  A simple geometry of 10KB, extracted from the full TGeo-geometry, is
  used to outline the central detectors of ALICE.

  All files are access from the web by using the "CACHEREAD" option.

*/

#if defined(__CINT__) && !defined(__MAKECINT__)
{
   Info("alice_vsd.C", "Has to be run in compiled mode ... doing this for you.");
   gSystem->CompileMacro("alice_vsd.C");
   alice_vsd();
}
#else

#include <TEveManager.h>
#include <TEveEventManager.h>
#include <TEveVSD.h>
#include <TEveVSDStructs.h>

#include <TEveTrack.h>
#include <TEveTrackPropagator.h>
#include <TEveGeoShape.h>

#include <TGTab.h>
#include <TGButton.h>

#include <TFile.h>
#include <TKey.h>
#include <TSystem.h>
#include <TPRegexp.h>

// Include componets -- compile time link :)

#include "MultiView.C"
MultiView* gMultiView = 0;

class TVSDReader
{
public:
   // ----------------------------------------------------------
   // File / Event Data
   // ----------------------------------------------------------

   TFile      *fFile;
   TDirectory *fDirectory;

   TObjArray  *fEvDirKeys;

   TEveVSD    *fVSD;

   Int_t       fMaxEv, fCurEv;

   // ----------------------------------------------------------
   // Event visualization structures
   // ----------------------------------------------------------

   TEveTrackList *fTrackList;
   TEvePointSet  *fITSClusters;
   TEvePointSet  *fTPCClusters;
   TEvePointSet  *fTRDClusters;
   TEvePointSet  *fTOFClusters;

public:
   TVSDReader(const char* file_name) :
      fFile(0), fDirectory(0), fEvDirKeys(0),
      fVSD(0),

      fMaxEv(-1), fCurEv(-1),

      fTrackList(0),
      fITSClusters(0), fTPCClusters(0), fTRDClusters(0), fTOFClusters(0)
   {
      fFile = TFile::Open(file_name);
      if (!fFile)
      {
         Error("VSD_Reader", "Can not open file '%s' ... terminating.", file_name);
         gSystem->Exit(1);
      }

      fEvDirKeys = new TObjArray;
      TPMERegexp name_re("Event\\d+");
      TObjLink* lnk = fFile->GetListOfKeys()->FirstLink();
      while (lnk)
      {
         if (name_re.Match(lnk->GetObject()->GetName()))
         {
            fEvDirKeys->Add(lnk->GetObject());
         }
         lnk = lnk->Next();
      }

      fMaxEv = fEvDirKeys->GetEntriesFast();
      if (fMaxEv == 0)
      {
         Error("VSD_Reader", "No events to show ... terminating.");
         gSystem->Exit(1);
      }

      fVSD = new TEveVSD;
   }

   virtual ~TVSDReader()
   {
      // Destructor.

      DropEvent();

      delete fVSD;
      delete fEvDirKeys;

      fFile->Close();
      delete fFile;
   }

   void AttachEvent()
   {
      // Attach event data from current directory.

      fVSD->LoadTrees();
      fVSD->SetBranchAddresses();
   }

   void DropEvent()
   {
      // Drup currently held event data, release current directory.

      // Drop old visualization structures.

      gEve->GetViewers()->DeleteAnnotations();
      gEve->GetCurrentEvent()->DestroyElements();

      // Drop old event-data.

      fVSD->DeleteTrees();
      delete fDirectory;
      fDirectory = 0;
   }

   //---------------------------------------------------------------------------
   // Event navigation
   //---------------------------------------------------------------------------

   void NextEvent()
   {
      GotoEvent(fCurEv + 1);
   }

   void PrevEvent()
   {
      GotoEvent(fCurEv - 1);
   }

   Bool_t GotoEvent(Int_t ev)
   {
      if (ev < 0 || ev >= fMaxEv)
      {
         Warning("GotoEvent", "Invalid event id %d.", ev);
         return kFALSE;
      }

      DropEvent();

      // Connect to new event-data.

      fCurEv = ev;
      fDirectory = (TDirectory*) ((TKey*) fEvDirKeys->At(fCurEv))->ReadObj();
      fVSD->SetDirectory(fDirectory);

      AttachEvent();

      // Load event data into visualization structures.

      LoadClusters(fITSClusters, "ITS", 0);
      LoadClusters(fTPCClusters, "TPC", 1);
      LoadClusters(fTRDClusters, "TRD", 2);
      LoadClusters(fTOFClusters, "TOF", 3);

      LoadEsdTracks();

      // Fill projected views.

      TEveElement* top = gEve->GetCurrentEvent();

      gMultiView->DestroyEventRPhi();
      gMultiView->ImportEventRPhi(top);

      gMultiView->DestroyEventRhoZ();
      gMultiView->ImportEventRhoZ(top);

      gEve->Redraw3D(kFALSE, kTRUE);

      return kTRUE;
   }

   //---------------------------------------------------------------------------
   // Cluster loading
   //---------------------------------------------------------------------------

   void LoadClusters(TEvePointSet*& ps, const TString& det_name, Int_t det_id)
   {
      if (ps == 0)
      {
         ps = new TEvePointSet(det_name);
         ps->SetMainColor((Color_t)(det_id + 2));
         ps->SetMarkerSize(0.5);
         ps->SetMarkerStyle(2);
         ps->IncDenyDestroy();
      }
      else
      {
         ps->Reset();
      }

      TEvePointSelector ss(fVSD->fTreeC, ps, "fV.fX:fV.fY:fV.fZ",
                           TString::Format("fDetId==%d", det_id));
      ss.Select();
      ps->SetTitle(TString::Format("N=%d", ps->Size()));

      gEve->AddElement(ps);
   }

   //---------------------------------------------------------------------------
   // Track loading
   //---------------------------------------------------------------------------

   enum ESDTrackFlags
   {
      kITSin=0x0001,kITSout=0x0002,kITSrefit=0x0004,kITSpid=0x0008,
      kTPCin=0x0010,kTPCout=0x0020,kTPCrefit=0x0040,kTPCpid=0x0080,
      kTRDin=0x0100,kTRDout=0x0200,kTRDrefit=0x0400,kTRDpid=0x0800,
      kTOFin=0x1000,kTOFout=0x2000,kTOFrefit=0x4000,kTOFpid=0x8000,
      kHMPIDpid=0x20000,
      kEMCALmatch=0x40000,
      kTRDbackup=0x80000,
      kTRDStop=0x20000000,
      kESDpid=0x40000000,
      kTIME=0x80000000
   };

   Bool_t trackIsOn(TEveTrack* t, Int_t mask)
   {
      // Check is track-flag specified by mask are set.

      return (t->fStatus & mask) > 0;
   }

   void LoadEsdTracks()
   {
      // Read reconstructed tracks from current event.

      if (fTrackList == 0)
      {
         fTrackList = new TEveTrackList("ESD Tracks");
         fTrackList->SetMainColor(6);
         fTrackList->SetMarkerColor(kYellow);
         fTrackList->SetMarkerStyle(4);
         fTrackList->SetMarkerSize(0.5);

         fTrackList->IncDenyDestroy();
      }
      else
      {
         fTrackList->DestroyElements();
      }

      TEveTrackPropagator* trkProp = fTrackList->GetPropagator();
      // !!!! Need to store field on file !!!!
      // Can store TEveMagField ?
      trkProp->SetMagField(0.5);

      Int_t nTracks = fVSD->fTreeR->GetEntries();
      for (Int_t n = 0; n < nTracks; ++n)
      {
         fVSD->fTreeR->GetEntry(n);

         TEveTrack* track = new TEveTrack(&fVSD->fR, trkProp);
         track->SetName(Form("ESD Track %d", fVSD->fR.fIndex));
         track->SetStdTitle();
         track->SetAttLineAttMarker(fTrackList);
         fTrackList->AddElement(track);
      }

      fTrackList->MakeTracks();

      gEve->AddElement(fTrackList);
   }

   ClassDef(TVSDReader, 0);
};

TVSDReader* gVSDReader = 0;

// Forward declaration.
void make_gui();

//______________________________________________________________________________
void alice_vsd(const char* vsd_file_name = "http://mtadel.home.cern.ch/mtadel/root/AliVSD.root")
{
   // Main function, initializes the application.
   //
   // 1. Load the auto-generated library holding ESD classes and ESD dictionaries.
   // 2. Open ESD data-files.
   // 3. Load cartoon geometry.
   // 4. Spawn simple GUI.
   // 5. Load first event.

   TFile::SetCacheFileDir(".");

   TEveVSD::DisableTObjectStreamersForVSDStruct();

   gVSDReader = new TVSDReader(vsd_file_name);

   TEveManager::Create();

   TEveGeoShape *gentle_geom = 0;

   { // Simple geometry
      TFile* geom = TFile::Open("http://mtadel.home.cern.ch/mtadel/root/alice_mini_geom.root", "CACHEREAD");
      if (!geom)
         return;
      TEveGeoShapeExtract* gse = (TEveGeoShapeExtract*) geom->Get("Gentle");
      gentle_geom = TEveGeoShape::ImportShapeExtract(gse, 0);
      geom->Close();
      delete geom;
      gEve->AddGlobalElement(gentle_geom);
   }

   // Standard multi-view
   //=====================

   gMultiView = new MultiView;
   gMultiView->f3DView->GetGLViewer()->SetStyle(TGLRnrCtx::kOutline);

   gMultiView->SetDepth(-10);
   gMultiView->ImportGeomRPhi(gentle_geom);
   gMultiView->ImportGeomRhoZ(gentle_geom);
   gMultiView->SetDepth(0);

   // Final stuff
   //=============

   gEve->GetViewers()->SwitchColorSet();
   gEve->GetDefaultGLViewer()->SetStyle(TGLRnrCtx::kOutline);

   gEve->GetBrowser()->GetTabRight()->SetTab(1);

   make_gui();

   gEve->AddEvent(new TEveEventManager("Event", "ALICE VSD Event"));

   gVSDReader->GotoEvent(0);

   gEve->Redraw3D(kTRUE); // Reset camera after the first event has been shown.
}

//______________________________________________________________________________
void make_gui()
{
   // Create minimal GUI for event navigation.

   TEveBrowser* browser = gEve->GetBrowser();
   browser->StartEmbedding(TRootBrowser::kLeft);

   TGMainFrame* frmMain = new TGMainFrame(gClient->GetRoot(), 1000, 600);
   frmMain->SetWindowName("XX GUI");
   frmMain->SetCleanup(kDeepCleanup);

   TGHorizontalFrame* hf = new TGHorizontalFrame(frmMain);
   {
      TString icondir(TString::Format("%s/icons/", gSystem->Getenv("ROOTSYS")) );
      TGPictureButton* b = 0;

      b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoBack.gif"));
      hf->AddFrame(b);
      b->Connect("Clicked()", "TVSDReader", gVSDReader, "PrevEvent()");

      b = new TGPictureButton(hf, gClient->GetPicture(icondir + "GoForward.gif"));
      hf->AddFrame(b);
      b->Connect("Clicked()", "TVSDReader", gVSDReader, "NextEvent()");
   }
   frmMain->AddFrame(hf);

   frmMain->MapSubwindows();
   frmMain->Resize();
   frmMain->MapWindow();

   browser->StopEmbedding();
   browser->SetTabTitle("Event Control", 0);
}

#endif
<|endoftext|>


<commit_before>/**
 * @file Internal.hpp
 * @author Mislav Novakovic <mislav.novakovic@sartura.hr>
 * @brief Internal C++ helper class
 *
 * Copyright (c) 2017 Deutsche Telekom AG.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#ifndef INTERNAL_H
#define INTERNAL_H

#define S_Deleter                std::shared_ptr<Deleter>

/* Xml.hpp */
#define S_Xml_Ns                 std::shared_ptr<Xml_Ns>
#define S_Xml_Attr               std::shared_ptr<Xml_Attr>
#define S_Xml_Elem               std::shared_ptr<Xml_Elem>

/* Libyang.hpp */
#define S_Context                std::shared_ptr<Context>
#define S_Set                    std::shared_ptr<Set>

/* Tree_Data.hpp */
#define S_Value                  std::shared_ptr<Value>
#define S_Data_Node              std::shared_ptr<Data_Node>
#define S_Data_Node_Leaf_List    std::shared_ptr<Data_Node_Leaf_List>
#define S_Data_Node_Anydata      std::shared_ptr<Data_Node_Anydata>
#define S_Attr                   std::shared_ptr<Attr>
#define S_Difflist               std::shared_ptr<Difflist>

/* Tree_Schema.hpp */
#define S_Module                 std::shared_ptr<Module>
#define S_Submodule              std::shared_ptr<Submodule>
#define S_Type_Info_Binary       std::shared_ptr<Type_Info_Binary>
#define S_Type_Bit               std::shared_ptr<Type_Bit>
#define S_Type_Info_Bits         std::shared_ptr<Type_Info_Bits>
#define S_Type_Info_Dec64        std::shared_ptr<Type_Info_Dec64>
#define S_Type_Enum              std::shared_ptr<Type_Enum>
#define S_Type_Info_Enums        std::shared_ptr<Type_Info_Enums>
#define S_Type_Info_Ident        std::shared_ptr<Type_Info_Ident>
#define S_Type_Info_Inst         std::shared_ptr<Type_Info_Inst>
#define S_Type_Info_Num          std::shared_ptr<Type_Info_Num>
#define S_Type_Info_Num          std::shared_ptr<Type_Info_Num>
#define S_Type_Info_Lref         std::shared_ptr<Type_Info_Lref>
#define S_Type_Info_Str          std::shared_ptr<Type_Info_Str>
#define S_Type_Info_Union        std::shared_ptr<Type_Info_Union>
#define S_Type_Info              std::shared_ptr<Type_Info>
#define S_Type                   std::shared_ptr<Type>
#define S_Iffeature              std::shared_ptr<Iffeature>
#define S_Ext_Instance           std::shared_ptr<Ext_Instance>
#define S_Revision               std::shared_ptr<Revision>
#define S_Schema_Node            std::shared_ptr<Schema_Node>
#define S_Schema_Node_Container  std::shared_ptr<Schema_Node_Container>
#define S_Schema_Node_Choice     std::shared_ptr<Schema_Node_Choice>
#define S_Schema_Node_Leaf       std::shared_ptr<Schema_Node_Leaf>
#define S_Schema_Node_Leaflist   std::shared_ptr<Schema_Node_Leaflist>
#define S_Schema_Node_List       std::shared_ptr<Schema_Node_List>
#define S_Schema_Node_Anydata    std::shared_ptr<Schema_Node_Anydata>
#define S_Schema_Node_Uses       std::shared_ptr<Schema_Node_Uses>
#define S_Schema_Node_Grp        std::shared_ptr<Schema_Node_Grp>
#define S_Schema_Node_Case       std::shared_ptr<Schema_Node_Case>
#define S_Schema_Node_Inout      std::shared_ptr<Schema_Node_Inout>
#define S_Schema_Node_Notif      std::shared_ptr<Schema_Node_Notif>
#define S_Schema_Node_Action     std::shared_ptr<Schema_Node_Action>
#define S_Schema_Node_Augment    std::shared_ptr<Schema_Node_Augment>
#define S_When                   std::shared_ptr<When>
#define S_Substmt                std::shared_ptr<Substmt>
#define S_Ext                    std::shared_ptr<Ext>
#define S_Refine_Mod_List        std::shared_ptr<Refine_Mod_List>
#define S_Refine_Mod             std::shared_ptr<Refine_Mod>
#define S_Refine                 std::shared_ptr<Refine>
#define S_Deviate                std::shared_ptr<Deviate>
#define S_Deviation              std::shared_ptr<Deviation>
#define S_Import                 std::shared_ptr<Import>
#define S_Include                std::shared_ptr<Include>
#define S_Tpdf                   std::shared_ptr<Tpdf>
#define S_Unique                 std::shared_ptr<Unique>
#define S_Feature                std::shared_ptr<Feature>
#define S_Restr                  std::shared_ptr<Restr>
#define S_Ident                  std::shared_ptr<Ident>

#define LY_NEW(data, element, class)                                                                                \
    {                                                                                \
        return data->element ? S_##class(new class(data->element, deleter)) : nullptr;                                                               \
    };

#define LY_NEW_CASTED(cast, data, element, class)                                                                                \
    {                                                                                \
        cast *casted = (struct cast *) data;                                                                                \
        return casted->element ? S_##class(new class(casted->element, deleter)) : nullptr;                                                           \
    };

#define LY_NEW_LIST(data, element, size, class)                                                                                \
    {                                                                                \
        auto s_vector = new std::vector<S_##class>;                                                                                \
                                                                                \
        for (uint8_t i = 0; i < data->size; i++) {                                                                                \
            s_vector->push_back(S_##class(new class(&data->element[i], deleter)));                                                                   \
        }                                                                                \
                                                                                \
        return s_vector;                                                                                \
    };

#define LY_NEW_LIST_CASTED(cast, data, element, size, class)                                                                                \
    {                                                                                \
        struct cast *casted = (struct cast *) data;                                                                                \
        LY_NEW_LIST(casted, element, size, class);                                                                                \
    };

#define LY_NEW_P_LIST(data, element, size, class)                                                                                \
    {                                                                                \
        auto s_vector = new std::vector<S_##class>;                                                                                \
                                                                                \
        for (uint8_t i = 0; i < data->size; i++) {                                                                                \
            s_vector->push_back(S_##class(new class(data->element[i], deleter)));                                                                    \
        }                                                                                \
                                                                                \
        return s_vector;                                                                                \
    };

#define LY_NEW_P_LIST_CASTED(cast, data, element, size, class)                                                                                \
    {                                                                                \
        struct cast *casted = (struct cast *) data;                                                                                \
        LY_NEW_P_LIST(casted, element, size, class);                                                                                \
    };

#define LY_NEW_STRING_LIST(data, element, size)                                                                                \
    {                                                                                \
        auto s_vector = new std::vector<std::string>;                                                                                \
                                                                                \
        for (uint8_t i = 0; i < data->size; i++) {                                                                                \
            s_vector->push_back(std::string(data->element[i]));                                                                                \
        }                                                                                \
                                                                                \
        return s_vector;                                                                                \
    };

#include <iostream>
#include <memory>
#include <vector>

extern "C" {
#include "libyang.h"
}

/* defined */
class Deleter;

/* used */
class Context;

enum class Free_Type {
    CONTEXT,
    DATA_NODE,
    //TODO DATA_NODE_WITHSIBLINGS,
    SCHEMA_NODE,
    MODULE,
    SUBMODULE,
    XML,
    SET,
    DIFFLIST,
};

typedef union value_e {
    struct ly_ctx *ctx;
    struct lyd_node *data;
    struct lys_node *schema;
    struct lys_module *module;
    struct lys_submodule *submodule;
    struct lyxml_elem *elem;
    struct ly_set *set;
    struct lyd_difflist *diff;
} value_t;

class Deleter
{
public:
    Deleter(ly_ctx *ctx, S_Deleter parent = nullptr);
    Deleter(struct lyd_node *data, S_Deleter parent = nullptr);
    Deleter(struct lys_node *schema, S_Deleter parent = nullptr);
    Deleter(struct lys_module *module, S_Deleter parent = nullptr);
    Deleter(struct lys_submodule *submodule, S_Deleter parent = nullptr);
    Deleter(S_Context context, struct lyxml_elem *elem, S_Deleter parent = nullptr);
    Deleter(struct ly_set *set, S_Deleter parent = nullptr);
    Deleter(struct lyd_difflist *diff, S_Deleter parent = nullptr);
    ~Deleter();

private:
    S_Context context;
    value_t v;
    Free_Type t;
    S_Deleter parent;
};

#endif
<commit_msg>C++: change macro code style<commit_after>/**
 * @file Internal.hpp
 * @author Mislav Novakovic <mislav.novakovic@sartura.hr>
 * @brief Internal C++ helper class
 *
 * Copyright (c) 2017 Deutsche Telekom AG.
 *
 * This source code is licensed under BSD 3-Clause License (the "License").
 * You may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     https://opensource.org/licenses/BSD-3-Clause
 */

#ifndef INTERNAL_H
#define INTERNAL_H

#define S_Deleter                std::shared_ptr<Deleter>

/* Xml.hpp */
#define S_Xml_Ns                 std::shared_ptr<Xml_Ns>
#define S_Xml_Attr               std::shared_ptr<Xml_Attr>
#define S_Xml_Elem               std::shared_ptr<Xml_Elem>

/* Libyang.hpp */
#define S_Context                std::shared_ptr<Context>
#define S_Set                    std::shared_ptr<Set>

/* Tree_Data.hpp */
#define S_Value                  std::shared_ptr<Value>
#define S_Data_Node              std::shared_ptr<Data_Node>
#define S_Data_Node_Leaf_List    std::shared_ptr<Data_Node_Leaf_List>
#define S_Data_Node_Anydata      std::shared_ptr<Data_Node_Anydata>
#define S_Attr                   std::shared_ptr<Attr>
#define S_Difflist               std::shared_ptr<Difflist>

/* Tree_Schema.hpp */
#define S_Module                 std::shared_ptr<Module>
#define S_Submodule              std::shared_ptr<Submodule>
#define S_Type_Info_Binary       std::shared_ptr<Type_Info_Binary>
#define S_Type_Bit               std::shared_ptr<Type_Bit>
#define S_Type_Info_Bits         std::shared_ptr<Type_Info_Bits>
#define S_Type_Info_Dec64        std::shared_ptr<Type_Info_Dec64>
#define S_Type_Enum              std::shared_ptr<Type_Enum>
#define S_Type_Info_Enums        std::shared_ptr<Type_Info_Enums>
#define S_Type_Info_Ident        std::shared_ptr<Type_Info_Ident>
#define S_Type_Info_Inst         std::shared_ptr<Type_Info_Inst>
#define S_Type_Info_Num          std::shared_ptr<Type_Info_Num>
#define S_Type_Info_Num          std::shared_ptr<Type_Info_Num>
#define S_Type_Info_Lref         std::shared_ptr<Type_Info_Lref>
#define S_Type_Info_Str          std::shared_ptr<Type_Info_Str>
#define S_Type_Info_Union        std::shared_ptr<Type_Info_Union>
#define S_Type_Info              std::shared_ptr<Type_Info>
#define S_Type                   std::shared_ptr<Type>
#define S_Iffeature              std::shared_ptr<Iffeature>
#define S_Ext_Instance           std::shared_ptr<Ext_Instance>
#define S_Revision               std::shared_ptr<Revision>
#define S_Schema_Node            std::shared_ptr<Schema_Node>
#define S_Schema_Node_Container  std::shared_ptr<Schema_Node_Container>
#define S_Schema_Node_Choice     std::shared_ptr<Schema_Node_Choice>
#define S_Schema_Node_Leaf       std::shared_ptr<Schema_Node_Leaf>
#define S_Schema_Node_Leaflist   std::shared_ptr<Schema_Node_Leaflist>
#define S_Schema_Node_List       std::shared_ptr<Schema_Node_List>
#define S_Schema_Node_Anydata    std::shared_ptr<Schema_Node_Anydata>
#define S_Schema_Node_Uses       std::shared_ptr<Schema_Node_Uses>
#define S_Schema_Node_Grp        std::shared_ptr<Schema_Node_Grp>
#define S_Schema_Node_Case       std::shared_ptr<Schema_Node_Case>
#define S_Schema_Node_Inout      std::shared_ptr<Schema_Node_Inout>
#define S_Schema_Node_Notif      std::shared_ptr<Schema_Node_Notif>
#define S_Schema_Node_Action     std::shared_ptr<Schema_Node_Action>
#define S_Schema_Node_Augment    std::shared_ptr<Schema_Node_Augment>
#define S_When                   std::shared_ptr<When>
#define S_Substmt                std::shared_ptr<Substmt>
#define S_Ext                    std::shared_ptr<Ext>
#define S_Refine_Mod_List        std::shared_ptr<Refine_Mod_List>
#define S_Refine_Mod             std::shared_ptr<Refine_Mod>
#define S_Refine                 std::shared_ptr<Refine>
#define S_Deviate                std::shared_ptr<Deviate>
#define S_Deviation              std::shared_ptr<Deviation>
#define S_Import                 std::shared_ptr<Import>
#define S_Include                std::shared_ptr<Include>
#define S_Tpdf                   std::shared_ptr<Tpdf>
#define S_Unique                 std::shared_ptr<Unique>
#define S_Feature                std::shared_ptr<Feature>
#define S_Restr                  std::shared_ptr<Restr>
#define S_Ident                  std::shared_ptr<Ident>

#define LY_NEW(data, element, class)\
    {\
        return data->element ? S_##class(new class(data->element, deleter)) : nullptr;\
    };

#define LY_NEW_CASTED(cast, data, element, class)\
    {\
        cast *casted = (struct cast *) data;\
        return casted->element ? S_##class(new class(casted->element, deleter)) : nullptr;\
    };

#define LY_NEW_LIST(data, element, size, class)\
    {\
        auto s_vector = new std::vector<S_##class>;\
        for (uint8_t i = 0; i < data->size; i++) {\
            s_vector->push_back(S_##class(new class(&data->element[i], deleter)));\
        }\
        return s_vector;\
    };

#define LY_NEW_LIST_CASTED(cast, data, element, size, class)\
    {\
        struct cast *casted = (struct cast *) data;\
        LY_NEW_LIST(casted, element, size, class);\
    };

#define LY_NEW_P_LIST(data, element, size, class)\
    {\
        auto s_vector = new std::vector<S_##class>;\
        for (uint8_t i = 0; i < data->size; i++) {\
            s_vector->push_back(S_##class(new class(data->element[i], deleter)));\
        }\
        return s_vector;\
    };

#define LY_NEW_P_LIST_CASTED(cast, data, element, size, class)\
    {\
        struct cast *casted = (struct cast *) data;\
        LY_NEW_P_LIST(casted, element, size, class);\
    };

#define LY_NEW_STRING_LIST(data, element, size)\
    {\
        auto s_vector = new std::vector<std::string>;\
        for (uint8_t i = 0; i < data->size; i++) {\
            s_vector->push_back(std::string(data->element[i]));\
        }\
        return s_vector;\
    };

#include <iostream>
#include <memory>
#include <vector>

extern "C" {
#include "libyang.h"
}

/* defined */
class Deleter;

/* used */
class Context;

enum class Free_Type {
    CONTEXT,
    DATA_NODE,
    //TODO DATA_NODE_WITHSIBLINGS,
    SCHEMA_NODE,
    MODULE,
    SUBMODULE,
    XML,
    SET,
    DIFFLIST,
};

typedef union value_e {
    struct ly_ctx *ctx;
    struct lyd_node *data;
    struct lys_node *schema;
    struct lys_module *module;
    struct lys_submodule *submodule;
    struct lyxml_elem *elem;
    struct ly_set *set;
    struct lyd_difflist *diff;
} value_t;

class Deleter
{
public:
    Deleter(ly_ctx *ctx, S_Deleter parent = nullptr);
    Deleter(struct lyd_node *data, S_Deleter parent = nullptr);
    Deleter(struct lys_node *schema, S_Deleter parent = nullptr);
    Deleter(struct lys_module *module, S_Deleter parent = nullptr);
    Deleter(struct lys_submodule *submodule, S_Deleter parent = nullptr);
    Deleter(S_Context context, struct lyxml_elem *elem, S_Deleter parent = nullptr);
    Deleter(struct ly_set *set, S_Deleter parent = nullptr);
    Deleter(struct lyd_difflist *diff, S_Deleter parent = nullptr);
    ~Deleter();

private:
    S_Context context;
    value_t v;
    Free_Type t;
    S_Deleter parent;
};

#endif
<|endoftext|>


<commit_before>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    TextfileOut.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    August 2008
*/

#include <fstream>
#include <stdarg.h>
#ifdef WIN32
  #include <windows.h>
#endif
#include "TextfileOut.h"
#include <ctime>

using namespace std;

/// ANSI escape codes for various colors.
///@{
static const char C_DGRAY[]  = "\033[01;30m";
static const char C_NORM[]   = "\033[00m";
static const char C_RED[]    = "\033[01;31m";
static const char C_YELLOW[] = "\033[01;33m";
static const char C_GREEN[]  = "\033[01;32m";
static const char C_MAG[]    = "\033[01;35m";
static const char C_LBLUE[]  = "\033[01;36m";
static const char C_WHITE[]  = "\033[01;27m";
///@}

TextfileOut::TextfileOut(std::string strFilename) :
  m_strFilename(strFilename)
{
  this->printf("MESSAGE (TextfileOut::TextfileOut:): Starting up");
}

TextfileOut::~TextfileOut() {
  this->printf("MESSAGE (TextfileOut::~TextfileOut:): Shutting down\n\n\n");
}

void TextfileOut::printf(const char* format, ...) const
{
  if (!m_bShowOther) return;

  char buff[16384];

  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif

  time_t epoch_time;
  time(&epoch_time);

#ifdef TUVOK_OS_WINDOWS
  struct tm now;
  localtime_s(&now, &epoch_time);
#define ADDR_NOW (&now)
#else
  struct tm* now;
  now = localtime(&epoch_time);
#define ADDR_NOW (now)
#endif
  char datetime[64];

  ofstream fs;
  fs.open(m_strFilename.c_str(),  ios_base::app);
  if (fs.fail()) return;

  if(strftime(datetime, 64, "(%d.%m.%Y %H:%M:%S)", ADDR_NOW) > 0) {
    fs << datetime << " " << buff << std::endl;
  } else {
    fs << buff << std::endl;
  }

  fs.flush();
  fs.close();
}

void TextfileOut::_printf(const char* format, ...) const
{
  char buff[16384];

  va_list args;
  va_start(args, format);

#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif

  time_t epoch_time;
  time(&epoch_time);

#ifdef TUVOK_OS_WINDOWS
  struct tm now;
  localtime_s(&now, &epoch_time);
#undef ADDR_NOW
#define ADDR_NOW (&now)
#else
  struct tm* now;
  now = localtime(&epoch_time);
#define ADDR_NOW (now)
#endif
  char datetime[64];

  ofstream fs;
  fs.open(m_strFilename.c_str(),  ios_base::app);
  if (fs.fail()) return;
  if(strftime(datetime, 64, "(%d.%m.%Y %H:%M:%S)", ADDR_NOW) > 0) {
    fs << datetime << " " << buff << std::endl;
  } else {
    fs << buff << std::endl;
  }
  fs.flush();
  fs.close();
}

void TextfileOut::Message(const char* source, const char* format, ...) {
  if (!m_bShowMessages) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
  this->_printf("MESSAGE (%s): %s", source, buff);
}

void TextfileOut::Warning(const char* source, const char* format, ...) {
  if (!m_bShowWarnings) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
#ifndef TUVOK_OS_WINDOWS
  this->_printf("%sWARNING%s (%s): %s", C_YELLOW, C_NORM, source, buff);
#else
  this->_printf("WARNING (%s): %s", source, buff);
#endif
}

void TextfileOut::Error(const char* source, const char* format, ...) {
  if (!m_bShowErrors) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
#ifndef TUVOK_OS_WINDOWS
  this->_printf("%sERROR%s (%s): %s", C_RED, C_NORM, source, buff);
#else
  this->_printf("ERROR (%s): %s", source, buff);
#endif
}
<commit_msg>Remove color codes from text file output.<commit_after>/*
   For more information, please see: http://software.sci.utah.edu

   The MIT License

   Copyright (c) 2008 Scientific Computing and Imaging Institute,
   University of Utah.

   Permission is hereby granted, free of charge, to any person obtaining a
   copy of this software and associated documentation files (the "Software"),
   to deal in the Software without restriction, including without limitation
   the rights to use, copy, modify, merge, publish, distribute, sublicense,
   and/or sell copies of the Software, and to permit persons to whom the
   Software is furnished to do so, subject to the following conditions:

   The above copyright notice and this permission notice shall be included
   in all copies or substantial portions of the Software.

   THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
   OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
   THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
   FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
   DEALINGS IN THE SOFTWARE.
*/

/**
  \file    TextfileOut.cpp
  \author  Jens Krueger
           SCI Institute
           University of Utah
  \date    August 2008
*/

#include <fstream>
#include <stdarg.h>
#ifdef WIN32
  #include <windows.h>
#endif
#include "TextfileOut.h"
#include <ctime>

using namespace std;

TextfileOut::TextfileOut(std::string strFilename) :
  m_strFilename(strFilename)
{
  this->printf("MESSAGE (TextfileOut::TextfileOut:): Starting up");
}

TextfileOut::~TextfileOut() {
  this->printf("MESSAGE (TextfileOut::~TextfileOut:): Shutting down\n\n\n");
}

void TextfileOut::printf(const char* format, ...) const
{
  if (!m_bShowOther) return;

  char buff[16384];

  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif

  time_t epoch_time;
  time(&epoch_time);

#ifdef TUVOK_OS_WINDOWS
  struct tm now;
  localtime_s(&now, &epoch_time);
#define ADDR_NOW (&now)
#else
  struct tm* now;
  now = localtime(&epoch_time);
#define ADDR_NOW (now)
#endif
  char datetime[64];

  ofstream fs;
  fs.open(m_strFilename.c_str(),  ios_base::app);
  if (fs.fail()) return;

  if(strftime(datetime, 64, "(%d.%m.%Y %H:%M:%S)", ADDR_NOW) > 0) {
    fs << datetime << " " << buff << std::endl;
  } else {
    fs << buff << std::endl;
  }

  fs.flush();
  fs.close();
}

void TextfileOut::_printf(const char* format, ...) const
{
  char buff[16384];

  va_list args;
  va_start(args, format);

#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif

  time_t epoch_time;
  time(&epoch_time);

#ifdef TUVOK_OS_WINDOWS
  struct tm now;
  localtime_s(&now, &epoch_time);
#undef ADDR_NOW
#define ADDR_NOW (&now)
#else
  struct tm* now;
  now = localtime(&epoch_time);
#define ADDR_NOW (now)
#endif
  char datetime[64];

  ofstream fs;
  fs.open(m_strFilename.c_str(),  ios_base::app);
  if (fs.fail()) return;
  if(strftime(datetime, 64, "(%d.%m.%Y %H:%M:%S)", ADDR_NOW) > 0) {
    fs << datetime << " " << buff << std::endl;
  } else {
    fs << buff << std::endl;
  }
  fs.flush();
  fs.close();
}

void TextfileOut::Message(const char* source, const char* format, ...) {
  if (!m_bShowMessages) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
  this->_printf("MESSAGE (%s): %s", source, buff);
}

void TextfileOut::Warning(const char* source, const char* format, ...) {
  if (!m_bShowWarnings) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
  this->_printf("WARNING (%s): %s", source, buff);
}

void TextfileOut::Error(const char* source, const char* format, ...) {
  if (!m_bShowErrors) return;
  char buff[16384];
  va_list args;
  va_start(args, format);
#ifdef WIN32
  _vsnprintf_s( buff, 16384, sizeof(buff), format, args);
#else
  vsnprintf( buff, sizeof(buff), format, args);
#endif
  this->_printf("ERROR (%s): %s", source, buff);
}
<|endoftext|>


<commit_before>/*
 * $File: test_btree.cpp
 * $Date: Thu Nov 06 01:05:26 2014 +0800
 * $Author: jiakai <jia.kai66@gmail.com>
 */

#include "./page_io_env.h"
#include "./utils.h"

#include "usql/ds/btree.h"

#include <map>

constexpr size_t TREE_INTERNAL_BRANCH = 4;

namespace {

struct Key {
    int key;

    Key() = default;

    explicit Key(int n):
        key(n)
    {
    }
};

struct KeyCmp {
    bool operator () (const Key &a, const Key & b) const {
        return a.key < b.key;
    }
};

using val_t = int;
using Btree = TypedBTree<Key, val_t, KeyCmp>;

using BTreeTestEnvBase = PageIOTestEnvTpl<
    (Btree::internal_header_size() + sizeof(Key) + sizeof(PageIO::page_id_t)) *
    TREE_INTERNAL_BRANCH>;

class BTreeTestEnv : public BTreeTestEnvBase {
    protected:
        PageIO::page_id_t m_tree_root = 0;
        std::unique_ptr<Btree> m_tree;

        void SetUp() override {
            BTreeTestEnvBase::SetUp();
            m_tree = std::make_unique<Btree>(*m_page_io);
            m_tree->load(m_tree_root, [this](const PageIO::Page &root) {
                m_tree_root = root.id();
            });
        }

        void TearDown() override {
            m_tree.reset();
        }
};

/*!
 * map that allows sampling
 */
class RandMap {
    std::map<Key, val_t, KeyCmp> m_map;
    std::vector<Key> m_key;

    public:
        void assign(const Key &key, const val_t &val) {
            auto r = m_map.insert({key, val});
            if (r.second)
                m_key.push_back(key);
        }

        const val_t& operator[] (const Key &key) const {
            auto iter = m_map.find(key);
            usql_assert(iter != m_map.end());
            return iter->second;
        }

        const Key& sample() {
            usql_assert(!m_key.empty());
            auto idx = randi(m_key.size());
            std::swap(m_key[idx], m_key.back());
            return m_key.back();
        }

        void remove_prev_sampled() {
            usql_assert(!m_key.empty());
            m_map.erase(m_key.back());
            m_key.pop_back();
        }

        size_t size() const {
            return m_map.size();
        }

        auto&& map() const {
            return m_map;
        }
};

} // annonymous namespace

TEST_F(BTreeTestEnv, simple_insert) {
    m_tree->visit(Key{123}) = 456;
    m_tree->sanity_check();
    EXPECT_EQ(456, m_tree->visit(Key{123}));
}

TEST_F(BTreeTestEnv, erase_after_insert) {
    RandMap check;
    const size_t NR = pow(TREE_INTERNAL_BRANCH, 7);

    auto check_read = [&](size_t i) {
        auto &&k = check.sample();
        auto v_check = check[k],
             v_get = m_tree->visit(k);
        usql_assert(v_check == v_get, "unequal: i=%zd expect=%d get=%d key=%d",
                i, v_check, v_get, k.key);
        return k;
    };

    for (size_t i = 0; i < NR; i ++) {
        // insert
        Key k{rand()};
        val_t v = rand();
        check.assign(k, v);
        m_tree->visit(k) = v;
        m_tree->sanity_check();

        check_read(i);
    }

    for (size_t i = 0; i < NR; i ++) {
        auto &&k = check_read(i);
        ASSERT_TRUE(m_tree->erase(k));
        m_tree->sanity_check();
        check.remove_prev_sampled();
    }
}

TEST_F(BTreeTestEnv, rand_opr) {
    RandMap check;
    const size_t NR_OPR = pow(TREE_INTERNAL_BRANCH, 10);
    for (size_t i = 0; i < NR_OPR; i ++) {
        bool do_insert = true;
        if (check.size()) {
            Key k{rand()};
            auto iter_expect = check.map().lower_bound(k);
            auto iter_get = m_tree->lookup(k, false);
            for (int t = randi(TREE_INTERNAL_BRANCH * 4); t >= 0; t --) {
                if (iter_expect == check.map().end()) {
                    ASSERT_FALSE(iter_get.valid());
                    break;
                }
                ASSERT_TRUE(iter_get.valid());
                ASSERT_EQ(iter_expect->first.key, iter_get.key().key);
                ASSERT_EQ(iter_expect->second, iter_get.payload());
                iter_get.next();
                iter_expect ++;
            }

            if (rand() <= RAND_MAX / 2) {
                // rand erase, do not insert
                do_insert = false;
                k = check.sample();
                ASSERT_TRUE(m_tree->erase(k));
                check.remove_prev_sampled();
            }
        }
        if (do_insert) {
            Key k{rand()};
            val_t v = rand();
            check.assign(k, v);
            m_tree->lookup(k, true).payload() = v;
        }

        if (rand() <= RAND_MAX / 5) {
            // check erase unexisting key
            Key k{rand()};
            if (check.map().find(k) == check.map().end()) {
                ASSERT_FALSE(m_tree->erase(k));
            }
        }
        m_tree->sanity_check();
    }

    while (check.size()) {
        auto &&k = check.sample();
        ASSERT_TRUE(m_tree->erase(k));
        check.remove_prev_sampled();
    }

    ASSERT_EQ(0, m_tree_root);
}

// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

<commit_msg>more tests<commit_after>/*
 * $File: test_btree.cpp
 * $Date: Thu Nov 06 01:13:10 2014 +0800
 * $Author: jiakai <jia.kai66@gmail.com>
 */

#include "./page_io_env.h"
#include "./utils.h"

#include "usql/ds/btree.h"

#include <map>

constexpr size_t TREE_INTERNAL_BRANCH = 4;

namespace {

struct Key {
    int key;

    Key() = default;

    explicit Key(int n):
        key(n)
    {
    }
};

struct KeyCmp {
    bool operator () (const Key &a, const Key & b) const {
        return a.key < b.key;
    }
};

using val_t = int;
using Btree = TypedBTree<Key, val_t, KeyCmp>;

using BTreeTestEnvBase = PageIOTestEnvTpl<
    (Btree::internal_header_size() + sizeof(Key) + sizeof(PageIO::page_id_t)) *
    TREE_INTERNAL_BRANCH>;

class BTreeTestEnv : public BTreeTestEnvBase {
    protected:
        PageIO::page_id_t m_tree_root = 0;
        std::unique_ptr<Btree> m_tree;

        void SetUp() override {
            BTreeTestEnvBase::SetUp();
            m_tree = std::make_unique<Btree>(*m_page_io);
            m_tree->load(m_tree_root, [this](const PageIO::Page &root) {
                m_tree_root = root.id();
            });
        }

        void TearDown() override {
            m_tree.reset();
        }
};

/*!
 * map that allows sampling
 */
class RandMap {
    std::map<Key, val_t, KeyCmp> m_map;
    std::vector<Key> m_key;

    public:
        void assign(const Key &key, const val_t &val) {
            auto r = m_map.insert({key, val});
            if (r.second)
                m_key.push_back(key);
            else
                r.first->second = val;
        }

        const val_t& operator[] (const Key &key) const {
            auto iter = m_map.find(key);
            usql_assert(iter != m_map.end());
            return iter->second;
        }

        const Key& sample() {
            usql_assert(!m_key.empty());
            auto idx = randi(m_key.size());
            std::swap(m_key[idx], m_key.back());
            return m_key.back();
        }

        void remove_prev_sampled() {
            usql_assert(!m_key.empty());
            m_map.erase(m_key.back());
            m_key.pop_back();
        }

        size_t size() const {
            return m_map.size();
        }

        auto&& map() const {
            return m_map;
        }
};

} // annonymous namespace

TEST_F(BTreeTestEnv, simple_insert) {
    m_tree->visit(Key{123}) = 456;
    m_tree->sanity_check();
    EXPECT_EQ(456, m_tree->visit(Key{123}));
}

TEST_F(BTreeTestEnv, erase_after_insert) {
    RandMap check;
    const size_t NR = pow(TREE_INTERNAL_BRANCH, 7);

    auto check_read = [&](size_t i) {
        auto &&k = check.sample();
        auto v_check = check[k],
             v_get = m_tree->visit(k);
        usql_assert(v_check == v_get, "unequal: i=%zd expect=%d get=%d key=%d",
                i, v_check, v_get, k.key);
        return k;
    };

    for (size_t i = 0; i < NR; i ++) {
        // insert
        Key k{rand()};
        val_t v = rand();
        check.assign(k, v);
        m_tree->visit(k) = v;
        m_tree->sanity_check();

        check_read(i);
    }

    for (size_t i = 0; i < NR; i ++) {
        auto &&k = check_read(i);
        ASSERT_TRUE(m_tree->erase(k));
        m_tree->sanity_check();
        check.remove_prev_sampled();
    }
}

TEST_F(BTreeTestEnv, rand_opr) {
    RandMap check;
    const size_t NR_OPR = pow(TREE_INTERNAL_BRANCH, 10);
    for (size_t i = 0; i < NR_OPR; i ++) {
        bool do_insert = true;
        if (check.size()) {
            Key k{rand()};
            auto iter_expect = check.map().lower_bound(k);
            auto iter_get = m_tree->lookup(k, false);
            for (int t = randi(TREE_INTERNAL_BRANCH * 4); t >= 0; t --) {
                if (iter_expect == check.map().end()) {
                    ASSERT_FALSE(iter_get.valid());
                    break;
                }
                ASSERT_TRUE(iter_get.valid());
                ASSERT_EQ(iter_expect->first.key, iter_get.key().key);
                ASSERT_EQ(iter_expect->second, iter_get.payload());
                iter_get.next();
                iter_expect ++;
            }

            if (rand() <= RAND_MAX / 2) {
                // rand erase, do not insert
                do_insert = false;
                k = check.sample();
                ASSERT_TRUE(m_tree->erase(k));
                check.remove_prev_sampled();
            }
        }
        if (do_insert) {
            Key k{rand()};
            val_t v = rand();
            check.assign(k, v);
            m_tree->lookup(k, true).payload() = v;
        }

        if (rand() <= RAND_MAX / 5) {
            // check erase unexisting key
            Key k{rand()};
            if (check.map().find(k) == check.map().end()) {
                ASSERT_FALSE(m_tree->erase(k));
            }
        }

        if (rand() <= RAND_MAX / 5 && check.size()) {
            // overwrite existing entry
            auto &&k = check.sample();
            val_t v = rand();
            check.assign(k, v);
            m_tree->visit(k) = v;
        }

        m_tree->sanity_check();
    }

    while (check.size()) {
        auto &&k = check.sample();
        ASSERT_TRUE(m_tree->erase(k));
        check.remove_prev_sampled();
    }

    ASSERT_EQ(0, m_tree_root);
}

// vim: syntax=cpp.doxygen foldmethod=marker foldmarker=f{{{,f}}}

<|endoftext|>


<commit_before>// Copyright (c) 2007, 2008 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include <QMenuBar>
#include <QFileDialog>

#include "libmv/image/array_nd.h"
#include "libmv/image/surf.h"
#include "libmv/image/surf_descriptor.h"
#include "libmv/multiview/focal_from_fundamental.h"
#include "libmv/logging/logging.h"
#include "ui/tvr/main_window.h"

TvrMainWindow::TvrMainWindow(QWidget *parent)
  : QMainWindow(parent) {

  viewer_ = new MatchViewer();
  setCentralWidget(viewer_);

  CreateActions();
  CreateMenus();
}

TvrMainWindow::~TvrMainWindow() {
}

void TvrMainWindow::CreateActions() {
  open_images_action_ = new QAction(tr("&Open Images..."), this);
  open_images_action_->setShortcut(tr("Ctrl+O"));
  open_images_action_->setStatusTip(tr("Open an image pair"));
  connect(open_images_action_, SIGNAL(triggered()),
          this, SLOT(OpenImages()));

  compute_features_action_ = new QAction(tr("&Compute Features"), this);
  compute_features_action_->setStatusTip(tr("Compute Surf Features"));
  connect(compute_features_action_, SIGNAL(triggered()),
          this, SLOT(ComputeFeatures()));

  compute_candidate_matches_action_ =
      new QAction(tr("&Compute Candidate Matches"), this);
  compute_candidate_matches_action_->setStatusTip(
      tr("Compute Candidate Matches"));
  connect(compute_candidate_matches_action_, SIGNAL(triggered()),
          this, SLOT(ComputeCandidateMatches()));

  compute_robust_matches_action_ = new QAction(tr("&Compute Robust Matches"),
                                               this);
  compute_robust_matches_action_->setStatusTip(tr("Compute Robust Matches"));
  connect(compute_robust_matches_action_, SIGNAL(triggered()),
          this, SLOT(ComputeRobustMatches()));

  focal_from_fundamental_action_ = new QAction(tr("&Focal from Fundamental"),
                                               this);
  focal_from_fundamental_action_->setStatusTip(
      tr("Compute Focal Distance from the Fundamental MatrixRobust Matrix"));
  connect(focal_from_fundamental_action_, SIGNAL(triggered()),
          this, SLOT(FocalFromFundamental()));
}

void TvrMainWindow::CreateMenus() {
  file_menu_ = menuBar()->addMenu(tr("&File"));
  file_menu_->addAction(open_images_action_);
  matching_menu_ = menuBar()->addMenu(tr("&Matching"));
  matching_menu_->addAction(compute_features_action_);
  matching_menu_->addAction(compute_candidate_matches_action_);
  matching_menu_->addAction(compute_robust_matches_action_);
  calibration_menu_ = menuBar()->addMenu(tr("&Calibration"));
  calibration_menu_->addAction(focal_from_fundamental_action_);
}

void TvrMainWindow::OpenImages() {
  QStringList filenames = QFileDialog::getOpenFileNames(this,
      "Select Two Images", "", "Image Files (*.png *.jpg *.bmp *.ppm *.pgm *.xpm)");

  // TODO(keir): Don't segfault if != 2 images are selected.
  for (int i = 0; i < 2; ++i) {
    document_.images[i].load(filenames[i]);
  }

  viewer_->SetDocument(&document_);
}

void TvrMainWindow::ComputeFeatures() {
  for (int i = 0; i < 2; ++i) {
    ComputeFeatures(i);
  }
}

void TvrMainWindow::ComputeFeatures(int image_index) {
  QImage &qimage = document_.images[image_index];
  int width = qimage.width(), height = qimage.height();
  SurfFeatureSet &fs = document_.feature_sets[image_index];

  // Convert to gray-scale.
  // TODO(keir): Make a libmv image <-> QImage interop library inside libmv for
  // easy bidirectional exchange of images between Qt and libmv.
  libmv::Array3Df image(height, width, 1);
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      // TODO(pau): there are better ways to compute intensity.
      //            Implement one and put it on libmv/image.
      int depth = qimage.depth() / 8;
      image(y, x) = 0;
      for (int c = 0; c < depth; ++c) {
        if (c != 3) {  // Skip alpha channel for RGBA.
          image(y, x) = float(qimage.bits()[depth*(y * width + x) + c]);
        }
      }
      image(y, x) /= depth == 4 ? 3 : depth;
    }
  }
  libmv::SurfFeatures(image, 3, 4, &fs.features);

  // Build the kd-tree.
  fs.tree.Build(&fs.features[0], fs.features.size(), 64, 10);

  viewer_->updateGL();
}

void TvrMainWindow::ComputeCandidateMatches() {
  FindCandidateMatches(document_.feature_sets[0],
                       document_.feature_sets[1],
                       &document_.correspondences);
  viewer_->updateGL();
}

void TvrMainWindow::ComputeRobustMatches() {
  libmv::Correspondences new_correspondences;

  ComputeFundamental(document_.correspondences,
                     &document_.F, &new_correspondences);

  // TODO(pau) Make sure this is not copying too many things.  We could
  //           implement an efficient swap for the biparted graph (just swaping
  //           the maps), or remove outlier tracks from the candidate matches
  //           instead of constructing a new correspondance set.
  std::swap(document_.correspondences, new_correspondences);
  viewer_->updateGL();
}

void TvrMainWindow::FocalFromFundamental() {
  libmv::Vec2 p0(document_.images[0].width(), document_.images[0].height());
  libmv::Vec2 p1(document_.images[1].width(), document_.images[1].height());
  libmv::FocalFromFundamental(document_.F, p0, p1,
                              &document_.focal_distance[0],
                              &document_.focal_distance[1]);

  LOG(INFO) << "focal 0: " << document_.focal_distance[0]
            << " focal 1: " << document_.focal_distance[1] << "\n";

  viewer_->updateGL();
}
<commit_msg>Fix typo.  Much less nans now :P<commit_after>// Copyright (c) 2007, 2008 libmv authors.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.

#include <QMenuBar>
#include <QFileDialog>

#include "libmv/image/array_nd.h"
#include "libmv/image/surf.h"
#include "libmv/image/surf_descriptor.h"
#include "libmv/multiview/focal_from_fundamental.h"
#include "libmv/logging/logging.h"
#include "ui/tvr/main_window.h"

TvrMainWindow::TvrMainWindow(QWidget *parent)
  : QMainWindow(parent) {

  viewer_ = new MatchViewer();
  setCentralWidget(viewer_);

  CreateActions();
  CreateMenus();
}

TvrMainWindow::~TvrMainWindow() {
}

void TvrMainWindow::CreateActions() {
  open_images_action_ = new QAction(tr("&Open Images..."), this);
  open_images_action_->setShortcut(tr("Ctrl+O"));
  open_images_action_->setStatusTip(tr("Open an image pair"));
  connect(open_images_action_, SIGNAL(triggered()),
          this, SLOT(OpenImages()));

  compute_features_action_ = new QAction(tr("&Compute Features"), this);
  compute_features_action_->setStatusTip(tr("Compute Surf Features"));
  connect(compute_features_action_, SIGNAL(triggered()),
          this, SLOT(ComputeFeatures()));

  compute_candidate_matches_action_ =
      new QAction(tr("&Compute Candidate Matches"), this);
  compute_candidate_matches_action_->setStatusTip(
      tr("Compute Candidate Matches"));
  connect(compute_candidate_matches_action_, SIGNAL(triggered()),
          this, SLOT(ComputeCandidateMatches()));

  compute_robust_matches_action_ = new QAction(tr("&Compute Robust Matches"),
                                               this);
  compute_robust_matches_action_->setStatusTip(tr("Compute Robust Matches"));
  connect(compute_robust_matches_action_, SIGNAL(triggered()),
          this, SLOT(ComputeRobustMatches()));

  focal_from_fundamental_action_ = new QAction(tr("&Focal from Fundamental"),
                                               this);
  focal_from_fundamental_action_->setStatusTip(
      tr("Compute Focal Distance from the Fundamental MatrixRobust Matrix"));
  connect(focal_from_fundamental_action_, SIGNAL(triggered()),
          this, SLOT(FocalFromFundamental()));
}

void TvrMainWindow::CreateMenus() {
  file_menu_ = menuBar()->addMenu(tr("&File"));
  file_menu_->addAction(open_images_action_);
  matching_menu_ = menuBar()->addMenu(tr("&Matching"));
  matching_menu_->addAction(compute_features_action_);
  matching_menu_->addAction(compute_candidate_matches_action_);
  matching_menu_->addAction(compute_robust_matches_action_);
  calibration_menu_ = menuBar()->addMenu(tr("&Calibration"));
  calibration_menu_->addAction(focal_from_fundamental_action_);
}

void TvrMainWindow::OpenImages() {
  QStringList filenames = QFileDialog::getOpenFileNames(this,
      "Select Two Images", "", "Image Files (*.png *.jpg *.bmp *.ppm *.pgm *.xpm)");

  // TODO(keir): Don't segfault if != 2 images are selected.
  for (int i = 0; i < 2; ++i) {
    document_.images[i].load(filenames[i]);
  }

  viewer_->SetDocument(&document_);
}

void TvrMainWindow::ComputeFeatures() {
  for (int i = 0; i < 2; ++i) {
    ComputeFeatures(i);
  }
}

void TvrMainWindow::ComputeFeatures(int image_index) {
  QImage &qimage = document_.images[image_index];
  int width = qimage.width(), height = qimage.height();
  SurfFeatureSet &fs = document_.feature_sets[image_index];

  // Convert to gray-scale.
  // TODO(keir): Make a libmv image <-> QImage interop library inside libmv for
  // easy bidirectional exchange of images between Qt and libmv.
  libmv::Array3Df image(height, width, 1);
  for (int y = 0; y < height; ++y) {
    for (int x = 0; x < width; ++x) {
      // TODO(pau): there are better ways to compute intensity.
      //            Implement one and put it on libmv/image.
      int depth = qimage.depth() / 8;
      image(y, x) = 0;
      for (int c = 0; c < depth; ++c) {
        if (c != 3) {  // Skip alpha channel for RGBA.
          image(y, x) = float(qimage.bits()[depth*(y * width + x) + c]);
        }
      }
      image(y, x) /= depth == 4 ? 3 : depth;
    }
  }
  libmv::SurfFeatures(image, 3, 4, &fs.features);

  // Build the kd-tree.
  fs.tree.Build(&fs.features[0], fs.features.size(), 64, 10);

  viewer_->updateGL();
}

void TvrMainWindow::ComputeCandidateMatches() {
  FindCandidateMatches(document_.feature_sets[0],
                       document_.feature_sets[1],
                       &document_.correspondences);
  viewer_->updateGL();
}

void TvrMainWindow::ComputeRobustMatches() {
  libmv::Correspondences new_correspondences;

  ComputeFundamental(document_.correspondences,
                     &document_.F, &new_correspondences);

  // TODO(pau) Make sure this is not copying too many things.  We could
  //           implement an efficient swap for the biparted graph (just swaping
  //           the maps), or remove outlier tracks from the candidate matches
  //           instead of constructing a new correspondance set.
  std::swap(document_.correspondences, new_correspondences);
  viewer_->updateGL();
}

void TvrMainWindow::FocalFromFundamental() {
  libmv::Vec2 p0(document_.images[0].width() / 2.,
                 document_.images[0].height() / 2.);
  libmv::Vec2 p1(document_.images[1].width() / 2.,
                 document_.images[1].height() / 2.);
  libmv::FocalFromFundamental(document_.F, p0, p1,
                              &document_.focal_distance[0],
                              &document_.focal_distance[1]);

  LOG(INFO) << "focal 0: " << document_.focal_distance[0]
            << " focal 1: " << document_.focal_distance[1] << "\n";

  viewer_->updateGL();
}
<|endoftext|>