<commit_before>Bool_t raytracing = kTRUE;

//______________________________________________________________________________
void csgdemo ()
{
   gSystem->Load("libGeom");
   bar = new TControlBar("vertical", "TGeo composite shapes",20,20);
   bar->AddButton("How to run  ","help()","Instructions ");
   bar->AddButton("Union ", "s_union()", "A + B ");
   bar->AddButton("Intersection ", "s_intersection()","A * B ");
   bar->AddButton("Difference ", "s_difference()","A - B ");
	//These two buttons are disabled cause of bugs
	//bar->AddButton("Complex1 ", "complex_1()","(A * B) - C");
	//bar->AddButton("RAY-TRACE ON/OFF","raytrace()","Toggle ray-tracing mode");
   bar->Show();

   gROOT->SaveContext();
}

//______________________________________________________________________________
void MakePicture()
{
	gGeoManager->GetGeomPainter()->SetRaytracing(kFALSE);
	gPad->Modified();
	gPad->Update();
}

void s_union()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Union boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoPgon *pgon = new TGeoPgon("pg",0.,360.,6,2);
   pgon->DefineSection(0,0,0,20);
   pgon->DefineSection(1, 30,0,20);

   TGeoSphere *sph = new TGeoSphere("sph", 40., 45., 5., 175., 0., 340.);
   // define named geometrical transformations with names
   TGeoTranslation *tr = new TGeoTranslation(0., 0., 45.);
   tr->SetName("tr");
   // register all used transformations
   tr->RegisterYourself();
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph:tr + pg");

   TGeoVolume *vol = new TGeoVolume("COMP1",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(100);
   top->Draw();
   MakePicture();

   c->cd(2);
   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);
   pt->SetLineColor(1);
   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");
   text->SetTextColor(2);
   pt->AddText("----- It's an example of boolean union operation : A + B");
   pt->AddText("----- A == part of sphere (5-175, 0-340), B == pgon");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(.044);
   pt->Draw();
   c->cd(1);
}

void s_intersection()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Intersection boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoBBox *box = new TGeoBBox("bx", 40., 40., 40.);
   TGeoSphere *sph = new TGeoSphere("sph", 40., 45.);
   // define named geometrical transformations with names
   TGeoTranslation *tr = new TGeoTranslation(0., 0., 45.);
   tr->SetName("tr");
   // register all used transformations
   tr->RegisterYourself();
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph:tr * bx");

   TGeoVolume *vol = new TGeoVolume("COMP2",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(100);
   top->Draw();
   MakePicture();

   c->cd(2);

   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);

   pt->SetLineColor(1);

   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");

   text->SetTextColor(2);
   pt->AddText("----- Here is an example of boolean intersection operation : A * B");
   pt->AddText("----- A == sphere (with inner radius non-zero), B == box");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);
}

void s_difference()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Difference boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoTorus *tor = new TGeoTorus("tor", 45., 15., 20., 45., 145.);
   TGeoSphere *sph = new TGeoSphere("sph", 20., 45., 0., 180., 0., 270.);
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph - tor");

   TGeoVolume *vol = new TGeoVolume("COMP3",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(60);
   top->Draw();
   MakePicture();

   c->cd(2);

   TPaveText *pt = new TPaveText(.01, .01, .99, .99);

   pt->SetLineColor(1);

   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");

   text->SetTextColor(2);

   pt->AddText("----- It's an example of boolean difference: A - B");
   pt->AddText("----- A == part of sphere (0-180, 0-270), B == partial torus (45-145)");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);
}

void complex_1()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "A * B - C", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoBBox *box = new TGeoBBox("box", 20., 20., 20.);
   TGeoBBox *box1 = new TGeoBBox("box1", 5., 5., 5.);
   TGeoSphere *sph = new TGeoSphere("sph", 5., 25.);
   TGeoSphere *sph1 = new TGeoSphere("sph1", 1., 15.);
   // create the composite shape based on a Boolean expression
   TGeoTranslation *tr = new TGeoTranslation(0., 30., 0.);
   TGeoTranslation *tr1 = new TGeoTranslation(0., 40., 0.);
   TGeoTranslation *tr2 = new TGeoTranslation(0., 30., 0.);
   TGeoTranslation *tr3 = new TGeoTranslation(0., 30., 0.);
   tr->SetName("tr");
   tr1->SetName("tr1");
   tr2->SetName("tr2");
   tr3->SetName("tr3");
   // register all used transformations
   tr->RegisterYourself();
   tr1->RegisterYourself();
   tr2->RegisterYourself();
   tr3->RegisterYourself();

   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "(sph * box) + (sph1:tr - box1:tr1)");

   TGeoVolume *vol = new TGeoVolume("COMP4",cs);
//   vol->SetLineColor(randomColor());
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(80);
   top->Draw();
   MakePicture();

   c->cd(2);
   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);
   pt->SetLineColor(1);
   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");
   text->SetTextColor(2);
   pt->AddText("----- Sphere * box - torus");

   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);

}

//______________________________________________________________________________
void AddText(TPaveText *pave, const char *datamember, Double_t value, const char *comment)
{
   char line[128];
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   memcpy(&line[0], datamember, strlen(datamember));
   line[10] = '=';
   char number[20];
   sprintf(number, "%5.2f", value);
   memcpy(&line[12], number, strlen(number));
   line[26] = '=';
   line[27] = '>';
   sprintf(&line[30], "%s",comment);
   TText *text = pave->AddText(line);
   text->SetTextAlign(12);
}

//______________________________________________________________________________
void AddText(TPaveText *pave, const char *datamember, Int_t value, const char *comment)
{
   char line[128];
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   memcpy(&line[0], datamember, strlen(datamember));
   line[10] = '=';
   char number[20];
   sprintf(number, "%5i", value);
   memcpy(&line[12], number, strlen(number));
   line[26] = '=';
   line[27] = '>';
   sprintf(&line[30], "%s",comment);
   TText *text = pave->AddText(line);
   text->SetTextAlign(12);
}

//______________________________________________________________________________
void AddText(TPaveText *pave, TObject *pf, Int_t iaxis)
{
   char line[128];
   TGeoPatternFinder *finder = (TGeoPatternFinder*)pf;
   if (!pave || !pf) return;
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   TGeoVolume *volume = finder->GetVolume();
   TGeoShape *sh = volume->GetShape();
   sprintf(line, "Division of %s on axis %d (%s)", volume->GetName(), iaxis,sh->GetAxisName(iaxis));
   TText *text = pave->AddText(line);
   text->SetTextColor(3);
   text->SetTextAlign(12);
   AddText(pave, "fNdiv",finder->GetNdiv(),"number of divisions");
   AddText(pave, "fStart",finder->GetStart(),"start divisioning position");
   AddText(pave, "fStep",finder->GetStep(),"division step");
}

//______________________________________________________________________________
void raytrace() {
   if (!gGeoManager) return;

   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();

   if (!painter) return;

   painter->SetRaytracing(raytracing);

   if (!gPad) return;

   gPad->Modified();
   gPad->Update();
}

//______________________________________________________________________________
void help() {
   //

   new TCanvas("chelp","Help to run demos",200,10,700,600);

   welcome = new TPaveText(.1,.8,.9,.97);
   welcome->AddText("Welcome to the new geometry package");
   welcome->SetTextFont(32);
   welcome->SetTextColor(4);
   welcome->SetFillColor(24);
   welcome->Draw();

   hdemo = new TPaveText(.05,.05,.95,.7);
   hdemo->SetTextAlign(12);
   hdemo->SetTextFont(52);
   hdemo->AddText("- Demo for building TGeo compoite shapes");
   hdemo->AddText(" ");
   hdemo->SetAllWith("....","color",2);
   hdemo->SetAllWith("....","font",72);
   hdemo->SetAllWith("....","size",0.03);

   hdemo->Draw();
}

<commit_msg>From Olivier: -fix a typo<commit_after>Bool_t raytracing = kTRUE;

//______________________________________________________________________________
void csgdemo ()
{
   gSystem->Load("libGeom");
   bar = new TControlBar("vertical", "TGeo composite shapes",20,20);
   bar->AddButton("How to run  ","help()","Instructions ");
   bar->AddButton("Union ", "s_union()", "A + B ");
   bar->AddButton("Intersection ", "s_intersection()","A * B ");
   bar->AddButton("Difference ", "s_difference()","A - B ");
	//These two buttons are disabled cause of bugs
	//bar->AddButton("Complex1 ", "complex_1()","(A * B) - C");
	//bar->AddButton("RAY-TRACE ON/OFF","raytrace()","Toggle ray-tracing mode");
   bar->Show();

   gROOT->SaveContext();
}

//______________________________________________________________________________
void MakePicture()
{
	gGeoManager->GetGeomPainter()->SetRaytracing(kFALSE);
	gPad->Modified();
	gPad->Update();
}

void s_union()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Union boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoPgon *pgon = new TGeoPgon("pg",0.,360.,6,2);
   pgon->DefineSection(0,0,0,20);
   pgon->DefineSection(1, 30,0,20);

   TGeoSphere *sph = new TGeoSphere("sph", 40., 45., 5., 175., 0., 340.);
   // define named geometrical transformations with names
   TGeoTranslation *tr = new TGeoTranslation(0., 0., 45.);
   tr->SetName("tr");
   // register all used transformations
   tr->RegisterYourself();
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph:tr + pg");

   TGeoVolume *vol = new TGeoVolume("COMP1",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(100);
   top->Draw();
   MakePicture();

   c->cd(2);
   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);
   pt->SetLineColor(1);
   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");
   text->SetTextColor(2);
   pt->AddText("----- It's an example of boolean union operation : A + B");
   pt->AddText("----- A == part of sphere (5-175, 0-340), B == pgon");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(.044);
   pt->Draw();
   c->cd(1);
}

void s_intersection()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Intersection boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoBBox *box = new TGeoBBox("bx", 40., 40., 40.);
   TGeoSphere *sph = new TGeoSphere("sph", 40., 45.);
   // define named geometrical transformations with names
   TGeoTranslation *tr = new TGeoTranslation(0., 0., 45.);
   tr->SetName("tr");
   // register all used transformations
   tr->RegisterYourself();
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph:tr * bx");

   TGeoVolume *vol = new TGeoVolume("COMP2",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(100);
   top->Draw();
   MakePicture();

   c->cd(2);

   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);

   pt->SetLineColor(1);

   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");

   text->SetTextColor(2);
   pt->AddText("----- Here is an example of boolean intersection operation : A * B");
   pt->AddText("----- A == sphere (with inner radius non-zero), B == box");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);
}

