2914{
2915
2917 if (nnodes == 0)
2918 {
2919 std::cerr
2920 << "HepPolyhedronTetMesh: Empty tetrahedron mesh" << std::endl;
2921 return;
2922 }
2923 G4int ntet = nnodes/4;
2924 if (nnodes != ntet*4)
2925 {
2926 std::cerr << "HepPolyhedronTetMesh: Number of nodes = " << nnodes
2927 << " in tetrahedron mesh is NOT multiple of 4"
2928 << std::endl;
2929 return;
2930 }
2931
2932
2933
2934
2935 std::vector<G4int> iheads(nnodes, -1);
2936 std::vector<std::pair<G4int,G4int>> ipairs(nnodes,std::pair(-1,-1));
2937 for (
G4int i = 0; i < nnodes; ++i)
2938 {
2939
2941 auto key = std::hash<G4double>()(point.
x());
2942 key ^= std::hash<G4double>()(point.
y());
2943 key ^= std::hash<G4double>()(point.
z());
2944 key %= nnodes;
2945
2946 if (iheads[key] < 0)
2947 {
2948 iheads[key] = i;
2949 ipairs[i].first = i;
2950 continue;
2951 }
2952
2953 for (
G4int icur = iheads[key], iprev = 0;;)
2954 {
2955 G4int icheck = ipairs[icur].first;
2956 if (tetrahedra[icheck] == point)
2957 {
2958 ipairs[i].first = icheck;
2959 break;
2960 }
2961 iprev = icur;
2962 icur = ipairs[icur].second;
2963
2964 if (icur < 0)
2965 {
2966 ipairs[i].first = i;
2967 ipairs[iprev].second = i;
2968 break;
2969 }
2970 }
2971 }
2972
2973
2974 struct facet
2975 {
2977 facet() : i1(0), i2(0), i3(0) {};
2979 };
2980 G4int nfacets = nnodes;
2981 std::vector<facet> ifacets(nfacets);
2982 for (
G4int i = 0; i < nfacets; i += 4)
2983 {
2984 G4int i0 = ipairs[i + 0].first;
2985 G4int i1 = ipairs[i + 1].first;
2986 G4int i2 = ipairs[i + 2].first;
2987 G4int i3 = ipairs[i + 3].first;
2988 if (i0 > i1) std::swap(i0, i1);
2989 if (i0 > i2) std::swap(i0, i2);
2990 if (i0 > i3) std::swap(i0, i3);
2991 if (i1 > i2) std::swap(i1, i2);
2992 if (i1 > i3) std::swap(i1, i3);
2997 if (volume > 0.) std::swap(i2, i3);
2998 ifacets[i + 0] = facet(i0, i1, i2);
2999 ifacets[i + 1] = facet(i0, i2, i3);
3000 ifacets[i + 2] = facet(i0, i3, i1);
3001 ifacets[i + 3] = facet(i1, i3, i2);
3002 }
3003
3004
3005 std::fill(iheads.begin(), iheads.end(), -1);
3006 std::fill(ipairs.begin(), ipairs.end(), std::pair(-1,-1));
3007 for (
G4int i = 0; i < nfacets; ++i)
3008 {
3009
3010 G4int key = ifacets[i].i1;
3011 if (iheads[key] < 0)
3012 {
3013 iheads[key] = i;
3014 ipairs[i].first = i;
3015 continue;
3016 }
3017
3018 G4int i2 = ifacets[i].i2, i3 = ifacets[i].i3;
3019 for (
G4int icur = iheads[key], iprev = -1;;)
3020 {
3021 G4int icheck = ipairs[icur].first;
3022 if (ifacets[icheck].i2 == i3 && ifacets[icheck].i3 == i2)
3023 {
3024 if (iprev < 0)
3025 {
3026 iheads[key] = ipairs[icur].second;
3027 }
3028 else
3029 {
3030 ipairs[iprev].second = ipairs[icur].second;
3031 }
3032 ipairs[icur].first = -1;
3033 ipairs[icur].second = -1;
3034 break;
3035 }
3036 iprev = icur;
3037 icur = ipairs[icur].second;
3038
3039 if (icur < 0)
3040 {
3041 ipairs[i].first = i;
3042 ipairs[iprev].second = i;
3043 break;
3044 }
3045 }
3046 }
3047
3048
3049 std::fill(iheads.begin(), iheads.end(), -1);
3050 G4int nver = 0, nfac = 0;
3051 for (
G4int i = 0; i < nfacets; ++i)
3052 {
3053 if (ipairs[i].first < 0) continue;
3054 G4int i1 = ifacets[i].i1;
3055 G4int i2 = ifacets[i].i2;
3056 G4int i3 = ifacets[i].i3;
3057 if (iheads[i1] < 0) iheads[i1] = nver++;
3058 if (iheads[i2] < 0) iheads[i2] = nver++;
3059 if (iheads[i3] < 0) iheads[i3] = nver++;
3060 nfac++;
3061 }
3062
3063
3065 for (
G4int i = 0; i < nnodes; ++i)
3066 {
3067 G4int k = iheads[i];
3068 if (k >= 0)
SetVertex(k + 1, tetrahedra[i]);
3069 }
3070 for (
G4int i = 0, k = 0; i < nfacets; ++i)
3071 {
3072 if (ipairs[i].first < 0) continue;
3073 G4int i1 = iheads[ifacets[i].i1] + 1;
3074 G4int i2 = iheads[ifacets[i].i2] + 1;
3075 G4int i3 = iheads[ifacets[i].i3] + 1;
3077 }
3079}
Hep3Vector cross(const Hep3Vector &) const
void SetVertex(G4int index, const G4Point3D &v)
void SetFacet(G4int index, G4int iv1, G4int iv2, G4int iv3, G4int iv4=0)
void AllocateMemory(G4int Nvert, G4int Nface)