Skip to content

Commit

Permalink
Added new features to geocad library.
Browse files Browse the repository at this point in the history
- New features are used to export partial geometries to STEP files.
- Added 3 new member functions TGeoToStep::CreatePartialGeometry taking
different arguments.
- The first takes a file_name and a max_level, and defaults to the
previous (default arguments) behavior. The max_level sets the node depth
that will be exported in the STEP file.
- The second version, in addition to the previous version, has a part_name  argument.
This is the name of a volume that is associated with a level 1 node.
Only this node and its children  down to max_level will be exported.
- Similarly, a third version takes a map of part_name/max_level key/value pairs.
This allows the multiple level 1 nodes to be selected and exported to
different max_levels.

	modified:   geom/geocad/inc/TGeoToStep.h
	modified:   geom/geocad/inc/TOCCToStep.h
	modified:   geom/geocad/src/TGeoToStep.cxx
	modified:   geom/geocad/src/TOCCToStep.cxx
  • Loading branch information
Whitney Armstrong authored and agheata committed Dec 12, 2017
1 parent 34cdbe6 commit 268747f
Show file tree
Hide file tree
Showing 4 changed files with 215 additions and 17 deletions.
8 changes: 7 additions & 1 deletion geom/geocad/inc/TGeoToStep.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,9 @@

#include "TObject.h"

#include <map>
#include <string>

class TGeoManager;
class TOCCToStep;

Expand All @@ -28,7 +31,10 @@ class TGeoToStep: public TObject {
TGeoToStep();
TGeoToStep(TGeoManager *geom);
~TGeoToStep();
void *CreateGeometry();

void CreateGeometry(const char* fname = "geometry.stp", int max_level = -1);
void CreatePartialGeometry(const char* part_name, int max_level = -1, const char* fname = "geometry.stp");
void CreatePartialGeometry(std::map<std::string,int> part_name_levels, const char* fname = "geometry.stp");

ClassDef(TGeoToStep,0)
};
Expand Down
10 changes: 9 additions & 1 deletion geom/geocad/inc/TOCCToStep.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ class TOCCToStep {

STEPCAFControl_Writer fWriter; //the step file pointer
Handle(TDocStd_Document) fDoc; //the step document element

// The following probably shouldn't be data members.
LabelMap_t fTree; //tree of Label's volumes
TDF_Label fLabel; //label of the OCC shape element
TGeoToOCC fRootShape;
Expand All @@ -43,11 +45,17 @@ class TOCCToStep {
void AddChildLabel(TDF_Label mother, TDF_Label child, TopLoc_Location loc);
TopLoc_Location CalcLocation(TGeoHMatrix matrix);

void FillOCCWithNode(TGeoManager* m, TGeoNode* currentNode, TGeoIterator& nextNode, int level, int max_level, int level1_skipped);

public:
TOCCToStep();
void PrintAssembly();
TDF_Label OCCShapeCreation(TGeoManager *m);
void OCCTreeCreation(TGeoManager *m);
void OCCTreeCreation(TGeoManager *m, int max_level = -1);
bool OCCPartialTreeCreation(TGeoManager *m, const char* node_name, int max_level = -1);
bool OCCPartialTreeCreation(TGeoManager *m, std::map<std::string,int> part_name_levels);


void OCCWriteStep(const char *fname);
};

Expand Down
49 changes: 43 additions & 6 deletions geom/geocad/src/TGeoToStep.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -33,11 +33,12 @@ CreateGeometry method:
~~~ {.cpp}
TGeoToStep * mygeom= new TGeoToStep(gGeoManager);
mygeom->CreateGeometry();
mygeom->CreateGeometry("output_geometry.stp",3);
~~~
The resulting STEP file will be saved in the current directory and called
geometry.stp
output_geometry.stp and will have converted all the nodes up to and
including level 3.
To compile the TGeoCad module on ROOT, OpenCascade must be installed!
*/

Expand All @@ -46,6 +47,8 @@ To compile the TGeoCad module on ROOT, OpenCascade must be installed!
#include "TGeoToStep.h"
#include "TString.h"
#include "TClass.h"
#include <string>
#include <map>

ClassImp(TGeoToStep);

Expand All @@ -64,14 +67,48 @@ TGeoToStep::~TGeoToStep()
if (fGeometry) delete fGeometry;
}