void s_difference()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "Difference boolean operation", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoTorus *tor = new TGeoTorus("tor", 45., 15., 20., 45., 145.);
   TGeoSphere *sph = new TGeoSphere("sph", 20., 45., 0., 180., 0., 270.);
   // create the composite shape based on a Boolean expression
   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "sph - tor");

   TGeoVolume *vol = new TGeoVolume("COMP3",cs);
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(60);
   top->Draw();
   MakePicture();

   c->cd(2);

   TPaveText *pt = new TPaveText(.01, .01, .99, .99);

   pt->SetLineColor(1);

   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");

   text->SetTextColor(2);

   pt->AddText("----- It's an example of boolean difference: A - B");
   pt->AddText("----- A == part of sphere (0-180, 0-270), B == partial torus (45-145)");
   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);
}

void complex_1()
{
   gROOT->GetListOfCanvases()->Delete();
   TCanvas *c = new TCanvas("composite shape", "A * B - C", 700, 1000);

   c->Divide(1,2,0,0);
   c->cd(2);
   gPad->SetPad(0,0,1,0.4);
   c->cd(1);
   gPad->SetPad(0,0.4,1,1);

   if (gGeoManager) delete gGeoManager;

   new TGeoManager("xtru", "poza12");
   TGeoMaterial *mat = new TGeoMaterial("Al", 26.98,13,2.7);
   TGeoMedium *med = new TGeoMedium("MED",1,mat);
   TGeoVolume *top = gGeoManager->MakeBox("TOP",med,100,100,100);
   gGeoManager->SetTopVolume(top);

   // define shape components with names
   TGeoBBox *box = new TGeoBBox("box", 20., 20., 20.);
   TGeoBBox *box1 = new TGeoBBox("box1", 5., 5., 5.);
   TGeoSphere *sph = new TGeoSphere("sph", 5., 25.);
   TGeoSphere *sph1 = new TGeoSphere("sph1", 1., 15.);
   // create the composite shape based on a Boolean expression
   TGeoTranslation *tr = new TGeoTranslation(0., 30., 0.);
   TGeoTranslation *tr1 = new TGeoTranslation(0., 40., 0.);
   TGeoTranslation *tr2 = new TGeoTranslation(0., 30., 0.);
   TGeoTranslation *tr3 = new TGeoTranslation(0., 30., 0.);
   tr->SetName("tr");
   tr1->SetName("tr1");
   tr2->SetName("tr2");
   tr3->SetName("tr3");
   // register all used transformations
   tr->RegisterYourself();
   tr1->RegisterYourself();
   tr2->RegisterYourself();
   tr3->RegisterYourself();

   TGeoCompositeShape *cs = new TGeoCompositeShape("mir", "(sph * box) + (sph1:tr - box1:tr1)");

   TGeoVolume *vol = new TGeoVolume("COMP4",cs);
//   vol->SetLineColor(randomColor());
   top->AddNode(vol,1);
   gGeoManager->CloseGeometry();
   gGeoManager->SetNsegments(80);
   top->Draw();
   MakePicture();

   c->cd(2);
   TPaveText *pt = new TPaveText(0.01,0.01,0.99,0.99);
   pt->SetLineColor(1);
   TText *text = pt->AddText("TGeoCompositeShape - composite shape class");
   text->SetTextColor(2);
   pt->AddText("----- Sphere * box - torus");

   pt->AddText(" ");
   pt->SetAllWith("-----","color",4);
   pt->SetAllWith("-----","font",72);
   pt->SetAllWith("-----","size",0.04);
   pt->SetTextAlign(12);
   pt->SetTextSize(0.044);
   pt->Draw();
   c->cd(1);

}

//______________________________________________________________________________
void AddText(TPaveText *pave, const char *datamember, Double_t value, const char *comment)
{
   char line[128];
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   memcpy(&line[0], datamember, strlen(datamember));
   line[10] = '=';
   char number[20];
   sprintf(number, "%5.2f", value);
   memcpy(&line[12], number, strlen(number));
   line[26] = '=';
   line[27] = '>';
   sprintf(&line[30], "%s",comment);
   TText *text = pave->AddText(line);
   text->SetTextAlign(12);
}

//______________________________________________________________________________
void AddText(TPaveText *pave, const char *datamember, Int_t value, const char *comment)
{
   char line[128];
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   memcpy(&line[0], datamember, strlen(datamember));
   line[10] = '=';
   char number[20];
   sprintf(number, "%5i", value);
   memcpy(&line[12], number, strlen(number));
   line[26] = '=';
   line[27] = '>';
   sprintf(&line[30], "%s",comment);
   TText *text = pave->AddText(line);
   text->SetTextAlign(12);
}

//______________________________________________________________________________
void AddText(TPaveText *pave, TObject *pf, Int_t iaxis)
{
   char line[128];
   TGeoPatternFinder *finder = (TGeoPatternFinder*)pf;
   if (!pave || !pf) return;
   for (Int_t i=0; i<128; i++) line[i] = ' ';
   TGeoVolume *volume = finder->GetVolume();
   TGeoShape *sh = volume->GetShape();
   sprintf(line, "Division of %s on axis %d (%s)", volume->GetName(), iaxis,sh->GetAxisName(iaxis));
   TText *text = pave->AddText(line);
   text->SetTextColor(3);
   text->SetTextAlign(12);
   AddText(pave, "fNdiv",finder->GetNdiv(),"number of divisions");
   AddText(pave, "fStart",finder->GetStart(),"start divisioning position");
   AddText(pave, "fStep",finder->GetStep(),"division step");
}

//______________________________________________________________________________
void raytrace() {
   if (!gGeoManager) return;

   TVirtualGeoPainter *painter = gGeoManager->GetGeomPainter();

   if (!painter) return;

   painter->SetRaytracing(raytracing);

   if (!gPad) return;

   gPad->Modified();
   gPad->Update();
}

//______________________________________________________________________________
void help() {
   //

   new TCanvas("chelp","Help to run demos",200,10,700,600);

   welcome = new TPaveText(.1,.8,.9,.97);
   welcome->AddText("Welcome to the new geometry package");
   welcome->SetTextFont(32);
   welcome->SetTextColor(4);
   welcome->SetFillColor(24);
   welcome->Draw();

   hdemo = new TPaveText(.05,.05,.95,.7);
   hdemo->SetTextAlign(12);
   hdemo->SetTextFont(52);
   hdemo->AddText("- Demo for building TGeo composite shapes");
   hdemo->AddText(" ");
   hdemo->SetAllWith("....","color",2);
   hdemo->SetAllWith("....","font",72);
   hdemo->SetAllWith("....","size",0.03);

   hdemo->Draw();
}

<|endoftext|>


<commit_before>#include <iostream>
#include <cctype>
#include <chrono>
#include <list>
#include <string.h>

#include "core/Halite.hpp"

bool quiet_output = false, ignore_timeout = false; //Need to be passed to the game.
Halite * my_game; //Is a pointer to avoid problems with assignment, dynamic memory, and default constructors.

