Geant4 Cross Reference

Cross-Referencing   Geant4
Geant4/externals/g4tools/include/tools/zb/polygon

Version: [ ReleaseNotes ] [ 1.0 ] [ 1.1 ] [ 2.0 ] [ 3.0 ] [ 3.1 ] [ 3.2 ] [ 4.0 ] [ 4.0.p1 ] [ 4.0.p2 ] [ 4.1 ] [ 4.1.p1 ] [ 5.0 ] [ 5.0.p1 ] [ 5.1 ] [ 5.1.p1 ] [ 5.2 ] [ 5.2.p1 ] [ 5.2.p2 ] [ 6.0 ] [ 6.0.p1 ] [ 6.1 ] [ 6.2 ] [ 6.2.p1 ] [ 6.2.p2 ] [ 7.0 ] [ 7.0.p1 ] [ 7.1 ] [ 7.1.p1 ] [ 8.0 ] [ 8.0.p1 ] [ 8.1 ] [ 8.1.p1 ] [ 8.1.p2 ] [ 8.2 ] [ 8.2.p1 ] [ 8.3 ] [ 8.3.p1 ] [ 8.3.p2 ] [ 9.0 ] [ 9.0.p1 ] [ 9.0.p2 ] [ 9.1 ] [ 9.1.p1 ] [ 9.1.p2 ] [ 9.1.p3 ] [ 9.2 ] [ 9.2.p1 ] [ 9.2.p2 ] [ 9.2.p3 ] [ 9.2.p4 ] [ 9.3 ] [ 9.3.p1 ] [ 9.3.p2 ] [ 9.4 ] [ 9.4.p1 ] [ 9.4.p2 ] [ 9.4.p3 ] [ 9.4.p4 ] [ 9.5 ] [ 9.5.p1 ] [ 9.5.p2 ] [ 9.6 ] [ 9.6.p1 ] [ 9.6.p2 ] [ 9.6.p3 ] [ 9.6.p4 ] [ 10.0 ] [ 10.0.p1 ] [ 10.0.p2 ] [ 10.0.p3 ] [ 10.0.p4 ] [ 10.1 ] [ 10.1.p1 ] [ 10.1.p2 ] [ 10.1.p3 ] [ 10.2 ] [ 10.2.p1 ] [ 10.2.p2 ] [ 10.2.p3 ] [ 10.3 ] [ 10.3.p1 ] [ 10.3.p2 ] [ 10.3.p3 ] [ 10.4 ] [ 10.4.p1 ] [ 10.4.p2 ] [ 10.4.p3 ] [ 10.5 ] [ 10.5.p1 ] [ 10.6 ] [ 10.6.p1 ] [ 10.6.p2 ] [ 10.6.p3 ] [ 10.7 ] [ 10.7.p1 ] [ 10.7.p2 ] [ 10.7.p3 ] [ 10.7.p4 ] [ 11.0 ] [ 11.0.p1 ] [ 11.0.p2 ] [ 11.0.p3, ] [ 11.0.p4 ] [ 11.1 ] [ 11.1.1 ] [ 11.1.2 ] [ 11.1.3 ] [ 11.2 ] [ 11.2.1 ] [ 11.2.2 ] [ 11.3.0 ]

  1 // Copyright (C) 2010, Guy Barrand. All rights reserved.
  2 // See the file tools.license for terms.
  3 
  4 #ifndef tools_zb_polygon
  5 #define tools_zb_polygon
  6 
  7 #include "edge_table"
  8 #include "../mnmx"
  9 
 10 namespace tools {
 11 namespace zb {
 12 
 13 class polygon {
 14 
 15   static const int NUMPTSTOBUFFER = 200;
 16 
 17   typedef struct _POINTBLOCK {
 18       point pts[NUMPTSTOBUFFER];
 19       struct _POINTBLOCK* next;
 20   } POINTBLOCK;
 21 
 22   int             m_pETEn;
 23   EdgeTableEntry* m_pETEs;
 24   int             m_numAllocPtBlocks;
 25   POINTBLOCK      m_FirstPtBlock;
 26 public:
 27   polygon():m_pETEn(0),m_pETEs(NULL),m_numAllocPtBlocks(0){}
 28   virtual ~polygon(){clear();}
 29 protected:
 30   polygon(const polygon&){}
 31   polygon& operator=(const polygon&){return *this;}
 32 public:
 33   void clear(){
 34     POINTBLOCK* curPtBlock;
 35     cmem_free(m_pETEs);
 36     m_pETEn = 0;
 37     for(curPtBlock = m_FirstPtBlock.next; --m_numAllocPtBlocks >= 0;){
 38         POINTBLOCK* tmpPtBlock;
 39         tmpPtBlock  = curPtBlock->next;
 40         cmem_free(curPtBlock);
 41         curPtBlock  = tmpPtBlock;
 42     }
 43     m_numAllocPtBlocks = 0;
 44   }
 45 
 46   typedef void (*scan_func)(void*,int,int,int);
 47 
 48   void scan(int    Count,         /* number of pts  */
 49             const point* Pts,   /* the pts        */
 50             int    rule,          /* winding rule   */
 51             scan_func a_proc,void* a_tag){
 52     // polytoregion
 53     //   Scan converts a polygon by returning a run-length
 54     //   encoding of the resultant bitmap -- the run-length
 55     //   encoding is in the form of an array of rectangles.
 56 
 57     EdgeTableEntry* pAET;   /* Active Edge Table       */
 58     int y;                  /* current scanline        */
 59     int iPts = 0;           /* number of pts in buffer */
 60     EdgeTableEntry* pWETE;  /* Winding Edge Table Entry*/
 61     ScanLineList*   pSLL;   /* current scanLineList    */
 62 
 63     EdgeTableEntry* pPrevAET;        /* ptr to previous AET     */
 64     EdgeTable ET;                    /* header node for ET      */
 65     EdgeTableEntry AET;              /* header node for AET     */
 66     ScanLineListBlock SLLBlock;      /* header for scanlinelist */
 67     int         fixWAET = 0;
 68     POINTBLOCK* curPtBlock;
 69     int         numFullPtBlocks = 0;
 70 
 71     if(a_proc==NULL) return;
 72     if(Count==0)  return;
 73 
 74     /* special case a rectangle */
 75     point* pts = (point*)Pts;
 76     if (((Count == 4) ||
 77    ((Count == 5) && (pts[4].x == pts[0].x) && (pts[4].y == pts[0].y))) &&
 78   (((pts[0].y == pts[1].y) &&
 79     (pts[1].x == pts[2].x) &&
 80     (pts[2].y == pts[3].y) &&
 81     (pts[3].x == pts[0].x)) ||
 82    ((pts[0].x == pts[1].x) &&
 83     (pts[1].y == pts[2].y) &&
 84     (pts[2].x == pts[3].x) &&
 85     (pts[3].y == pts[0].y))))
 86       {
 87         int  xmin,xmax,ymin,ymax;
 88   xmin = (int)mn(pts[0].x, pts[2].x);
 89   ymin = (int)mn(pts[0].y, pts[2].y);
 90   xmax = (int)mx(pts[0].x, pts[2].x);
 91   ymax = (int)mx(pts[0].y, pts[2].y);
 92   if ((xmin != xmax) && (ymin != ymax))
 93       {
 94               for(y=ymin;y<=ymax;y++)  a_proc(a_tag,xmin  ,xmax  ,y);
 95       }
 96   return;
 97     }
 98 
 99     if(Count>m_pETEn)
100       {
101   cmem_free(m_pETEs);
102   m_pETEn = Count;
103   m_pETEs = cmem_alloc<EdgeTableEntry>(m_pETEn);
104   if(m_pETEs==NULL)
105     {
106       m_pETEn = 0;
107       return;
108     }
109       }
110 
111     /*G.Barrand : quiet g++-11 warnings : begin :*/
112     ET.scanlines.next = (ScanLineList*)NULL;
113     ET.ymax = SMALL_COORDINATE;
114     ET.ymin = LARGE_COORDINATE;
115     
116     AET.next = (EdgeTableEntry*)NULL;
117     AET.back = (EdgeTableEntry*)NULL;
118     AET.nextWETE = (EdgeTableEntry*)NULL;
119     AET.bres.minor_axis = SMALL_COORDINATE;
120     
121     SLLBlock.next = (ScanLineListBlock*)NULL;
122     /*G.Barrand : end.*/
123     
124     CreateETandAET (Count,(point*)Pts, &ET, &AET, m_pETEs, &SLLBlock);
125 
126     pSLL           = ET.scanlines.next;
127 
128     curPtBlock     = &m_FirstPtBlock;
129     pts            =  m_FirstPtBlock.pts;
130 
131 
132     if (rule==0)
133       {
134         /*
135          *  for each scanline
136          */
137         for (y = ET.ymin; y < ET.ymax; y++) {
138             /*
139              *  Add a new edge to the active edge table when we
140              *  get to the next edge.
141              */
142             if (pSLL != NULL && y == pSLL->scanline)
143         {
144                 LoadAET(&AET, pSLL->edgelist);
145                 pSLL = pSLL->next;
146         }
147             pPrevAET = &AET;
148             pAET = AET.next;
149 
150             /*
151              *  for each active edge
152              */
153             while (pAET) {
154                 pts->x = pAET->bres.minor_axis;
155                 pts->y = y;
156                 pts++;
157                 iPts++;
158 
159                 /*
160                  *  send out the buffer
161                  */
162                 if (iPts == NUMPTSTOBUFFER)
163       {
164                     if(numFullPtBlocks < m_numAllocPtBlocks)
165                       {
166                         curPtBlock = curPtBlock->next;
167                       }
168         else
169           {
170       POINTBLOCK* tmpPtBlock = cmem_alloc<POINTBLOCK>(1);
171                         if(tmpPtBlock==NULL)
172         {
173           FreeStorage(SLLBlock.next);
174           return;
175         }
176       tmpPtBlock->next = NULL; /*Barrand*/
177       curPtBlock->next = tmpPtBlock;
178       curPtBlock       = tmpPtBlock;
179       m_numAllocPtBlocks++;
180           }
181         numFullPtBlocks++;
182         pts  = curPtBlock->pts;
183                     iPts = 0;
184       }
185 
186                 EVALUATEEDGEEVENODD(pAET, pPrevAET, y)
187             }
188             (void) InsertAndSort(&AET);
189         }
190       }
191     else
192       {
193         /*
194          *  for each scanline
195          */
196         for (y = ET.ymin; y < ET.ymax; y++) {
197             /*
198              *  Add a new edge to the active edge table when we
199              *  get to the next edge.
200              */
201             if (pSLL != NULL && y == pSLL->scanline)
202         {
203                 LoadAET(&AET, pSLL->edgelist);
204                 ComputeWAET(&AET);
205                 pSLL = pSLL->next;
206         }
207             pPrevAET = &AET;
208             pAET = AET.next;
209             pWETE = pAET;
210 
211             /*
212              *  for each active edge
213              */
214             while (pAET) {
215                 /*
216                  *  add to the buffer only those edges that
217                  *  are in the Winding active edge table.
218                  */
219                 if (pWETE == pAET) {
220                     pts->x = pAET->bres.minor_axis;
221                     pts->y = y;
222                     pts++;
223         iPts++;
224 
225                     /*
226                      *  send out the buffer
227                      */
228         if (iPts == NUMPTSTOBUFFER)
229           {
230       if(numFullPtBlocks < m_numAllocPtBlocks)
231         {
232           curPtBlock = curPtBlock->next;
233         }
234       else
235         {
236           POINTBLOCK* tmpPtBlock = cmem_alloc<POINTBLOCK>(1);
237                             if(tmpPtBlock==NULL)
238             {
239         FreeStorage(SLLBlock.next);
240         return;
241             }
242           tmpPtBlock->next = NULL; /*Barrand*/
243           curPtBlock->next = tmpPtBlock;
244           curPtBlock       = tmpPtBlock;
245           m_numAllocPtBlocks++;
246         }
247       numFullPtBlocks++;
248       pts  = curPtBlock->pts;
249       iPts = 0;
250           }
251                     pWETE = pWETE->nextWETE;
252                 }
253                 EVALUATEEDGEWINDING(pAET, pPrevAET, y, fixWAET)
254             }
255 
256             /*
257              *  recompute the winding active edge table if
258              *  we just resorted or have exited an edge.
259              */
260             if ( (InsertAndSort(&AET)!=0) || (fixWAET!=0) )
261         {
262                 ComputeWAET(&AET);
263                 fixWAET = 0;
264         }
265         }
266       }
267     FreeStorage   (SLLBlock.next);
268 
269     ScanPoints (numFullPtBlocks, iPts, &m_FirstPtBlock,a_proc,a_tag);
270 
271   }
272 protected:
273   void ScanPoints (int  numFullPtBlocks,
274                    int  iCurPtBlock,
275                    POINTBLOCK* FirstPtBlock,
276                    scan_func a_proc,void* a_tag) {
277     point*  pts;
278     POINTBLOCK* CurPtBlock;
279     int         i;
280     CurPtBlock = FirstPtBlock;
281     for ( ; numFullPtBlocks >= 0; numFullPtBlocks--)
282       {
283         /* the loop uses 2 points per iteration */
284         i = numFullPtBlocks!=0 ? NUMPTSTOBUFFER >> 1 : iCurPtBlock >> 1 ;
285         for (pts = CurPtBlock->pts; i--; pts += 2)
286     {
287       a_proc (a_tag,(int)(pts->x),(int)pts[1].x,(int)pts->y);
288     }
289         CurPtBlock = CurPtBlock->next;
290       }
291   }
292 
293 
294 };
295 
296 }}
297 
298 #endif