diff --git a/DDCAD/src/ASSIMPWriter.cpp b/DDCAD/src/ASSIMPWriter.cpp index 6db0575fc61d364f4c62cbf34dfe9a823a99d465..bdddac197f5a0e2d68f4d6f3db7beefcd75c1203 100644 --- a/DDCAD/src/ASSIMPWriter.cpp +++ b/DDCAD/src/ASSIMPWriter.cpp @@ -23,6 +23,8 @@ #include "assimp/scene.h" #include <TBuffer3D.h> +#include <TBuffer3DTypes.h> +#include <TGeoBoolNode.h> #include <TGeoMatrix.h> /// C/C++ include files @@ -71,55 +73,28 @@ namespace { vertex operator+(const vertex& v1, const vertex& v2) { return vertex(v1.x+v2.x, v1.y+v2.y, v1.z+v2.z); } #endif -#if 0 - num_facet = tes->GetNfacets(); - int *nn = new int[num_facet]; - bool* flipped = new bool[num_facet]; - for( i=0; i < num_facet; ++i ) - flipped[i] = false, nn[0] = 0; - for( i=0; i < num_facet; ++i ) { - for( size_t j= i+1; j < num_facet; ++j) { - bool isneighbour = tes->GetFacet(i).IsNeighbour(tes->GetFacet(j), flipped[j]); - if ( isneighbour ) { - if ( flipped[i] ) flipped[j] = !flipped[j]; - ++nn[i]; - ++nn[j]; - if ( nn[i] == tes->GetFacet(i).GetNvert() ) - break; - } - } - } - for( i=0; i < num_facet; ++i ) { - if ( flipped[i] ) { - const_cast<TGeoFacet*>(&tes->GetFacet(i))->Flip(); - } - } - delete [] flipped; - delete [] nn; -#endif -#if 0 - template <typename TGBinder> - TPlane3 compute_plane(const TGBinder &poly) { - TPoint3 plast(poly[poly.Size()-1]); - TPoint3 pivot; - TVector3 edge; - Int_t j; - for (j = 0; j < poly.Size(); j++) { - pivot = poly[j]; - edge = pivot - plast; - if (!edge.FuzzyZero()) break; - } - for (; j < poly.Size(); j++) { - TVector3 v2 = poly[j] - pivot; - TVector3 v3 = edge.Cross(v2); - if (!v3.FuzzyZero()) - return TPlane3(v3,pivot); - } - return TPlane3(); - } + unique_ptr<TGeoTessellated> _tessellate_primitive(const std::string& name, Solid solid) { + typedef vertex vtx_t; + const TBuffer3D& buf3D = solid->GetBuffer3D(TBuffer3D::kAll, false); + struct pol_t { int c, n; int segs[1]; } *pol = nullptr; + struct seg_t { int c, _1, _2; }; + const seg_t* segs = (seg_t*)buf3D.fSegs; + const vtx_t* vtcs = (vtx_t*)buf3D.fPnts; + size_t i, num_facet = 0; + const Int_t* q; + for( i=0, q=buf3D.fPols; i<buf3D.NbPols(); ++i, q += (2+pol->n)) { + pol = (pol_t*)q; + for( int j=0; j < pol->n-1; ++j ) num_facet += 2; + } + unique_ptr<TGeoTessellated> tes = make_unique<TGeoTessellated>(name.c_str(), num_facet); + q = buf3D.fPols; + for( i=0, q=buf3D.fPols; i<buf3D.NbPols(); ++i) { + pol = (pol_t*)q; + q += (2+pol->n); + for( int j=0; j < pol->n; j += 2 ) { /* ------------------------------------------------------------ // Convert quadri-linear facet to 2 tri-linear facets // @@ -130,46 +105,63 @@ namespace { // +---------------+ // v0 v1 v2/v3 // --------------------------------------------------------- */ - int num_points[3]; - pol_t* pol = (pol_t*)q; - int s1 = pol->segs[0], s2 = pol->segs[1]; - int ends[4] = {segs[s1]._1,segs[s1]._2,segs[s2]._1,segs[s2]._2}; + const int s1 = pol->segs[j], s2 = pol->segs[(j+1)%pol->n]; + const int s[] = { segs[s1]._1, segs[s1]._2, segs[s2]._1, segs[s2]._2 }; + const vtx_t& v0 = vtcs[s[0]], &v1=vtcs[s[1]], &v2=vtcs[s[2]], &v3=vtcs[s[3]]; - q += (2+pol->n); - if (ends[0] == ends[2]) { - numPnts[0] = ends[1]; - numPnts[1] = ends[0]; - numPnts[2] = ends[3]; - } - else if (ends[0] == ends[3]) { - numPnts[0] = ends[1]; - numPnts[1] = ends[0]; - numPnts[2] = ends[2]; + if ( s[0] == s[2] ) { // Points are ( s[1], s[0], s[3] ) + tes->AddFacet(v1, v0, v3); } - else if (ends[1] == ends[2]) { - numPnts[0] = ends[0]; - numPnts[1] = ends[1]; - numPnts[2] = ends[3]; + else if ( s[0] == s[3] ) { // Points are ( s[1], s[0], s[2] ) + tes->AddFacet(v1, v0, v2); } - else { - numPnts[0] = ends[0]; - numPnts[1] = ends[1]; - numPnts[2] = ends[2]; + else if ( s[1] == s[2] ) { // Points are ( s[0], s[1], s[3] ) + tes->AddFacet(v0, v1, v3); } - Int_t lastAdded = numPnts[2]; - for( int j=pol->n; j != 2; --j ) { - ends[0] = segs[pol->segs[j]]._1; - ends[1] = segs[pol->segs[j]]._2; - if (ends[0] == lastAdded) { - lastAdded = ends[1]; - } - else { - lastAdded = ends[0]; - } + else { // Points are ( s[0], s[1], s[2] ) + tes->AddFacet(v0, v1, v2); } + } + } + return tes; + } - -#endif + + struct TessellateComposite { + TBuffer3D buffer { TBuffer3DTypes::kComposite }; + std::vector<unique_ptr<TGeoTessellated> > meshes; + public: + TessellateComposite() = default; + virtual ~TessellateComposite() = default; + void collect_mesh(TGeoShape* s) { + if (TGeoCompositeShape *shape = dynamic_cast<TGeoCompositeShape *>(s)) + collect_composite(shape); + else + meshes.push_back(move(_tessellate_primitive(s->GetName(),s))); + } + void collect_composite(TGeoCompositeShape* sh) { + TGeoBoolNode* node = sh->GetBoolNode(); + TGeoShape* left = node->GetLeftShape(); + TGeoShape* right = node->GetRightShape(); + TGeoHMatrix *glmat = (TGeoHMatrix*)sh->GetTransform(); + TGeoHMatrix mat; + mat = glmat; // keep a copy + + glmat->Multiply(node->GetLeftMatrix()); + collect_mesh(left); + *glmat = &mat; + + glmat->Multiply(node->GetRightMatrix()); + collect_mesh(right); + *glmat = &mat; + } + unique_ptr<TGeoTessellated> build_composite(const std::string& name, TGeoCompositeShape* shape) { + int num_facet = 0; + this->collect_composite(shape); + unique_ptr<TGeoTessellated> tes = make_unique<TGeoTessellated>(name.c_str(), num_facet); + return tes; + } + }; } /// Write output file @@ -206,62 +198,21 @@ int ASSIMPWriter::write(const std::string& file_name, unique_ptr<TGeoHMatrix> trafo(placements[imesh].second); PlacedVolume pv = placements[imesh].first; Volume v = pv.volume(); + Solid s = v.solid(); Material m = v.material(); - TessellatedSolid tes = v.solid(); + TessellatedSolid tes = s; aiString node_name(v.name()); - // unique_ptr<TGeoTessellated> buf; if ( !tes.isValid() ) { - typedef vertex vtx_t; - unique_ptr<TBuffer3D> buf3D(v.solid()->MakeBuffer3D()); - struct pol_t { int c, n; int segs[1]; } *pol = nullptr; - struct seg_t { int c, _1, _2; }; - const seg_t* segs = (seg_t*)buf3D->fSegs; - const vtx_t* vtcs = (vtx_t*)buf3D->fPnts; - size_t i, num_facet = 0; - const Int_t* q; - - for( i=0, q=buf3D->fPols; i<buf3D->NbPols(); ++i, q += (2+pol->n)) { - pol = (pol_t*)q; - for( int j=0; j < pol->n-1; ++j ) num_facet += 2; + if ( auto* shape=dynamic_cast<TGeoCompositeShape*>(s.ptr()) ) { + TessellateComposite helper; + buf = helper.build_composite(v.name(), shape); } - - buf = make_unique<TGeoTessellated>(v.name(), num_facet); - tes = buf.get(); - q = buf3D->fPols; - for( i=0, q=buf3D->fPols; i<buf3D->NbPols(); ++i) { - pol = (pol_t*)q; - q += (2+pol->n); - for( int j=0; j < pol->n; j += 2 ) { - /* ------------------------------------------------------------ - // Convert quadri-linear facet to 2 tri-linear facets - // - // f1 +---------------+ v2/v3: f0 - // / / - // / / - // / / - // +---------------+ - // v0 v1 v2/v3 - // --------------------------------------------------------- */ - const int s1 = pol->segs[j], s2 = pol->segs[(j+1)%pol->n]; - const int s[] = { segs[s1]._1, segs[s1]._2, segs[s2]._1, segs[s2]._2 }; - const vtx_t& v0 = vtcs[s[0]], &v1=vtcs[s[1]], &v2=vtcs[s[2]], &v3=vtcs[s[3]]; - - if ( s[0] == s[2] ) { // Points are ( s[1], s[0], s[3] ) - tes->AddFacet(v1, v0, v3); - } - else if ( s[0] == s[3] ) { // Points are ( s[1], s[0], s[2] ) - tes->AddFacet(v1, v0, v2); - } - else if ( s[1] == s[2] ) { // Points are ( s[0], s[1], s[3] ) - tes->AddFacet(v0, v1, v3); - } - else { // Points are ( s[0], s[1], s[2] ) - tes->AddFacet(v0, v1, v2); - } - } + else { + buf = _tessellate_primitive(v.name(), s); } + tes = buf.get(); } if ( tes->GetNfacets() == 0 ) { continue; diff --git a/DDCore/include/XML/UnicodeValues.h b/DDCore/include/XML/UnicodeValues.h index 083656939ea989118c7a2527ef5edfebdc94394b..f45140618c717196fdfd34907fe3cb79f13c7e22 100644 --- a/DDCore/include/XML/UnicodeValues.h +++ b/DDCore/include/XML/UnicodeValues.h @@ -148,6 +148,8 @@ UNICODE (end_x); UNICODE (end_y); UNICODE (end_z); UNICODE (eval); +UNICODE (extend); +UNICODE (extends); UNICODE (f); UNICODE (F); diff --git a/DDCore/src/Shapes.cpp b/DDCore/src/Shapes.cpp index 66ee8ec70ab97b579a6d2c2eb64ca2717ef44fdc..ec2c84b58387cccbfd1bc092e9fef3a94f6eedde 100644 --- a/DDCore/src/Shapes.cpp +++ b/DDCore/src/Shapes.cpp @@ -609,17 +609,23 @@ Trap::Trap(const string& nam, } /// Constructor to be used when creating a new anonymous object with attribute initialization -void Trap::make(const string& nam, double pz, double py, double px, double pLTX) { - double z = pz / 2e0; - double theta = 0e0; - double phi = 0e0; - double h = py / 2e0; - double bl = px / 2e0; - double tl = pLTX / 2e0; - double alpha1 = (pLTX - px) / py; - _assign(new TGeoTrap(nam.c_str(), z, theta, phi, - h, bl, tl, alpha1/units::deg, - h, bl, tl, alpha1/units::deg), "", TRAP_TAG, true); +void Trap::make(const string& nam, double pZ, double pY, double pX, double pLTX) { + double fDz = 0.5*pZ; + double fTthetaCphi = 0; + double fTthetaSphi = 0; + double fDy1 = 0.5*pY; + double fDx1 = 0.5*pX; + double fDx2 = 0.5*pLTX; + double fTalpha1 = 0.5*(pLTX - pX)/pY; + double fDy2 = fDy1; + double fDx3 = fDx1; + double fDx4 = fDx2; + double fTalpha2 = fTalpha1; + + _assign(new TGeoTrap(nam.c_str(), + fDz, fTthetaCphi /* = 0 */, fTthetaSphi /* = 0 */, + fDy1, fDx1, fDx2, fTalpha1/units::deg, + fDy2, fDx3, fDx4, fTalpha2/units::deg), "", TRAP_TAG, true); } /// Set the trap dimensions