15 #define _BINARY_STL_HEADER_SIZE_ 80
17 #include <TGeoManager.h>
18 #include <TGeoMedium.h>
19 #include <TRotation.h>
21 #include <TGeoVolume.h>
23 #include <TGeoMatrix.h>
33 const double vCoord1[],
const double vCoord2[],
34 const double vCoord3[])
45 for(
unsigned iq=0; iq<3; iq++)
80 float fnn[3], fvCoord1[3], fvCoord2[3], fvCoord3[3];
85 for(
unsigned itr=0; itr<trCount; itr++)
88 fread(fnn,
sizeof(
float), 3, fin);
89 fread(fvCoord1,
sizeof(
float), 3, fin);
90 fread(fvCoord2,
sizeof(
float), 3, fin);
91 fread(fvCoord3,
sizeof(
float), 3, fin);
92 fread(&attr,
sizeof(
__u16), 1, fin);
101 double dnn[3], dvCoord1[3], dvCoord2[3], dvCoord3[3];
103 for(
unsigned iq=0; iq<3; iq++) {
104 dnn [iq] = double(fnn [iq]);
105 dvCoord1[iq] = scale * double(fvCoord1[iq]);
106 dvCoord2[iq] = scale * double(fvCoord2[iq]);
107 dvCoord3[iq] = scale * double(fvCoord3[iq]);
113 dvCoord1, dvCoord2, dvCoord3);
125 unsigned solidId = 0, vtxId = 0;
126 Bool_t inSolid = kFALSE, inFacet = kFALSE, inLoop = kFALSE;
134 buffer.ReadLine(is, kTRUE);
139 if (buffer.BeginsWith(
"solid"))
141 assert (inSolid == kFALSE && inFacet == kFALSE && inLoop == kFALSE);
145 if (buffer.BeginsWith(
"endsolid"))
147 assert (inSolid == kTRUE && inFacet == kFALSE && inLoop == kFALSE);
159 assert (inFacet == kFALSE && inLoop == kFALSE);
165 char key[128], medium[128];
167 sscanf(buffer.Data(),
"%s %s", key, medium);
170 assert(currentMedium);
176 assert (inSolid == kTRUE && inFacet == kFALSE && inLoop == kFALSE);
184 sscanf(buffer.Data(),
"%s %f %f %f",
color, rgb + 0, rgb + 1, rgb + 2);
190 assert(fMediaHub->fMediaMap->find(&key) != fMediaHub->fMediaMap->end());
191 currentMedium = (*fMediaHub->fMediaMap)[&key];
196 if ((
mType ==
AsciiStl && buffer.Contains(
"facet normal")) ||
197 (
mType ==
AsciiSlp && buffer.Contains(
"facet") && !buffer.Contains(
"endfacet")))
201 assert (inSolid == kTRUE && inFacet == kFALSE && inLoop == kFALSE);
205 if (buffer.Contains(
"endfacet"))
207 assert (inSolid == kTRUE && inFacet == kTRUE && inLoop == kFALSE);
211 if (buffer.Contains(
"outer loop"))
213 assert (inSolid == kTRUE && inFacet == kTRUE && inLoop == kFALSE);
217 if (buffer.Contains(
"endloop"))
219 assert (inSolid == kTRUE && inFacet == kTRUE && inLoop == kTRUE);
224 if (buffer.Contains(
"vertex"))
226 assert (inSolid == kTRUE && inFacet == kTRUE && inLoop == kTRUE && vtxId <= 2);
229 sscanf(buffer.Data(),
"%s %lf %lf %lf", vertex,
230 vCoord[vtxId] + 0, vCoord[vtxId] + 1, vCoord[vtxId] + 2);
241 assert(currentMedium);
243 for(
unsigned ip=0;
ip<3;
ip++)
244 for(
unsigned iq=0; iq<3; iq++)
245 vCoord[
ip][iq] *= scale;
259 bool acknowledge_config_file_scaling):
260 mGeometryName(geometryName), mVolumeName(vname), mConfig(config)
262 double scale = (config && acknowledge_config_file_scaling) ? config->
scale() * config->
units() : 1.0;
274 FILE *fin = fopen(geometryName,
"r");
286 fseek(fin, 0, SEEK_END);
287 long fSize = ftell(fin);
293 fread(&trCount, 1,
sizeof(
__u32), fin) ==
sizeof(
__u32) &&
323 static TVector3 GetTetPoint(
tetgenio &io,
unsigned index_offset)
337 FILE *fout = fopen(stlActualFileName,
"w");
340 stlActualFileName.Data());
343 fprintf(fout,
"solid MySolid\n");
345 for(
unsigned fc=0; fc<assembly->
facets().size(); fc++) {
347 double sign = assembly->
facets()[fc].second ? 1.0 : -1.0;
351 fprintf(fout,
" facet normal %16.8f %16.8f %16.8f\n",
353 fprintf(fout,
" outer loop\n");
357 for(vEntry::const_iterator vt=facet->
vertices()->begin(); vt!=facet->
vertices()->end() ; vt++) {
358 const double *coord = vt->second->key()->GetData();
359 fprintf(fout,
" vertex %16.8f %16.8f %16.8f\n", coord[0], coord[1], coord[2]);
361 fprintf(fout,
" endloop\n");
362 fprintf(fout,
" endfacet\n");
367 fprintf(fout,
"endsolid MySolid\n");
374 char name[], TGeoVolume *fMother,
const TGeoMedium *medium, TVector3 shift)
381 TVector3 p21 = p2 - p1, p31 = p3 - p1, nn = p31.Cross(p21).Unit();
384 TVector3 p41 = p4 - p1;
385 double projection = p41 * nn;
398 projection = fabs(projection);
399 TVector3 p41perp = projection * nn, translation = p4 - 0.5 * p41perp;
402 TVector3 zz(0., 0., 1.);
403 double angle = nn.Angle(zz);
404 TVector3 axis = (nn.Cross(zz)).Unit();
406 TRotation
rr, qrr; rr.SetToIdentity();
411 if (angle == TMath::Pi())
413 qrr = rr.RotateY(TMath::Pi());
415 qrr = rr.Rotate(angle, axis);
416 TVector3 q1, q2, q3, q4;
417 q1 = qrr * (p1 - translation);
418 q2 = qrr * (p2 - translation);
419 q3 = qrr * (p3 - translation);
420 q4 = qrr * (p4 - translation);
435 double data[9] = {qrr.XX(), qrr.XY(), qrr.XZ(),
436 qrr.YX(), qrr.YY(), qrr.YZ(),
437 qrr.ZX(), qrr.ZY(), qrr.ZZ()};
439 TGeoRotation *grr =
new TGeoRotation();
440 grr->SetMatrix(data);
442 TGeoArb8 *tet =
new TGeoArb8 (name, projection/2., (
double*)vtx);
443 TGeoVolume *vtet =
new TGeoVolume(name, tet, medium);
444 fMother->AddNode(vtet, 0,
new TGeoCombiTrans(translation.x() + shift.x(),
445 translation.y() + shift.y(), translation.z() + shift.z(), grr));
450 vtet->RegisterYourself();
471 std::vector<TGeoVolume*> *volumes)
484 static unsigned counter;
489 TGeoSphere *sphere =
new TGeoSphere(
"SPHERE", 0.0, fsize/2);
490 TGeoVolume *vsphere =
new TGeoVolume(
"SPHERE", sphere,
it->first.second);
491 vsphere->RegisterYourself();
495 char cmd[16384] =
"";
496 for (vEntry::const_iterator vt=mgroup->
vertices()->begin(); vt != mgroup->
vertices()->end(); vt++) {
509 mother->AddNode(vsphere, counter,
new TGeoCombiTrans(src[0], src[1], src[2], 0));
544 for(
unsigned ass=0; ass<mgroup->
assemblies().size(); ass++)
550 snprintf(buffer, 128-1,
"./%05d-%06d-%s.stl", getpid(), ass,
it->first.second->GetName());
551 TString stlActualFileName = TString(buffer);
560 unsigned ret = in.
load_stl((
char*)stlActualFileName.Data());
577 snprintf(name, 128-1,
"@RV@%s-Ass%04d-Tet%06d-%s",
mVolumeName.Data(), ass, iq,
578 it->first.second->GetName());
581 int index_offset = iq * 4;
584 TVector3 p1 = GetTetPoint(out, index_offset );
585 TVector3 p2 = GetTetPoint(out, index_offset + 1);
586 TVector3 p3 = GetTetPoint(out, index_offset + 2);
587 TVector3 p4 = GetTetPoint(out, index_offset + 3);
598 vtet =
CreateTetrahedron(swpp1, swpp2, swpp3, swpp4, name, mother,
it->first.second, shift);
602 if (volumes) volumes->push_back(vtet);
611 "support is not compiled in! \033[0m");
614 unlink(stlActualFileName.Data());
633 for(
unsigned ass=0; ass<mgroup->
assemblies().size(); ass++) {
638 snprintf(buffer, 128-1,
"./%05d-%06d-%s.stl", getpid(), ass,
it->first.second->GetName());
639 TString stlActualFileName = TString(buffer);
648 unsigned ret = in.
load_stl((
char*)stlActualFileName.Data());
660 snprintf(name, 128-1,
"@RV@%s-Ass%04d-Tet%06d-%s",
mVolumeName.Data(), ass, iq,
661 it->first.second->GetName());
664 int index_offset = iq * 4;
667 TVector3 p1 = GetTetPoint(out, index_offset );
668 TVector3 p2 = GetTetPoint(out, index_offset + 1);
669 TVector3 p3 = GetTetPoint(out, index_offset + 2);
670 TVector3 p4 = GetTetPoint(out, index_offset + 3);
677 printf(
"STL file meshing required but Tetgen support is not compiled in!\n");
682 unlink(stlActualFileName.Data());