ATLAS Offline Software
BooleanProcessor.h
Go to the documentation of this file.
1 /*
2  Copyright (C) 2002-2021 CERN for the benefit of the ATLAS collaboration
3 */
4 
5 /*
6  * PLEASE NOTE: This file has been copied and pasted from GEANT4, rel. 4.9.6.cand00
7  *
8  * original source file:
9  * /afs/cern.ch/sw/geant4/releases/geant4.9.6.cand00/share/source/graphics_reps/src/BooleanProcessor.src
10  *
11  *
12  * Update: Riccardo-Maria BIANCHI <rbianchi@cern.ch> - 2012-11-16
13  *
14  *
15  * NOTES:
16  *
17  * ===================
18  * VP1 Customization:
19  *
20  * - look into the code for comments "// VP1 change"
21  *
22  *
23 */
24 
25 
26 /***********************************************************************
27  * *
28  * Name: BooleanProcessor Date: 10.12.99 *
29  * Author: E.Chernyaev Revised: *
30  * *
31  * Function: Internal class for executing boolean operations *
32  * on Polyhedra *
33  * *
34  ***********************************************************************/
35 
36 
37 
38 
39 /* // VP1 change
40 //G.Barrand : begin
41 #define BP_GEANT4
42 */
43 
44 #ifdef BP_GEANT4 //G.Barrand
45 #include "G4Plane3D.hh"
46 #include "G4Point3D.hh"
47 #include "G4Normal3D.hh"
48 typedef G4Plane3D HVPlane3D;
49 typedef G4Point3D HVPoint3D;
50 typedef G4Normal3D HVNormal3D;
51 
52 #else //BP_HEPVIS
53 
54 #define ExtNode HEPVis_ExtNode
55 #define ExtEdge HEPVis_ExtEdge
56 #define ExtFace HEPVis_ExtFace
57 #define FaceList HEPVis_FaceList
58 #define ExtPolyhedron HEPVis_ExtPolyhedron
59 #define BooleanProcessor HEPVis_BooleanProcessor
60 
61 #define HepPolyhedron SbPolyhedron
62 #define G4Facet SbFacet
63 
64 // VP1 change
65 //#include <HEPVis/SbPlane.h>
66 #include <VP1HEPVis/SbPlane.h>
68 //---
69 
70 
71 #endif
72 
73 
74 
75 
76 //using namespace HepGeom;
77 
78 //#define BP_DEBUG
79 
80 //G.Barrand : end
81 
82 #define INITIAL_SIZE 200
83 #define CRAZY_POINT HVPoint3D(-10.e+6, -10.e+6, -10.e+6)
84 //#define GRANULARITY 10.e+5;
85 #define GRANULARITY 10.e+5 //G.Barrand : rm the trailing ;
86 
87 #define SWAP(A,B) w = A; A = B; B = w
88 
89 #define OP_UNION 0 // Operations
90 #define OP_INTERSECTION 1
91 #define OP_SUBTRACTION 2
92 
93 #define OUT_OF_PLANE 0 // Face vs face statuses
94 #define ON_PLANE 1
95 #define INTERSECTION 2
96 #define EDGE 3
97 #define NON_PLANAR_FACE 4
98 
99 #define UNKNOWN_FACE 0 // Face statuses
100 #define ORIGINAL_FACE -1
101 #define NEW_FACE -2
102 #define UNSUITABLE_FACE -3
103 #define DEFECTIVE_FACE -4
104 
105 
106 
107 // -------------------------------------------- Simplified STL vector ---
108 //G.Barrand : begin
109 #include <vector>
110 /*
111 template<class T>
112 class vector {
113  private:
114  int cur_size, max_size;
115  T * v;
116 
117  public:
118  vector(): cur_size(0), max_size(INITIAL_SIZE), v(new T[INITIAL_SIZE]) {}
119  ~vector() { delete [] v; }
120 
121  void clear() { cur_size = 0; }
122  int size() const { return cur_size; }
123  T & operator[](int i) { return v[i]; }
124  const T & operator[](int i) const { return v[i]; }
125  T & front() { return v[0]; }
126  const T & front() const { return v[0]; }
127  T & back() { return v[cur_size-1]; }
128  const T & back() const { return v[cur_size-1]; }
129  void pop_back() { cur_size--; }
130  void push_back(const T & a) {
131  if (cur_size == max_size) {
132  T * w = v;
133  max_size *= 2;
134  v = new T[max_size];
135  for (int i=0; i<cur_size; i++) v[i] = w[i];
136  v[cur_size++] = a;
137  delete [] w;
138  }else{
139  v[cur_size++] = a;
140  }
141  }
142 };
143 */
144 //G.Barrand : end
145 
146 // ---------------------------------------------------- Extended node ---
147 class ExtNode {
148  public:
150  int s;
151 
152  public:
154  : v(vertex), s(status) {}
155  ~ExtNode() {}
156 
157  ExtNode(const ExtNode & node) : v(node.v), s(node.s) {}
158 
160  if (&node == this) return *this;
161  v = node.v;
162  s = node.s;
163  return *this;
164  }
165 };
166 
167 // ---------------------------------------------------- Extended edge ---
168 class ExtEdge {
169  public:
170  int i1, i2; // end points
171  int iface1; // native face
172  int iface2; // neighbouring face
173  int ivis; // visibility: +1 (visible), -1 (invisible)
174  int inext; // index of next edge
175 
176  public:
177  ExtEdge(int k1=0, int k2=0, int kface1=0, int kface2=0, int kvis=0) :
178  i1(k1), i2(k2), iface1(kface1), iface2(kface2), ivis(kvis), inext(0) {}
179 
180  ~ExtEdge() {};
181 
182  ExtEdge(const ExtEdge & edge) :
183  i1(edge.i1), i2(edge.i2), iface1(edge.iface1), iface2(edge.iface2),
184  ivis(edge.ivis), inext(edge.inext) {}
185 
186  ExtEdge & operator=(const ExtEdge & edge) {
187  if (&edge == this) return *this;
188  i1 = edge.i1;
189  i2 = edge.i2;
190  iface1 = edge.iface1;
191  iface2 = edge.iface2;
192  ivis = edge.ivis;
193  inext = edge.inext;
194  return *this;
195  }
196 
197  void invert() {
198  int w;
199  SWAP(i1, i2);
200  }
201 };
202 
203 // ---------------------------------------------------- Extended face ---
204 class ExtFace {
205  private:
206  std::vector<ExtEdge>& m_edges; //G.Barrand // VP1 change
207  public:
208  int iedges[4]; // indices of original edges
209  HVPlane3D plane; // face plane
210  double rmin[3], rmax[3]; // bounding box
211  int iold; // head of the list of the original edges
212  int inew; // head of the list of the new edges
213  int iprev; // index of previous face
214  int inext; // index of next face
215 
216  public:
217  //G.Barrand : ExtFace(int iedge=0) : iold(iedge), inew(0), iprev(iprev), inext(0) {}
218  ExtFace(std::vector<ExtEdge>& a_edges,int iedge)
219  : m_edges(a_edges), iold(iedge), inew(0), iprev(0), inext(0) {
220  //G.Barrand : initialize arrays to quiet valgrind.
221  {for (int i=0; i<4; i++) { iedges[i] = 0; }}
222  {for (int i=0; i<3; i++) { rmin[i] = 0; rmax[i] = 0; }}
223  }
224  ~ExtFace() {}
225 
226  ExtFace(const ExtFace & face) :
227  m_edges(face.m_edges), //G.Barrand
228  plane(face.plane), iold(face.iold), inew(face.inew),
229  iprev(face.iprev), inext(face.inext)
230  {
231  int i;
232  for (i=0; i<4; i++) { iedges[i] = face.iedges[i]; }
233  for (i=0; i<3; i++) { rmin[i] = face.rmin[i]; rmax[i] = face.rmax[i]; }
234  }
235 
236  ExtFace & operator=(const ExtFace & face) {
237  if (&face == this) return *this;
238  //FIXME : edges(face.edges) ???? //G.Barrand
239  int i;
240  for (i=0; i<4; i++) { iedges[i] = face.iedges[i]; }
241  plane = face.plane;
242  for (i=0; i<3; i++) { rmin[i] = face.rmin[i]; rmax[i] = face.rmax[i]; }
243  iold = face.iold;
244  inew = face.inew;
245  iprev = face.iprev;
246  inext = face.inext;
247  return *this;
248  }
249 
250  void invert();
251 };
252 
253 // ---------------------------------------------------- Global arrays ---
254 //G.Barrand : MacIntel : crash with g++-4.0.1 with -O on some subtract.
255 // Anyway static of objects is proved to be not safe.
256 // We put the below vector as members of BooleanProcessor.
257 //GB static std::vector<ExtNode> nodes; // vector of nodes
258 //GB static std::vector<ExtEdge> edges; // vector of edges
259 //GB static std::vector<ExtFace> faces; // vector of faces
260 
261 // ---------------------------------------------------- List of faces ---
262 class FaceList {
263  private:
264  std::vector<ExtFace>& m_faces; //G.Barrad : end // VP1 change
265  private:
266  int m_ihead;
267  int m_ilast;
268 
269  public:
270  //G.Barrand : FaceList() : ihead(0), ilast(0) {}
271  FaceList(std::vector<ExtFace>& a_faces) : m_faces(a_faces),m_ihead(0),m_ilast(0) {}
273 
274  void clean() { m_ihead = 0; m_ilast = 0; }
275  int front() { return m_ihead; }
276 
277  void push_back(int i) {
278  if (m_ilast == 0) { m_ihead = i; } else { m_faces[m_ilast].inext = i; }
279  ExtFace& face = m_faces[i]; //G.Barrand : optimize.
280  face.iprev = m_ilast;
281  face.inext = 0;
282  m_ilast = i;
283  }
284 
285  void remove(int i) {
286  ExtFace& face = m_faces[i]; //G.Barrand : optimize.
287  if (m_ihead == i) {
288  m_ihead = face.inext;
289  }else{
290  m_faces[face.iprev].inext = face.inext;
291  }
292  if (m_ilast == i) {
293  m_ilast = face.iprev;
294  }else{
295  m_faces[face.inext].iprev = face.iprev;
296  }
297  face.iprev = 0;
298  face.inext = 0;
299  }
300 };
301 
302 // --------------------- Polyhedron with extended access to
303 // its members from the BooleanProcessor class ---
304 class ExtPolyhedron : public HepPolyhedron {
305  friend class BooleanProcessor;
306  virtual HepPolyhedron& operator = (const HepPolyhedron& from) {
307  return HepPolyhedron::operator = (from);
308  }
309 };
310 
311 // ----------------------------------------- Boolean processor class ---
313  private:
314  static int s_ishift; //G.Barrand // VP1 change
315  std::vector<ExtNode> m_nodes; // vector of nodes //G.Barrand // VP1 change
316  std::vector<ExtEdge> m_edges; // vector of edges //G.Barrand // VP1 change
317  std::vector<ExtFace> m_faces; // vector of faces //G.Barrand // VP1 change
318  private:
319  int m_processor_error; // is set in case of error // VP1 change
320  int m_operation; // 0 (union), 1 (intersection), 2 (subtraction) // VP1 change
321  int m_ifaces1, m_ifaces2; // lists of faces // VP1 change
322  int m_iout1, m_iout2; // lists of faces with status "out" // VP1 change
323  int m_iunk1, m_iunk2; // lists of faces with status "unknown" // VP1 change
324  double m_rmin[3], m_rmax[3]; // intersection of bounding boxes // VP1 change
325  double m_del; // precision (tolerance) // VP1 change
326 
327  FaceList m_result_faces; // list of accepted faces // VP1 change
328  FaceList m_suitable_faces; // list of suitable faces // VP1 change
329  FaceList m_unsuitable_faces; // list of unsuitable faces // VP1 change
330  FaceList m_unknown_faces; // list of unknown faces // VP1 change
331 
332  std::vector<int> m_external_contours; // heads of external contours // VP1 change
333  std::vector<int> m_internal_contours; // heads of internal contours // VP1 change
334 
335  private:
336  void takePolyhedron(const HepPolyhedron & p, double, double, double);
337  double findMinMax();
338  void selectOutsideFaces(int & ifaces, int & iout);
339  int testFaceVsPlane(ExtEdge & edge);
340  void renumberNodes(int & i1, int & i2, int & i3, int & i4);
341  int testEdgeVsEdge(ExtEdge & edge1, ExtEdge & edge2);
342  void removeJunkNodes() { while(m_nodes.back().s != 0) m_nodes.pop_back(); }
343  void divideEdge(int & i1, int & i2);
344  void insertEdge(const ExtEdge & edge);
345  void caseII(ExtEdge & edge1, ExtEdge & edge2);
346  void caseIE(ExtEdge & edge1, ExtEdge & edge2);
347  void caseEE(ExtEdge & edge1, ExtEdge & edge2);
348  void testFaceVsFace(int iface1, int iface2);
349  void invertNewEdges(int iface);
350  void checkDoubleEdges(int iface);
351  void assembleFace(int what, int iface);
352  void assembleNewFaces(int what, int ihead);
353  void initiateLists();
354  void assemblePolyhedra();
355  void findABC(double x1, double y1, double x2, double y2,
356  double &a, double &b, double &c) const;
357  int checkDirection(double *x, double *y) const;
358  int checkIntersection(int ix, int iy, int i1, int i2) const;
359  void mergeContours(int ix, int iy, int kext, int kint);
360  int checkTriangle(int iedge1, int iedge2, int ix, int iy) const;
361  void triangulateContour(int ix, int iy, int ihead);
362  void modifyReference(int iface, int i1, int i2, int iref);
363  void triangulateFace(int iface);
365 
366  public:
367  //G.Barrand : BooleanProcessor() {}
368  BooleanProcessor() //G.Barrand
369  :m_processor_error(0) // The next few fields are work space, initialised
370  ,m_operation(0) // here to prevent Coverity warnings.
371  ,m_ifaces1(0) // "
372  ,m_ifaces2(0) // "
373  ,m_iout1(0) // "
374  ,m_iout2(0) // "
375  ,m_iunk1(0) // "
376  ,m_iunk2(0) // "
377  ,m_del(0.) // "
382  { // rmin, rmax also initialised here to prevent Coverity warnings.
383  for (int i = 0; i < 3; i++) {
384  m_rmin[i] = 0.;
385  m_rmax[i] = 0.;
386  }
387  }
388 
390 
391  HepPolyhedron execute(int op,
392  const HepPolyhedron &a,
393  const HepPolyhedron &b,
394  int& err);
395 
396  void draw();
397  void draw_edge(int, int);
398  void draw_contour(int, int, int);
399  void draw_faces(int, int, int);
400  void print_face(int);
401  void print_edge(int);
403 
404  void dump(); //G.Barrand
405  static int get_shift(); //G.Barrand
406  static void set_shift(int); //G.Barrand
407  static int get_num_shift(); //G.Barrand
408 };
409 
410 inline void ExtFace::invert()
411 /***********************************************************************
412  * *
413  * Name: ExtFace::invert() Date: 28.02.00 *
414  * Author: E.Chernyaev Revised: *
415  * *
416  * Function: Invert face *
417  * *
418  ***********************************************************************/
419 {
420  int iEprev, iEcur, iEnext;
421 
422  iEprev = 0; iEcur = iold;
423  while (iEcur > 0) {
424  ExtEdge& edge = m_edges[iEcur]; //G.Barrand : optimize.
425  edge.invert();
426  iEnext = edge.inext;
427  edge.inext = iEprev;
428  iEprev = iEcur;
429  iEcur = iEnext;
430  }
431  if (iold > 0) iold = iEprev;
432 
433  iEprev = 0; iEcur = inew;
434  while (iEcur > 0) {
435  ExtEdge& edge = m_edges[iEcur]; //G.Barrand : optimize.
436  edge.invert();
437  iEnext = edge.inext;
438  edge.inext = iEprev;
439  iEprev = iEcur;
440  iEcur = iEnext;
441  }
442  if (inew > 0) inew = iEprev;
443 
444 #ifdef BP_GEANT4 //G.Barrand
445  plane = HVPlane3D(-plane.a(), -plane.b(), -plane.c(), -plane.d());
446 #else
448 #endif
449 }
450 
452  double dx, double dy, double dz)
453 /***********************************************************************
454  * *
455  * Name: BooleanProcessor::takePolyhedron Date: 16.12.99 *
456  * Author: E.Chernyaev Revised: *
457  * *
458  * Function: Transfer Polyhedron to internal representation *
459  * *
460  ***********************************************************************/
461 {
462  int i, k, nnode, iNodes[5], iVis[4], iFaces[4];
463  int dnode = m_nodes.size() - 1;
464  int dface = m_faces.size() - 1;
465 
466  // S E T N O D E S
467 
468  // for (i=1; i <= p.GetNoVertices(); i++) {
469  // nodes.push_back(ExtNode(p.GetVertex(i)));
470  // }
471 
472  HVPoint3D ppp;
473  for (i=1; i <= p.GetNoVertices(); i++) {
474 #ifdef BP_GEANT4 //G.Barrand
475  ppp = p.GetVertex(i);
476  ppp.setX(ppp.x()+dx);
477  ppp.setY(ppp.y()+dy);
478  ppp.setZ(ppp.z()+dz);
479 #else
480  ppp = p.GetVertexFast(i);
481  ppp += HVPoint3D(dx,dy,dz);
482 #endif
483  m_nodes.push_back(ExtNode(ppp));
484  }
485 
486  // S E T F A C E S
487 
488  for (int iface=1; iface <= p.GetNoFacets(); iface++) {
489  m_faces.push_back(ExtFace(m_edges,m_edges.size()));
490 
491  // S E T F A C E N O D E S
492 
493  p.GetFacet(iface, nnode, iNodes, iVis, iFaces);
494  for (i=0; i<nnode; i++) {
495  //if (iNodes[i] < 1 || iNodes[i] > p.GetNoVertices()) m_processor_error = 1;
496  //if (iFaces[i] < 1 || iFaces[i] > p.GetNoFacets()) m_processor_error = 1;
497 
498  if (iNodes[i] < 1 || iNodes[i] > p.GetNoVertices()) { //G.Barrand
499  m_processor_error = 1;
500 #ifdef BP_DEBUG
501  G4cerr
502  << "BooleanProcessor::takePolyhedron : problem 1."
503  << G4endl;
504 #endif
505  }
506  if (iFaces[i] < 1 || iFaces[i] > p.GetNoFacets()) { //G.Barrand
507  m_processor_error = 1;
508 #ifdef BP_DEBUG
509  G4cerr
510  << "BooleanProcessor::takePolyhedron : problem 2."
511  << G4endl;
512 #endif
513  }
514  iNodes[i] += dnode;
515  iFaces[i] += dface;
516  }
517 
518  // S E T E D G E S
519 
520  iNodes[nnode] = iNodes[0];
521  m_faces.back().iedges[3] = 0;
522  for (i=0; i<nnode; i++) {
523  m_faces.back().iedges[i] = m_edges.size();
524  m_edges.push_back(ExtEdge(iNodes[i], iNodes[i+1],
525  iface+dface, iFaces[i], iVis[i]));
526  m_edges.back().inext = m_edges.size();
527  }
528  m_edges.back().inext = 0;
529 
530  // S E T F A C E M I N - M A X
531 
532  ExtFace& face = m_faces.back(); //G.Barrand : optimize.
533  for (i=0; i<3; i++) {
534  face.rmin[i] = m_nodes[iNodes[0]].v[i];
535  face.rmax[i] = m_nodes[iNodes[0]].v[i];
536  }
537  for (i=1; i<nnode; i++) {
538  ExtNode& node = m_nodes[iNodes[i]]; //G.Barrand : optimize.
539  for (k=0; k<3; k++) {
540  if (face.rmin[k] > node.v[k])
541  face.rmin[k] = node.v[k];
542  if (face.rmax[k] < node.v[k])
543  face.rmax[k] = node.v[k];
544  }
545  }
546 
547  // S E T F A C E P L A N E
548 
549  HVNormal3D n = (m_nodes[iNodes[2]].v-m_nodes[iNodes[0]].v).cross
550  (m_nodes[iNodes[3]].v-m_nodes[iNodes[1]].v);
551  HVPoint3D point(0,0,0);
552 
553  for (i=0; i<nnode; i++) { point += m_nodes[iNodes[i]].v; }
554  if (nnode > 1) point *= (1./nnode);
555 
556 
557  //G.Barrand : faces.back().plane = HVPlane3D(n.unit(), point);
558  m_faces.back().plane = HVPlane3D(n, point); //G.Barrand
559 
560  // S E T R E F E R E N C E T O T H E N E X T F A C E
561 
562  m_faces.back().inext = m_faces.size();
563  }
564  m_faces.back().inext = 0;
565 }
566 
568 /***********************************************************************
569  * *
570  * Name: BooleanProcessor::findMinMax Date: 16.12.99 *
571  * Author: E.Chernyaev Revised: *
572  * *
573  * Function: Find min-max (bounding) boxes for polyhedra *
574  * *
575  ***********************************************************************/
576 {
577  if (m_ifaces1 == 0 || m_ifaces2 == 0) return 0;
578 
579  int i, iface;
580  double rmin1[3], rmax1[3];
581  double rmin2[3], rmax2[3];
582 
583  // F I N D B O U N D I N G B O X E S
584 
585  for (i=0; i<3; i++) {
586  rmin1[i] = m_faces[m_ifaces1].rmin[i];
587  rmax1[i] = m_faces[m_ifaces1].rmax[i];
588  rmin2[i] = m_faces[m_ifaces2].rmin[i];
589  rmax2[i] = m_faces[m_ifaces2].rmax[i];
590  }
591 
592  iface = m_faces[m_ifaces1].inext;
593  while(iface > 0) {
594  ExtFace& face = m_faces[iface]; //G.Barrand
595  for (i=0; i<3; i++) {
596  if (rmin1[i] > face.rmin[i]) rmin1[i] = face.rmin[i];
597  if (rmax1[i] < face.rmax[i]) rmax1[i] = face.rmax[i];
598  }
599  iface = face.inext;
600  }
601 
602  iface = m_faces[m_ifaces2].inext;
603  while(iface > 0) {
604  ExtFace& face = m_faces[iface]; //G.Barrand
605  for (i=0; i<3; i++) {
606  if (rmin2[i] > face.rmin[i]) rmin2[i] = face.rmin[i];
607  if (rmax2[i] < face.rmax[i]) rmax2[i] = face.rmax[i];
608  }
609  iface = face.inext;
610  }
611 
612  // F I N D I N T E R S E C T I O N O F B O U N D I N G B O X E S
613 
614  for (i=0; i<3; i++) {
615  m_rmin[i] = (rmin1[i] > rmin2[i]) ? rmin1[i] : rmin2[i];
616  m_rmax[i] = (rmax1[i] < rmax2[i]) ? rmax1[i] : rmax2[i];
617  }
618 
619  // F I N D T O L E R A N C E
620 
621  double del1 = 0;
622  double del2 = 0;
623  for (i=0; i<3; i++) {
624  if ((rmax1[i]-rmin1[i]) > del1) del1 = rmax1[i]-rmin1[i];
625  if ((rmax2[i]-rmin2[i]) > del2) del2 = rmax2[i]-rmin2[i];
626  }
627  return ((del1 < del2) ? del1 : del2) / GRANULARITY;
628 }
629 
630 void BooleanProcessor::selectOutsideFaces(int & ifaces, int & iout)
631 /***********************************************************************
632  * *
633  * Name: BooleanProcessor::selectOutsideFaces Date: 10.01.00 *
634  * Author: E.Chernyaev Revised: *
635  * *
636  * Function: Preselection of outside faces *
637  * *
638  ***********************************************************************/
639 {
640  int i, outflag, iface = ifaces, *prev;
641  HVPoint3D mmbox[8] = { HVPoint3D(m_rmin[0],m_rmin[1],m_rmin[2]),
642  HVPoint3D(m_rmax[0],m_rmin[1],m_rmin[2]),
643  HVPoint3D(m_rmin[0],m_rmax[1],m_rmin[2]),
644  HVPoint3D(m_rmax[0],m_rmax[1],m_rmin[2]),
645  HVPoint3D(m_rmin[0],m_rmin[1],m_rmax[2]),
646  HVPoint3D(m_rmax[0],m_rmin[1],m_rmax[2]),
647  HVPoint3D(m_rmin[0],m_rmax[1],m_rmax[2]),
648  HVPoint3D(m_rmax[0],m_rmax[1],m_rmax[2]) };
649  prev = &ifaces;
650  while (iface > 0) {
651 
652  // B O U N D I N G B O X vs B O U N D I N G B O X
653 
654  outflag = 0;
655  ExtFace& face = m_faces[iface]; //G.Barrand : optimize.
656  for (i=0; i<3; i++) {
657  if (face.rmin[i] > m_rmax[i] + m_del) { outflag = 1; break; }
658  if (face.rmax[i] < m_rmin[i] - m_del) { outflag = 1; break; }
659  }
660 
661  // B O U N D I N G B O X vs P L A N E
662 
663  if (outflag == 0) {
664  int npos = 0, nneg = 0;
665  double d;
666  for (i=0; i<8; i++) {
667  d = face.plane.distance(mmbox[i]); //G.Barrand : optimize
668  if (d > +m_del) npos++;
669  if (d < -m_del) nneg++;
670  }
671  if (npos == 8 || nneg == 8) outflag = 1;
672  }
673 
674  // U P D A T E L I S T S
675 
676  if (outflag == 1) {
677  *prev = face.inext;
678  face.inext = iout;
679  iout = iface;
680  }else{
681  prev = &face.inext;
682  }
683 
684  iface = *prev;
685  }
686 }
687 
689 /***********************************************************************
690  * *
691  * Name: BooleanProcessor::testFaceVsPlane Date: 19.01.00 *
692  * Author: E.Chernyaev Revised: *
693  * *
694  * Function: Find result of intersection of face by plane *
695  * *
696  ***********************************************************************/
697 {
698  int iface = edge.iface1;
699  HVPlane3D plane = m_faces[edge.iface2].plane;
700  int i, nnode, npos = 0, nneg = 0, nzer = 0;
701  double dd[5];
702 
703  // F I N D D I S T A N C E S
704 
705  nnode = (m_faces[iface].iedges[3] == 0) ? 3 : 4;
706  for (i=0; i<nnode; i++) {
707  dd[i] = plane.distance(m_nodes[m_edges[m_faces[iface].iedges[i]].i1].v);
708  if (dd[i] > m_del) {
709  npos++;
710  }else if (dd[i] < -m_del) {
711  nneg++;
712  }else{
713  nzer++; dd[i] = 0;
714  }
715  }
716 
717  // S O M E S I M P L E C A S E S ( N O I N T E R S E C T I O N )
718 
719  if (npos == nnode || nneg == nnode) return OUT_OF_PLANE;
720  if (nzer == 1 && nneg == 0) return OUT_OF_PLANE;
721  if (nzer == 1 && npos == 0) return OUT_OF_PLANE;
722  if (nzer == nnode) return ON_PLANE;
723  if (nzer == 3) return NON_PLANAR_FACE;
724 
725  // F I N D I N T E R S E C T I O N
726 
727  int ie1 = 0, ie2 = 0, s1 = 0, s2 = 0, status, nint = 0;
728  enum { PLUS_MINUS, MINUS_PLUS, ZERO_ZERO, ZERO_PLUS, ZERO_MINUS };
729 
730  dd[nnode] = dd[0];
731  for (i=0; i<nnode; i++) {
732  if (dd[i] > 0) {
733  if (dd[i+1] >= 0) continue;
734  status = PLUS_MINUS;
735  }else if (dd[i] < 0) {
736  if (dd[i+1] <= 0) continue;
737  status = MINUS_PLUS;
738  }else{
739  status = ZERO_ZERO;
740  if (dd[i+1] > 0) status = ZERO_PLUS;
741  if (dd[i+1] < 0) status = ZERO_MINUS;
742  }
743  switch (nint) {
744  case 0:
745  ie1 = i; s1 = status; nint++; break;
746  case 1:
747  ie2 = i; s2 = status; nint++; break;
748  default:
749  return NON_PLANAR_FACE;
750  }
751  }
752  if (nint != 2) return NON_PLANAR_FACE;
753 
754  // F O R M I N T E R S E C T I O N S E G M E N T
755 
756  if (s1 != ZERO_ZERO && s2 != ZERO_ZERO) {
757  if (s1 == s2) return NON_PLANAR_FACE;
758  int iedge, i1 = 0, i2 = 0, ii[2];
759  double d1 = 0., d2 = 0., d3 = 0.;
760  ii[0] = ie1; ii[1] = ie2;
761  for (i=0; i<2; i++) {
762  iedge = m_faces[iface].iedges[ii[i]];
763  while (iedge > 0) {
764  i1 = m_edges[iedge].i1;
765  i2 = m_edges[iedge].i2;
766 
767  d1 = plane.distance(m_nodes[i1].v);
768  d2 = plane.distance(m_nodes[i2].v);
769  if (d1 > m_del) {
770  if (d2 < -m_del) { ii[i] = m_nodes.size(); break; } // +-
771  }else if (d1 < -m_del) {
772  if (d2 > m_del) { ii[i] = m_nodes.size(); break; } // -+
773  }else{
774  ii[i] = i1; break; // 0+ or 0-
775  }
776  iedge = m_edges[iedge].inext;
777  }
778  if (ii[i] == (int)m_nodes.size()) {
779  d3 = d2-d1; d1 = d1/d3; d2 = d2/d3;
780  m_nodes.push_back(ExtNode(d2*m_nodes[i1].v-d1*m_nodes[i2].v, iedge));
781  }
782  }
783  edge.inext = 0;
784  if (s1 == MINUS_PLUS || s1 == ZERO_PLUS) {
785  edge.i1 = ii[1];
786  edge.i2 = ii[0];
787  }else{
788  edge.i1 = ii[0];
789  edge.i2 = ii[1];
790  }
791  return INTERSECTION;
792  }else{
793  if (npos == nneg) return NON_PLANAR_FACE;
794  edge.inext = (s1 == ZERO_ZERO) ? ie1+1 : ie2+1;
795  if (s1 == ZERO_PLUS || s2 == ZERO_MINUS) {
796  edge.i1 = m_edges[m_faces[iface].iedges[ie2]].i1;
797  edge.i2 = m_edges[m_faces[iface].iedges[ie1]].i1;
798  }else{
799  edge.i1 = m_edges[m_faces[iface].iedges[ie1]].i1;
800  edge.i2 = m_edges[m_faces[iface].iedges[ie2]].i1;
801  }
802  return EDGE;
803  }
804 }
805 
806 void BooleanProcessor::renumberNodes(int & i1, int & i2, int & i3, int & i4)
807 /***********************************************************************
808  * *
809  * Name: BooleanProcessor::renumberNodes Date: 19.01.00 *
810  * Author: E.Chernyaev Revised: *
811  * *
812  * Function: Renumber nodes and remove last temporary node. *
813  * Remark: In principal this routine can be replaced just *
814  * with i1 = i2; *
815  * Removal of temporary nodes provides additional control *
816  * on number of nodes, that is very useful for debugging. *
817  * *
818  ***********************************************************************/
819 {
820  if (i1 == i2) return;
821  if (m_nodes[i1].s == 0 || m_nodes.back().s == 0) { i1 = i2; return; }
822 
823  int ilast = m_nodes.size()-1;
824  if (i1 == ilast) { i1 = i2; m_nodes.pop_back(); return; }
825  if (i2 == ilast) { i2 = i1; }
826  if (i3 == ilast) { i3 = i1; }
827  if (i4 == ilast) { i4 = i1; }
828  m_nodes[i1] = m_nodes.back(); i1 = i2; m_nodes.pop_back();
829 }
830 
832 /***********************************************************************
833  * *
834  * Name: BooleanProcessor::testEdgeVsEdge Date: 19.01.00 *
835  * Author: E.Chernyaev Revised: *
836  * *
837  * Function: Find common part of two edges *
838  * *
839  ***********************************************************************/
840 {
841  int i, ii = 0;
842  double d, dd = 0.;
843 
844  for (i=0; i<3; i++) {
845  d = m_nodes[edge1.i1].v[i]-m_nodes[edge1.i2].v[i];
846  if (d < 0.) d = -d;
847  if (d > dd) { dd = d; ii = i; }
848  }
849  double t1 = m_nodes[edge1.i1].v[ii];
850  double t2 = m_nodes[edge1.i2].v[ii];
851  double t3 = m_nodes[edge2.i1].v[ii];
852  double t4 = m_nodes[edge2.i2].v[ii];
853  if (t2-t1 < 0.) { t1 = -t1; t2 = -t2; t3 = -t3; t4 = -t4; }
854 
855  if (t3 <= t1+m_del || t4 >= t2-m_del) return 0;
856  if (t3 > t2+m_del) {
857  renumberNodes(edge2.i1, edge1.i2, edge1.i1, edge2.i2);
858  }else if (t3 < t2-m_del) {
859  renumberNodes(edge1.i2, edge2.i1, edge1.i1, edge2.i2);
860  }
861  if (t4 < t1-m_del) {
862  renumberNodes(edge2.i2, edge1.i1, edge1.i2, edge2.i1);
863  }else if (t4 > t1+m_del) {
864  renumberNodes(edge1.i1, edge2.i2, edge1.i2, edge2.i1);
865  }
866  return 1;
867 }
868 
869 void BooleanProcessor::divideEdge(int & i1, int & i2)
870 /***********************************************************************
871  * *
872  * Name: BooleanProcessor::divideEdge Date: 24.01.00 *
873  * Author: E.Chernyaev Revised: *
874  * *
875  * Function: Unify the nodes and divide edge on two parts by the node. *
876  * *
877  ***********************************************************************/
878 {
879  int iedges[2];
880  iedges[0] = m_nodes[i1].s;
881  iedges[1] = m_nodes[i2].s;
882 
883  // U N I F Y N O D E S
884 
885  if (i1 < i2) { i2 = i1; }
886  else if (i1 > i2) { i1 = i2; }
887  else { iedges[1] = 0; }
888  if (iedges[0] == iedges[1]) return;
889 
890  int ie1, ie2, inode = i1;
891  m_nodes[inode].s = 0;
892  for (int i=0; i<2; i++) {
893 
894  // F I N D C O R R E S P O N D I N G E D G E
895 
896  if ((ie1 = iedges[i]) == 0) continue;
897  ie2 = m_faces[m_edges[ie1].iface2].iedges[0];
898  while (ie2 > 0) {
899  if (m_edges[ie2].i1 == m_edges[ie1].i2 &&
900  m_edges[ie2].i2 == m_edges[ie1].i1) break;
901  ie2 = m_edges[ie2].inext;
902  }
903 
904  // D I V I D E E D G E S
905 
906  m_edges.push_back(m_edges[ie1]);
907  m_edges[ie1].inext = m_edges.size() - 1;
908  m_edges[ie1].i2 = inode;
909  m_edges.back().i1 = inode;
910 
911  m_edges.push_back(m_edges[ie2]);
912  m_edges[ie2].inext = m_edges.size() - 1;
913  m_edges[ie2].i2 = inode;
914  m_edges.back().i1 = inode;
915  }
916 }
917 
919 /***********************************************************************
920  * *
921  * Name: BooleanProcessor::insertEdge Date: 24.01.00 *
922  * Author: E.Chernyaev Revised: *
923  * *
924  * Function: Insert edge to the list of new edges *
925  * *
926  ***********************************************************************/
927 {
928  int iface = edge.iface1;
929  m_edges.push_back(edge);
930  m_edges.back().inext = m_faces[iface].inew;
931  m_faces[iface].inew = m_edges.size() - 1;
932 }
933 
935 /***********************************************************************
936  * *
937  * Name: BooleanProcessor::caseII Date: 19.01.00 *
938  * Author: E.Chernyaev Revised: *
939  * *
940  * Function: Intersection/Intersection case *
941  * *
942  ***********************************************************************/
943 {
944  divideEdge(edge1.i1, edge2.i2);
945  divideEdge(edge1.i2, edge2.i1);
946  edge1.ivis = 1;
947  edge2.ivis = 1;
948  insertEdge(edge1);
949  insertEdge(edge2);
950 }
951 
953 /***********************************************************************
954  * *
955  * Name: BooleanProcessor::caseIE Date: 19.01.00 *
956  * Author: E.Chernyaev Revised: *
957  * *
958  * Function: Intersection/Edge-touch case *
959  * *
960  ***********************************************************************/
961 {
962  m_processor_error = 1;
963 #ifdef BP_DEBUG
964  G4cout
965  << "BooleanProcessor::caseIE : unimplemented case"
966  << G4endl;
967 #endif
968 }
969 
971 /***********************************************************************
972  * *
973  * Name: BooleanProcessor::caseEE Date: 19.01.00 *
974  * Author: E.Chernyaev Revised: *
975  * *
976  * Function: Edge-touch/Edge-touch case *
977  * *
978  ***********************************************************************/
979 {
980  m_processor_error = 1;
981 #ifdef BP_DEBUG
982  G4cout
983  << "BooleanProcessor::caseEE : unimplemented case"
984  << G4endl;
985 #endif
986 }
987 
988 void BooleanProcessor::testFaceVsFace(int iface1, int iface2)
989 /***********************************************************************
990  * *
991  * Name: BooleanProcessor::testFaceVsFace Date: 11.01.00 *
992  * Author: E.Chernyaev Revised: *
993  * *
994  * Function: Find result (an edge) of intersection of two faces *
995  * *
996  ***********************************************************************/
997 {
998  ExtEdge edge1, edge2;
999  int irep1, irep2;
1000 
1001  // M I N - M A X
1002 
1003  {const ExtFace& face_1 = m_faces[iface1]; //G.Barrand : optimize
1004  const ExtFace& face_2 = m_faces[iface2];
1005  for (int i=0; i<3; i++) {
1006  if (face_1.rmin[i] > face_2.rmax[i] + m_del) return;
1007  if (face_1.rmax[i] < face_2.rmin[i] - m_del) return;
1008  }}
1009 
1010  // F A C E - 1 vs P L A N E - 2
1011 
1012  edge1.iface1 = iface1;
1013  edge1.iface2 = iface2;
1014  irep1 = testFaceVsPlane(edge1);
1015  if (irep1 == OUT_OF_PLANE || irep1 == ON_PLANE) {
1016  removeJunkNodes();
1017  return;
1018  }
1019 
1020  // F A C E - 2 vs P L A N E - 1
1021 
1022  edge2.iface1 = iface2;
1023  edge2.iface2 = iface1;
1024  irep2 = testFaceVsPlane(edge2);
1025  if (irep2 == OUT_OF_PLANE || irep2 == ON_PLANE) {
1026  removeJunkNodes();
1027  return;
1028  }
1029 
1030  // C H E C K F O R N O N P L A N A R F A C E
1031 
1032  if (irep1 == NON_PLANAR_FACE || irep2 == NON_PLANAR_FACE) {
1033  removeJunkNodes();
1034  return;
1035  }
1036 
1037  // F I N D I N T E R S E C T I O N P A R T
1038 
1039  if (testEdgeVsEdge(edge1, edge2) == 0) return;
1040 
1041  // C O N S I D E R D I F F E R E N T C A S E S
1042 
1043  if (irep1 == INTERSECTION && irep2 == INTERSECTION) caseII(edge1, edge2);
1044  if (irep1 == INTERSECTION && irep2 == EDGE) caseIE(edge1, edge2);
1045  if (irep1 == EDGE && irep2 == INTERSECTION) caseIE(edge2, edge1);
1046  if (irep1 == EDGE && irep2 == EDGE) caseEE(edge1, edge2);
1047  removeJunkNodes();
1048 
1049 }
1050 
1052 /***********************************************************************
1053  * *
1054  * Name: BooleanProcessor::invertNewEdges Date: 04.02.00 *
1055  * Author: E.Chernyaev Revised: *
1056  * *
1057  * Function: Invert direction of new edges *
1058  * *
1059  ***********************************************************************/
1060 {
1061  int iedge = m_faces[iface].inew;
1062  while (iedge > 0) {
1063  m_edges[iedge].invert();
1064  iedge = m_edges[iedge].inext;
1065  }
1066 }
1067 
1069 /***********************************************************************
1070  * *
1071  * Name: BooleanProcessor::checkDoubleEdges Date: 04.02.00 *
1072  * Author: E.Chernyaev Revised: *
1073  * *
1074  * Function: Eliminate duplication of edges *
1075  * *
1076  ***********************************************************************/
1077 {
1078 
1079 }
1080 
1082 /***********************************************************************
1083  * *
1084  * Name: BooleanProcessor::assembleFace Date: 19.02.00 *
1085  * Author: E.Chernyaev Revised: *
1086  * *
1087  * Function: Assemble face *
1088  * *
1089  ***********************************************************************/
1090 {
1091  // A S S E M B L E N E W F A C E
1092 
1093  int ihead = 0; // head of the list of edges for new face
1094  int icur; // current edge in the list - last edge inserted to the list
1095  int *ilink; // pointer to the current link
1096  int ifirst; // first node of a contour
1097  int *i; // pointer to the index of the current edge in a loop
1098  int ioldflag=0; // is set if an edge from iold has been taken
1099 
1100 #define INSERT_EDGE_TO_THE_LIST(A) \
1101 *ilink = A; ilink = &m_edges[A].inext; *ilink = 0
1102 
1103  ExtFace& face = m_faces[iface]; //G.Barrand : optimize.
1104  ilink = &ihead;
1105  for(;;) {
1106  if (face.inew == 0) break;
1107 
1108  // S T A R T N E W C O N T O U R
1109 
1110  icur = face.inew;
1111  face.inew = m_edges[icur].inext;
1113  ifirst = m_edges[icur].i1;
1114 
1115  // C O N S T R U C T T H E C O N T O U R
1116 
1117  for (;;) {
1118  i = &face.inew;
1119  ExtEdge& edge_cur = m_edges[icur];
1120  while(*i > 0) {
1121  ExtEdge& edge_i = m_edges[*i];
1122  if (edge_i.i1 == edge_cur.i2) break;
1123  i = &edge_i.inext;
1124  }
1125  if (*i == 0) {
1126  i = &face.iold;
1127  while(*i > 0) {
1128  ExtEdge& edge_i = m_edges[*i];
1129  if (edge_i.i1 == edge_cur.i2) {
1130  ioldflag = 1;
1131  break;
1132  }
1133  i = &edge_i.inext;
1134  }
1135  }
1136  if (*i > 0) {
1137  icur = *i;
1138  *i = m_edges[icur].inext;
1140  if (m_edges[icur].i2 == ifirst) { break; } else { continue; }
1141  }else{
1142  m_processor_error = 1;
1143 #ifdef BP_DEBUG
1144  G4cerr
1145  << "BooleanProcessor::assembleFace(" << iface << ") : "
1146  << "could not find next edge of the contour"
1147  << G4endl;
1148 #endif
1149  face.inew = DEFECTIVE_FACE;
1150  return;
1151  }
1152  }
1153  }
1154 
1155  // C H E C K O R I G I N A L C O N T O U R
1156 
1157  int iedge;
1158  iedge = face.iold;
1159  if (what == 0 && ioldflag == 0 && iedge > 0) {
1160  for (;;) {
1161  if (m_edges[iedge].inext > 0) {
1162  if (m_edges[iedge].i2 == m_edges[m_edges[iedge].inext].i1) {
1163  iedge = m_edges[iedge].inext;
1164  }else{
1165  break;
1166  }
1167  }else{
1168  if (m_edges[iedge].i2 == m_edges[face.iold].i1) {
1169  m_edges[iedge].inext = ihead; // set new face
1170  return;
1171  }else{
1172  break;
1173  }
1174  }
1175  }
1176  }
1177 
1178  // M A R K U N S U I T A B L E N E I G H B O U R I N G F A C E S
1179 
1180  int iface2;
1181  iedge = face.iold;
1182  while(iedge > 0) {
1183  iface2 = m_edges[iedge].iface2;
1184  if (m_faces[iface2].inew == 0) m_faces[iface2].inew = UNSUITABLE_FACE;
1185  iedge = m_edges[iedge].inext;
1186  }
1187  face.iold = ihead; // set new face
1188 }
1189 
1191 /***********************************************************************
1192  * *
1193  * Name: BooleanProcessor::assembleNewFaces Date: 30.01.00 *
1194  * Author: E.Chernyaev Revised: *
1195  * *
1196  * Function: Assemble internal or external parts of faces *
1197  * *
1198  ***********************************************************************/
1199 {
1200  int iface = ihead;
1201  while(iface > 0) {
1202  if (m_faces[iface].inew > 0) {
1203  if (what != 0) invertNewEdges(iface);
1204  checkDoubleEdges(iface);
1205  assembleFace(what, iface);
1206  m_faces[iface].inew =
1207  (m_faces[iface].iold == 0) ? UNSUITABLE_FACE : NEW_FACE;
1208  }
1209  iface = m_faces[iface].inext;
1210  }
1211 }
1212 
1214 /***********************************************************************
1215  * *
1216  * Name: BooleanProcessor::initiateLists Date: 28.02.00 *
1217  * Author: E.Chernyaev Revised: *
1218  * *
1219  * Function: Initiate lists of faces. *
1220  * *
1221  ***********************************************************************/
1222 {
1223  int i, iface;
1224 
1225  // R E S E T L I S T S O F F A C E S
1226 
1231 
1232  // I N I T I A T E T H E L I S T S
1233 
1234  iface = m_iout1;
1235  while (iface > 0) {
1236  i = iface;
1237  iface = m_faces[i].inext;
1238  if (m_operation == OP_INTERSECTION) {
1240  m_faces[i].inew = UNSUITABLE_FACE;
1241  }else{
1243  m_faces[i].inew = ORIGINAL_FACE;
1244  }
1245  }
1246  iface = m_iout2;
1247  while (iface > 0) {
1248  i = iface;
1249  iface = m_faces[i].inext;
1250  if (m_operation == OP_UNION) {
1252  m_faces[i].inew = ORIGINAL_FACE;
1253  }else{
1255  m_faces[i].inew = UNSUITABLE_FACE;
1256  }
1257  }
1258 
1259  iface = m_iunk1;
1260  while (iface > 0) {
1261  i = iface;
1262  iface = m_faces[i].inext;
1264  }
1265  iface = m_iunk2;
1266  while (iface > 0) {
1267  i = iface;
1268  iface = m_faces[i].inext;
1269  if (m_operation == OP_SUBTRACTION) m_faces[i].invert();
1271  }
1272 
1273  iface = m_ifaces1;
1274  while (iface > 0) {
1275  i = iface;
1276  iface = m_faces[i].inext;
1277  switch(m_faces[i].inew) {
1278  case UNKNOWN_FACE:
1280  break;
1281  case ORIGINAL_FACE: case NEW_FACE:
1283  break;
1284  case UNSUITABLE_FACE:
1286  break;
1287  default:
1288  m_faces[i].iprev = 0;
1289  m_faces[i].inext = 0;
1290  break;
1291  }
1292  }
1293  iface = m_ifaces2;
1294  while (iface > 0) {
1295  i = iface;
1296  iface = m_faces[i].inext;
1297  if (m_operation == OP_SUBTRACTION) m_faces[i].invert();
1298  switch(m_faces[i].inew) {
1299  case UNKNOWN_FACE:
1301  break;
1302  case ORIGINAL_FACE: case NEW_FACE:
1304  break;
1305  case UNSUITABLE_FACE:
1307  break;
1308  default:
1309  m_faces[i].iprev = 0;
1310  m_faces[i].inext = 0;
1311  break;
1312  }
1313  }
1315 }
1316 
1318 /***********************************************************************
1319  * *
1320  * Name: BooleanProcessor::assemblePolyhedra() Date: 10.12.99 *
1321  * Author: E.Chernyaev Revised: *
1322  * *
1323  * Function: Collect suitable faces and remove unsuitable ones. *
1324  * *
1325  ***********************************************************************/
1326 {
1327  int i, iedge, iface;
1328 
1329  // L O O P A L O N G S U I T A B L E F A C E S
1330 
1331  iface = m_suitable_faces.front();
1332  while(iface > 0) {
1333  i = iface;
1334  iedge = m_faces[i].iold;
1335  while(iedge > 0) {
1336  iface = m_edges[iedge].iface2;
1337  if (m_faces[iface].inew == UNKNOWN_FACE) {
1338  m_unknown_faces.remove(iface);
1339  m_suitable_faces.push_back(iface);
1340  m_faces[iface].inew = ORIGINAL_FACE;
1341  }
1342  iedge = m_edges[iedge].inext;
1343  }
1344  iface = m_faces[i].inext;
1347  }
1348  if (m_unknown_faces.front() == 0) return;
1349 
1350  // L O O P A L O N G U N S U I T A B L E F A C E S
1351 
1352  iface = m_unsuitable_faces.front();
1353  while(iface > 0) {
1354  i = iface;
1355  iedge = m_faces[i].iold;
1356  while(iedge > 0) {
1357  iface = m_edges[iedge].iface2;
1358  if (m_faces[iface].inew == UNKNOWN_FACE) {
1359  m_unknown_faces.remove(iface);
1361  m_faces[iface].inew = UNSUITABLE_FACE;
1362  }
1363  iedge = m_edges[iedge].inext;
1364  }
1365  iface = m_faces[i].inext;
1367  }
1368 
1369  //G.Barrand : begin
1370  /* From S.Ponce
1371  At last, there is a problem in the assemblePolyhedra method. At least, I
1372  think it is there. The problem deals with boolean operations on solids,
1373  when one of the two contains entirely the other one. It has no sense for
1374  intersection and union but still has sense for subtraction. In this
1375  case, faces from the inner solid are stored in the m_unknown_faces
1376  FaceList. And an error occurs in the execute method. This may be correct
1377  for intersection and union but in the case of subtraction, one should do
1378  that in assemblePolyhedra :
1379  */
1380  // Unknown faces are actually suitable face !!!
1381  iface = m_unknown_faces.front();
1382  while(iface > 0) {
1383  i = iface;
1384  m_faces[i].inew = ORIGINAL_FACE;
1385  iface = m_faces[i].inext;
1388  }
1389  /*
1390  Otherwise, the inner hole that the second solid was building in the
1391  first one does not exist. I'm not very clear on what to do for unions
1392  and intersections. I think this kind of situation should be detected and
1393  one of the solid should simply be ignored.
1394  */
1395  //G.Barrand : end
1396 }
1397 
1398 inline void
1399 BooleanProcessor::findABC(double x1, double y1, double x2, double y2,
1400  double &a, double &b, double &c) const
1401 /***********************************************************************
1402  * *
1403  * Name: BooleanProcessor::findABC Date: 07.03.00 *
1404  * Author: E.Chernyaev Revised: *
1405  * *
1406  * Function: Find line equation Ax+By+C=0 *
1407  * *
1408  ***********************************************************************/
1409 {
1410  double w;
1411  a = y1 - y2;
1412  b = x2 - x1;
1413  //G.Barrand : w = std::abs(a)+std::abs(b);
1414  w = ::fabs(a)+::fabs(b); //G.Barrand
1415  a /= w;
1416  b /= w;
1417  c = -(a*x2 + b*y2);
1418 }
1419 
1420 int BooleanProcessor::checkDirection(double *x, double *y) const
1421 /***********************************************************************
1422  * *
1423  * Name: BooleanProcessor::checkDirection Date: 06.03.00 *
1424  * Author: E.Chernyaev Revised: *
1425  * *
1426  * Function: Check direction of line 1-4 *
1427  * *
1428  ***********************************************************************/
1429 {
1430  double a1, b1, c1, a2, b2, c2, d1, d2;
1431 
1432  // T E S T L I N E 1 - 4 V S E X T E R N A L C O N T O U R
1433 
1434  findABC(x[0], y[0], x[1], y[1], a1, b1, c1);
1435  findABC(x[1], y[1], x[2], y[2], a2, b2, c2);
1436  d1 = a1*x[4] + b1*y[4] + c1;
1437  d2 = a2*x[4] + b2*y[4] + c2;
1438  if (d1 <= m_del && d2 <= m_del) return 1;
1439  if (! (d1 > m_del && d2 > m_del)) {
1440  if ( a1*x[2] + b1*y[2] + c1 >= -m_del) return 1;
1441  }
1442 
1443  // T E S T L I N E 1 - 4 V S I N T E R N A L C O N T O U R
1444 
1445  findABC(x[3], y[3], x[4], y[4], a1, b1, c1);
1446  findABC(x[4], y[4], x[5], y[5], a2, b2, c2);
1447  d1 = a1*x[1] + b1*y[1] + c1;
1448  d2 = a2*x[1] + b2*y[1] + c2;
1449  if (d1 <= m_del && d2 <= m_del) return 1;
1450  if (!(d1 > m_del && d2 > m_del)) {
1451  if ( a1*x[5] + b1*y[5] + c1 >= -m_del) return 1;
1452  }
1453  return 0;
1454 }
1455 
1456 int BooleanProcessor::checkIntersection(int ix, int iy, int i1, int i2) const
1457 /***********************************************************************
1458  * *
1459  * Name: BooleanProcessor::checkDirection Date: 06.03.00 *
1460  * Author: E.Chernyaev Revised: *
1461  * *
1462  * Function: Check line i1-i2 on intersection with contours *
1463  * *
1464  ***********************************************************************/
1465 {
1466  // F I N D L I N E E Q U A T I O N
1467 
1468  double x1, y1, x2, y2, a1, b1, c1;
1469  x1 = m_nodes[i1].v[ix];
1470  y1 = m_nodes[i1].v[iy];
1471  x2 = m_nodes[i2].v[ix];
1472  y2 = m_nodes[i2].v[iy];
1473  findABC(x1, y1, x2, y2, a1, b1, c1);
1474 
1475  // L O O P A L O N G E X T E R N A L C O N T O U R S
1476 
1477  int icontour, iedge, k1, k2;
1478  double x3, y3, x4, y4, a2, b2, c2, d1, d2;
1479  for(icontour=0; icontour<(int)m_external_contours.size(); icontour++) {
1480  iedge = m_external_contours[icontour];
1481  while(iedge > 0) {
1482  k1 = m_edges[iedge].i1;
1483  k2 = m_edges[iedge].i2;
1484  iedge = m_edges[iedge].inext;
1485  if (k1 == i1 || k2 == i1) continue;
1486  if (k1 == i2 || k2 == i2) continue;
1487  x3 = m_nodes[k1].v[ix];
1488  y3 = m_nodes[k1].v[iy];
1489  x4 = m_nodes[k2].v[ix];
1490  y4 = m_nodes[k2].v[iy];
1491  d1 = a1*x3 + b1*y3 + c1;
1492  d2 = a1*x4 + b1*y4 + c1;
1493  if (d1 > m_del && d2 > m_del) continue;
1494  if (d1 < -m_del && d2 < -m_del) continue;
1495 
1496  findABC(x3, y3, x4, y4, a2, b2, c2);
1497  d1 = a2*x1 + b2*y1 + c2;
1498  d2 = a2*x2 + b2*y2 + c2;
1499  if (d1 > m_del && d2 > m_del) continue;
1500  if (d1 < -m_del && d2 < -m_del) continue;
1501  return 1;
1502  }
1503  }
1504 
1505  // L O O P A L O N G E X T E R N A L C O N T O U R S
1506 
1507  for(icontour=0; icontour<(int)m_internal_contours.size(); icontour++) {
1508  iedge = m_internal_contours[icontour];
1509  while(iedge > 0) {
1510  k1 = m_edges[iedge].i1;
1511  k2 = m_edges[iedge].i2;
1512  iedge = m_edges[iedge].inext;
1513  if (k1 == i1 || k2 == i1) continue;
1514  if (k1 == i2 || k2 == i2) continue;
1515  x3 = m_nodes[k1].v[ix];
1516  y3 = m_nodes[k1].v[iy];
1517  x4 = m_nodes[k2].v[ix];
1518  y4 = m_nodes[k2].v[iy];
1519  d1 = a1*x3 + b1*y3 + c1;
1520  d2 = a1*x4 + b1*y4 + c1;
1521  if (d1 > m_del && d2 > m_del) continue;
1522  if (d1 < -m_del && d2 < -m_del) continue;
1523 
1524  findABC(x3, y3, x4, y4, a2, b2, c2);
1525  d1 = a2*x1 + b2*y1 + c2;
1526  d2 = a2*x2 + b2*y2 + c2;
1527  if (d1 > m_del && d2 > m_del) continue;
1528  if (d1 < -m_del && d2 < -m_del) continue;
1529  return 1;
1530  }
1531  }
1532  return 0;
1533 }
1534 
1535 void BooleanProcessor::mergeContours(int ix, int iy, int kext, int kint)
1536 /***********************************************************************
1537  * *
1538  * Name: BooleanProcessor::mergeContours Date: 06.03.00 *
1539  * Author: E.Chernyaev Revised: *
1540  * *
1541  * Function: Attemp to merge internal contour with external one *
1542  * *
1543  ***********************************************************************/
1544 {
1545  int i1ext, i2ext, i1int, i2int, i, k[6];
1546  double x[6], y[6];
1547 
1548  // L O O P A L O N G E X T E R N A L C O N T O U R
1549 
1550  i1ext = m_external_contours[kext];
1551  while (i1ext > 0) {
1552  i2ext = m_edges[i1ext].inext;
1553  if (i2ext == 0) i2ext = m_external_contours[kext];
1554  k[0] = m_edges[i1ext].i1;
1555  k[1] = m_edges[i1ext].i2;
1556  k[2] = m_edges[i2ext].i2;
1557  for (i=0; i<3; i++) {
1558  x[i] = m_nodes[k[i]].v[ix];
1559  y[i] = m_nodes[k[i]].v[iy];
1560  }
1561 
1562  // L O O P A L O N G I N T E R N A L C O N T O U R
1563 
1564  i1int = m_internal_contours[kint];
1565  while (i1int > 0) {
1566  i2int = m_edges[i1int].inext;
1567  if (i2int == 0) i2int = m_internal_contours[kint];
1568  k[3] = m_edges[i1int].i1;
1569  k[4] = m_edges[i1int].i2;
1570  k[5] = m_edges[i2int].i2;
1571  for (i=3; i<6; i++) {
1572  x[i] = m_nodes[k[i]].v[ix];
1573  y[i] = m_nodes[k[i]].v[iy];
1574  }
1575 
1576  // T E S T L I N E K1 - K4
1577  // I F O K T H E N M E R G E C O N T O U R S
1578 
1579  if (checkDirection(x, y) == 0) {
1580  if (checkIntersection(ix, iy, k[1], k[4]) == 0) {
1581  i = i1int;
1582  for(;;) {
1583  if (m_edges[i].inext == 0) {
1584  m_edges[i].inext = m_internal_contours[kint];
1585  m_internal_contours[kint] = 0;
1586  break;
1587  }else{
1588  i = m_edges[i].inext;
1589  }
1590  }
1591  i = m_edges[i1int].iface1;
1592  m_edges.push_back(ExtEdge(k[1], k[4], i, -(int(m_edges.size())+1), -1));
1593  m_edges.back().inext = i2int;
1594  m_edges.push_back(ExtEdge(k[4], k[1], i, -(int(m_edges.size())-1), -1));
1595  m_edges.back().inext = m_edges[i1ext].inext;
1596  m_edges[i1ext].inext = m_edges.size()-2;
1597  m_edges[i1int].inext = m_edges.size()-1;
1598  return;
1599  }
1600  }
1601  i1int = m_edges[i1int].inext;
1602  }
1603  i1ext = m_edges[i1ext].inext;
1604  }
1605 }
1606 
1607 int BooleanProcessor::checkTriangle(int iedge1, int iedge2, int ix, int iy) const
1608 /***********************************************************************
1609  * *
1610  * Name: BooleanProcessor::checkTriangle Date: 08.03.00 *
1611  * Author: E.Chernyaev Revised: *
1612  * *
1613  * Function: Check triangle for correctness *
1614  * *
1615  ***********************************************************************/
1616 {
1617  int k[3];
1618  double x[3], y[3];
1619  double a1, b1, c1;
1620 
1621  k[0] = m_edges[iedge1].i1;
1622  k[1] = m_edges[iedge1].i2;
1623  k[2] = m_edges[iedge2].i2;
1624  for (int i=0; i<3; i++) {
1625  x[i] = m_nodes[k[i]].v[ix];
1626  y[i] = m_nodes[k[i]].v[iy];
1627  }
1628 
1629  // C H E C K P R I N C I P A L C O R R E C T N E S S
1630 
1631  findABC(x[2], y[2], x[0], y[0], a1, b1, c1);
1632  if (a1*x[1]+b1*y[1]+c1 <= 0.1*m_del) return 1;
1633 
1634  // C H E C K T H A T T H E R E I S N O P O I N T S I N S I D E
1635 
1636  int inode, iedge;
1637  double a2, b2, c2, a3, b3, c3;
1638 
1639  findABC(x[0], y[0], x[1], y[1], a2, b2, c2);
1640  findABC(x[1], y[1], x[2], y[2], a3, b3, c3);
1641  iedge = iedge2;
1642  for (;;) {
1643  iedge = m_edges[iedge].inext;
1644  if (m_edges[iedge].inext == iedge1) return 0;
1645  inode = m_edges[iedge].i2;
1646  if (inode == k[0]) continue;
1647  if (inode == k[1]) continue;
1648  if (inode == k[2]) continue;
1649  x[1] = m_nodes[inode].v[ix];
1650  y[1] = m_nodes[inode].v[iy];
1651  if (a1*x[1]+b1*y[1]+c1 < -0.1*m_del) continue;
1652  if (a2*x[1]+b2*y[1]+c2 < -0.1*m_del) continue;
1653  if (a3*x[1]+b3*y[1]+c3 < -0.1*m_del) continue;
1654  return 1;
1655  }
1656  return 0; // default return
1657 }
1658 
1659 void BooleanProcessor::triangulateContour(int ix, int iy, int ihead)
1660 /***********************************************************************
1661  * *
1662  * Name: BooleanProcessor::triangulateContour Date: 06.03.00 *
1663  * Author: E.Chernyaev Revised: *
1664  * *
1665  * Function: Triangulate external contour *
1666  * *
1667  ***********************************************************************/
1668 {
1669 
1670  //G4cout << "Next Countour" << G4endl;
1671  //int draw_flag = 0;
1672  //if (draw_flag) draw_contour(5, 3, ihead);
1673 
1674  // C L O S E C O N T O U R
1675 
1676  int ipnext = ihead, nnode = 1;
1677  for (;;) {
1678  if (m_edges[ipnext].inext > 0) {
1679  ipnext = m_edges[ipnext].inext;
1680  nnode++;
1681  }else{
1682  m_edges[ipnext].inext = ihead;
1683  break;
1684  }
1685  }
1686 
1687  // L O O P A L O N G C O N T O U R
1688 
1689  //G4cerr << "debug : contour : begin : =================" << G4endl;
1690  //dump();//debug
1691 
1692  int iedge1, iedge2, iedge3, istart = 0;
1693  for (;;) {
1694  iedge1 = m_edges[ipnext].inext;
1695  iedge2 = m_edges[iedge1].inext;
1696 /*
1697  G4cerr << "debug :"
1698  << " ipnext " << ipnext
1699  << " iedge1 " << iedge1
1700  << " iedge2 " << iedge2
1701  << " : istart " << istart
1702  << G4endl;
1703 */
1704  if (istart == 0) {
1705  istart = iedge1;
1706  if (nnode <= 3) {
1707  iedge3 = m_edges[iedge2].inext;
1708  m_edges[iedge1].iface1 = m_faces.size();
1709  m_edges[iedge2].iface1 = m_faces.size();
1710  m_edges[iedge3].iface1 = m_faces.size();
1711  m_edges[iedge3].inext = 0;
1712  m_faces.push_back(ExtFace(m_edges,0)); //G.Barrand : ok ?
1713  m_faces.back().iold = iedge1;
1714  m_faces.back().inew = ORIGINAL_FACE;
1715 
1716  //if (draw_flag) draw_contour(4, 2, iedge1);
1717 
1718  break;
1719  }
1720  }else if (istart == iedge1) {
1721  m_processor_error = 1;
1722 #ifdef BP_DEBUG
1723  G4cerr
1724  << "BooleanProcessor::triangulateContour : "
1725  << "could not generate a triangle (infinite loop)"
1726  << G4endl;
1727 #endif
1728  break;
1729  }
1730 
1731  // C H E C K C O R E C T N E S S O F T H E T R I A N G L E
1732 
1733  if (checkTriangle(iedge1,iedge2,ix,iy) != 0) {
1734  ipnext = m_edges[ipnext].inext;
1735  continue;
1736  }
1737 
1738  // M O D I F Y C O N T O U R
1739 
1740  int i1 = m_edges[iedge1].i1;
1741  int i3 = m_edges[iedge2].i2;
1742  int iface1 = m_edges[iedge1].iface1;
1743  int iface2 = m_faces.size();
1744 
1745  m_edges[ipnext].inext = m_edges.size();
1746  m_edges.push_back(ExtEdge(i1, i3, iface1, -(int(m_edges.size())+1), -1));
1747  m_edges.back().inext = m_edges[iedge2].inext;
1748 
1749  // A D D N E W T R I A N G L E T O T H E L I S T
1750 
1751  m_edges[iedge2].inext = m_edges.size();
1752  m_edges.push_back(ExtEdge(i3, i1, iface2, -(int(m_edges.size())-1), -1));
1753  m_faces.push_back(ExtFace(m_edges,0)); //G.Barrand : ok ?
1754  m_faces.back().iold = iedge1;
1755  m_faces.back().inew = ORIGINAL_FACE;
1756  m_edges[iedge1].iface1 = iface2;
1757  m_edges[iedge2].iface1 = iface2;
1758  ipnext = m_edges[ipnext].inext;
1759  istart = 0;
1760  nnode--;
1761 
1762  //if (draw_flag) draw_contour(4, 2, iedge1);
1763 
1764  }
1765 }
1766 
1767 void BooleanProcessor::modifyReference(int iface, int i1, int i2, int iref)
1768 /***********************************************************************
1769  * *
1770  * Name: BooleanProcessor::modifyReference Date: 13.03.00 *
1771  * Author: E.Chernyaev Revised: *
1772  * *
1773  * Function: Modify reference to the neighbouring face *
1774  * *
1775  ***********************************************************************/
1776 {
1777  int iedge = m_faces[iface].iold;
1778  while (iedge > 0) {
1779  if (m_edges[iedge].i1 == i2 && m_edges[iedge].i2 == i1) {
1780  m_edges[iedge].iface2 = iref;
1781  return;
1782  }
1783  iedge = m_edges[iedge].inext;
1784  }
1785  m_processor_error = 1;
1786 #ifdef BP_DEBUG
1787  G4cerr
1788  << "BooleanProcessor::modifyReference : could not find the edge, "
1789  << "iface=" << iface << ", i1,i2=" << i1 << "," << i2 << ", iref=" << iref
1790  << G4endl;
1791 #endif
1792 }
1793 
1795 /***********************************************************************
1796  * *
1797  * Name: BooleanProcessor::triangulateFace Date: 02.03.00 *
1798  * Author: E.Chernyaev Revised: *
1799  * *
1800  * Function: Triangulation of an extended face *
1801  * *
1802  ***********************************************************************/
1803 {
1804 
1805  // F I N D M A X C O M P O N E N T O F T H E N O R M A L
1806  // S E T IX, IY, IZ
1807 
1808 #ifdef BP_GEANT4 //G.Barrand
1809  HVNormal3D normal = m_faces[iface].plane.normal();
1810 #else
1811  const HVNormal3D& normal = m_faces[iface].plane.getNormal();
1812 #endif
1813  int ix, iy, iz = 0;
1814  //G.Barrand : if (std::abs(normal[1]) > std::abs(normal[iz])) iz = 1;
1815  //G.Barrand : if (std::abs(normal[2]) > std::abs(normal[iz])) iz = 2;
1816  if (::fabs(normal[1]) > ::fabs(normal[iz])) iz = 1; //G.Barrand
1817  if (::fabs(normal[2]) > ::fabs(normal[iz])) iz = 2; //G.Barrand
1818  if (normal[iz] > 0) {
1819  ix = (iz+1)%3; iy = (ix+1)%3;
1820  }else{
1821  iy = (iz+1)%3; ix = (iy+1)%3;
1822  }
1823 
1824  // F I L L L I S T S O F C O N T O U R S
1825 
1826  m_external_contours.clear();
1827  m_internal_contours.clear();
1828  double z;
1829  int i1, i2, ifirst, iedge, icontour = m_faces[iface].iold;
1830  while (icontour > 0) {
1831  iedge = icontour;
1832  ifirst = m_edges[iedge].i1;
1833  z = 0.0;
1834  for(;;) {
1835  if (iedge > 0) {
1836  i1 = m_edges[iedge].i1;
1837  i2 = m_edges[iedge].i2;
1838  ExtNode& node_1 = m_nodes[i1];
1839  ExtNode& node_2 = m_nodes[i2];
1840  z += node_1.v[ix]*node_2.v[iy]-node_2.v[ix]*node_1.v[iy];
1841  if (ifirst != i2) {
1842  iedge = m_edges[iedge].inext;
1843  continue;
1844  }else{
1845  if (z > m_del*m_del) {
1846  m_external_contours.push_back(icontour);
1847  }else if (z < -m_del*m_del) {
1848  m_internal_contours.push_back(icontour);
1849  }else{
1850  m_processor_error = 1;
1851 #ifdef BP_DEBUG
1852  G4cerr
1853  << "BooleanProcessor::triangulateFace : too small contour"
1854  << G4endl;
1855 #endif
1856  }
1857  icontour = m_edges[iedge].inext;
1858  m_edges[iedge].inext = 0;
1859  break;
1860  }
1861  }else{
1862  m_processor_error = 1;
1863 #ifdef BP_DEBUG
1864  G4cerr
1865  << "BooleanProcessor::triangulateFace : broken contour"
1866  << G4endl;
1867 #endif
1868  icontour = 0;
1869  break;
1870  }
1871  }
1872  }
1873 
1874  // G E T R I D O F I N T E R N A L C O N T O U R S
1875 
1876  int kint, kext;
1877  for (kint=0; kint < (int)m_internal_contours.size(); kint++) {
1878  for (kext=0; kext < (int)m_external_contours.size(); kext++) {
1879  mergeContours(ix, iy, kext, kint);
1880  if (m_internal_contours[kint] == 0) break;
1881  }
1882  if (kext == (int)m_external_contours.size()) {
1883  m_processor_error = 1;
1884 #ifdef BP_DEBUG
1885  G4cerr
1886  << "BooleanProcessor::triangulateFace : "
1887  << "could not merge internal contour " << kint
1888  << G4endl;
1889 #endif
1890  }
1891  }
1892 
1893  // T R I A N G U L A T E C O N T O U R S
1894 
1895  int nface = m_faces.size();
1896  for (kext=0; kext < (int)m_external_contours.size(); kext++) {
1897  triangulateContour(ix, iy, m_external_contours[kext]);
1898 #ifdef BP_DEBUG
1899  if(m_processor_error) { //G.Barrand
1900  G4cerr
1901  << "BooleanProcessor::triangulateFace : "
1902  << "triangulateContour failed."
1903  << G4endl;
1904  break; //G.Barrand : ok ?
1905  }
1906 #endif
1907  }
1908  m_faces[iface].inew = UNSUITABLE_FACE;
1909 
1910  // M O D I F Y R E F E R E N C E S
1911 
1912  for (int ifa=nface; ifa<(int)m_faces.size(); ifa++) {
1913  iedge = m_faces[ifa].iold;
1914  while (iedge > 0) {
1915  if (m_edges[iedge].iface1 != ifa) {
1916  m_processor_error = 1;
1917 #ifdef BP_DEBUG
1918  G4cerr
1919  << "BooleanProcessor::triangulateFace : wrong reference to itself, "
1920  << "iface=" << ifa << ", iface1=" << m_edges[iedge].iface1
1921  << G4endl;
1922 #endif
1923  }else if (m_edges[iedge].iface2 > 0) {
1924  modifyReference(m_edges[iedge].iface2,
1925  m_edges[iedge].i1, m_edges[iedge].i2, ifa);
1926  }else if (m_edges[iedge].iface2 < 0) {
1927  m_edges[iedge].iface2 = m_edges[-m_edges[iedge].iface2].iface1;
1928  }
1929  iedge = m_edges[iedge].inext;
1930  }
1931  }
1932 }
1933 
1935 /***********************************************************************
1936  * *
1937  * Name: BooleanProcessor::createPolyhedron() Date: 14.03.00 *
1938  * Author: E.Chernyaev Revised: *
1939  * *
1940  * Function: Create HepPolyhedron. *
1941  * *
1942  ***********************************************************************/
1943 {
1944  int i, iedge, nnode = 0, nface = 0;
1945 
1946  // R E N U M E R A T E N O D E S A N D F A C E S
1947 
1948  for (i=1; i<(int)m_nodes.size(); i++) m_nodes[i].s = 0;
1949 
1950  for (i=1; i<(int)m_faces.size(); i++) {
1951  if (m_faces[i].inew == ORIGINAL_FACE) {
1952  m_faces[i].inew = ++nface;
1953  iedge = m_faces[i].iold;
1954  while (iedge > 0) {
1955  m_nodes[m_edges[iedge].i1].s = 1;
1956  iedge = m_edges[iedge].inext;
1957  }
1958  }else{
1959  m_faces[i].inew = 0;
1960  }
1961  }
1962 
1963  for (i=1; i<(int)m_nodes.size(); i++) {
1964  if (m_nodes[i].s == 1) m_nodes[i].s = ++nnode;
1965  }
1966 
1967  // A L L O C A T E M E M O R Y
1968 
1969  ExtPolyhedron polyhedron;
1970  if (nface == 0) return polyhedron;
1971  polyhedron.AllocateMemory(nnode, nface);
1972 
1973  // S E T N O D E S
1974 
1975  for (i=1; i<(int)m_nodes.size(); i++) {
1976  if (m_nodes[i].s != 0) polyhedron.m_pV[m_nodes[i].s] = m_nodes[i].v;
1977  }
1978 
1979  // S E T F A C E S
1980 
1981  int k, v[4]={0}, f[4]={0};
1982  for (i=1; i<(int)m_faces.size(); i++) {
1983  if (m_faces[i].inew == 0) continue;
1984  v[3] = f[3] = k = 0;
1985  iedge = m_faces[i].iold;
1986  while (iedge > 0) {
1987  if (k > 3) {
1988  std::cerr << "BooleanProcessor::createPolyhedron : too many edges" << std::endl;
1989  break;
1990  }
1991  v[k] = m_nodes[m_edges[iedge].i1].s;
1992  if (m_edges[iedge].ivis < 0) v[k] = -v[k];
1993  f[k] = m_faces[m_edges[iedge].iface2].inew;
1994  iedge = m_edges[iedge].inext;
1995  k++;
1996  }
1997  if (k < 3) {
1998  std::cerr << "BooleanProcessor::createPolyhedron : "
1999  << "face has only " << k << " edges"
2000  << std::endl;
2001  }
2002  polyhedron.m_pF[m_faces[i].inew] =
2003  G4Facet(v[0],f[0], v[1],f[1], v[2],f[2], v[3],f[3]);
2004  }
2005  return polyhedron;
2006 }
2007 
2008 int BooleanProcessor::s_ishift = 0; //G.Barrand
2009 int BooleanProcessor::get_shift() { return s_ishift;} //G.Barrand
2010 void BooleanProcessor::set_shift(int a_shift) { s_ishift = a_shift;} //G.Barrand
2011 #define NUM_SHIFT 8
2012 int BooleanProcessor::get_num_shift() { return NUM_SHIFT;} //G.Barrand
2013 
2015  const HepPolyhedron & a,
2016  const HepPolyhedron & b,
2017  int& err) //G.Barrand
2018 /***********************************************************************
2019  * *
2020  * Name: BooleanProcessor::execute Date: 10.12.99 *
2021  * Author: E.Chernyaev Revised: *
2022  * *
2023  * Function: Execute boolean operation. *
2024  * *
2025  ***********************************************************************/
2026 {
2027  //static int ishift = 0; //G.Barrand
2028  //static double shift[8][3] = {
2029  static double shift[NUM_SHIFT][3] = { //G.Barrand
2030  { 31, 23, 17},
2031  { -31, -23, -17},
2032  { -23, 17, 31},
2033  { 23, -17, -31},
2034  { -17, -31, 23},
2035  { 17, 31, -23},
2036  { 31, -23, 17},
2037  { -31, 23, -17}
2038  };
2039 
2040 /*
2041  G4cerr << "BooleanProcessor::execute : ++++++++++++++++++++++"
2042  << a.getName().getString()
2043  << b.getName().getString()
2044  << G4endl;
2045 */
2046 
2047  // I N I T I A T E P R O C E S S O R
2048 
2049  m_processor_error = 0;
2050  m_operation = op;
2051  m_nodes.clear(); m_nodes.push_back(CRAZY_POINT);
2052  m_edges.clear(); m_edges.push_back(ExtEdge());
2053  m_faces.clear(); m_faces.push_back(ExtFace(m_edges,0)); //G.Barrand : ok ?
2054 
2055  // T A K E P O L Y H E D R A
2056 
2057  m_ifaces1 = m_faces.size(); takePolyhedron(a,0,0,0);
2058  m_ifaces2 = m_faces.size(); takePolyhedron(b,0,0,0);
2059 
2060  if (m_processor_error) { // corrupted polyhedron
2061  std::cerr
2062  << "BooleanProcessor: corrupted input polyhedron"
2063  << std::endl;
2064  err = m_processor_error; //G.Barrand
2065  return HepPolyhedron();
2066  }
2067  if (m_ifaces1 == m_ifaces2) { // a is empty
2068  err = m_processor_error; //G.Barrand
2069  switch (m_operation) {
2070  case OP_UNION:
2071  return b;
2072  case OP_INTERSECTION:
2073  std::cerr
2074  << "BooleanProcessor: intersection with empty polyhedron"
2075  << std::endl;
2076  return HepPolyhedron();
2077  case OP_SUBTRACTION:
2078  std::cerr
2079  << "BooleanProcessor: subtraction from empty polyhedron"
2080  << std::endl;
2081  return HepPolyhedron();
2082  }
2083  }
2084  if (m_ifaces2 == (int)m_faces.size()) { // b is empty
2085  err = m_processor_error; //G.Barrand
2086  switch (m_operation) {
2087  case OP_UNION:
2088  return a;
2089  case OP_INTERSECTION:
2090  std::cerr
2091  << "BooleanProcessor: intersection with empty polyhedron"
2092  << std::endl;
2093  return HepPolyhedron();
2094  case OP_SUBTRACTION:
2095  return a;
2096  }
2097  }
2098 
2099  // S E T I N I T I A L M I N - M A X A N D T O L E R A N C E
2100 
2101  m_del = findMinMax();
2102 
2103  // W O R K A R O U N D T O A V O I D I E A N D E E
2104 
2105 /*
2106 #define PROCESSOR_ERROR(a_what) \
2107  G4cerr << "BooleanProcessor: boolean operation problem (" << a_what \
2108  << "). Try again with other shifts."\
2109  << G4endl;
2110 */
2111 #define PROCESSOR_ERROR(a_what)
2112 
2113  unsigned int try_count = 1;
2114  while(true) { //G.Barrand
2115 
2116  double ddxx = m_del*shift[s_ishift][0];
2117  double ddyy = m_del*shift[s_ishift][1];
2118  double ddzz = m_del*shift[s_ishift][2];
2119  s_ishift++; if (s_ishift == get_num_shift()) s_ishift = 0;
2120 
2121  m_processor_error = 0; //G.Barrand
2122  m_operation = op;
2123  m_nodes.clear(); m_nodes.push_back(CRAZY_POINT);
2124  m_edges.clear(); m_edges.push_back(ExtEdge());
2125  m_faces.clear(); m_faces.push_back(ExtFace(m_edges,0)); //G.Barrand : ok ?
2126 
2127  m_ifaces1 = m_faces.size(); takePolyhedron(a,0,0,0);
2128  m_ifaces2 = m_faces.size(); takePolyhedron(b,ddxx,ddyy,ddzz);
2129 
2130  if (m_processor_error) { PROCESSOR_ERROR(1) } //G.Barrand
2131 
2132  m_del = findMinMax();
2133 
2134  // P R E S E L E C T O U T S I D E F A C E S
2135 
2136  m_iout1 = m_iout2 = 0;
2139 
2140  if (m_processor_error) { PROCESSOR_ERROR(2) } //G.Barrand
2141 
2142  // P R E S E L E C T N O I N T E R S E C T I O N F A C E S
2143 
2144  int ifa1, ifa2;
2145  m_iunk1 = m_iunk2 = 0;
2146  if (m_iout1 != 0 || m_iout2 != 0) {
2147  for(;;) {
2148  ifa1 = m_iunk1;
2149  ifa2 = m_iunk2;
2152  if (m_iunk1 == ifa1 && m_iunk2 == ifa2) break;
2153  findMinMax();
2154  }
2155  }
2156 
2157  if (m_processor_error) { PROCESSOR_ERROR(3) } //G.Barrand
2158 
2159  // F I N D N E W E D G E S
2160 
2161  if (m_ifaces1 != 0 && m_ifaces2 != 0 ) {
2162  ifa1 = m_ifaces1;
2163  while (ifa1 > 0) {
2164  ifa2 = m_ifaces2;
2165  while (ifa2 > 0) {
2166  testFaceVsFace(ifa1, ifa2);
2167  ifa2 = m_faces[ifa2].inext;
2168  }
2169  ifa1 = m_faces[ifa1].inext;
2170  }
2171  }
2172  if (m_processor_error) { PROCESSOR_ERROR(4) } //G.Barrand
2173 
2174  // C O N S T R U C T N E W F A C E S
2175 
2177  if (m_processor_error) { PROCESSOR_ERROR(5) } //G.Barrand
2179  if (m_processor_error) { PROCESSOR_ERROR(6) } //G.Barrand
2180 
2181  // A S S E M B L E S U I T A B L E F A C E S
2182 
2183  initiateLists();
2185  if (m_unknown_faces.front() != 0) {
2186  m_processor_error = 1;
2187 #ifdef BP_DEBUG
2188  G4cerr
2189  << "BooleanProcessor::execute : unknown faces !!!"
2190  << G4endl;
2191 #endif
2192  }
2193  if (m_processor_error) { PROCESSOR_ERROR(7) } //G.Barrand
2194 
2195  // T R I A N G U L A T E A C C E P T E D F A C E S
2196 
2197  ifa1 = m_result_faces.front();
2198  while (ifa1 > 0) {
2199  ifa2 = ifa1;
2200  ifa1 = m_faces[ifa2].inext;
2201  if (m_faces[ifa2].inew == NEW_FACE) triangulateFace(ifa2);
2202  if (m_processor_error) {
2203  PROCESSOR_ERROR(8) //G.Barrand
2204  break; //G.Barrand
2205  }
2206  }
2207 
2208  if(!m_processor_error) {
2209 #ifdef BP_DEBUG
2210  if(try_count!=1) {
2211  G4cerr
2212  << "BooleanProcessor::execute : had converged."
2213  << G4endl;
2214  }
2215 #endif
2216  break;
2217  }
2218 
2219  if((int)try_count>get_num_shift()) {
2220 #ifdef BP_DEBUG
2221  /*** Commented out because HepPolyhedron does not have getName...?!
2222  G4cerr << "BooleanProcessor: "
2223  << " all shifts tried. Boolean operation (" << op << ") failure."
2224  << " a name \"" << a.getName().getString() << "\""
2225  << " b name \"" << b.getName().getString() << "\""
2226  << G4endl;
2227  ***/
2228 #endif
2230  return a;
2231  }
2232 
2233 #ifdef BP_DEBUG
2234  G4cerr
2235  << "BooleanProcessor::execute : try another tilt..."
2236  << G4endl;
2237 #endif
2238 
2239  try_count++;
2240 
2241  } //G.Barrand : end while shift.
2242 #undef PROCESSOR_ERROR //G.Barrand
2243 
2244  // C R E A T E P O L Y H E D R O N
2245 
2247  return createPolyhedron();
2248 }
2249 
2250 
2251 //#include <cfortran.h>
2252 //#include <higz.h>
2253 //#include "zbuf.h"
2254 //void BooleanProcessor::draw()
2255 /***********************************************************************
2256  * *
2257  * Name: BooleanProcessor::draw Date: 10.12.99 *
2258  * Author: E.Chernyaev Revised: *
2259  * *
2260  * Function: Draw *
2261  * *
2262  ***********************************************************************/
2263 /*
2264 {
2265  int II;
2266  int icol, i1, i2, iedge, iface, ilist[4];
2267  float p1[3], p2[3];
2268 
2269  ilist[0] = m_ifaces1;
2270  ilist[1] = m_ifaces2;
2271  ilist[2] = m_iout1;
2272  ilist[3] = m_iout2;
2273 
2274  for (int i=0; i<4; i++) {
2275 
2276  if (i == 0) G4cout << "========= Ifaces_1" << G4endl;
2277  if (i == 1) G4cout << "========= Ifaces_2" << G4endl;
2278  if (i == 2) G4cout << "========= Iout_1" << G4endl;
2279  if (i == 3) G4cout << "========= Iout_2" << G4endl;
2280 
2281  icol = i+1;
2282  iface = ilist[i];
2283  while (iface > 0) {
2284 
2285  G4cout << "iface = " << iface << G4endl;
2286  G4cout << "--- iold" << G4endl;
2287 
2288  iedge = m_faces[iface].iold;
2289  icol = 2;
2290 
2291  while (iedge > 0) {
2292 
2293  G4cout << " iegde = " << iedge
2294  << " i1,i2 =" << m_edges[iedge].i1 << "," << m_edges[iedge].i2
2295  << " iface1,iface2 = "
2296  << m_edges[iedge].iface1 << "," << m_edges[iedge].iface2
2297  << G4endl;
2298 
2299  i1 = m_edges[iedge].i1;
2300  p1[0] = m_nodes[i1].v.x();
2301  p1[1] = m_nodes[i1].v.y();
2302  p1[2] = m_nodes[i1].v.z();
2303  IHWTON(p1,p1);
2304  i2 = m_edges[iedge].i2;
2305  p2[0] = m_nodes[i2].v.x();
2306  p2[1] = m_nodes[i2].v.y();
2307  p2[2] = m_nodes[i2].v.z();
2308  IHWTON(p2,p2);
2309 // icol = (m_edges[iedge].ivis > 0) ? 1 : 2;
2310  IHZLIN(icol,p1[0],p1[1],p1[2], p2[0],p2[1],p2[2]);
2311  iedge = m_edges[iedge].inext;
2312  }
2313 
2314  G4cout << "--- inew" << G4endl;
2315 
2316  iedge = m_faces[iface].inew;
2317  icol = 3;
2318 
2319  while (iedge > 0) {
2320 
2321  G4cout << " iegde = " << iedge
2322  << " i1,i2 =" << m_edges[iedge].i1 << "," << m_edges[iedge].i2
2323  << " iface1,iface2 = "
2324  << m_edges[iedge].iface1 << "," << m_edges[iedge].iface2
2325  << G4endl;
2326 
2327  i1 = m_edges[iedge].i1;
2328  p1[0] = m_nodes[i1].v.x();
2329  p1[1] = m_nodes[i1].v.y();
2330  p1[2] = m_nodes[i1].v.z();
2331  IHWTON(p1,p1);
2332  i2 = m_edges[iedge].i2;
2333  p2[0] = m_nodes[i2].v.x();
2334  p2[1] = m_nodes[i2].v.y();
2335  p2[2] = m_nodes[i2].v.z();
2336  IHWTON(p2,p2);
2337 // icol = (m_edges[iedge].ivis > 0) ? 1 : 2;
2338  IHZLIN(icol,p1[0],p1[1],p1[2], p2[0],p2[1],p2[2]);
2339  iedge = m_edges[iedge].inext;
2340  }
2341  iface = m_faces[iface].inext;
2342 
2343  IHZTOX(0,100,100);
2344  ixupdwi(0);
2345  cin >> II;
2346  ixclrwi();
2347  IHZCLE(0);
2348  }
2349  }
2350 }
2351 */
2352 
2353 /*
2354 //--------------------------------------------------------------------
2355 void
2356 BooleanProcessor::draw_edge(int icol, int iedge) {
2357  int i1, i2;
2358  float p1[3], p2[3];
2359 
2360  i1 = m_edges[iedge].i1;
2361  p1[0] = m_nodes[i1].v.x();
2362  p1[1] = m_nodes[i1].v.y();
2363  p1[2] = m_nodes[i1].v.z();
2364  IHWTON(p1,p1);
2365  i2 = m_edges[iedge].i2;
2366  p2[0] = m_nodes[i2].v.x();
2367  p2[1] = m_nodes[i2].v.y();
2368  p2[2] = m_nodes[i2].v.z();
2369  IHWTON(p2,p2);
2370  IHZLIN(icol,p1[0],p1[1],p1[2], p2[0],p2[1],p2[2]);
2371 }
2372 
2373 //--------------------------------------------------------------------
2374 void
2375 BooleanProcessor::draw_contour(int i1col, int i2col, int ihead) {
2376  int iedge, icol;
2377  iedge = ihead;
2378  while (iedge > 0) {
2379  icol = (m_edges[iedge].ivis > 0) ? i1col : i2col;
2380  draw_edge(icol, iedge);
2381  iedge = m_edges[iedge].inext;
2382  }
2383 
2384  IHZTOX(0,100,100);
2385  ixupdwi(0);
2386 
2387  int i;
2388  std::cin >> i;
2389 }
2390 
2391 //--------------------------------------------------------------------
2392 void
2393 BooleanProcessor::print_face(int iface) {
2394  G4cout.precision(3);
2395  G4cout << "\n====== Face N " << iface << G4endl;
2396  G4cout << "iedges[4] = "
2397  << m_faces[iface].iedges[0] << ", "
2398  << m_faces[iface].iedges[1] << ", "
2399  << m_faces[iface].iedges[2] << ", "
2400  << m_faces[iface].iedges[3] << G4endl;
2401  G4cout << "rmin[3] = "
2402  << m_faces[iface].m_rmin[0] << ", "
2403  << m_faces[iface].m_rmin[1] << ", "
2404  << m_faces[iface].m_rmin[2] << G4endl;
2405  G4cout << "rmax[3] = "
2406  << m_faces[iface].m_rmax[0] << ", "
2407  << m_faces[iface].m_rmax[1] << ", "
2408  << m_faces[iface].m_rmax[2] << G4endl;
2409  G4cout << "iprev,inext = "
2410  << m_faces[iface].iprev << ", "
2411  << m_faces[iface].inext << G4endl;
2412  G4cout << "iold = " << m_faces[iface].iold << G4endl;
2413  for(int i = m_faces[iface].iold; i != 0;) {
2414  print_edge(i);
2415  i = m_edges[abs(i)].inext;
2416  }
2417 
2418  G4cout << "inew = ";
2419  switch (m_faces[iface].inew) {
2420  case UNKNOWN_FACE:
2421  G4cout << "UNKNOWN_FACE" << G4endl;
2422  break;
2423  case ORIGINAL_FACE:
2424  G4cout << "ORIGINAL_FACE" << G4endl;
2425  break;
2426  case NEW_FACE:
2427  G4cout << "NEW_FACE" << G4endl;
2428  break;
2429  case UNSUITABLE_FACE:
2430  G4cout << "UNSUITABLE_FACE" << G4endl;
2431  break;
2432  case DEFECTIVE_FACE:
2433  G4cout << "DEFECTIVE_FACE" << G4endl;
2434  break;
2435  default:
2436  G4cout << m_faces[iface].inew << G4endl;
2437  for(int k = m_faces[iface].inew; k != 0;) {
2438  print_edge(k);
2439  k = m_edges[abs(k)].inext;
2440  }
2441  }
2442 }
2443 
2444 //--------------------------------------------------------------------
2445 void
2446 BooleanProcessor::print_edge(int iedge) {
2447  G4cout << "==== Edge N " << iedge << G4endl;
2448  int i = std::abs(iedge);
2449  int i1 = m_edges[i].i1;
2450  int i2 = m_edges[i].i2;
2451  G4cout << "node[" << i1 << "] = "
2452  << m_nodes[i1].v.x() << ", "
2453  << m_nodes[i1].v.y() << ", "
2454  << m_nodes[i1].v.z() << G4endl;
2455 
2456  G4cout << "node[" << i2 << "] = "
2457  << m_nodes[i2].v.x() << ", "
2458  << m_nodes[i2].v.y() << ", "
2459  << m_nodes[i2].v.z() << G4endl;
2460 
2461  G4cout << "iface1,iface2,ivis,inext = "
2462  << m_edges[i].iface1 << ", "
2463  << m_edges[i].iface2 << ", "
2464  << m_edges[i].ivis << ", "
2465  << m_edges[i].inext << G4endl;
2466 }
2467 */
2468 
2469 void BooleanProcessor::dump() {//G.Barrand
2470  unsigned int number = m_nodes.size();
2471  std::cerr << "nodes : " << number << std::endl;
2472  for(unsigned int index=0;index<number;index++) {
2473  const ExtNode& node = m_nodes[index];
2474  std::cerr << " " << index
2475  << " x = " << node.v[0]
2476  << " y = " << node.v[1]
2477  << " z = " << node.v[2]
2478  << std::endl;
2479  }
2480 }
BooleanProcessor::testFaceVsFace
void testFaceVsFace(int iface1, int iface2)
Definition: BooleanProcessor.h:988
UNSUITABLE_FACE
#define UNSUITABLE_FACE
Definition: BooleanProcessor.h:102
ExtEdge::iface1
int iface1
Definition: BooleanProcessor.h:171
ExtEdge::operator=
ExtEdge & operator=(const ExtEdge &edge)
Definition: BooleanProcessor.h:186
ExtNode::operator=
ExtNode & operator=(const ExtNode &node)
Definition: BooleanProcessor.h:159
plotBeamSpotCompare.x1
x1
Definition: plotBeamSpotCompare.py:216
BooleanProcessor::removeJunkNodes
void removeJunkNodes()
Definition: BooleanProcessor.h:342
ExtFace::iprev
int iprev
Definition: BooleanProcessor.h:213
FaceList::push_back
void push_back(int i)
Definition: BooleanProcessor.h:277
SbPlane.h
FaceList::~FaceList
~FaceList()
Definition: BooleanProcessor.h:272
ReadCellNoiseFromCoolCompare.s1
s1
Definition: ReadCellNoiseFromCoolCompare.py:378
BooleanProcessor::m_iout2
int m_iout2
Definition: BooleanProcessor.h:322
BooleanProcessor::m_ifaces2
int m_ifaces2
Definition: BooleanProcessor.h:321
GRANULARITY
#define GRANULARITY
Definition: BooleanProcessor.h:85
python.SystemOfUnits.s
int s
Definition: SystemOfUnits.py:131
NON_PLANAR_FACE
#define NON_PLANAR_FACE
Definition: BooleanProcessor.h:97
BooleanProcessor::print_edge
void print_edge(int)
BooleanProcessor::initiateLists
void initiateLists()
Definition: BooleanProcessor.h:1213
BooleanProcessor::caseII
void caseII(ExtEdge &edge1, ExtEdge &edge2)
Definition: BooleanProcessor.h:934
CaloCellPos2Ntuple.int
int
Definition: CaloCellPos2Ntuple.py:24
BooleanProcessor::set_shift
static void set_shift(int)
Definition: BooleanProcessor.h:2010
index
Definition: index.py:1
CRAZY_POINT
#define CRAZY_POINT
Definition: BooleanProcessor.h:83
hist_file_dump.d
d
Definition: hist_file_dump.py:137
LUCID_EventTPCnv_Dict::t3
std::vector< LUCID_RawData_p1 > t3
Definition: LUCID_EventTPCnvDict.h:28
FaceList::FaceList
FaceList(std::vector< ExtFace > &a_faces)
Definition: BooleanProcessor.h:271
INSERT_EDGE_TO_THE_LIST
#define INSERT_EDGE_TO_THE_LIST(A)
BooleanProcessor::m_iunk2
int m_iunk2
Definition: BooleanProcessor.h:323
OP_INTERSECTION
#define OP_INTERSECTION
Definition: BooleanProcessor.h:90
BooleanProcessor
Definition: BooleanProcessor.h:312
plotBeamSpotCompare.x2
x2
Definition: plotBeamSpotCompare.py:218
extractSporadic.c1
c1
Definition: extractSporadic.py:134
BooleanProcessor::divideEdge
void divideEdge(int &i1, int &i2)
Definition: BooleanProcessor.h:869
BooleanProcessor::checkDoubleEdges
void checkDoubleEdges(int iface)
Definition: BooleanProcessor.h:1068
BooleanProcessor::print_face
void print_face(int)
ALFA_EventTPCnv_Dict::t1
std::vector< ALFA_RawDataCollection_p1 > t1
Definition: ALFA_EventTPCnvDict.h:43
BooleanProcessor::caseEE
void caseEE(ExtEdge &edge1, ExtEdge &edge2)
Definition: BooleanProcessor.h:970
HEPVis::SbPlane::distance
double distance(const SbVec3d &point) const
Definition: SbPlane.cxx:74
ExtEdge::ExtEdge
ExtEdge(int k1=0, int k2=0, int kface1=0, int kface2=0, int kvis=0)
Definition: BooleanProcessor.h:177
FaceList::clean
void clean()
Definition: BooleanProcessor.h:274
dq_defect_virtual_defect_validation.d1
d1
Definition: dq_defect_virtual_defect_validation.py:79
ExtNode::~ExtNode
~ExtNode()
Definition: BooleanProcessor.h:155
BooleanProcessor::~BooleanProcessor
~BooleanProcessor()
Definition: BooleanProcessor.h:389
BooleanProcessor::m_rmin
double m_rmin[3]
Definition: BooleanProcessor.h:324
HEPVis::SbPlane
Definition: SbPlane.h:40
BooleanProcessor::triangulateFace
void triangulateFace(int iface)
Definition: BooleanProcessor.h:1794
HVPlane3D
HEPVis::SbPlane HVPlane3D
Definition: BooleanProcessor.h:67
BooleanProcessor::s_ishift
static int s_ishift
Definition: BooleanProcessor.h:314
BooleanProcessor::get_shift
static int get_shift()
Definition: BooleanProcessor.h:2009
G4Facet
#define G4Facet
Definition: BooleanProcessor.h:62
BooleanProcessor::draw_edge
void draw_edge(int, int)
x
#define x
ExtFace::operator=
ExtFace & operator=(const ExtFace &face)
Definition: BooleanProcessor.h:236
FaceList::front
int front()
Definition: BooleanProcessor.h:275
BooleanProcessor::assembleNewFaces
void assembleNewFaces(int what, int ihead)
Definition: BooleanProcessor.h:1190
BooleanProcessor::draw_faces
void draw_faces(int, int, int)
makeTRTBarrelCans.y1
tuple y1
Definition: makeTRTBarrelCans.py:15
BooleanProcessor::m_unsuitable_faces
FaceList m_unsuitable_faces
Definition: BooleanProcessor.h:329
ExtNode
#define ExtNode
Definition: BooleanProcessor.h:54
BooleanProcessor::assembleFace
void assembleFace(int what, int iface)
Definition: BooleanProcessor.h:1081
BooleanProcessor::m_iout1
int m_iout1
Definition: BooleanProcessor.h:322
OP_UNION
#define OP_UNION
Definition: BooleanProcessor.h:89
BooleanProcessor::m_edges
std::vector< ExtEdge > m_edges
Definition: BooleanProcessor.h:316
ExtFace
Definition: BooleanProcessor.h:204
python.DataFormatRates.c3
c3
Definition: DataFormatRates.py:127
EDGE
#define EDGE
Definition: BooleanProcessor.h:96
ExtEdge::invert
void invert()
Definition: BooleanProcessor.h:197
ExtNode::v
HVPoint3D v
Definition: BooleanProcessor.h:149
python.utils.AtlRunQueryDQUtils.p
p
Definition: AtlRunQueryDQUtils.py:210
FaceList::remove
void remove(int i)
Definition: BooleanProcessor.h:285
BooleanProcessor::m_ifaces1
int m_ifaces1
Definition: BooleanProcessor.h:321
BooleanProcessor::m_suitable_faces
FaceList m_suitable_faces
Definition: BooleanProcessor.h:328
dqt_zlumi_pandas.err
err
Definition: dqt_zlumi_pandas.py:182
BooleanProcessor::draw_contour
void draw_contour(int, int, int)
ExtEdge
Definition: BooleanProcessor.h:168
ExtNode
Definition: BooleanProcessor.h:147
lumiFormat.i
int i
Definition: lumiFormat.py:85
BooleanProcessor::get_num_shift
static int get_num_shift()
Definition: BooleanProcessor.h:2012
BooleanProcessor::checkDirection
int checkDirection(double *x, double *y) const
Definition: BooleanProcessor.h:1420
z
#define z
BooleanProcessor::m_nodes
std::vector< ExtNode > m_nodes
Definition: BooleanProcessor.h:315
HEPVis::SbPlane::getNormal
const SbVec3d & getNormal() const
Definition: SbPlane.cxx:77
beamspotman.n
n
Definition: beamspotman.py:731
BooleanProcessor::assemblePolyhedra
void assemblePolyhedra()
Definition: BooleanProcessor.h:1317
makeTRTBarrelCans.y2
tuple y2
Definition: makeTRTBarrelCans.py:18
FaceList::m_ilast
int m_ilast
Definition: BooleanProcessor.h:267
ExtFace::rmax
double rmax[3]
Definition: BooleanProcessor.h:210
FaceList::m_ihead
int m_ihead
Definition: BooleanProcessor.h:266
ExtFace::inew
int inew
Definition: BooleanProcessor.h:212
ExtEdge::~ExtEdge
~ExtEdge()
Definition: BooleanProcessor.h:180
BooleanProcessor::m_faces
std::vector< ExtFace > m_faces
Definition: BooleanProcessor.h:317
BooleanProcessor::checkIntersection
int checkIntersection(int ix, int iy, int i1, int i2) const
Definition: BooleanProcessor.h:1456
HepPolyhedron
#define HepPolyhedron
Definition: BooleanProcessor.h:61
ExtEdge::ivis
int ivis
Definition: BooleanProcessor.h:173
hist_file_dump.f
f
Definition: hist_file_dump.py:135
ExtEdge::i2
int i2
Definition: BooleanProcessor.h:170
BooleanProcessor::invertNewEdges
void invertNewEdges(int iface)
Definition: BooleanProcessor.h:1051
ExtFace::iedges
int iedges[4]
Definition: BooleanProcessor.h:208
SWAP
#define SWAP(A, B)
Definition: BooleanProcessor.h:87
NEW_FACE
#define NEW_FACE
Definition: BooleanProcessor.h:101
FaceList
Definition: BooleanProcessor.h:262
ON_PLANE
#define ON_PLANE
Definition: BooleanProcessor.h:94
NUM_SHIFT
#define NUM_SHIFT
Definition: BooleanProcessor.h:2011
BooleanProcessor::findABC
void findABC(double x1, double y1, double x2, double y2, double &a, double &b, double &c) const
Definition: BooleanProcessor.h:1399
ExtEdge
#define ExtEdge
Definition: BooleanProcessor.h:55
ExtNode::ExtNode
ExtNode(HVPoint3D vertex=HVPoint3D(), int status=0)
Definition: BooleanProcessor.h:153
LUCID_EventTPCnv_Dict::t4
std::vector< LUCID_RawDataContainer_p1 > t4
Definition: LUCID_EventTPCnvDict.h:29
OUT_OF_PLANE
#define OUT_OF_PLANE
Definition: BooleanProcessor.h:93
BooleanProcessor::draw
void draw()
INTERSECTION
#define INTERSECTION
Definition: BooleanProcessor.h:95
BooleanProcessor::m_processor_error
int m_processor_error
Definition: BooleanProcessor.h:319
python.ExitCodes.what
def what(code)
Definition: ExitCodes.py:73
ExtEdge::i1
int i1
Definition: BooleanProcessor.h:170
OP_SUBTRACTION
#define OP_SUBTRACTION
Definition: BooleanProcessor.h:91
python.selection.number
number
Definition: selection.py:20
ExtFace::inext
int inext
Definition: BooleanProcessor.h:214
plotBeamSpotMon.b
b
Definition: plotBeamSpotMon.py:77
ExtEdge::iface2
int iface2
Definition: BooleanProcessor.h:172
ExtFace::plane
HVPlane3D plane
Definition: BooleanProcessor.h:209
ExtFace::ExtFace
ExtFace(std::vector< ExtEdge > &a_edges, int iedge)
Definition: BooleanProcessor.h:218
BooleanProcessor::mergeContours
void mergeContours(int ix, int iy, int kext, int kint)
Definition: BooleanProcessor.h:1535
ExtPolyhedron
Definition: BooleanProcessor.h:304
BooleanProcessor::m_rmax
double m_rmax[3]
Definition: BooleanProcessor.h:324
ExtEdge::ExtEdge
ExtEdge(const ExtEdge &edge)
Definition: BooleanProcessor.h:182
library_scraper.dd
list dd
Definition: library_scraper.py:46
BooleanProcessor::m_external_contours
std::vector< int > m_external_contours
Definition: BooleanProcessor.h:332
BooleanProcessor::modifyReference
void modifyReference(int iface, int i1, int i2, int iref)
Definition: BooleanProcessor.h:1767
HVNormal3D
HVPoint3D HVNormal3D
Definition: SbPolyhedron.h:199
python.PyAthena.v
v
Definition: PyAthena.py:154
makeTRTBarrelCans.dy
tuple dy
Definition: makeTRTBarrelCans.py:21
BooleanProcessor::m_result_faces
FaceList m_result_faces
Definition: BooleanProcessor.h:327
BooleanProcessor::checkTriangle
int checkTriangle(int iedge1, int iedge2, int ix, int iy) const
Definition: BooleanProcessor.h:1607
ALFA_EventTPCnv_Dict::t2
std::vector< ALFA_RawDataContainer_p1 > t2
Definition: ALFA_EventTPCnvDict.h:44
BooleanProcessor::testFaceVsPlane
int testFaceVsPlane(ExtEdge &edge)
Definition: BooleanProcessor.h:688
BooleanProcessor::m_internal_contours
std::vector< int > m_internal_contours
Definition: BooleanProcessor.h:333
ExtNode::ExtNode
ExtNode(const ExtNode &node)
Definition: BooleanProcessor.h:157
python.DataFormatRates.c2
c2
Definition: DataFormatRates.py:123
Trk::vertex
@ vertex
Definition: MeasurementType.h:21
BooleanProcessor::m_unknown_faces
FaceList m_unknown_faces
Definition: BooleanProcessor.h:330
DeMoScan.index
string index
Definition: DeMoScan.py:364
BooleanProcessor::BooleanProcessor
BooleanProcessor()
Definition: BooleanProcessor.h:368
BooleanProcessor::takePolyhedron
void takePolyhedron(const HepPolyhedron &p, double, double, double)
Definition: BooleanProcessor.h:451
a
TList * a
Definition: liststreamerinfos.cxx:10
y
#define y
UNKNOWN_FACE
#define UNKNOWN_FACE
Definition: BooleanProcessor.h:99
dq_defect_virtual_defect_validation.d2
d2
Definition: dq_defect_virtual_defect_validation.py:81
FaceList::m_faces
std::vector< ExtFace > & m_faces
Definition: BooleanProcessor.h:264
ReadCellNoiseFromCoolCompare.s2
s2
Definition: ReadCellNoiseFromCoolCompare.py:379
makeTRTBarrelCans.dx
tuple dx
Definition: makeTRTBarrelCans.py:20
ExtFace
#define ExtFace
Definition: BooleanProcessor.h:56
HEPVis::SbPlane::getDistanceFromOrigin
double getDistanceFromOrigin() const
Definition: SbPlane.cxx:78
BooleanProcessor::selectOutsideFaces
void selectOutsideFaces(int &ifaces, int &iout)
Definition: BooleanProcessor.h:630
BooleanProcessor::createPolyhedron
HepPolyhedron createPolyhedron()
Definition: BooleanProcessor.h:1934
ExtFace::m_edges
std::vector< ExtEdge > & m_edges
Definition: BooleanProcessor.h:206
BooleanProcessor::renumberNodes
void renumberNodes(int &i1, int &i2, int &i3, int &i4)
Definition: BooleanProcessor.h:806
ExtFace::invert
void invert()
Definition: BooleanProcessor.h:410
merge.status
status
Definition: merge.py:17
ExtNode::s
int s
Definition: BooleanProcessor.h:150
BooleanProcessor::triangulateContour
void triangulateContour(int ix, int iy, int ihead)
Definition: BooleanProcessor.h:1659
BooleanProcessor::findMinMax
double findMinMax()
Definition: BooleanProcessor.h:567
PROCESSOR_ERROR
#define PROCESSOR_ERROR(a_what)
ExtFace::ExtFace
ExtFace(const ExtFace &face)
Definition: BooleanProcessor.h:226
BooleanProcessor::get_processor_error
int get_processor_error() const
Definition: BooleanProcessor.h:402
ExtEdge::inext
int inext
Definition: BooleanProcessor.h:174
BooleanProcessor::m_operation
int m_operation
Definition: BooleanProcessor.h:320
DEFECTIVE_FACE
#define DEFECTIVE_FACE
Definition: BooleanProcessor.h:103
python.IoTestsLib.w
def w
Definition: IoTestsLib.py:200
BooleanProcessor::m_del
double m_del
Definition: BooleanProcessor.h:325
BooleanProcessor::dump
void dump()
Definition: BooleanProcessor.h:2469
BooleanProcessor::m_iunk1
int m_iunk1
Definition: BooleanProcessor.h:323
ExtFace::iold
int iold
Definition: BooleanProcessor.h:211
python.compressB64.c
def c
Definition: compressB64.py:93
BooleanProcessor::insertEdge
void insertEdge(const ExtEdge &edge)
Definition: BooleanProcessor.h:918
BooleanProcessor::caseIE
void caseIE(ExtEdge &edge1, ExtEdge &edge2)
Definition: BooleanProcessor.h:952
ExtFace::rmin
double rmin[3]
Definition: BooleanProcessor.h:210
ExtFace::~ExtFace
~ExtFace()
Definition: BooleanProcessor.h:224
ORIGINAL_FACE
#define ORIGINAL_FACE
Definition: BooleanProcessor.h:100
HVPoint3D
Definition: SbPolyhedron.h:188
node
Definition: memory_hooks-stdcmalloc.h:74
BooleanProcessor::execute
HepPolyhedron execute(int op, const HepPolyhedron &a, const HepPolyhedron &b, int &err)
Definition: BooleanProcessor.h:2014
fitman.k
k
Definition: fitman.py:528
inode
Definition: listroot.cxx:155
BooleanProcessor::testEdgeVsEdge
int testEdgeVsEdge(ExtEdge &edge1, ExtEdge &edge2)
Definition: BooleanProcessor.h:831
ExtPolyhedron::operator=
virtual HepPolyhedron & operator=(const HepPolyhedron &from)
Definition: BooleanProcessor.h:306