void * TGeoToStep::CreateGeometry()
void TGeoToStep::CreateGeometry(const char* fname, int max_level)
{
//ROOT CAD CONVERSION
fCreate = new TOCCToStep();
fCreate->OCCShapeCreation(fGeometry);
fCreate->OCCTreeCreation(fGeometry);
fCreate->OCCWriteStep("geometry.stp");
fCreate->OCCTreeCreation(fGeometry, max_level);
fCreate->OCCWriteStep(fname);
//fCreate->PrintAssembly();
delete(fCreate);
return NULL;
}

void TGeoToStep::CreatePartialGeometry(const char* part_name, int max_level, const char* fname)
{
//ROOT CAD CONVERSION
fCreate = new TOCCToStep();
fCreate->OCCShapeCreation(fGeometry);
if( !(fCreate->OCCPartialTreeCreation(fGeometry, part_name, max_level)) ) {
// std::cout << " Part: " << part_name << ", max_level = " << max_level;
// std::cout << ", Found.\n";
//} else {
std::cout << " Part: " << part_name << ", max_level = " << max_level;
std::cout << ", NOT FOUND!\n";
}
fCreate->OCCWriteStep(fname);
//fCreate->PrintAssembly();
delete(fCreate);
}


void TGeoToStep::CreatePartialGeometry(std::map<std::string,int> part_name_levels, const char* fname)
{
//ROOT CAD CONVERSION
fCreate = new TOCCToStep();
fCreate->OCCShapeCreation(fGeometry);
if( !(fCreate->OCCPartialTreeCreation(fGeometry, part_name_levels)) ) {
// std::cout << " At least one part found.\n";
//} else {
std::cout << " NO PARTS FOUND!\n";
}
fCreate->OCCWriteStep(fname);
//fCreate->PrintAssembly();
delete(fCreate);
}


165 changes: 156 additions & 9 deletions geom/geocad/src/TOCCToStep.cxx
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ TDF_Label TOCCToStep::OCCShapeCreation(TGeoManager *m)
fTree[Top] = fLabel;
while ((currentVolume = (TGeoVolume *)next())) {
if (GetLabelOfVolume(currentVolume).IsNull()) {
num = currentVolume->GetNdaughters();
//num = currentVolume->GetNdaughters();
if ((GetLabelOfVolume(currentVolume).IsNull())) {
if (currentVolume->GetShape()->IsA()==TGeoCompositeShape::Class()) {
fShape = fRootShape.OCC_CompositeShape((TGeoCompositeShape*)currentVolume->GetShape(), TGeoIdentity());
Expand Down Expand Up @@ -207,7 +207,7 @@ TopLoc_Location TOCCToStep::CalcLocation (TGeoHMatrix matrix)

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

void TOCCToStep::OCCTreeCreation(TGeoManager * m)
void TOCCToStep::OCCTreeCreation(TGeoManager * m, int max_level)
{
TGeoIterator nextNode(m->GetTopVolume());
TGeoNode *currentNode = 0;
Expand All @@ -220,30 +220,177 @@ void TOCCToStep::OCCTreeCreation(TGeoManager * m)

while ((currentNode = nextNode())) {
level = nextNode.GetLevel();
if( level > max_level ){
continue;
}
// This loop looks for nodes which are the end of line (ancestrally) then navigates
// back up the family tree. As it does so, the OCC tree is constructed.
// It is not clear why it must be done this way, but it could be an idiosyncracy
// in OCC (which I am not too familar with at the moment).
nd = currentNode->GetNdaughters();
if (!nd) {
for (int i = level; i > 0; i--) {
if (i == 1) {
motherNode = m->GetTopNode();
} else
} else {
motherNode = nextNode.GetNode(--level);
labelMother = GetLabelOfVolume(motherNode->GetVolume());
}
labelMother = GetLabelOfVolume(motherNode->GetVolume());
Int_t ndMother = motherNode->GetNdaughters();
fLabel = GetLabelOfVolume(currentNode->GetVolume());
loc = CalcLocation((*(currentNode->GetMatrix())));
fLabel = GetLabelOfVolume(currentNode->GetVolume());
loc = CalcLocation((*(currentNode->GetMatrix())));
if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) < ndMother) && (!nd)) {
AddChildLabel(labelMother, fLabel, loc);
} else if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(fLabel) == nd) && (XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) == motherNode->GetVolume()->GetIndex(currentNode))) {
} else if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(fLabel) == nd) &&
(XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) == motherNode->GetVolume()->GetIndex(currentNode))) {
AddChildLabel(labelMother, fLabel, loc);
}
currentNode = motherNode;
fLabel = labelMother;
nd = currentNode->GetNdaughters();
fLabel = labelMother;
nd = currentNode->GetNdaughters();
}
}
}
}
//______________________________________________________________________________