int main(int argc, char* args[]) {
	srand(time(NULL)); //For all non-seeded randomness.

	bool watch_game = false, override_names = false; //Extra parameters.

	//Paramters to start up a game.
	bool passed_dimensions = false, passed_seed = false, passed_bot_names = false;
	unsigned short mapWidth, mapHeight;
	unsigned int seed = (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 4294967295); //Using milliseconds to prevent same maps from coming up due to multiple worker servers.
	Networking networking;
	std::vector<std::string> * names = NULL;

	std::list<std::string> sArgs;
	for(int a = 1; a < argc; a++) sArgs.push_back(args[a]);

	for(auto a = sArgs.begin(); a != sArgs.end();) {
		if(*a == "-d") {
			passed_dimensions = true;
			a = sArgs.erase(a);
			try {
				mapWidth = std::stoll(*a);
				a = sArgs.erase(a);
				mapHeight = std::stoll(*a);
				a = sArgs.erase(a);
			}
			catch(...) {
				std::cout << "The dimension parameters were either not present or invalid." << std::endl;
				return EXIT_FAILURE;
			}
		}
		if(*a == "-w") {
			watch_game = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-q") {
			quiet_output = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-o") {
			override_names = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-s") {
			passed_seed = true;
			a = sArgs.erase(a);
			try {
				seed = std::stoll(*a);
				a = sArgs.erase(a);
			}
			catch(...) {
				std::cout << "The seed parameter was either not present or invalid." << std::endl;
				return EXIT_FAILURE;
			}
		}
		else if(*a == "-t") {
			ignore_timeout = true;
			a = sArgs.erase(a);
		}
		else a++;
	}

	if(!passed_dimensions) {
		std::string in;
		std::cout << "Please enter the width of the map: ";
		std::getline(std::cin, in);
		while(true) {
			try{
				mapWidth = std::stoi(in);
				break;
			}
			catch(std::exception e) {
				std::cout << "That isn't a valid input. Please enter a positive integer width of the map: ";
				std::getline(std::cin, in);
			}
		}
		std::cout << "Please enter the height of the map: ";
		std::getline(std::cin, in);
		while(true) {
			try{
				mapHeight = std::stoi(in);
				break;
			}
			catch(std::exception e) {
				std::cout << "That isn't a valid input. Please enter a positive integer height of the map: ";
				std::getline(std::cin, in);
			}
		}
	}

	if(override_names) {
		if(sArgs.size() < 4 || sArgs.size() % 2 == 0) {
			std::cout << "Invalid player parameters (inferred from #) - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
		try {
			names = new std::vector<std::string>();
			while(!sArgs.empty()) {
				networking.startAndConnectBot(sArgs.front());
				sArgs.pop_front();
				names->push_back(sArgs.front());
				sArgs.pop_front();
			}
		}
		catch(...) {
			std::cout << "Invalid player parameters - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
	}
	else {
		if(sArgs.size() < 2) {
			std::cout << "Invalid player parameters (inferred from #) - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
		try {
			while(!sArgs.empty()) {
				std::cout << sArgs.front() << std::endl;
				networking.startAndConnectBot(sArgs.front());
				sArgs.pop_front();
			}
		}
		catch(...) {
			std::cout << "Invalid  playerparameters - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
	}

	//Create game. Null parameters will be ignored.
	my_game = new Halite(mapWidth, mapHeight, seed, networking, names);

	std::string filename = "Replays/" + std::to_string(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock().now().time_since_epoch()).count()) + ".hlt";

	GameStatistics stats = my_game->runGame();

	try{
		my_game->output(filename);
	}
	catch(std::runtime_error & e) {
		filename = filename.substr(8);
		if(!quiet_output) {
			std::cout << "Map seed is " << seed << std::endl << "Opening a file at " << filename << std::endl;
		}
		my_game->output(filename);
	}

	std::string victoryOut;
	if(quiet_output) {
		std::cout << filename << ' ' << seed << std::endl << stats;
	}
	else {
		for(unsigned int a = 0; a < stats.player_statistics.size(); a++) std::cout << "Player #" << stats.player_statistics[a].tag << ", " << my_game->getName(stats.player_statistics[a].tag) << ", came in rank #" << stats.player_statistics[a].rank << "!\n";
	}

	delete my_game;

	if(watch_game) {
#ifdef _WIN32
		std::string command = ".\\visualizer " + filename;
#else
		std::string command = "./visualizer " + filename;
#endif
		system(command.c_str());
	}

	return 0;
}
<commit_msg>Fixed override param<commit_after>#include <iostream>
#include <cctype>
#include <chrono>
#include <list>
#include <string.h>

#include "core/Halite.hpp"

bool quiet_output = false, ignore_timeout = false; //Need to be passed to the game.
Halite * my_game; //Is a pointer to avoid problems with assignment, dynamic memory, and default constructors.

int main(int argc, char* args[]) {
	srand(time(NULL)); //For all non-seeded randomness.

	bool watch_game = false, override_names = false; //Extra parameters.

	//Paramters to start up a game.
	bool passed_dimensions = false, passed_seed = false, passed_bot_names = false;
	unsigned short mapWidth, mapHeight;
	unsigned int seed = (std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::system_clock::now().time_since_epoch()).count() % 4294967295); //Using milliseconds to prevent same maps from coming up due to multiple worker servers.
	Networking networking;
	std::vector<std::string> * names = NULL;

	std::list<std::string> sArgs;
	for(int a = 1; a < argc; a++) sArgs.push_back(args[a]);

	for(auto a = sArgs.begin(); a != sArgs.end();) {
		if(*a == "-d") {
			passed_dimensions = true;
			a = sArgs.erase(a);
			try {
				mapWidth = std::stoll(*a);
				a = sArgs.erase(a);
				mapHeight = std::stoll(*a);
				a = sArgs.erase(a);
			}
			catch(...) {
				std::cout << "The dimension parameters were either not present or invalid." << std::endl;
				return EXIT_FAILURE;
			}
		}
		if(*a == "-w") {
			watch_game = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-q") {
			quiet_output = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-o") {
			override_names = true;
			a = sArgs.erase(a);
		}
		else if(*a == "-s") {
			passed_seed = true;
			a = sArgs.erase(a);
			try {
				seed = std::stoll(*a);
				a = sArgs.erase(a);
			}
			catch(...) {
				std::cout << "The seed parameter was either not present or invalid." << std::endl;
				return EXIT_FAILURE;
			}
		}
		else if(*a == "-t") {
			ignore_timeout = true;
			a = sArgs.erase(a);
		}
		else a++;
	}

	if(!passed_dimensions) {
		std::string in;
		std::cout << "Please enter the width of the map: ";
		std::getline(std::cin, in);
		while(true) {
			try{
				mapWidth = std::stoi(in);
				break;
			}
			catch(std::exception e) {
				std::cout << "That isn't a valid input. Please enter a positive integer width of the map: ";
				std::getline(std::cin, in);
			}
		}
		std::cout << "Please enter the height of the map: ";
		std::getline(std::cin, in);
		while(true) {
			try{
				mapHeight = std::stoi(in);
				break;
			}
			catch(std::exception e) {
				std::cout << "That isn't a valid input. Please enter a positive integer height of the map: ";
				std::getline(std::cin, in);
			}
		}
	}

	if(override_names) {
		if(sArgs.size() < 4 || sArgs.size() % 2 != 0) {
			std::cout << "Invalid player parameters (inferred from #) - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
		try {
			names = new std::vector<std::string>();
			while(!sArgs.empty()) {
				networking.startAndConnectBot(sArgs.front());
				sArgs.pop_front();
				names->push_back(sArgs.front());
				sArgs.pop_front();
			}
		}
		catch(...) {
			std::cout << "Invalid player parameters - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
	}
	else {
		if(sArgs.size() < 2) {
			std::cout << "Invalid player parameters (inferred from #) - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
		try {
			while(!sArgs.empty()) {
				std::cout << sArgs.front() << std::endl;
				networking.startAndConnectBot(sArgs.front());
				sArgs.pop_front();
			}
		}
		catch(...) {
			std::cout << "Invalid  playerparameters - couldn't start game." << std::endl;
			return EXIT_FAILURE;
		}
	}

	//Create game. Null parameters will be ignored.
	my_game = new Halite(mapWidth, mapHeight, seed, networking, names);

	std::string filename = "Replays/" + std::to_string(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::high_resolution_clock().now().time_since_epoch()).count()) + ".hlt";

	GameStatistics stats = my_game->runGame();

	try{
		my_game->output(filename);
	}
	catch(std::runtime_error & e) {
		filename = filename.substr(8);
		if(!quiet_output) {
			std::cout << "Map seed is " << seed << std::endl << "Opening a file at " << filename << std::endl;
		}
		my_game->output(filename);
	}

	std::string victoryOut;
	if(quiet_output) {
		std::cout << filename << ' ' << seed << std::endl << stats;
	}
	else {
		for(unsigned int a = 0; a < stats.player_statistics.size(); a++) std::cout << "Player #" << stats.player_statistics[a].tag << ", " << my_game->getName(stats.player_statistics[a].tag) << ", came in rank #" << stats.player_statistics[a].rank << "!\n";
	}

	delete my_game;

	if(watch_game) {
#ifdef _WIN32
		std::string command = ".\\visualizer " + filename;
#else
		std::string command = "./visualizer " + filename;
#endif
		system(command.c_str());
	}

	return 0;
}
<|endoftext|>


<commit_before>/*
 * Copyright (C) 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "assoctree.h"
#include <QDebug>

/// Dumps a QVariant into a multi-line string for debugging purposes.
QString AssocTree::dump(int level) const
{
    QString s;
    for (int i = 0; i < level; i++)
        s += "  ";

    if (type() == QVariant::String)
        s += toString() + "\n";
    else if (type() == QVariant::List) {
        s += "[\n";

        foreach(QVariant v, toList())
            s += AssocTree(v).dump(level + 1);

        for (int i = 0; i < level; i++)
            s += "  ";

        s += "]\n";
    }

    return s;
}

/// Returns the name of this association tree.
QString AssocTree::name() const
{
    if (type() == QVariant::String)
        return toString();

    if (type() != QVariant::List
        || toList().size() < 1)
        return QString();

    return toList().at(0).toString();
}

/// Returns the sub-tree with the given name
AssocTree AssocTree::node(const QString &name) const
{
    const QVariant nameVariant(name); // So we can directly compare...

    if (type() != QVariant::List)
        return AssocTree();

    foreach(const QVariant &child, toList())
    {
        if (child.type() == QVariant::List
            && child.toList().count() >= 1
            && child.toList().at(0) == nameVariant)
            return AssocTree(child);
    }

    return AssocTree();
}

/// Returns the sub-tree named \a name2 of the sub-tree named \a name1
AssocTree AssocTree::node(const QString &name1,
                          const QString &name2) const
{
    return node(name1).node(name2);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3) const
{
    return node(name1).node(name2).node(name3);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4) const
{
    return node(name1).node(name2).node(name3),node(name4);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4,
                          const QString &name5) const
{
    return node(name1).node(name2).node(name3),node(name4).node(name5);
}

/// Returns the value of this tree.
QVariant AssocTree::value() const
{
    if (type() != QVariant::List)
        return QVariant();

    if (toList().size() < 2)
        return QVariant();

    return toList().at(1);
}

/// Returns the value of the sub-tree named name1.
QVariant AssocTree::value(const QString &name1) const
{
    return node(name1).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2) const
{
    return node(name1, name2).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3) const
{
    return node(name1, name2, name3).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4) const
{
    return node(name1, name2, name3, name4).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4,
                          const QString &name5) const
{
    return node(name1, name2, name3, name4, name5).value();
}

/// Returns a list of all sub-trees.
const QVariantList AssocTree::nodes() const
{
    if (type() == QVariant::List)
        return toList().mid(1);
    else
        return QVariantList();
}
<commit_msg>desktop types: Fixing unintentional commas in assoc tree.<commit_after>/*
 * Copyright (C) 2009 Nokia Corporation.
 *
 * Contact: Marius Vollmer <marius.vollmer@nokia.com>
 *
 * 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., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

#include "assoctree.h"
#include <QDebug>

/// Dumps a QVariant into a multi-line string for debugging purposes.
QString AssocTree::dump(int level) const
{
    QString s;
    for (int i = 0; i < level; i++)
        s += "  ";

    if (type() == QVariant::String)
        s += toString() + "\n";
    else if (type() == QVariant::List) {
        s += "[\n";

        foreach(QVariant v, toList())
            s += AssocTree(v).dump(level + 1);

        for (int i = 0; i < level; i++)
            s += "  ";

        s += "]\n";
    }

    return s;
}

/// Returns the name of this association tree.
QString AssocTree::name() const
{
    if (type() == QVariant::String)
        return toString();

    if (type() != QVariant::List
        || toList().size() < 1)
        return QString();

    return toList().at(0).toString();
}

/// Returns the sub-tree with the given name
AssocTree AssocTree::node(const QString &name) const
{
    const QVariant nameVariant(name); // So we can directly compare...

    if (type() != QVariant::List)
        return AssocTree();

    foreach(const QVariant &child, toList())
    {
        if (child.type() == QVariant::List
            && child.toList().count() >= 1
            && child.toList().at(0) == nameVariant)
            return AssocTree(child);
    }

    return AssocTree();
}

/// Returns the sub-tree named \a name2 of the sub-tree named \a name1
AssocTree AssocTree::node(const QString &name1,
                          const QString &name2) const
{
    return node(name1).node(name2);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3) const
{
    return node(name1).node(name2).node(name3);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4) const
{
    return node(name1).node(name2).node(name3).node(name4);
}

AssocTree AssocTree::node(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4,
                          const QString &name5) const
{
    return node(name1).node(name2).node(name3).node(name4).node(name5);
}

/// Returns the value of this tree.
QVariant AssocTree::value() const
{
    if (type() != QVariant::List)
        return QVariant();

    if (toList().size() < 2)
        return QVariant();

    return toList().at(1);
}

/// Returns the value of the sub-tree named name1.
QVariant AssocTree::value(const QString &name1) const
{
    return node(name1).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2) const
{
    return node(name1, name2).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3) const
{
    return node(name1, name2, name3).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4) const
{
    return node(name1, name2, name3, name4).value();
}

QVariant AssocTree::value(const QString &name1,
                          const QString &name2,
                          const QString &name3,
                          const QString &name4,
                          const QString &name5) const
{
    return node(name1, name2, name3, name4, name5).value();
}

/// Returns a list of all sub-trees.
const QVariantList AssocTree::nodes() const
{
    if (type() == QVariant::List)
        return toList().mid(1);
    else
        return QVariantList();
}
<|endoftext|>


<commit_before>/*
 * Copyright (c) 2015-2018 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * 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 <graphene/chain/database.hpp>
#include <graphene/chain/proposal_evaluator.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/hardfork.hpp>

namespace graphene { namespace chain {

struct proposal_operation_hardfork_visitor
{
   typedef void result_type;
   const fc::time_point_sec &block_time;

   proposal_operation_hardfork_visitor(const fc::time_point_sec t) : block_time(t) {}

   template<typename T>
   void operator()(const T &v) const {}

   // hf_620
   void operator()(const graphene::chain::asset_create_operation &v) const {
      if (block_time < HARDFORK_CORE_620_TIME) {
         static const std::locale &loc = std::locale::classic();
         FC_ASSERT(isalpha(v.symbol.back(), loc), "Asset ${s} must end with alpha character before hardfork 620", ("s", v.symbol));
      }
   }
   // hf_199
   void operator()(const graphene::chain::asset_update_issuer_operation &v) const {
      if (block_time < HARDFORK_CORE_199_TIME) {
         FC_ASSERT(false, "Not allowed until hardfork 199");
      }
   }
   // hf_188
   void operator()(const graphene::chain::asset_claim_pool_operation &v) const {
      if (block_time < HARDFORK_CORE_188_TIME) {
         FC_ASSERT(false, "Not allowed until hardfork 188");
      }
   }
   // hf_588
   // issue #588
   //
   // As a virtual operation which has no evaluator `asset_settle_cancel_operation`
   // originally won't be packed into blocks, yet its loose `validate()` method
   // make it able to slip into blocks.
   //
   // We need to forbid this operation being packed into blocks via proposal but
   // this will lead to a hardfork (this operation in proposal will denied by new
   // node while accept by old node), so a hardfork guard code needed and a
   // consensus upgrade over all nodes needed in future. And because the
   // `validate()` method not suitable to check database status, so we put the
   // code here.
   //
   // After the hardfork, all nodes will deny packing this operation into a block,
   // and then we will check whether exists a proposal containing this kind of
   // operation, if not exists, we can harden the `validate()` method to deny
   // it in a earlier stage.
   //
   void operator()(const graphene::chain::asset_settle_cancel_operation &v) const {
      if (block_time > HARDFORK_CORE_588_TIME) {
         FC_ASSERT(!"Virtual operation");
      }
   }
   // loop and self visit in proposals
   void operator()(const graphene::chain::proposal_create_operation &v) const {
      for (const op_wrapper &op : v.proposed_ops)
         op.op.visit(*this);
   }
};

void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
   const database& d = db();
   const auto& global_parameters = d.get_global_properties().parameters;

   FC_ASSERT( o.expiration_time > d.head_block_time(), "Proposal has already expired on creation." );
   FC_ASSERT( o.expiration_time <= d.head_block_time() + global_parameters.maximum_proposal_lifetime,
              "Proposal expiration time is too far in the future.");
   FC_ASSERT( !o.review_period_seconds || fc::seconds(*o.review_period_seconds) < (o.expiration_time - d.head_block_time()),
              "Proposal review period must be less than its overall lifetime." );

   {
      // If we're dealing with the committee authority, make sure this transaction has a sufficient review period.
      flat_set<account_id_type> auths;
      vector<authority> other;
      for( auto& op : o.proposed_ops )
      {
         operation_get_required_authorities(op.op, auths, auths, other);
      }

      FC_ASSERT( other.size() == 0 ); // TODO: what about other???

      if( auths.find(GRAPHENE_COMMITTEE_ACCOUNT) != auths.end() )
      {
         GRAPHENE_ASSERT(
            o.review_period_seconds.valid(),
            proposal_create_review_period_required,
            "Review period not given, but at least ${min} required",
            ("min", global_parameters.committee_proposal_review_period)
         );
         GRAPHENE_ASSERT(
            *o.review_period_seconds >= global_parameters.committee_proposal_review_period,
            proposal_create_review_period_insufficient,
            "Review period of ${t} specified, but at least ${min} required",
            ("t", *o.review_period_seconds)
            ("min", global_parameters.committee_proposal_review_period)
         );
      }
   }

   for( const op_wrapper& op : o.proposed_ops )
      _proposed_trx.operations.push_back(op.op);

   _proposed_trx.validate();

   // Calling the proposal hardfork visitor
   const fc::time_point_sec& block_time = d.head_block_time();
   proposal_operation_hardfork_visitor vtor(block_time);
   vtor( o );

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

object_id_type proposal_create_evaluator::do_apply(const proposal_create_operation& o)
{ try {
   database& d = db();

   const proposal_object& proposal = d.create<proposal_object>([&](proposal_object& proposal) {
      _proposed_trx.expiration = o.expiration_time;
      proposal.proposed_transaction = _proposed_trx;
      proposal.expiration_time = o.expiration_time;
      proposal.proposer = o.fee_paying_account;
      if( o.review_period_seconds )
         proposal.review_period_time = o.expiration_time - *o.review_period_seconds;

      //Populate the required approval sets
      flat_set<account_id_type> required_active;
      vector<authority> other;

      // TODO: consider caching values from evaluate?
      for( auto& op : _proposed_trx.operations )
         operation_get_required_authorities(op, required_active, proposal.required_owner_approvals, other);

      //All accounts which must provide both owner and active authority should be omitted from the active authority set;
      //owner authority approval implies active authority approval.
      std::set_difference(required_active.begin(), required_active.end(),
                          proposal.required_owner_approvals.begin(), proposal.required_owner_approvals.end(),
                          std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin()));
   });

   return proposal.id;
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_update_evaluator::do_evaluate(const proposal_update_operation& o)
{ try {
   database& d = db();

   _proposal = &o.proposal(d);

   if( _proposal->review_period_time && d.head_block_time() >= *_proposal->review_period_time )
      FC_ASSERT( o.active_approvals_to_add.empty() && o.owner_approvals_to_add.empty(),
                 "This proposal is in its review period. No new approvals may be added." );

   for( account_id_type id : o.active_approvals_to_remove )
   {
      FC_ASSERT( _proposal->available_active_approvals.find(id) != _proposal->available_active_approvals.end(),
                 "", ("id", id)("available", _proposal->available_active_approvals) );
   }
   for( account_id_type id : o.owner_approvals_to_remove )
   {
      FC_ASSERT( _proposal->available_owner_approvals.find(id) != _proposal->available_owner_approvals.end(),
                 "", ("id", id)("available", _proposal->available_owner_approvals) );
   }

   /*  All authority checks happen outside of evaluators
   if( (d.get_node_properties().skip_flags & database::skip_authority_check) == 0 )
   {
      for( const auto& id : o.key_approvals_to_add )
      {
         FC_ASSERT( trx_state->signed_by(id) );
      }
      for( const auto& id : o.key_approvals_to_remove )
      {
         FC_ASSERT( trx_state->signed_by(id) );
      }
   }
   */

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_update_evaluator::do_apply(const proposal_update_operation& o)
{ try {
   database& d = db();

   // Potential optimization: if _executed_proposal is true, we can skip the modify step and make push_proposal skip
   // signature checks. This isn't done now because I just wrote all the proposals code, and I'm not yet 100% sure the
   // required approvals are sufficient to authorize the transaction.
   d.modify(*_proposal, [&o, &d](proposal_object& p) {
      p.available_active_approvals.insert(o.active_approvals_to_add.begin(), o.active_approvals_to_add.end());
      p.available_owner_approvals.insert(o.owner_approvals_to_add.begin(), o.owner_approvals_to_add.end());
      for( account_id_type id : o.active_approvals_to_remove )
         p.available_active_approvals.erase(id);
      for( account_id_type id : o.owner_approvals_to_remove )
         p.available_owner_approvals.erase(id);
      for( const auto& id : o.key_approvals_to_add )
         p.available_key_approvals.insert(id);
      for( const auto& id : o.key_approvals_to_remove )
         p.available_key_approvals.erase(id);
   });

   // If the proposal has a review period, don't bother attempting to authorize/execute it.
   // Proposals with a review period may never be executed except at their expiration.
   if( _proposal->review_period_time )
      return void_result();

   if( _proposal->is_authorized_to_execute(d) )
   {
      // All required approvals are satisfied. Execute!
      _executed_proposal = true;
      try {
         _processed_transaction = d.push_proposal(*_proposal);
      } catch(fc::exception& e) {
         wlog("Proposed transaction ${id} failed to apply once approved with exception:\n----\n${reason}\n----\nWill try again when it expires.",
              ("id", o.proposal)("reason", e.to_detail_string()));
         _proposal_failed = true;
      }
   }

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_delete_evaluator::do_evaluate(const proposal_delete_operation& o)
{ try {
   database& d = db();

   _proposal = &o.proposal(d);

   auto required_approvals = o.using_owner_authority? &_proposal->required_owner_approvals
                                                    : &_proposal->required_active_approvals;
   FC_ASSERT( required_approvals->find(o.fee_paying_account) != required_approvals->end(),
              "Provided authority is not authoritative for this proposal.",
              ("provided", o.fee_paying_account)("required", *required_approvals));

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_delete_evaluator::do_apply(const proposal_delete_operation& o)
{ try {
   db().remove(*_proposal);

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

} } // graphene::chain
<commit_msg>move hf visitor to first check of evaluator<commit_after>/*
 * Copyright (c) 2015-2018 Cryptonomex, Inc., and contributors.
 *
 * The MIT License
 *
 * 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 <graphene/chain/database.hpp>
#include <graphene/chain/proposal_evaluator.hpp>
#include <graphene/chain/proposal_object.hpp>
#include <graphene/chain/hardfork.hpp>

namespace graphene { namespace chain {

struct proposal_operation_hardfork_visitor
{
   typedef void result_type;
   const fc::time_point_sec &block_time;

   proposal_operation_hardfork_visitor(const fc::time_point_sec t) : block_time(t) {}

   template<typename T>
   void operator()(const T &v) const {}

   // hf_620
   void operator()(const graphene::chain::asset_create_operation &v) const {
      if (block_time < HARDFORK_CORE_620_TIME) {
         static const std::locale &loc = std::locale::classic();
         FC_ASSERT(isalpha(v.symbol.back(), loc), "Asset ${s} must end with alpha character before hardfork 620", ("s", v.symbol));
      }
   }
   // hf_199
   void operator()(const graphene::chain::asset_update_issuer_operation &v) const {
      if (block_time < HARDFORK_CORE_199_TIME) {
         FC_ASSERT(false, "Not allowed until hardfork 199");
      }
   }
   // hf_188
   void operator()(const graphene::chain::asset_claim_pool_operation &v) const {
      if (block_time < HARDFORK_CORE_188_TIME) {
         FC_ASSERT(false, "Not allowed until hardfork 188");
      }
   }
   // hf_588
   // issue #588
   //
   // As a virtual operation which has no evaluator `asset_settle_cancel_operation`
   // originally won't be packed into blocks, yet its loose `validate()` method
   // make it able to slip into blocks.
   //
   // We need to forbid this operation being packed into blocks via proposal but
   // this will lead to a hardfork (this operation in proposal will denied by new
   // node while accept by old node), so a hardfork guard code needed and a
   // consensus upgrade over all nodes needed in future. And because the
   // `validate()` method not suitable to check database status, so we put the
   // code here.
   //
   // After the hardfork, all nodes will deny packing this operation into a block,
   // and then we will check whether exists a proposal containing this kind of
   // operation, if not exists, we can harden the `validate()` method to deny
   // it in a earlier stage.
   //
   void operator()(const graphene::chain::asset_settle_cancel_operation &v) const {
      if (block_time > HARDFORK_CORE_588_TIME) {
         FC_ASSERT(!"Virtual operation");
      }
   }
   // loop and self visit in proposals
   void operator()(const graphene::chain::proposal_create_operation &v) const {
      for (const op_wrapper &op : v.proposed_ops)
         op.op.visit(*this);
   }
};

void_result proposal_create_evaluator::do_evaluate(const proposal_create_operation& o)
{ try {
   const database& d = db();

   // Calling the proposal hardfork visitor
   const fc::time_point_sec& block_time = d.head_block_time();
   proposal_operation_hardfork_visitor vtor(block_time);
   vtor( o );

   const auto& global_parameters = d.get_global_properties().parameters;

   FC_ASSERT( o.expiration_time > d.head_block_time(), "Proposal has already expired on creation." );
   FC_ASSERT( o.expiration_time <= d.head_block_time() + global_parameters.maximum_proposal_lifetime,
              "Proposal expiration time is too far in the future.");
   FC_ASSERT( !o.review_period_seconds || fc::seconds(*o.review_period_seconds) < (o.expiration_time - d.head_block_time()),
              "Proposal review period must be less than its overall lifetime." );

   {
      // If we're dealing with the committee authority, make sure this transaction has a sufficient review period.
      flat_set<account_id_type> auths;
      vector<authority> other;
      for( auto& op : o.proposed_ops )
      {
         operation_get_required_authorities(op.op, auths, auths, other);
      }

      FC_ASSERT( other.size() == 0 ); // TODO: what about other???

      if( auths.find(GRAPHENE_COMMITTEE_ACCOUNT) != auths.end() )
      {
         GRAPHENE_ASSERT(
            o.review_period_seconds.valid(),
            proposal_create_review_period_required,
            "Review period not given, but at least ${min} required",
            ("min", global_parameters.committee_proposal_review_period)
         );
         GRAPHENE_ASSERT(
            *o.review_period_seconds >= global_parameters.committee_proposal_review_period,
            proposal_create_review_period_insufficient,
            "Review period of ${t} specified, but at least ${min} required",
            ("t", *o.review_period_seconds)
            ("min", global_parameters.committee_proposal_review_period)
         );
      }
   }

   for( const op_wrapper& op : o.proposed_ops )
      _proposed_trx.operations.push_back(op.op);

   _proposed_trx.validate();

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

object_id_type proposal_create_evaluator::do_apply(const proposal_create_operation& o)
{ try {
   database& d = db();

   const proposal_object& proposal = d.create<proposal_object>([&](proposal_object& proposal) {
      _proposed_trx.expiration = o.expiration_time;
      proposal.proposed_transaction = _proposed_trx;
      proposal.expiration_time = o.expiration_time;
      proposal.proposer = o.fee_paying_account;
      if( o.review_period_seconds )
         proposal.review_period_time = o.expiration_time - *o.review_period_seconds;

      //Populate the required approval sets
      flat_set<account_id_type> required_active;
      vector<authority> other;

      // TODO: consider caching values from evaluate?
      for( auto& op : _proposed_trx.operations )
         operation_get_required_authorities(op, required_active, proposal.required_owner_approvals, other);

      //All accounts which must provide both owner and active authority should be omitted from the active authority set;
      //owner authority approval implies active authority approval.
      std::set_difference(required_active.begin(), required_active.end(),
                          proposal.required_owner_approvals.begin(), proposal.required_owner_approvals.end(),
                          std::inserter(proposal.required_active_approvals, proposal.required_active_approvals.begin()));
   });

   return proposal.id;
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_update_evaluator::do_evaluate(const proposal_update_operation& o)
{ try {
   database& d = db();

   _proposal = &o.proposal(d);

   if( _proposal->review_period_time && d.head_block_time() >= *_proposal->review_period_time )
      FC_ASSERT( o.active_approvals_to_add.empty() && o.owner_approvals_to_add.empty(),
                 "This proposal is in its review period. No new approvals may be added." );

   for( account_id_type id : o.active_approvals_to_remove )
   {
      FC_ASSERT( _proposal->available_active_approvals.find(id) != _proposal->available_active_approvals.end(),
                 "", ("id", id)("available", _proposal->available_active_approvals) );
   }
   for( account_id_type id : o.owner_approvals_to_remove )
   {
      FC_ASSERT( _proposal->available_owner_approvals.find(id) != _proposal->available_owner_approvals.end(),
                 "", ("id", id)("available", _proposal->available_owner_approvals) );
   }

   /*  All authority checks happen outside of evaluators
   if( (d.get_node_properties().skip_flags & database::skip_authority_check) == 0 )
   {
      for( const auto& id : o.key_approvals_to_add )
      {
         FC_ASSERT( trx_state->signed_by(id) );
      }
      for( const auto& id : o.key_approvals_to_remove )
      {
         FC_ASSERT( trx_state->signed_by(id) );
      }
   }
   */

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_update_evaluator::do_apply(const proposal_update_operation& o)
{ try {
   database& d = db();

   // Potential optimization: if _executed_proposal is true, we can skip the modify step and make push_proposal skip
   // signature checks. This isn't done now because I just wrote all the proposals code, and I'm not yet 100% sure the
   // required approvals are sufficient to authorize the transaction.
   d.modify(*_proposal, [&o, &d](proposal_object& p) {
      p.available_active_approvals.insert(o.active_approvals_to_add.begin(), o.active_approvals_to_add.end());
      p.available_owner_approvals.insert(o.owner_approvals_to_add.begin(), o.owner_approvals_to_add.end());
      for( account_id_type id : o.active_approvals_to_remove )
         p.available_active_approvals.erase(id);
      for( account_id_type id : o.owner_approvals_to_remove )
         p.available_owner_approvals.erase(id);
      for( const auto& id : o.key_approvals_to_add )
         p.available_key_approvals.insert(id);
      for( const auto& id : o.key_approvals_to_remove )
         p.available_key_approvals.erase(id);
   });

   // If the proposal has a review period, don't bother attempting to authorize/execute it.
   // Proposals with a review period may never be executed except at their expiration.
   if( _proposal->review_period_time )
      return void_result();

   if( _proposal->is_authorized_to_execute(d) )
   {
      // All required approvals are satisfied. Execute!
      _executed_proposal = true;
      try {
         _processed_transaction = d.push_proposal(*_proposal);
      } catch(fc::exception& e) {
         wlog("Proposed transaction ${id} failed to apply once approved with exception:\n----\n${reason}\n----\nWill try again when it expires.",
              ("id", o.proposal)("reason", e.to_detail_string()));
         _proposal_failed = true;
      }
   }

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_delete_evaluator::do_evaluate(const proposal_delete_operation& o)
{ try {
   database& d = db();

   _proposal = &o.proposal(d);

   auto required_approvals = o.using_owner_authority? &_proposal->required_owner_approvals
                                                    : &_proposal->required_active_approvals;
   FC_ASSERT( required_approvals->find(o.fee_paying_account) != required_approvals->end(),
              "Provided authority is not authoritative for this proposal.",
              ("provided", o.fee_paying_account)("required", *required_approvals));

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

void_result proposal_delete_evaluator::do_apply(const proposal_delete_operation& o)
{ try {
   db().remove(*_proposal);

   return void_result();
} FC_CAPTURE_AND_RETHROW( (o) ) }

} } // graphene::chain
<|endoftext|>


<commit_before>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include "vast/detail/fill_status_map.hpp"

#include <caf/config_value.hpp>
#include <caf/downstream_manager.hpp>
#include <caf/inbound_path.hpp>
#include <caf/outbound_path.hpp>
#include <caf/scheduled_actor.hpp>
#include <caf/stream_manager.hpp>

#include "vast/detail/algorithms.hpp"

namespace vast::detail {

void fill_status_map(caf::dictionary<caf::config_value>& xs,
                     caf::stream_manager& mgr) {
  // Manager status.
  put(xs, "idle", mgr.idle());
  put(xs, "congested", mgr.idle());
  // Downstream status.
  auto& out = mgr.out();
  auto& downstream = put_dictionary(xs, "downstream");
  put(downstream, "buffered", out.buffered());
  put(downstream, "max-capacity", out.max_capacity());
  put(downstream, "paths", out.num_paths());
  put(downstream, "stalled", out.stalled());
  put(downstream, "clean", out.stalled());
  out.for_each_path([&](auto& opath) {
    auto name = "slot-" + std::to_string(opath.slots.sender);
    auto& slot = put_dictionary(downstream, name);
    put(slot, "pending", opath.pending());
    put(slot, "clean", opath.clean());
    put(slot, "closing", opath.closing);
    put(slot, "next-batch-id", opath.next_batch_id);
    put(slot, "open-credit", opath.open_credit);
    put(slot, "desired-batch-size", opath.desired_batch_size);
    put(slot, "max-capacity", opath.max_capacity);
  });
  // Upstream status.
  auto& upstream = put_dictionary(xs, "upstream");
  auto& ipaths = mgr.inbound_paths();
  for (auto ipath : ipaths) {
    auto name = "slot-" + std::to_string(ipath->slots.receiver);
    auto& slot = put_dictionary(upstream, name);
    put(slot, "priority", to_string(ipath->prio));
    put(slot, "assigned-credit", ipath->assigned_credit);
    put(slot, "last-acked-batch-id", ipath->last_acked_batch_id);
  }
}

void fill_status_map(caf::dictionary<caf::config_value>& xs,
                     caf::scheduled_actor* self) {
  put(xs, "actor-id", self->id());
  put(xs, "name", self->name());
  put(xs, "mailbox-size", self->mailbox().size());
  size_t counter = 0;
  std::string name;
  for (auto& mgr : unique_values(self->stream_managers())) {
    name = "stream-";
    name += std::to_string(counter++);
    fill_status_map(put_dictionary(xs, name), *mgr);
  }
}

} // namespace vast::detail
<commit_msg>Fix stream manager status inspection<commit_after>/******************************************************************************
 *                    _   _____   __________                                  *
 *                   | | / / _ | / __/_  __/     Visibility                   *
 *                   | |/ / __ |_\ \  / /          Across                     *
 *                   |___/_/ |_/___/ /_/       Space and Time                 *
 *                                                                            *
 * This file is part of VAST. It is subject to the license terms in the       *
 * LICENSE file found in the top-level directory of this distribution and at  *
 * http://vast.io/license. No part of VAST, including this file, may be       *
 * copied, modified, propagated, or distributed except according to the terms *
 * contained in the LICENSE file.                                             *
 ******************************************************************************/

#include "vast/detail/fill_status_map.hpp"

#include <caf/config_value.hpp>
#include <caf/downstream_manager.hpp>
#include <caf/inbound_path.hpp>
#include <caf/outbound_path.hpp>
#include <caf/scheduled_actor.hpp>
#include <caf/stream_manager.hpp>

#include "vast/detail/algorithms.hpp"

namespace vast::detail {

void fill_status_map(caf::dictionary<caf::config_value>& xs,
                     caf::stream_manager& mgr) {
  // Manager status.
  put(xs, "idle", mgr.idle());
  put(xs, "congested", mgr.congested());
  // Downstream status.
  auto& out = mgr.out();
  auto& downstream = put_dictionary(xs, "downstream");
  put(downstream, "buffered", out.buffered());
  put(downstream, "max-capacity", out.max_capacity());
  put(downstream, "paths", out.num_paths());
  put(downstream, "stalled", out.stalled());
  put(downstream, "clean", out.stalled());
  out.for_each_path([&](auto& opath) {
    auto name = "slot-" + std::to_string(opath.slots.sender);
    auto& slot = put_dictionary(downstream, name);
    put(slot, "pending", opath.pending());
    put(slot, "clean", opath.clean());
    put(slot, "closing", opath.closing);
    put(slot, "next-batch-id", opath.next_batch_id);
    put(slot, "open-credit", opath.open_credit);
    put(slot, "desired-batch-size", opath.desired_batch_size);
    put(slot, "max-capacity", opath.max_capacity);
  });
  // Upstream status.
  auto& upstream = put_dictionary(xs, "upstream");
  auto& ipaths = mgr.inbound_paths();
  for (auto ipath : ipaths) {
    auto name = "slot-" + std::to_string(ipath->slots.receiver);
    auto& slot = put_dictionary(upstream, name);
    put(slot, "priority", to_string(ipath->prio));
    put(slot, "assigned-credit", ipath->assigned_credit);
    put(slot, "last-acked-batch-id", ipath->last_acked_batch_id);
  }
}

void fill_status_map(caf::dictionary<caf::config_value>& xs,
                     caf::scheduled_actor* self) {
  put(xs, "actor-id", self->id());
  put(xs, "name", self->name());
  put(xs, "mailbox-size", self->mailbox().size());
  size_t counter = 0;
  std::string name;
  for (auto& mgr : unique_values(self->stream_managers())) {
    name = "stream-";
    name += std::to_string(counter++);
    fill_status_map(put_dictionary(xs, name), *mgr);
  }
}

} // namespace vast::detail
<|endoftext|>


<commit_before>/**
    @file Rigidbody.cpp
    @brief Methods that manages non-passing through elements in game.
    @copyright LGPL. MIT License.
*/

#include "Components/Rigidbody.hpp"
#include "Globals/ComponentTypes.hpp"
#include "Math/Vector.hpp"

#include "Log/log.hpp"

/**
    @brief Initializes RectangleCollider instance.
    @param[in] GameObject *owner - owns the component.
    @param[in] C_PHYSICS - physics component.
*/
Rigidbody::Rigidbody(GameObject *owner) : Component(owner, C_PHYSICS) {}

/**
    @brief Updates the position of a fixed component, based on it velocity.
*/
void Rigidbody::FixedComponentUpdate() {
    // Check for gravity, and if exists, sets its force on a vector.
    if (m_gravity) {
        GetOwner()->AddVelocity(Vector(0, m_gravityForce));
    }
    else {
       // Do nothing
    }

    // Sets the x,y positions in the owner component of the gameobject, according to its velocity.
    auto velocity  = GetOwner()->GetVelocity();
    GetOwner()->GetPosition()->m_x += velocity.m_x;
    GetOwner()->GetPosition()->m_y += velocity.m_y;
}
<commit_msg>Applying assertive in Rigidbody.cpp<commit_after>/**
    @file Rigidbody.cpp
    @brief Methods that manages non-passing through elements in game.
    @copyright LGPL. MIT License.
*/

#include "Components/Rigidbody.hpp"
#include "Globals/ComponentTypes.hpp"
#include "Math/Vector.hpp"

#include "Log/log.hpp"

#include <cassert>

/**
    @brief Initializes RectangleCollider instance.
    @param[in] GameObject *owner - owns the component.
    @param[in] C_PHYSICS - physics component.
*/
Rigidbody::Rigidbody(GameObject *owner) : Component(owner, C_PHYSICS) {
    assert((owner != NULL) && "the owner must be equal to NULL");
}

/**
    @brief Updates the position of a fixed component, based on it velocity.
*/
void Rigidbody::FixedComponentUpdate() {
    // Check for gravity, and if exists, sets its force on a vector.
    if (m_gravity) {
        GetOwner()->AddVelocity(Vector(0, m_gravityForce));
    }
    else {
       // Do nothing
    }

    // Sets the x,y positions in the owner component of the gameobject, according to its velocity.
    auto velocity  = GetOwner()->GetVelocity();
    GetOwner()->GetPosition()->m_x += velocity.m_x;
    GetOwner()->GetPosition()->m_y += velocity.m_y;
}
<|endoftext|>


<commit_before>#ifndef __CPP_EVENTS__THREADING__HPP
#define __CPP_EVENTS__THREADING__HPP

namespace Cpp {
//------------------------------------------------------------------------------
class Threading
{
public:
	// Implementation-specific
	class ThreadData;

	static ThreadData * currentThreadData();

	static void constructProcessData();
	static void destructProcessData();

	static void constructThreadData();
	static void destructThreadData();

	class ProcessInit
	{
	public:
		ProcessInit() { constructProcessData(); }
		~ProcessInit() { destructProcessData(); }
	};

	class ThreadInit
	{
	public:
		ThreadInit() { constructThreadData(); }
		~ThreadInit() { destructThreadData(); }
	};
};
//------------------------------------------------------------------------------
} //namespace Cpp

#endif //__CPP_EVENTS__THREADING__HPP<commit_msg>+: Cpp::Threading class documented<commit_after>#ifndef __CPP_EVENTS__THREADING__HPP
#define __CPP_EVENTS__THREADING__HPP

namespace Cpp {
//------------------------------------------------------------------------------
class Threading
{
public:
	//! \internal
	class ThreadData;

	//! \internal
	static ThreadData * currentThreadData();

	//! Initializes internal data for entire process and the main thread.
	/**
	 Should be called once before constructing any instance of the library classes in any thread.
	 Should be called from the main thread before starting any other thread.
	 \see destructProcessData(), ProcessInit, constructThreadData()
	*/
	static void constructProcessData();

	//! Deinitializes internal data for entire process and the main thread.
	/**
	 Should be called once after destructing all instances of the library classes in all threads.
	 Should be called from the main thread after finishing all other threads.
	 \see constructProcessData(), ProcessInit, destructThreadData()
	*/
	static void destructProcessData();

	//! Initializes internal data for the current thread.
	/**
	 Should be called once for each created thread that constructs any instance of the library classes.
	 You may omit per-thread initialization for threads that use existing library objects, but does not create new one.
	 Do not call this function for the main thread.
	 \see destructThreadData(), ThreadInit, constructProcessData()
	*/
	static void constructThreadData();

	//! Deinitializes internal data for the current thread.
	/**
	 Should be called once for each thread that called constructThreadData().
	 No more instances of the library classes can be constructed in the current thread after calling this function,
	 but instances constructed earlier remain valid and can be used in different threads.
	 Do not call this function for the main thread.
	 \see constructThreadData(), ThreadInit, destructProcessData()
	*/
	static void destructThreadData();

	//! Convenience RAII wrapper for constructProcessData()/destructProcessData().
	/**
	 Create single instance of this class on the stack of the main() function.
	 This class simply calls constructProcessData() in the constructor and destructProcessData() in the destructor.
	 This class is non-copyable.
	 \see constructProcessData(), destructProcessData()
	*/
	class ProcessInit
	{
	public:
		ProcessInit() { constructProcessData(); }
		~ProcessInit() { destructProcessData(); }
	};

	//! Convenience exception-safe per-thread library initializer.
	/**
	 Create single instance of this class on the stack of the created thread.
	 This class simply calls constructThreadData() in the constructor and destructThreadData() in the destructor.
	 This class is non-copyable.
	 \see constructThreadData(), destructThreadData()
	*/
	class ThreadInit
	{
	public:
		ThreadInit() { constructThreadData(); }
		~ThreadInit() { destructThreadData(); }
	};
};
//------------------------------------------------------------------------------
} //namespace Cpp

#endif //__CPP_EVENTS__THREADING__HPP<|endoftext|>


<commit_before>#include "McMaker/TpcEffFitter.h"
#include "Common.h"

// ROOT
#include "TGraphAsymmErrors.h"
#include "TFile.h"

#include "Logger.h"
#include "Reporter.h"
#include "RooPlotLib.h"
using namespace jdb;

void TpcEffFitter::initialize(  ){

	DEBUG( classname(), "( " << config.getFilename() << ", " << nodePath << " )" )
	outputPath = config.getString( nodePath + ".output:path", "" );

	book = unique_ptr<HistoBook>( new HistoBook( outputPath + config.getString( nodePath +  ".output.data", "TpcEff.root" ), config, "", "" ) );
}

void TpcEffFitter::make(){
	DEBUG(classname(), "")

	RooPlotLib rpl;

	gStyle->SetOptFit( 111 );
	string params_file =  config.getString( nodePath + ".output.params" );
	if ( "" == params_file ){
		ERROR( classname(), "Specifiy an output params file for the parameters" )
		return;
	}

	ofstream out( params_file.c_str() );

	out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
	out << "<config>" << endl;

	vector<string> labels = config.getStringVector( nodePath + ".CentralityLabels" );
	vector< int> cbins = config.getIntVector( nodePath + ".CentralityBins" );
	Reporter rp( config, nodePath + "Reporter." );

	double minP0Error = config.getDouble( nodePath + ".Systematics:minP0Error" );

	DEBUG( "Starting plc loop" )
	for ( string plc : Common::species ){
		if ( "E" == plc || "D" == plc )	// skip Electrons and Deuterons if I've got those in the list
			continue;

		for ( string c : Common::sCharges ){

			out << "\t<" << plc << "_" << c << ">" << endl;

			string fnMc = config.getString( nodePath + ".input:url" ) + "TpcEff_" + plc + "_" + c + "_mc" + ".root";
			TFile * fmc = new TFile( fnMc.c_str(), "READ" );
			string fnRc = config.getString( nodePath + ".input:url" ) + "TpcEff_" + plc + "_" + c + "_rc" + ".root";
			TFile * frc = new TFile( fnRc.c_str(), "READ" );

			DEBUG( classname(), "Mc File = " << fmc );
			DEBUG( classname(), "Rc File = " << frc );

			if ( !fmc->IsOpen() || !frc->IsOpen() )
				continue;

			// build an efficiency for each centrality
			for ( int b : cbins ){

				TH1 * hMc = (TH1*)fmc->Get( ("inclusive/pt_" + ts( b ) + "_" + c ).c_str() );
				TH1 * hRc = (TH1*)frc->Get( ("inclusive/pt_" + ts( b ) + "_" + c ).c_str() );

				INFO( classname(), "N bins MC = " << hMc->GetNbinsX() );
				INFO( classname(), "N bins RC = " << hRc->GetNbinsX() );

				for ( int i = 0; i <= hMc->GetNbinsX() + 1; i++ ){
					if ( hMc->GetBinContent( i ) < hRc->GetBinContent( i ) ){
						// set to 100%
						if ( i > 5 )
							hMc->SetBinContent( i, hRc->GetBinContent( i ) );
						else{
							hRc->SetBinContent( i, 0 );
							hMc->SetBinContent( i, 0 );
						}
					}
				}

				hMc->Sumw2();
				hRc->Sumw2();

				TGraphAsymmErrors g;

				g.SetName( (plc + "_" + c + "_" + ts(b)).c_str() );
				g.BayesDivide( hRc, hMc );

				INFO( classname(), "Adding TGraphAsymmErrors to book" );
				book->add( plc + "_" + c + "_" + ts(b),  &g );

				// do the fit
				TF1 * fitFunc = new TF1( "effFitFunc", "[0] * exp( - pow( [1] / x, [2] ) )", 0.0, 5.0 );
				fitFunc->SetParameters( .85, 0.05, 5.0, -0.05 );
				fitFunc->SetParLimits( 0, 0.5, 1.0 );
				fitFunc->SetParLimits( 1, 0.0, 0.5 );
				fitFunc->SetParLimits( 2, 0.0, 100000 );

				// fist fit shape
				TFitResultPtr fitPointer = g.Fit( fitFunc, "RSWW" );
				fitPointer = g.Fit( fitFunc, "RS" );

				// ensure that uncertainty on efficiency is at least 2%
				// if ( fitFunc->GetParError( 0 ) < minP0Error ) {
				// 	INFO( classname(), "P0 uncertainty below threshold (" << (minP0Error * 100) << "%" );
				// 	INFO( classname(), "Setting P0 error to " << (minP0Error * 100) << "%" );
				// 	fitFunc->SetParError( 0, minP0Error );
				// }

				INFO( classname(), "FitPointer = " << fitPointer );
				TGraphErrors * band = Common::choleskyBands( fitPointer, fitFunc, 5000, 200, &rp );

				rp.newPage();
				rpl.style( &g ).set( "title", Common::plc_label( plc, c ) + " : " + labels[ b ] + ", 68%CL (Red)" ).set( "yr", 0, 1.1 ).set( "optfit", 111 )
					.set( "xr", 0, 4.5 )
					.set("y", "Efficiency x Acceptance").set( "x", "p_{T}^{MC} [GeV/c]" ).draw();

				INFO( classname(), "Stat Box" );
				gStyle->SetStatY( 0.5 );
				gStyle->SetStatX( 0.85 );

				fitFunc->SetLineColor( kRed );
				fitFunc->Draw("same");

				INFO( classname(), "Drawing CL band" );

				band->SetFillColorAlpha( kRed, 0.5 );
				band->Draw( "same e3" );

				rp.savePage();
				string imgName = outputPath + "/img/TpcEff_" + plc + "_" + c + "_" +  + ".png";
				INFO( classname(), "Exporting image to : " << imgName );
				rp.saveImage( imgName );

				INFO( classname(), "Exporting Params" );
				exportParams( b, fitFunc, fitPointer, out );

			} // loop centrality bins

			out << "\t</" << plc << "_" << c << ">" << endl;

		} // loop on charge
	} // loop on plc

	out << "</config>" << endl;
	out.close();

}

void TpcEffFitter::exportParams( int bin, TF1 * f, TFitResultPtr result, ofstream &out ){
	INFO( classname(), "(bin=" << bin << ", f=" << f << ", fPtr=" << result << " )" )
	out << "\t\t<TpcEffParams bin=\"" << bin << "\" ";
	out << Common::toXml( f, result );
	out << "/>" << endl;
}<commit_msg>fix TpcEff output path for image export<commit_after>#include "McMaker/TpcEffFitter.h"
#include "Common.h"

// ROOT
#include "TGraphAsymmErrors.h"
#include "TFile.h"

#include "Logger.h"
#include "Reporter.h"
#include "RooPlotLib.h"
using namespace jdb;

void TpcEffFitter::initialize(  ){

	DEBUG( classname(), "( " << config.getFilename() << ", " << nodePath << " )" )
	outputPath = config.getString( nodePath + ".output:path", "" );

	book = unique_ptr<HistoBook>( new HistoBook( outputPath + config.getString( nodePath +  ".output.data", "TpcEff.root" ), config, "", "" ) );
}

void TpcEffFitter::make(){
	DEBUG(classname(), "")

	RooPlotLib rpl;

	gStyle->SetOptFit( 111 );
	string params_file =  config.getString( nodePath + ".output.params" );
	if ( "" == params_file ){
		ERROR( classname(), "Specifiy an output params file for the parameters" )
		return;
	}

	ofstream out( params_file.c_str() );

	out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>" << endl;
	out << "<config>" << endl;

	vector<string> labels = config.getStringVector( nodePath + ".CentralityLabels" );
	vector< int> cbins = config.getIntVector( nodePath + ".CentralityBins" );
	Reporter rp( config, nodePath + "Reporter." );

	double minP0Error = config.getDouble( nodePath + ".Systematics:minP0Error" );

	DEBUG( "Starting plc loop" )
	for ( string plc : Common::species ){
		if ( "E" == plc || "D" == plc )	// skip Electrons and Deuterons if I've got those in the list
			continue;

		for ( string c : Common::sCharges ){

			out << "\t<" << plc << "_" << c << ">" << endl;

			string fnMc = config.getString( nodePath + ".input:url" ) + "TpcEff_" + plc + "_" + c + "_mc" + ".root";
			TFile * fmc = new TFile( fnMc.c_str(), "READ" );
			string fnRc = config.getString( nodePath + ".input:url" ) + "TpcEff_" + plc + "_" + c + "_rc" + ".root";
			TFile * frc = new TFile( fnRc.c_str(), "READ" );

			DEBUG( classname(), "Mc File = " << fmc );
			DEBUG( classname(), "Rc File = " << frc );

			if ( !fmc->IsOpen() || !frc->IsOpen() )
				continue;

			// build an efficiency for each centrality
			for ( int b : cbins ){

				TH1 * hMc = (TH1*)fmc->Get( ("inclusive/pt_" + ts( b ) + "_" + c ).c_str() );
				TH1 * hRc = (TH1*)frc->Get( ("inclusive/pt_" + ts( b ) + "_" + c ).c_str() );

				INFO( classname(), "N bins MC = " << hMc->GetNbinsX() );
				INFO( classname(), "N bins RC = " << hRc->GetNbinsX() );

				for ( int i = 0; i <= hMc->GetNbinsX() + 1; i++ ){
					if ( hMc->GetBinContent( i ) < hRc->GetBinContent( i ) ){
						// set to 100%
						if ( i > 5 )
							hMc->SetBinContent( i, hRc->GetBinContent( i ) );
						else{
							hRc->SetBinContent( i, 0 );
							hMc->SetBinContent( i, 0 );
						}
					}
				}

				hMc->Sumw2();
				hRc->Sumw2();

				TGraphAsymmErrors g;

				g.SetName( (plc + "_" + c + "_" + ts(b)).c_str() );
				g.BayesDivide( hRc, hMc );

				INFO( classname(), "Adding TGraphAsymmErrors to book" );
				book->add( plc + "_" + c + "_" + ts(b),  &g );

				// do the fit
				TF1 * fitFunc = new TF1( "effFitFunc", "[0] * exp( - pow( [1] / x, [2] ) )", 0.0, 5.0 );
				fitFunc->SetParameters( .85, 0.05, 5.0, -0.05 );
				fitFunc->SetParLimits( 0, 0.5, 1.0 );
				fitFunc->SetParLimits( 1, 0.0, 0.5 );
				fitFunc->SetParLimits( 2, 0.0, 100000 );

				// fist fit shape
				TFitResultPtr fitPointer = g.Fit( fitFunc, "RSWW" );
				fitPointer = g.Fit( fitFunc, "RS" );

				// ensure that uncertainty on efficiency is at least 2%
				// if ( fitFunc->GetParError( 0 ) < minP0Error ) {
				// 	INFO( classname(), "P0 uncertainty below threshold (" << (minP0Error * 100) << "%" );
				// 	INFO( classname(), "Setting P0 error to " << (minP0Error * 100) << "%" );
				// 	fitFunc->SetParError( 0, minP0Error );
				// }

				INFO( classname(), "FitPointer = " << fitPointer );
				TGraphErrors * band = Common::choleskyBands( fitPointer, fitFunc, 5000, 200, &rp );

				rp.newPage();
				rpl.style( &g ).set( "title", Common::plc_label( plc, c ) + " : " + labels[ b ] + ", 68%CL (Red)" ).set( "yr", 0, 1.1 ).set( "optfit", 111 )
					.set( "xr", 0, 4.5 )
					.set("y", "Efficiency x Acceptance").set( "x", "p_{T}^{MC} [GeV/c]" ).draw();

				INFO( classname(), "Stat Box" );
				gStyle->SetStatY( 0.5 );
				gStyle->SetStatX( 0.85 );

				fitFunc->SetLineColor( kRed );
				fitFunc->Draw("same");

				INFO( classname(), "Drawing CL band" );

				band->SetFillColorAlpha( kRed, 0.5 );
				band->Draw( "same e3" );

				rp.savePage();
				string imgName = outputPath + "img/TpcEff_" + plc + "_" + c + "_" + ts(b) + ".png";
				INFO( classname(), "Exporting image to : " << imgName );
				rp.saveImage( imgName );

				INFO( classname(), "Exporting Params" );
				exportParams( b, fitFunc, fitPointer, out );

			} // loop centrality bins

			out << "\t</" << plc << "_" << c << ">" << endl;

		} // loop on charge
	} // loop on plc

	out << "</config>" << endl;
	out.close();

}

void TpcEffFitter::exportParams( int bin, TF1 * f, TFitResultPtr result, ofstream &out ){
	INFO( classname(), "(bin=" << bin << ", f=" << f << ", fPtr=" << result << " )" )
	out << "\t\t<TpcEffParams bin=\"" << bin << "\" ";
	out << Common::toXml( f, result );
	out << "/>" << endl;
}<|endoftext|>


<commit_before>#include "Common/config.h"
#include "Sofa/Core/ObjectFactory.h"
#include <iostream>
#include <fstream>

namespace Sofa
{

namespace Components
{

void init()
{
    static bool first = true;
    if (first)
    {
        std::cout << "Sofa Components Initialized"<<std::endl;
        Sofa::Core::ObjectFactory::getInstance()->dump();
        std::ofstream ofile("sofa-classes.html");
        ofile << "\n";
        Sofa::Core::ObjectFactory::getInstance()->dumpHTML(ofile);
        ofile << "\n";
        first = false;
    }
}

} // namespace Components

} // namespace SOFA

////////// BEGIN CLASS LIST //////////
SOFA_LINK_CLASS(BarycentricLagrangianMultiplierContact)
SOFA_LINK_CLASS(BarycentricMapping)
SOFA_LINK_CLASS(BarycentricPenalityContact)
SOFA_LINK_CLASS(BruteForce)
SOFA_LINK_CLASS(CGImplicit)
SOFA_LINK_CLASS(MatrixStatic)
SOFA_LINK_CLASS(CollisionGroupManagerSofa)
SOFA_LINK_CLASS(ContactManagerSofa)
SOFA_LINK_CLASS(ContinuousIntersection)
SOFA_LINK_CLASS(CoordinateSystem)
SOFA_LINK_CLASS(Cube)
SOFA_LINK_CLASS(DiagonalMass)
SOFA_LINK_CLASS(DiscreteIntersection)
SOFA_LINK_CLASS(EdgePressureForceField)
SOFA_LINK_CLASS(EdgeSetTopology)
SOFA_LINK_CLASS(Euler)
SOFA_LINK_CLASS(ExternalForceField)
SOFA_LINK_CLASS(FixedConstraint)
SOFA_LINK_CLASS(FixedPlaneConstraint)
SOFA_LINK_CLASS(GNode)
SOFA_LINK_CLASS(Gravity)
SOFA_LINK_CLASS(GridTopology)
SOFA_LINK_CLASS(IdentityMapping)
SOFA_LINK_CLASS(ImageBMP)
SOFA_LINK_CLASS(ImagePNG)
SOFA_LINK_CLASS(ImplicitSurfaceMapping)
SOFA_LINK_CLASS(InteractionConstraintImpl)
SOFA_LINK_CLASS(LagrangianMultiplierAttachConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierContactConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierFixedConstraint)
SOFA_LINK_CLASS(LaparoscopicRigidMapping)
SOFA_LINK_CLASS(LennardJonesForceField)
SOFA_LINK_CLASS(Line)
SOFA_LINK_CLASS(MechanicalObject)
SOFA_LINK_CLASS(MeshOBJ)
SOFA_LINK_CLASS(MeshSpringForceField)
SOFA_LINK_CLASS(MeshTopology)
SOFA_LINK_CLASS(MeshTrian)
SOFA_LINK_CLASS(MinProximityIntersection)
SOFA_LINK_CLASS(MultiResSparseGridTopology)
SOFA_LINK_CLASS(Node)
SOFA_LINK_CLASS(Object)
SOFA_LINK_CLASS(OglModel)
SOFA_LINK_CLASS(OscillatorConstraint)
SOFA_LINK_CLASS(PenalityContactForceField)
SOFA_LINK_CLASS(PipelineSofa)
SOFA_LINK_CLASS(PlaneForceField)
SOFA_LINK_CLASS(Point)
SOFA_LINK_CLASS(PointSetTopology)
SOFA_LINK_CLASS(ProximityIntersection)
SOFA_LINK_CLASS(Ray)
SOFA_LINK_CLASS(RayContact)
SOFA_LINK_CLASS(RegularGridSpringForceField)
SOFA_LINK_CLASS(RegularGridTopology)
SOFA_LINK_CLASS(RepulsiveSpringForceField)
SOFA_LINK_CLASS(RigidMapping)
SOFA_LINK_CLASS(RungeKutta4)
SOFA_LINK_CLASS(BoxConstraint)
SOFA_LINK_CLASS(SparseGridSpringForceField)
SOFA_LINK_CLASS(Sphere)
SOFA_LINK_CLASS(SPHFluidForceField)
SOFA_LINK_CLASS(SPHFluidSurfaceMapping)
SOFA_LINK_CLASS(SpringForceField)
SOFA_LINK_CLASS(SpringEdgeDataForceField)
SOFA_LINK_CLASS(StaticSolver)
SOFA_LINK_CLASS(StiffSpringForceField)
SOFA_LINK_CLASS(SurfaceIdentityMapping)
SOFA_LINK_CLASS(SubsetMapping)
SOFA_LINK_CLASS(TensorForceField)
SOFA_LINK_CLASS(TetrahedronFEMForceField)
SOFA_LINK_CLASS(ThreadSimulation)
SOFA_LINK_CLASS(Triangle)
SOFA_LINK_CLASS(TriangleBendingSprings)
SOFA_LINK_CLASS(TriangleFEMForceField)
SOFA_LINK_CLASS(TrimmedRegularGridTopology)
SOFA_LINK_CLASS(UniformMass)
SOFA_LINK_CLASS(TestDetection)
SOFA_LINK_CLASS(SphereTreeModel)
SOFA_LINK_CLASS(SingleSphere)
//SOFA_LINK_CLASS(VoxelGrid)
SOFA_LINK_CLASS(WashingMachineForceField)
SOFA_LINK_CLASS(EdgeRemoveContact)
<commit_msg>r784/sofa-dev : FIX compilation<commit_after>#include "Common/config.h"
#include <iostream>

namespace Sofa
{

namespace Components
{

void init()
{
    static bool first = true;
    if (first)
    {
        std::cout << "Sofa Components Initialized"<<std::endl;
        first = false;
    }
}

} // namespace Components

} // namespace SOFA

////////// BEGIN CLASS LIST //////////
SOFA_LINK_CLASS(BarycentricLagrangianMultiplierContact)
SOFA_LINK_CLASS(BarycentricMapping)
SOFA_LINK_CLASS(BarycentricPenalityContact)
SOFA_LINK_CLASS(BruteForce)
SOFA_LINK_CLASS(CGImplicit)
SOFA_LINK_CLASS(MatrixStatic)
SOFA_LINK_CLASS(CollisionGroupManagerSofa)
SOFA_LINK_CLASS(ContactManagerSofa)
SOFA_LINK_CLASS(ContinuousIntersection)
SOFA_LINK_CLASS(CoordinateSystem)
SOFA_LINK_CLASS(Cube)
SOFA_LINK_CLASS(DiagonalMass)
SOFA_LINK_CLASS(DiscreteIntersection)
SOFA_LINK_CLASS(EdgePressureForceField)
SOFA_LINK_CLASS(EdgeSetTopology)
SOFA_LINK_CLASS(Euler)
SOFA_LINK_CLASS(ExternalForceField)
SOFA_LINK_CLASS(FixedConstraint)
SOFA_LINK_CLASS(FixedPlaneConstraint)
SOFA_LINK_CLASS(GNode)
SOFA_LINK_CLASS(Gravity)
SOFA_LINK_CLASS(GridTopology)
SOFA_LINK_CLASS(IdentityMapping)
SOFA_LINK_CLASS(ImageBMP)
SOFA_LINK_CLASS(ImagePNG)
SOFA_LINK_CLASS(ImplicitSurfaceMapping)
SOFA_LINK_CLASS(InteractionConstraintImpl)
SOFA_LINK_CLASS(LagrangianMultiplierAttachConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierContactConstraint)
SOFA_LINK_CLASS(LagrangianMultiplierFixedConstraint)
SOFA_LINK_CLASS(LaparoscopicRigidMapping)
SOFA_LINK_CLASS(LennardJonesForceField)
SOFA_LINK_CLASS(Line)
SOFA_LINK_CLASS(MechanicalObject)
SOFA_LINK_CLASS(MeshOBJ)
SOFA_LINK_CLASS(MeshSpringForceField)
SOFA_LINK_CLASS(MeshTopology)
SOFA_LINK_CLASS(MeshTrian)
SOFA_LINK_CLASS(MinProximityIntersection)
SOFA_LINK_CLASS(MultiResSparseGridTopology)
SOFA_LINK_CLASS(Node)
SOFA_LINK_CLASS(Object)
SOFA_LINK_CLASS(OglModel)
SOFA_LINK_CLASS(OscillatorConstraint)
SOFA_LINK_CLASS(PenalityContactForceField)
SOFA_LINK_CLASS(PipelineSofa)
SOFA_LINK_CLASS(PlaneForceField)
SOFA_LINK_CLASS(Point)
SOFA_LINK_CLASS(PointSetTopology)
SOFA_LINK_CLASS(ProximityIntersection)
SOFA_LINK_CLASS(Ray)
SOFA_LINK_CLASS(RayContact)
SOFA_LINK_CLASS(RegularGridSpringForceField)
SOFA_LINK_CLASS(RegularGridTopology)
SOFA_LINK_CLASS(RepulsiveSpringForceField)
SOFA_LINK_CLASS(RigidMapping)
SOFA_LINK_CLASS(RungeKutta4)
SOFA_LINK_CLASS(BoxConstraint)
SOFA_LINK_CLASS(SparseGridSpringForceField)
SOFA_LINK_CLASS(Sphere)
SOFA_LINK_CLASS(SPHFluidForceField)
SOFA_LINK_CLASS(SPHFluidSurfaceMapping)
SOFA_LINK_CLASS(SpringForceField)
SOFA_LINK_CLASS(SpringEdgeDataForceField)
SOFA_LINK_CLASS(StaticSolver)
SOFA_LINK_CLASS(StiffSpringForceField)
SOFA_LINK_CLASS(SurfaceIdentityMapping)
SOFA_LINK_CLASS(SubsetMapping)
SOFA_LINK_CLASS(TensorForceField)
SOFA_LINK_CLASS(TetrahedronFEMForceField)
SOFA_LINK_CLASS(ThreadSimulation)
SOFA_LINK_CLASS(Triangle)
SOFA_LINK_CLASS(TriangleBendingSprings)
SOFA_LINK_CLASS(TriangleFEMForceField)
SOFA_LINK_CLASS(TrimmedRegularGridTopology)
SOFA_LINK_CLASS(UniformMass)
SOFA_LINK_CLASS(TestDetection)
SOFA_LINK_CLASS(SphereTreeModel)
SOFA_LINK_CLASS(SingleSphere)
//SOFA_LINK_CLASS(VoxelGrid)
SOFA_LINK_CLASS(WashingMachineForceField)
SOFA_LINK_CLASS(EdgeRemoveContact)
<|endoftext|>