### Content Skeleton

#### Previous topic

VRML2FILE export debugging

#### Next topic

VRML2FILE implementation

# Polyhedron¶

## Relation Between Vertices, Edges and Faces¶

For a convex polyhedron: V - E + F = 2

## VRML2FILE Polyhedron Export¶

external/build/LCG/geant4.9.2.p01/source/visualization/VRML/src/G4VRML2SceneHandlerFunc.icc:

169 void G4VRML2SCENEHANDLER::AddPrimitive(const G4Polyhedron& polyhedron)
170 {
171 #if defined DEBUG_SCENE_FUNC
172     G4cerr << "***** AddPrimitive(G4Polyhedron)" << "\n";
173 #endif
174
175     if (polyhedron.GetNoFacets() == 0) return;
...
199     fDest << "\t"; fDest << "Shape {" << "\n";
200
201     SendMaterialNode();
202
203     fDest << "\t\t" << "geometry IndexedFaceSet {" << "\n";
204
205     fDest << "\t\t\t"   << "coord Coordinate {" << "\n";
206     fDest << "\t\t\t\t" <<      "point [" << "\n";
207     G4int i, j;
208     for (i = 1, j = polyhedron.GetNoVertices(); j; j--, i++) {
209         G4Point3D point = polyhedron.GetVertex(i);
210
211         point.transform( *fpObjectTransformation );
212
213         fDest << "\t\t\t\t\t";
214         fDest <<                   point.x() << " ";
215         fDest <<                   point.y() << " ";
216         fDest <<                   point.z() << "," << "\n";
217     }
218     fDest << "\t\t\t\t" <<      "]" << "\n"; // point
219     fDest << "\t\t\t"   << "}"      << "\n"; // coord
220
221     fDest << "\t\t\t"   << "coordIndex [" << "\n";
222
223     // facet loop
224     G4int f;
225     for (f = polyhedron.GetNoFacets(); f; f--) {
226
227         // edge loop
228         G4bool notLastEdge;
229         G4int index = -1, edgeFlag = 1;
230         fDest << "\t\t\t\t";
231         do {
232             notLastEdge = polyhedron.GetNextVertexIndex(index, edgeFlag);
233             fDest << index - 1 << ", ";
234         } while (notLastEdge);
235         fDest << "-1," << "\n";
236     }
237     fDest << "\t\t\t"   << "]" << "\n"; // coordIndex
238
239     fDest << "\t\t\t"   << "solid FALSE" << "\n"; // draw backfaces
240
241     fDest << "\t\t" << "}"     << "\n"; // IndexFaceSet
242     fDest << "\t" << "}"       << "\n"; // Shape

/data/env/local/dyb/trunk/external/build/LCG/geant4.9.2.p01/source/graphics_reps/src/HepPolyhedron.cc:

858 bool HepPolyhedron::GetNextVertexIndex(int &index, int &edgeFlag) const
859 /***********************************************************************
860  *                                                                     *
861  * Name: HepPolyhedron::GetNextVertexIndex          Date:    03.09.96  *
862  * Author: Yasuhide Sawada                          Revised:           *
863  *                                                                     *
864  * Function:                                                           *
865  *                                                                     *
866  ***********************************************************************/
867 {
868   static int iFace = 1;
869   static int iQVertex = 0;
870   int vIndex = pF[iFace].edge[iQVertex].v;
871
872   edgeFlag = (vIndex > 0) ? 1 : 0;
873   index = std::abs(vIndex);
874
875   if (iQVertex >= 3 || pF[iFace].edge[iQVertex+1].v == 0) {
876     iQVertex = 0;
877     if (++iFace > nface) iFace = 1;
878     return false;  // Last Edge
879   }else{
880     ++iQVertex;
881     return true;  // not Last Edge
882   }
883 }

../include/HepPolyhedron.h:

168 #ifndef HEP_POLYHEDRON_HH
169 #define HEP_POLYHEDRON_HH
170
171 #include <CLHEP/Geometry/Point3D.h>
172 #include <CLHEP/Geometry/Normal3D.h>
173
174 #ifndef DEFAULT_NUMBER_OF_STEPS
175 #define DEFAULT_NUMBER_OF_STEPS 24
176 #endif
177
178 class G4Facet {
179   friend class HepPolyhedron;
180   friend std::ostream& operator<<(std::ostream&, const G4Facet &facet);
181
182  private:
183   struct G4Edge { int v,f; };
184   G4Edge edge[4];
###     a facet can have either 3 or 4 edges
185
186  public:
187   G4Facet(int v1=0, int f1=0,
int v2=0, int f2=0,
188           int v3=0, int f3=0,
int v4=0, int f4=0)
189   { edge[0].v=v1; edge[0].f=f1;
edge[1].v=v2; edge[1].f=f2;
190     edge[2].v=v3; edge[2].f=f3;
edge[3].v=v4; edge[3].f=f4; }
191 };
192
193 class HepPolyhedron {
194   friend std::ostream& operator<<(std::ostream&, const HepPolyhedron &ph);
195
196  protected:
197   static int fNumberOfRotationSteps;
198   int nvert, nface;
199   HepGeom::Point3D<double> *pV;
200   G4Facet    *pF;
201
1260 double HepPolyhedron::GetVolume() const
1261 /***********************************************************************
1262  *                                                                     *
1263  * Name: HepPolyhedron::GetVolume                   Date:    25.05.01  *
1264  * Author: E.Chernyaev                              Revised:           *
1265  *                                                                     *
1266  * Function: Returns volume of the polyhedron.                         *
1267  *                                                                     *
1268  ***********************************************************************/
1269 {
1270   double v = 0.;
1271   for (int iFace=1; iFace<=nface; iFace++) {
1272     int i0 = std::abs(pF[iFace].edge[0].v);
1273     int i1 = std::abs(pF[iFace].edge[1].v);
1274     int i2 = std::abs(pF[iFace].edge[2].v);
1275     int i3 = std::abs(pF[iFace].edge[3].v);
1276     Point3D<double> g;
1277     if (i3 == 0) {
1278       i3 = i0;
1279       g  = (pV[i0]+pV[i1]+pV[i2]) * (1./3.);
1280     }else{
1281       g  = (pV[i0]+pV[i1]+pV[i2]+pV[i3]) * 0.25;
1282     }
1283     v += ((pV[i2] - pV[i0]).cross(pV[i3] - pV[i1])).dot(g);
1284   }
1285   return v/6.;
1286 }
1065 void HepPolyhedron::GetFacet(int iFace, int &n, int *iNodes,
1066                             int *edgeFlags, int *iFaces) const
1067 /***********************************************************************
1068  *                                                                     *
1069  * Name: HepPolyhedron::GetFacet                    Date:    15.12.99  *
1070  * Author: E.Chernyaev                              Revised:           *
1071  *                                                                     *
1072  * Function: Get face by index                                         *
1073  *                                                                     *
1074  ***********************************************************************/
1075 {
1076   if (iFace < 1 || iFace > nface) {
1077     std::cerr
1078       << "HepPolyhedron::GetFacet: irrelevant index " << iFace
1079       << std::endl;
1080     n = 0;
1081   }else{
1082     int i, k;
1083     for (i=0; i<4; i++) {
1084       k = pF[iFace].edge[i].v;
1085       if (k == 0) break;
1086       if (iFaces != 0) iFaces[i] = pF[iFace].edge[i].f;
1087       if (k > 0) {
1088         iNodes[i] = k;
1089         if (edgeFlags != 0) edgeFlags[i] = 1;
1090       }else{
1091         iNodes[i] = -k;
1092         if (edgeFlags != 0) edgeFlags[i] = -1;
1093       }
1094     }
1095     n = i;
1096   }
1097 }
270 void HepPolyhedron::CreatePrism()
271 /***********************************************************************
272  *                                                                     *
273  * Name: HepPolyhedron::CreatePrism                  Date:    15.07.96 *
274  * Author: E.Chernyaev (IHEP/Protvino)               Revised:          *
275  *                                                                     *
276  * Function: Set facets for a prism                                    *
277  *                                                                     *
278  ***********************************************************************/
279 {
280   enum {DUMMY, BOTTOM, LEFT, BACK, RIGHT, FRONT, TOP};
281
282   pF[1] = G4Facet(1,LEFT,  4,BACK,  3,RIGHT,  2,FRONT);
283   pF[2] = G4Facet(5,TOP,   8,BACK,  4,BOTTOM, 1,FRONT);
284   pF[3] = G4Facet(8,TOP,   7,RIGHT, 3,BOTTOM, 4,LEFT);
285   pF[4] = G4Facet(7,TOP,   6,FRONT, 2,BOTTOM, 3,BACK);
286   pF[5] = G4Facet(6,TOP,   5,LEFT,  1,BOTTOM, 2,RIGHT);
287   pF[6] = G4Facet(5,FRONT, 6,RIGHT, 7,BACK,   8,LEFT);
288 }
1388 HepPolyhedronTrd2::HepPolyhedronTrd2(double Dx1, double Dx2,
1389                                      double Dy1, double Dy2,
1390                                      double Dz)
1391 /***********************************************************************
1392  *                                                                     *
1393  * Name: HepPolyhedronTrd2                           Date:    22.07.96 *
1394  * Author: E.Chernyaev (IHEP/Protvino)               Revised:          *
1395  *                                                                     *
1396  * Function: Create GEANT4 TRD2-trapezoid                              *
1397  *                                                                     *
1398  * Input: Dx1 - half-length along X at -Dz           8----7            *
1399  *        Dx2 - half-length along X ay +Dz        5----6  !            *
1400  *        Dy1 - half-length along Y ay -Dz        !  4-!--3            *
1401  *        Dy2 - half-length along Y ay +Dz        1----2               *
1402  *        Dz  - half-length along Z                                    *
1403  *                                                                     *
1404  ***********************************************************************/
1405 {
1406   AllocateMemory(8,6);
1407
1408   pV[1] = Point3D<double>(-Dx1,-Dy1,-Dz);
1409   pV[2] = Point3D<double>( Dx1,-Dy1,-Dz);
1410   pV[3] = Point3D<double>( Dx1, Dy1,-Dz);
1411   pV[4] = Point3D<double>(-Dx1, Dy1,-Dz);
1412   pV[5] = Point3D<double>(-Dx2,-Dy2, Dz);
1413   pV[6] = Point3D<double>( Dx2,-Dy2, Dz);
1414   pV[7] = Point3D<double>( Dx2, Dy2, Dz);
1415   pV[8] = Point3D<double>(-Dx2, Dy2, Dz);
1416
1417   CreatePrism();
1418 }