bool TOCCToStep::OCCPartialTreeCreation(TGeoManager * m, const char* node_name, int max_level)
{
TGeoIterator nextNode(m->GetTopVolume());
std::string search_n = node_name;
bool found_once = false;
bool found_in_level_1 = false;
auto volume = m->GetVolume(node_name);
int level1_skipped = 0;
TGeoNode* currentNode = 0;

nextNode.SetType(0);
while ((currentNode = nextNode())) {
nextNode.SetType(0);
int level = nextNode.GetLevel();
if( level > max_level ){
continue;
}
if(level == 1) {
found_in_level_1 = false;
if( volume == currentNode->GetVolume() ) {
found_in_level_1 = true;
found_once = true;
}
}
if(!found_in_level_1) {
if(level == 1) {
level1_skipped++;
}
nextNode.SetType(1);
continue;
}
FillOCCWithNode(m, currentNode, nextNode, level, max_level, level1_skipped);
}
return found_once;
}
//______________________________________________________________________________

bool TOCCToStep::OCCPartialTreeCreation(TGeoManager * m, std::map<std::string,int> part_name_levels)
{
bool found_once = false;
bool found_in_level_1 = false;
int level1_skipped = 0;

std::map<TGeoVolume*,std::string> part_name_vols;
std::vector<TGeoVolume*> vols;

for(const auto& pl : part_name_levels) {
TGeoVolume* avol = m->GetVolume(pl.first.c_str());
part_name_vols[avol] = pl.first;
vols.push_back(avol);
}

TGeoIterator nextNode(m->GetTopVolume());
TGeoNode* currentNode = nullptr;
TGeoVolume* matched_vol = nullptr;

nextNode.SetType(0);
while ((currentNode = nextNode())) {
nextNode.SetType(0);
int level = nextNode.GetLevel();

// Currently we only isolate level 1 node/volumes.
// In the future this could be generalized.
if(level == 1) {
found_in_level_1 = false;
for(auto v: vols) {
if( v == currentNode->GetVolume() ) {
// could there be more than one?
matched_vol = v;
found_in_level_1 = true;
found_once = true;
}
}
}
if(!found_in_level_1) {
if(level == 1) {
level1_skipped++;
}
// switch the iterator type to go directly to sibling nodes
nextNode.SetType(1);
continue;
}
int max_level = part_name_levels[ part_name_vols[matched_vol]];
if( level > max_level ){
continue;
}

FillOCCWithNode(m, currentNode, nextNode, level, max_level, level1_skipped);
}
return found_once;
}
//______________________________________________________________________________


void TOCCToStep::FillOCCWithNode(TGeoManager* m, TGeoNode* currentNode, TGeoIterator& nextNode, int level, int max_level, int level1_skipped)
{
// This loop looks for nodes which are the end of line (ancestrally) then navigates
// back up the family tree. As it does so, the OCC tree is constructed.
// It is not clear why it must be done this way, but it could be an idiosyncracy
// in OCC (which I am not too familar with at the moment).
int nd = currentNode->GetNdaughters();
if(level == max_level) {
nd = 0;
}
if( nd == 0 ) {
int level_start = std::min(level,max_level);
for (int i = level_start; i > 0; i--) {
TGeoNode* motherNode = 0;
TDF_Label labelMother;
TopLoc_Location loc;

if (i == 1) {
motherNode = m->GetTopNode();
} else {
motherNode = nextNode.GetNode(i-1);
}
labelMother = GetLabelOfVolume(motherNode->GetVolume());
Int_t ndMother = motherNode->GetNdaughters();
// Why are we using a data member here?
fLabel = GetLabelOfVolume(currentNode->GetVolume());
loc = CalcLocation((*(currentNode->GetMatrix())));
// Need to account for the missing daughters from those nodes skipped in level 1
int skipped_this_level = 0;
if(i == 1 ) skipped_this_level = level1_skipped;
if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother) < ndMother) && (!nd)) {

AddChildLabel(labelMother, fLabel, loc);
} else if ((XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(fLabel) == currentNode->GetNdaughters()) &&
(XCAFDoc_DocumentTool::ShapeTool(fDoc->Main())->NbComponents(labelMother)+skipped_this_level == motherNode->GetVolume()->GetIndex(currentNode))) {
AddChildLabel(labelMother, fLabel, loc);
}
currentNode = motherNode;
fLabel = labelMother; // again, why a data member?
nd = currentNode->GetNdaughters();
}
}
}
////////////////////////////////////////////////////////////////////////////////

void TOCCToStep::PrintAssembly()
Expand Down

0 comments on commit 268747f

Please sign in to comment.