source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/vrip/scanLinePerspRLE.cc @ 37

Last change on this file since 37 was 37, checked in by (none), 14 years ago

Added original make3d

File size: 36.4 KB
Line 
1/*
2
3Brian Curless
4
5Computer Graphics Laboratory
6Stanford University
7
8---------------------------------------------------------------------
9
10Copyright (1997) The Board of Trustees of the Leland Stanford Junior
11University. Except for commercial resale, lease, license or other
12commercial transactions, permission is hereby given to use, copy,
13modify this software for academic purposes only.  No part of this
14software or any derivatives thereof may be used in the production of
15computer models for resale or for use in a commercial
16product. STANFORD MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND
17CONCERNING THIS SOFTWARE.  No support is implied or provided.
18
19*/
20
21
22#include <math.h>
23#include <limits.h>
24#include <stdio.h>
25#include <unistd.h>
26
27#include "vrip.h"
28#include "vripGlobals.h"
29#include "linePersp.h"
30#include "resample.h"
31#include "occFunc.h"
32#include "scanLinePerspRLE.h"
33
34
35static OccScanlineRLE *theOutScanline;
36static OccGridRLE *theInGrid;
37static int currentType;
38static RunLength currentLength;
39static OccElement lastElement;
40
41
42static void initScanline(OccGridRLE *, OccScanlineRLE *);
43static void appendScanlinePortion(OccGridRLE *inGrid, int inType, 
44                                  OccElement *inElement, RunLength length);
45static void appendScanline(OccElement *inElement);
46static void sealScanline();
47
48
49
50
51void
52scanConvertLinePersp(OccGridRLE *gridIn, OccGridRLE *gridOut, 
53                     OrthoShear *shear, DepthMap *depthMap)
54{
55    float xOff, yOff, res, depth, confidence;
56    OccElement *buf, *scanline;
57    int xx,yy,zz;
58    Vec3f pos, newpos;
59
60    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
61
62    res = gridIn->resolution;
63
64    gridOut->copyParams(gridIn);
65
66    gridOut->reset();
67
68    for (zz = 0; zz < gridIn->zdim; zz++) {
69        if (!Quiet)
70            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
71        fflush(stdout);
72        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
73        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
74            buf = scanline = gridIn->getScanline(yy,zz);
75            xOff = (gridIn->sliceOrigins[zz][0] - depthMap->origin[0])/res;
76            for (xx = 0; xx < gridIn->xdim; xx++, xOff++, buf++) {
77
78                pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
79                             yy*res+gridIn->sliceOrigins[zz][1],
80                             gridIn->sliceOrigins[zz][2]);
81                applyLinePersp(pos, newpos);
82                xOff = (newpos.x - depthMap->origin[0])/res;
83                yOff = (newpos.y - depthMap->origin[1])/res;
84
85#if 1
86                resampleForCarving(depthMap, xOff, yOff, 
87                                   &depth, &confidence);
88
89                // Using the full-blown filler!
90                updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
91                                     sampleSpacing, confidence, buf);
92#else
93
94                resample(depthMap, xOff, yOff, &depth, &confidence);
95                updateCell(gridIn->sliceOrigins[zz][2], depth, 
96                           sampleSpacing, confidence, buf);
97
98#endif
99
100            }
101            gridOut->putScanline(scanline,yy,zz);
102        }
103    }
104    if (!Quiet)
105        printf("\n");
106}
107
108
109void
110scanConvertLinePerspTree(OccGridRLE *gridIn, OccGridRLE *gridOut, 
111                         OrthoShear *shear, DepthMap *depthMap)
112{
113    float xOff, yOff, res, depth, confidence;
114    OccElement *buf, *scanline;
115    int xx,yy,zz;
116    Vec3f pos, newpos;
117    int *depthRuns, numRuns;
118    float zmin, zmax, xNewOff, y1, y2;
119    int xmin, xmax;
120    OccScanlineRLE *rleScanline;
121
122    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
123
124    res = gridIn->resolution;
125
126    gridOut->copyParams(gridIn);
127
128    gridOut->reset();
129
130    for (zz = 0; zz < gridIn->zdim; zz++) {
131        if (!Quiet)
132            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
133        fflush(stdout);
134
135        // Something is really backwards here!
136
137/*
138        zmin = gridIn->sliceOrigins[zz][2] + C5/sampleSpacing;
139        zmax = gridIn->sliceOrigins[zz][2] + 2*C1/sampleSpacing;
140*/
141        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
142        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
143        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
144        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
145
146            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
147                         yy*res+gridIn->sliceOrigins[zz][1],
148                         gridIn->sliceOrigins[zz][2]);
149            applyLinePersp(pos, newpos);
150            y1 = (newpos.y - depthMap->origin[1])/res;
151
152            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
153                         yy*res+gridIn->sliceOrigins[zz][1],
154                         gridIn->sliceOrigins[zz][2]);
155            applyLinePersp(pos, newpos);
156            y2 = (newpos.y - depthMap->origin[1])/res;
157
158            // Split the y-value down the middle
159            yOff = (y1+y2)/2;
160
161            // Huber fix of 4/5/01
162            // look for areas with depth between zmin and zmax in this row
163            if ((int(yOff) >= 0) && (int(yOff) < depthMap->ydim)) {
164               depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
165            } else {
166               numRuns = 0;
167               printf("y out of range (z=%d y=%d offset=%f)\n", zz, yy, yOff);
168            }
169
170            if (numRuns == 0) {
171                rleScanline = gridIn->getRLEScanline(yy, zz);
172                gridOut->copyScanline(rleScanline, yy, zz);
173                continue;
174
175            }
176            scanline = gridIn->getScanline(yy,zz);
177            for (int i = 0; i < numRuns; i++) {
178
179                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
180                             y1*res + depthMap->origin[1],
181                             gridIn->sliceOrigins[zz][2]);
182                applyInvLinePersp(pos, newpos);
183                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
184
185                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
186                             y2*res + depthMap->origin[1],
187                             gridIn->sliceOrigins[zz][2]);
188                applyInvLinePersp(pos, newpos);
189                xmin = MIN(xmin, int((newpos.x - 
190                                      gridIn->sliceOrigins[zz][0])/res));
191                xmin = MAX(xmin, 0);
192
193
194                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
195                             y1*res + depthMap->origin[1],
196                             gridIn->sliceOrigins[zz][2]);
197                applyInvLinePersp(pos, newpos);
198                xmax = int(ceil((newpos.x - 
199                                 gridIn->sliceOrigins[zz][0])/res));
200
201                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
202                             y2*res + depthMap->origin[1],
203                             gridIn->sliceOrigins[zz][2]);
204                applyInvLinePersp(pos, newpos);
205                xmax = MAX(xmax, 
206                           int(ceil((newpos.x - 
207                                     gridIn->sliceOrigins[zz][0])/res)));
208                xmax = MIN(xmax, gridIn->xdim-1);
209
210                buf = scanline + xmin;
211                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
212
213                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
214                                 yy*res+gridIn->sliceOrigins[zz][1],
215                                 gridIn->sliceOrigins[zz][2]);
216                    applyLinePersp(pos, newpos);
217                    xOff = (newpos.x - depthMap->origin[0])/res;
218                    yOff = (newpos.y - depthMap->origin[1])/res;
219
220                    resample(depthMap, xOff, yOff, &depth, &confidence);
221                    updateCell(gridIn->sliceOrigins[zz][2], depth, 
222                               sampleSpacing, confidence, buf);
223                }
224            }
225            gridOut->putScanline(scanline,yy,zz);
226        }
227    }
228    if (!Quiet)
229        printf("\n");
230}
231
232
233
234void
235scanConvertLinePerspTreeDragTails(OccGridRLE *gridIn, OccGridRLE *gridOut, 
236                                  OrthoShear *shear, DepthMap *depthMap)
237{
238    float xOff, yOff, res, depth, confidence;
239    OccElement *buf, *scanline;
240    int xx,yy,zz;
241    Vec3f pos, newpos;
242    int *depthRuns, numRuns, oldNumRuns;
243    float zmin, zmax, xNewOff, y1, y2;
244    int xmin, xmax;
245    OccScanlineRLE *rleScanline;
246
247    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
248
249    res = gridIn->resolution;
250
251    gridOut->copyParams(gridIn);
252
253    gridOut->reset();
254
255    for (zz = 0; zz < gridIn->zdim; zz++) {
256        if (!Quiet)
257            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
258        fflush(stdout);
259
260        // Something is really backwards here!
261
262/*
263        zmin = gridIn->sliceOrigins[zz][2] + C5/sampleSpacing;
264        zmax = gridIn->sliceOrigins[zz][2] + 2*C1/sampleSpacing;
265*/
266        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
267        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
268        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
269        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
270
271            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
272                         yy*res+gridIn->sliceOrigins[zz][1],
273                         gridIn->sliceOrigins[zz][2]);
274            applyLinePersp(pos, newpos);
275            y1 = (newpos.y - depthMap->origin[1])/res;
276
277            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
278                         yy*res+gridIn->sliceOrigins[zz][1],
279                         gridIn->sliceOrigins[zz][2]);
280            applyLinePersp(pos, newpos);
281            y2 = (newpos.y - depthMap->origin[1])/res;
282
283            // Split the y-value down the middle
284            yOff = (y1+y2)/2;
285
286            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
287            if (numRuns != 0) {
288                scanline = gridIn->getScanline(yy,zz);
289                for (int i = 0; i < numRuns; i++) {
290
291                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
292                                 y1*res + depthMap->origin[1],
293                                 gridIn->sliceOrigins[zz][2]);
294                    applyInvLinePersp(pos, newpos);
295                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
296
297                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
298                                 y2*res + depthMap->origin[1],
299                                 gridIn->sliceOrigins[zz][2]);
300                    applyInvLinePersp(pos, newpos);
301                    xmin = MIN(xmin, int((newpos.x - 
302                                          gridIn->sliceOrigins[zz][0])/res));
303                    xmin = MAX(xmin, 0);
304
305
306                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
307                                 y1*res + depthMap->origin[1],
308                                 gridIn->sliceOrigins[zz][2]);
309                    applyInvLinePersp(pos, newpos);
310                    xmax = int(ceil((newpos.x - 
311                                     gridIn->sliceOrigins[zz][0])/res));
312
313                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
314                                 y2*res + depthMap->origin[1],
315                                 gridIn->sliceOrigins[zz][2]);
316                    applyInvLinePersp(pos, newpos);
317                    xmax = MAX(xmax, 
318                               int(ceil((newpos.x - 
319                                         gridIn->sliceOrigins[zz][0])/res)));
320                    xmax = MIN(xmax, gridIn->xdim-1);
321
322                    buf = scanline + xmin;
323                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
324
325                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
326                                     yy*res+gridIn->sliceOrigins[zz][1],
327                                     gridIn->sliceOrigins[zz][2]);
328                        applyLinePersp(pos, newpos);
329                        xOff = (newpos.x - depthMap->origin[0])/res;
330                        yOff = (newpos.y - depthMap->origin[1])/res;
331
332                        resampleForCarving(depthMap, xOff, yOff, 
333                                           &depth, &confidence);
334                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
335                                             depth, 
336                                             sampleSpacing, confidence, buf);
337                    }
338                }
339            }
340            oldNumRuns = numRuns;
341
342            // Points in front of the surface
343            yOff = (y1+y2)/2;
344            depthRuns = depthMap->getDepthRunsUpperBound
345                (yOff, zmin, &numRuns);
346
347            int skip = 0;
348            if (oldNumRuns == 0 && numRuns == 0) {
349                rleScanline = gridIn->getRLEScanline(yy, zz);
350                gridOut->copyScanline(rleScanline, yy, zz);
351                skip = 1;
352            } else if (numRuns == 0) {
353                gridOut->putScanline(scanline,yy,zz);
354                skip = 1;
355            } else if (oldNumRuns == 0) {
356                scanline = gridIn->getScanline(yy,zz);
357                skip = 0;
358            }
359
360            if (!skip) {
361                for (int i = 0; i < numRuns; i++) {
362
363                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
364                                 y1*res + depthMap->origin[1],
365                                 gridIn->sliceOrigins[zz][2]);
366                    applyInvLinePersp(pos, newpos);
367                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
368
369                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
370                                 y2*res + depthMap->origin[1],
371                                 gridIn->sliceOrigins[zz][2]);
372                    applyInvLinePersp(pos, newpos);
373                    xmin = MIN(xmin, int((newpos.x - 
374                                          gridIn->sliceOrigins[zz][0])/res));
375                    xmin = MAX(xmin, 0);
376
377
378                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
379                                 y1*res + depthMap->origin[1],
380                                 gridIn->sliceOrigins[zz][2]);
381                    applyInvLinePersp(pos, newpos);
382                    xmax = int(ceil((newpos.x - 
383                                     gridIn->sliceOrigins[zz][0])/res));
384
385                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
386                                 y2*res + depthMap->origin[1],
387                                 gridIn->sliceOrigins[zz][2]);
388                    applyInvLinePersp(pos, newpos);
389                    xmax = MAX(xmax, 
390                               int(ceil((newpos.x - 
391                                         gridIn->sliceOrigins[zz][0])/res)));
392                    xmax = MIN(xmax, gridIn->xdim-1);
393
394                    buf = scanline + xmin;
395                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
396                        if (buf->totalWeight == 0) {
397                            buf->value = 0;
398                        }
399                    }
400                }
401            }
402
403            oldNumRuns += numRuns;
404
405            yOff = (y1+y2)/2;
406            depthRuns = depthMap->getDepthRunsEdges
407                (yOff, zmin, &numRuns);
408
409            if (oldNumRuns == 0 && numRuns == 0) {
410                rleScanline = gridIn->getRLEScanline(yy, zz);
411                gridOut->copyScanline(rleScanline, yy, zz);
412                continue;
413            } else if (numRuns == 0) {
414                gridOut->putScanline(scanline,yy,zz);
415                continue;
416            } else if (oldNumRuns == 0) {
417                scanline = gridIn->getScanline(yy,zz);
418            }
419
420            for (int i = 0; i < numRuns; i++) {
421
422                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
423                             y1*res + depthMap->origin[1],
424                             gridIn->sliceOrigins[zz][2]);
425                applyInvLinePersp(pos, newpos);
426                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
427
428                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
429                             y2*res + depthMap->origin[1],
430                             gridIn->sliceOrigins[zz][2]);
431                applyInvLinePersp(pos, newpos);
432                xmin = MIN(xmin, int((newpos.x - 
433                                      gridIn->sliceOrigins[zz][0])/res));
434                xmin = MAX(xmin, 0);
435
436
437                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
438                             y1*res + depthMap->origin[1],
439                             gridIn->sliceOrigins[zz][2]);
440                applyInvLinePersp(pos, newpos);
441                xmax = int(ceil((newpos.x - 
442                                 gridIn->sliceOrigins[zz][0])/res));
443
444                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
445                             y2*res + depthMap->origin[1],
446                             gridIn->sliceOrigins[zz][2]);
447                applyInvLinePersp(pos, newpos);
448                xmax = MAX(xmax, 
449                           int(ceil((newpos.x - 
450                                     gridIn->sliceOrigins[zz][0])/res)));
451                xmax = MIN(xmax, gridIn->xdim-1);
452
453                buf = scanline + xmin;
454                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
455
456                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
457                                 yy*res+gridIn->sliceOrigins[zz][1],
458                                 gridIn->sliceOrigins[zz][2]);
459                    applyLinePersp(pos, newpos);
460                    xOff = (newpos.x - depthMap->origin[0])/res;
461                    yOff = (newpos.y - depthMap->origin[1])/res;
462
463                    resampleForCarving(depthMap, xOff, yOff, 
464                                       &depth, &confidence);
465                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
466                                         sampleSpacing, confidence, buf);
467                }
468            }
469
470            gridOut->putScanline(scanline,yy,zz);
471        }
472    }
473    if (!Quiet)
474        printf("\n");
475}
476
477
478void
479scanConvertLinePerspTreeTailsOnly(OccGridRLE *gridIn, OccGridRLE *gridOut, 
480                                  OrthoShear *shear, DepthMap *depthMap)
481{
482    float xOff, yOff, res, depth, confidence;
483    OccElement *buf, *scanline;
484    int xx,yy,zz;
485    Vec3f pos, newpos;
486    int *depthRuns, numRuns, oldNumRuns;
487    float zmin, zmax, xNewOff, y1, y2;
488    int xmin, xmax;
489    OccScanlineRLE *rleScanline;
490
491    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
492
493    res = gridIn->resolution;
494
495    gridOut->copyParams(gridIn);
496
497    gridOut->reset();
498
499    for (zz = 0; zz < gridIn->zdim; zz++) {
500        if (!Quiet)
501            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
502        fflush(stdout);
503
504        // Something is really backwards here!
505
506/*
507        zmin = gridIn->sliceOrigins[zz][2] + C5/sampleSpacing;
508        zmax = gridIn->sliceOrigins[zz][2] + 2*C1/sampleSpacing;
509*/
510        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
511        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
512        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
513        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
514
515            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
516                         yy*res+gridIn->sliceOrigins[zz][1],
517                         gridIn->sliceOrigins[zz][2]);
518            applyLinePersp(pos, newpos);
519            y1 = (newpos.y - depthMap->origin[1])/res;
520
521            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
522                         yy*res+gridIn->sliceOrigins[zz][1],
523                         gridIn->sliceOrigins[zz][2]);
524            applyLinePersp(pos, newpos);
525            y2 = (newpos.y - depthMap->origin[1])/res;
526
527            // Split the y-value down the middle
528            yOff = (y1+y2)/2;
529
530            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
531            if (numRuns != 0) {
532                scanline = gridIn->getScanline(yy,zz);
533                for (int i = 0; i < numRuns; i++) {
534
535                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
536                                 y1*res + depthMap->origin[1],
537                                 gridIn->sliceOrigins[zz][2]);
538                    applyInvLinePersp(pos, newpos);
539                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
540
541                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
542                                 y2*res + depthMap->origin[1],
543                                 gridIn->sliceOrigins[zz][2]);
544                    applyInvLinePersp(pos, newpos);
545                    xmin = MIN(xmin, int((newpos.x - 
546                                          gridIn->sliceOrigins[zz][0])/res));
547                    xmin = MAX(xmin, 0);
548
549
550                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
551                                 y1*res + depthMap->origin[1],
552                                 gridIn->sliceOrigins[zz][2]);
553                    applyInvLinePersp(pos, newpos);
554                    xmax = int(ceil((newpos.x - 
555                                     gridIn->sliceOrigins[zz][0])/res));
556
557                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
558                                 y2*res + depthMap->origin[1],
559                                 gridIn->sliceOrigins[zz][2]);
560                    applyInvLinePersp(pos, newpos);
561                    xmax = MAX(xmax, 
562                               int(ceil((newpos.x - 
563                                         gridIn->sliceOrigins[zz][0])/res)));
564                    xmax = MIN(xmax, gridIn->xdim-1);
565
566                    buf = scanline + xmin;
567                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
568
569                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
570                                     yy*res+gridIn->sliceOrigins[zz][1],
571                                     gridIn->sliceOrigins[zz][2]);
572                        applyLinePersp(pos, newpos);
573                        xOff = (newpos.x - depthMap->origin[0])/res;
574                        yOff = (newpos.y - depthMap->origin[1])/res;
575
576                        resampleForCarving(depthMap, xOff, yOff, 
577                                           &depth, &confidence);
578
579                        // Setting confidence to zero only allows for carving
580                        confidence = 0;
581                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
582                                             depth, 
583                                             sampleSpacing, confidence, buf);
584                    }
585                }
586            }
587            oldNumRuns = numRuns;
588
589            // Points in front of the surface
590            yOff = (y1+y2)/2;
591            depthRuns = depthMap->getDepthRunsUpperBound
592                (yOff, zmin, &numRuns);
593
594            int skip = 0;
595            if (oldNumRuns == 0 && numRuns == 0) {
596                rleScanline = gridIn->getRLEScanline(yy, zz);
597                gridOut->copyScanline(rleScanline, yy, zz);
598                skip = 1;
599            } else if (numRuns == 0) {
600                gridOut->putScanline(scanline,yy,zz);
601                skip = 1;
602            } else if (oldNumRuns == 0) {
603                scanline = gridIn->getScanline(yy,zz);
604                skip = 0;
605            }
606
607            if (!skip) {
608                for (int i = 0; i < numRuns; i++) {
609
610                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
611                                 y1*res + depthMap->origin[1],
612                                 gridIn->sliceOrigins[zz][2]);
613                    applyInvLinePersp(pos, newpos);
614                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
615
616                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
617                                 y2*res + depthMap->origin[1],
618                                 gridIn->sliceOrigins[zz][2]);
619                    applyInvLinePersp(pos, newpos);
620                    xmin = MIN(xmin, int((newpos.x - 
621                                          gridIn->sliceOrigins[zz][0])/res));
622                    xmin = MAX(xmin, 0);
623
624
625                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
626                                 y1*res + depthMap->origin[1],
627                                 gridIn->sliceOrigins[zz][2]);
628                    applyInvLinePersp(pos, newpos);
629                    xmax = int(ceil((newpos.x - 
630                                     gridIn->sliceOrigins[zz][0])/res));
631
632                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
633                                 y2*res + depthMap->origin[1],
634                                 gridIn->sliceOrigins[zz][2]);
635                    applyInvLinePersp(pos, newpos);
636                    xmax = MAX(xmax, 
637                               int(ceil((newpos.x - 
638                                         gridIn->sliceOrigins[zz][0])/res)));
639                    xmax = MIN(xmax, gridIn->xdim-1);
640
641                    buf = scanline + xmin;
642                    for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
643                        if (buf->totalWeight == 0) {
644                            buf->value = 0;
645                        }
646                    }
647                }
648            }
649
650            oldNumRuns += numRuns;
651
652            yOff = (y1+y2)/2;
653            depthRuns = depthMap->getDepthRunsEdges
654                (yOff, zmin, &numRuns);
655
656            if (oldNumRuns == 0 && numRuns == 0) {
657                rleScanline = gridIn->getRLEScanline(yy, zz);
658                gridOut->copyScanline(rleScanline, yy, zz);
659                continue;
660            } else if (numRuns == 0) {
661                gridOut->putScanline(scanline,yy,zz);
662                continue;
663            } else if (oldNumRuns == 0) {
664                scanline = gridIn->getScanline(yy,zz);
665            }
666
667            for (int i = 0; i < numRuns; i++) {
668
669                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
670                             y1*res + depthMap->origin[1],
671                             gridIn->sliceOrigins[zz][2]);
672                applyInvLinePersp(pos, newpos);
673                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
674
675                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
676                             y2*res + depthMap->origin[1],
677                             gridIn->sliceOrigins[zz][2]);
678                applyInvLinePersp(pos, newpos);
679                xmin = MIN(xmin, int((newpos.x - 
680                                      gridIn->sliceOrigins[zz][0])/res));
681                xmin = MAX(xmin, 0);
682
683
684                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
685                             y1*res + depthMap->origin[1],
686                             gridIn->sliceOrigins[zz][2]);
687                applyInvLinePersp(pos, newpos);
688                xmax = int(ceil((newpos.x - 
689                                 gridIn->sliceOrigins[zz][0])/res));
690
691                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
692                             y2*res + depthMap->origin[1],
693                             gridIn->sliceOrigins[zz][2]);
694                applyInvLinePersp(pos, newpos);
695                xmax = MAX(xmax, 
696                           int(ceil((newpos.x - 
697                                     gridIn->sliceOrigins[zz][0])/res)));
698                xmax = MIN(xmax, gridIn->xdim-1);
699
700                buf = scanline + xmin;
701                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
702
703                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
704                                 yy*res+gridIn->sliceOrigins[zz][1],
705                                 gridIn->sliceOrigins[zz][2]);
706                    applyLinePersp(pos, newpos);
707                    xOff = (newpos.x - depthMap->origin[0])/res;
708                    yOff = (newpos.y - depthMap->origin[1])/res;
709
710
711                    resampleForCarving(depthMap, xOff, yOff, 
712                                       &depth, &confidence);
713
714                    // Setting confidence to zero only allows for carving
715                    confidence = 0;
716                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
717                                         sampleSpacing, confidence, buf);
718                }
719            }
720
721            gridOut->putScanline(scanline,yy,zz);
722        }
723    }
724    if (!Quiet)
725        printf("\n");
726}
727
728
729
730void
731scanConvertLinePerspTreeTailsOnlyFast(OccGridRLE *gridIn, OccGridRLE *gridOut, 
732                                      OrthoShear *shear, DepthMap *depthMap)
733{
734    float xOff, yOff, res, depth, confidence;
735    OccElement *buf, *scanline, outElement;
736    int xx,yy,zz;
737    Vec3f pos, newpos;
738    int *depthRuns, numRuns, oldNumRuns;
739    float zmin, zmax, xNewOff, y1, y2;
740    int xmin, xmax;
741    OccScanlineRLE *rleScanline, *outScanline, *inScanline, *tempScanline;
742
743    inScanline = new OccScanlineRLE(gridIn->xdim);
744    outScanline = new OccScanlineRLE(gridIn->xdim);
745
746    float sampleSpacing = sqrt(1 + shear->sx*shear->sx + shear->sy*shear->sy);
747
748    res = gridIn->resolution;
749
750    gridOut->copyParams(gridIn);
751
752    gridOut->reset();
753
754    for (zz = 0; zz < gridIn->zdim; zz++) {
755        if (!Quiet)
756            printf("\rTraversing slice %d of %d.", zz, gridIn->zdim-1);
757        fflush(stdout);
758
759        // Something is really backwards here!
760
761/*
762        zmin = gridIn->sliceOrigins[zz][2] + C5/sampleSpacing;
763        zmax = gridIn->sliceOrigins[zz][2] + 2*C1/sampleSpacing;
764*/
765        zmin = gridIn->sliceOrigins[zz][2] - C1/sampleSpacing;
766        zmax = gridIn->sliceOrigins[zz][2] - C5/sampleSpacing;
767        yOff = (gridIn->sliceOrigins[zz][1] - depthMap->origin[1])/res;
768        for (yy = 0; yy < gridIn->ydim; yy++, yOff++) { 
769
770            pos.setValue(0*res+gridIn->sliceOrigins[zz][0],
771                         yy*res+gridIn->sliceOrigins[zz][1],
772                         gridIn->sliceOrigins[zz][2]);
773            applyLinePersp(pos, newpos);
774            y1 = (newpos.y - depthMap->origin[1])/res;
775
776            pos.setValue(gridIn->xdim*res+gridIn->sliceOrigins[zz][0],
777                         yy*res+gridIn->sliceOrigins[zz][1],
778                         gridIn->sliceOrigins[zz][2]);
779            applyLinePersp(pos, newpos);
780            y2 = (newpos.y - depthMap->origin[1])/res;
781
782            // Split the y-value down the middle
783            yOff = (y1+y2)/2;
784
785            depthRuns = depthMap->getDepthRuns(yOff, zmin, zmax, &numRuns);
786            if (numRuns != 0) {
787
788                gridIn->setScanline(yy, zz);
789                RunLength inLength = gridIn->getNextLength();
790                int inType = gridIn->getRunType(&inLength);
791                int nextInOffset = inLength;
792                OccElement *inElement;
793
794                if (inType == OccGridRLE::CONSTANT_DATA)
795                    inElement = gridIn->getNextElement();
796
797                // Prepare output scanline
798                initScanline(gridIn, outScanline);
799                xx = 0;
800
801                for (int i = 0; i < numRuns; i++) {
802
803                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
804                                 y1*res + depthMap->origin[1],
805                                 gridIn->sliceOrigins[zz][2]);
806                    applyInvLinePersp(pos, newpos);
807                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
808
809                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
810                                 y2*res + depthMap->origin[1],
811                                 gridIn->sliceOrigins[zz][2]);
812                    applyInvLinePersp(pos, newpos);
813                    xmin = MIN(xmin, int((newpos.x - 
814                                          gridIn->sliceOrigins[zz][0])/res));
815                    xmin = MAX(xmin, 0);
816
817
818                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
819                                 y1*res + depthMap->origin[1],
820                                 gridIn->sliceOrigins[zz][2]);
821                    applyInvLinePersp(pos, newpos);
822                    xmax = int(ceil((newpos.x - 
823                                     gridIn->sliceOrigins[zz][0])/res));
824
825                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
826                                 y2*res + depthMap->origin[1],
827                                 gridIn->sliceOrigins[zz][2]);
828                    applyInvLinePersp(pos, newpos);
829                    xmax = MAX(xmax, 
830                               int(ceil((newpos.x - 
831                                         gridIn->sliceOrigins[zz][0])/res)));
832                    xmax = MIN(xmax, gridIn->xdim-1);
833
834                    // Copy over all whole runs that precede the current xmin
835
836                    while (nextInOffset < xmin) {
837                        if (nextInOffset != xx) {
838                            appendScanlinePortion(gridIn, inType, inElement, 
839                                                  nextInOffset - xx);
840                        }
841                        xx = nextInOffset;
842
843                        // Update for next run
844                        inLength = gridIn->getNextLength();
845                        inType = gridIn->getRunType(&inLength);
846                        nextInOffset += inLength; 
847                        if (inType == OccGridRLE::CONSTANT_DATA) {
848                            inElement = gridIn->getNextElement();
849                        }
850                    }
851               
852
853                    // Copy over the remaining portion of the first
854                    // overlapping run
855
856                    if (xx != xmin) {
857                        appendScanlinePortion(gridIn, inType, inElement, 
858                                              xmin - xx);
859                    }
860
861                    xx = xmin;
862                   
863                    // Update the output based on new data combined with
864                    //  old data
865
866                    while (xx <= xmax) {
867
868                        // If old input run is finished, start a new one
869
870                        if (xx == nextInOffset) {
871                            inLength = gridIn->getNextLength();
872                            inType = gridIn->getRunType(&inLength);
873                            nextInOffset += inLength; 
874                            if (inType == OccGridRLE::CONSTANT_DATA) {
875                                inElement = gridIn->getNextElement();
876                            }
877                        }
878
879                        // If varying run, get next element
880
881                        if (inType == OccGridRLE::VARYING_DATA) {
882                            inElement = gridIn->getNextElement();
883                        }
884
885                        // Copy over element and update
886
887                        outElement = *inElement;
888
889                        pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
890                                     yy*res+gridIn->sliceOrigins[zz][1],
891                                     gridIn->sliceOrigins[zz][2]);
892                        applyLinePersp(pos, newpos);
893                        xOff = (newpos.x - depthMap->origin[0])/res;
894                        yOff = (newpos.y - depthMap->origin[1])/res;
895
896                        resampleForCarving(depthMap, xOff, yOff, 
897                                           &depth, &confidence);
898
899                        // Setting confidence to zero only allows for carving
900                        confidence = 0;
901                        updateCellForCarving(gridIn->sliceOrigins[zz][2], 
902                                             depth, 
903                                             sampleSpacing, confidence, 
904                                             &outElement);
905
906                        // Write element to the output grid
907                        appendScanline(&outElement);
908
909                        xNewOff++;
910                        xx++;
911                    }
912                }
913
914                // Finish up any remaining runs
915
916                while (xx < gridOut->xdim) {
917                    if (nextInOffset != xx) {
918                        appendScanlinePortion(gridIn, inType, inElement, 
919                                              nextInOffset - xx);
920                    }
921                    xx = nextInOffset;
922
923                    // Update for next run
924                    inLength = gridIn->getNextLength();
925                    inType = gridIn->getRunType(&inLength);
926
927                    if (inType == OccGridRLE::END_OF_RUN) {
928                        break;
929                    }
930
931                    nextInOffset += inLength; 
932                    if (inType == OccGridRLE::CONSTANT_DATA) {
933                        inElement = gridIn->getNextElement();
934                    }
935                }
936
937                // Seal off the old run
938                sealScanline();
939
940                gridOut->copyScanline(outScanline, yy, zz);
941                scanline = gridOut->getScanline(yy, zz);
942
943                gridIn->copyScanline(outScanline, yy, zz);
944            }
945
946            oldNumRuns = numRuns;
947
948            // Points in front of the surface
949            yOff = (y1+y2)/2;
950            depthRuns = depthMap->getDepthRunsUpperBound
951                (yOff, zmin, &numRuns);
952
953            int skip = 0;
954            if (oldNumRuns == 0 && numRuns == 0) {
955                rleScanline = gridIn->getRLEScanline(yy, zz);
956                gridOut->copyScanline(rleScanline, yy, zz);
957                skip = 1;
958            } else if (numRuns == 0) {
959                gridOut->copyScanline(outScanline,yy,zz);
960                skip = 1;
961            } else if (oldNumRuns == 0) {
962                skip = 0;
963            }
964
965            if (!skip) {
966
967                gridIn->setScanline(yy, zz);
968                RunLength inLength = gridIn->getNextLength();
969                int inType = gridIn->getRunType(&inLength);
970                int nextInOffset = inLength;
971                OccElement *inElement;
972
973                if (inType == OccGridRLE::CONSTANT_DATA)
974                    inElement = gridIn->getNextElement();
975
976                // Prepare output scanline
977                initScanline(gridIn, outScanline);
978                xx = 0;
979
980                for (int i = 0; i < numRuns; i++) {
981
982                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
983                                 y1*res + depthMap->origin[1],
984                                 gridIn->sliceOrigins[zz][2]);
985                    applyInvLinePersp(pos, newpos);
986                    xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
987
988                    pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
989                                 y2*res + depthMap->origin[1],
990                                 gridIn->sliceOrigins[zz][2]);
991                    applyInvLinePersp(pos, newpos);
992                    xmin = MIN(xmin, int((newpos.x - 
993                                          gridIn->sliceOrigins[zz][0])/res));
994                    xmin = MAX(xmin, 0);
995
996
997                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
998                                 y1*res + depthMap->origin[1],
999                                 gridIn->sliceOrigins[zz][2]);
1000                    applyInvLinePersp(pos, newpos);
1001                    xmax = int(ceil((newpos.x - 
1002                                     gridIn->sliceOrigins[zz][0])/res));
1003
1004                    pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
1005                                 y2*res + depthMap->origin[1],
1006                                 gridIn->sliceOrigins[zz][2]);
1007                    applyInvLinePersp(pos, newpos);
1008                    xmax = MAX(xmax, 
1009                               int(ceil((newpos.x - 
1010                                         gridIn->sliceOrigins[zz][0])/res)));
1011                    xmax = MIN(xmax, gridIn->xdim-1);
1012
1013
1014                    // Copy over all whole runs that precede the current xmin
1015
1016                    while (nextInOffset < xmin) {
1017                        if (nextInOffset != xx) {
1018                            appendScanlinePortion(gridIn, inType, inElement, 
1019                                                  nextInOffset - xx);
1020                        }
1021                        xx = nextInOffset;
1022
1023                        // Update for next run
1024                        inLength = gridIn->getNextLength();
1025                        inType = gridIn->getRunType(&inLength);
1026                        nextInOffset += inLength; 
1027                        if (inType == OccGridRLE::CONSTANT_DATA) {
1028                            inElement = gridIn->getNextElement();
1029                        }
1030                    }
1031               
1032
1033                    // Copy over the remaining portion of the first
1034                    // overlapping run
1035
1036                    if (xx != xmin) {
1037                        appendScanlinePortion(gridIn, inType, inElement, 
1038                                              xmin - xx);
1039                    }
1040
1041                    xx = xmin;
1042                   
1043                    // Update the output based on new data combined with
1044                    //  old data
1045
1046                    while (xx <= xmax) {
1047
1048                        // If old input run is finished, start a new one
1049
1050                        if (xx == nextInOffset) {
1051                            inLength = gridIn->getNextLength();
1052                            inType = gridIn->getRunType(&inLength);
1053                            nextInOffset += inLength; 
1054                            if (inType == OccGridRLE::CONSTANT_DATA) {
1055                                inElement = gridIn->getNextElement();
1056                            }
1057                        }
1058
1059                        // If varying run, get next element
1060
1061                        if (inType == OccGridRLE::VARYING_DATA) {
1062                            inElement = gridIn->getNextElement();
1063                        }
1064
1065                        // Copy over element and update
1066
1067                        outElement = *inElement;
1068
1069                        if (outElement.totalWeight == 0)
1070                            outElement.value = 0;
1071
1072                        // Write element to the output grid
1073                        appendScanline(&outElement);
1074
1075                        xNewOff++;
1076                        xx++;
1077                    }
1078                }
1079
1080
1081                // Finish up any remaining runs
1082
1083                while (xx < gridOut->xdim) {
1084                    if (nextInOffset != xx) {
1085                        appendScanlinePortion(gridIn, inType, inElement, 
1086                                              nextInOffset - xx);
1087                    }
1088                    xx = nextInOffset;
1089
1090                    // Update for next run
1091                    inLength = gridIn->getNextLength();
1092                    inType = gridIn->getRunType(&inLength);
1093
1094                    if (inType == OccGridRLE::END_OF_RUN) {
1095                        break;
1096                    }
1097
1098                    nextInOffset += inLength; 
1099                    if (inType == OccGridRLE::CONSTANT_DATA) {
1100                        inElement = gridIn->getNextElement();
1101                    }
1102                }
1103
1104                // Seal off the old run
1105                sealScanline();
1106
1107                gridOut->copyScanline(outScanline, yy, zz);
1108                scanline = gridOut->getScanline(yy, zz);
1109                gridIn->copyScanline(outScanline, yy, zz);
1110            }
1111
1112            oldNumRuns += numRuns;
1113
1114            yOff = (y1+y2)/2;
1115            depthRuns = depthMap->getDepthRunsEdges
1116                (yOff, zmin, &numRuns);
1117
1118            if (oldNumRuns == 0 && numRuns == 0) {
1119                rleScanline = gridIn->getRLEScanline(yy, zz);
1120                gridOut->copyScanline(rleScanline, yy, zz);
1121                continue;
1122            } else if (numRuns == 0) {
1123                gridOut->putScanline(scanline,yy,zz);
1124                continue;
1125            } else if (oldNumRuns == 0) {
1126                scanline = gridIn->getScanline(yy,zz);
1127            }
1128
1129            for (int i = 0; i < numRuns; i++) {
1130
1131                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
1132                             y1*res + depthMap->origin[1],
1133                             gridIn->sliceOrigins[zz][2]);
1134                applyInvLinePersp(pos, newpos);
1135                xmin = int((newpos.x - gridIn->sliceOrigins[zz][0])/res);
1136
1137                pos.setValue(depthRuns[2*i]*res + depthMap->origin[0],
1138                             y2*res + depthMap->origin[1],
1139                             gridIn->sliceOrigins[zz][2]);
1140                applyInvLinePersp(pos, newpos);
1141                xmin = MIN(xmin, int((newpos.x - 
1142                                      gridIn->sliceOrigins[zz][0])/res));
1143                xmin = MAX(xmin, 0);
1144
1145
1146                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
1147                             y1*res + depthMap->origin[1],
1148                             gridIn->sliceOrigins[zz][2]);
1149                applyInvLinePersp(pos, newpos);
1150                xmax = int(ceil((newpos.x - 
1151                                 gridIn->sliceOrigins[zz][0])/res));
1152
1153                pos.setValue(depthRuns[2*i+1]*res + depthMap->origin[0],
1154                             y2*res + depthMap->origin[1],
1155                             gridIn->sliceOrigins[zz][2]);
1156                applyInvLinePersp(pos, newpos);
1157                xmax = MAX(xmax, 
1158                           int(ceil((newpos.x - 
1159                                     gridIn->sliceOrigins[zz][0])/res)));
1160                xmax = MIN(xmax, gridIn->xdim-1);
1161
1162                buf = scanline + xmin;
1163                for (xx = xmin; xx <= xmax; xx++, xNewOff++, buf++) {
1164
1165                    pos.setValue(xx*res+gridIn->sliceOrigins[zz][0],
1166                                 yy*res+gridIn->sliceOrigins[zz][1],
1167                                 gridIn->sliceOrigins[zz][2]);
1168                    applyLinePersp(pos, newpos);
1169                    xOff = (newpos.x - depthMap->origin[0])/res;
1170                    yOff = (newpos.y - depthMap->origin[1])/res;
1171
1172
1173                    resampleForCarving(depthMap, xOff, yOff, 
1174                                       &depth, &confidence);
1175
1176                    // Setting confidence to zero only allows for carving
1177                    confidence = 0;
1178                    updateCellForCarving(gridIn->sliceOrigins[zz][2], depth, 
1179                                         sampleSpacing, confidence, buf);
1180                }
1181            }
1182
1183            gridOut->putScanline(scanline,yy,zz);
1184        }
1185    }
1186    if (!Quiet)
1187        printf("\n");
1188
1189   
1190    delete inScanline;
1191    delete outScanline;
1192}
1193
1194
1195
1196
1197static void
1198initScanline(OccGridRLE *inGrid, OccScanlineRLE *scanline)
1199{
1200    theInGrid = inGrid;
1201    theOutScanline = scanline;
1202    theOutScanline->reset();
1203    currentLength = 0;
1204}
1205
1206
1207static void
1208appendScanlinePortion(OccGridRLE *inGrid, int inType, 
1209                      OccElement *inElement, RunLength length)
1210{
1211    int i;
1212
1213    if (currentType == inType && currentLength > 0) {
1214
1215        if (currentType == OccGridRLE::CONSTANT_DATA) {
1216
1217            if (inElement->value == lastElement.value &&
1218                inElement->totalWeight == lastElement.totalWeight) {
1219
1220                // If same constant then just increment length.
1221                currentLength += length;
1222            } else {
1223               
1224                // If different constants, then seal old run and start
1225                // a new one
1226                inGrid->setRunType(&currentLength, currentType);
1227                theOutScanline->putNextLength(currentLength);
1228
1229                theOutScanline->putNextElement(inElement);
1230                lastElement = *inElement;
1231                currentLength = length;
1232            }
1233        } else {
1234
1235            // If old and new are varying, then add on new data
1236            for (i = 0; i < length-1; i++) {
1237                theOutScanline->putNextElement(inGrid->getNextElement());
1238            }
1239            lastElement = *(inGrid->getNextElement());
1240            theOutScanline->putNextElement(&lastElement);
1241            currentLength += length;
1242        }
1243    }
1244    else {
1245        // If different, then seal up the old run and start a
1246        // new one
1247
1248        if (currentLength > 0) {
1249            inGrid->setRunType(&currentLength, currentType);
1250            theOutScanline->putNextLength(currentLength);
1251        }
1252       
1253        if (inType == OccGridRLE::CONSTANT_DATA) {
1254            theOutScanline->putNextElement(inElement);
1255            lastElement = *inElement;
1256        } else {
1257            for (i = 0; i < length-1; i++) {
1258                theOutScanline->putNextElement(inGrid->getNextElement());
1259            }
1260            lastElement = *(inGrid->getNextElement());
1261            theOutScanline->putNextElement(&lastElement);
1262        }
1263        currentLength = length;
1264        currentType = inType;
1265    }
1266}
1267
1268
1269static void
1270appendScanline(OccElement *inElement)
1271{
1272    int i, inType;
1273
1274    inType = theInGrid->decideType(inElement);
1275    if (currentType == inType && currentLength > 0) {
1276        if (currentType == OccGridRLE::CONSTANT_DATA) {
1277            if (inElement->value == lastElement.value &&
1278                inElement->totalWeight == lastElement.totalWeight) {
1279
1280                // If same constant then just increment length.
1281                currentLength++;
1282            } else {
1283
1284                // If different constants, then seal old run and start
1285                // a new one
1286                theInGrid->setRunType(&currentLength, currentType);
1287                theOutScanline->putNextLength(currentLength);
1288                theOutScanline->putNextElement(inElement);
1289                lastElement = *inElement;
1290                currentLength = 1;
1291            }
1292        } else {
1293
1294            // If old and new are varying, then add on new data
1295            theOutScanline->putNextElement(inElement);
1296            lastElement = *inElement;
1297            currentLength++;
1298        }
1299    }
1300    else {
1301        // If different, then seal up the old run and start a
1302        // new one
1303
1304        if (currentLength > 0) {
1305            theInGrid->setRunType(&currentLength, currentType);
1306            theOutScanline->putNextLength(currentLength);
1307        }
1308
1309        lastElement = *inElement;
1310        theOutScanline->putNextElement(inElement);
1311        currentLength = 1;
1312        currentType = inType;
1313    }
1314}
1315
1316
1317static void
1318sealScanline()
1319{
1320    theInGrid->setRunType(&currentLength, currentType);
1321    theOutScanline->putNextLength(currentLength);
1322    theOutScanline->putNextLength(OccGridRLE::END_OF_RUN);         
1323}
1324
1325
Note: See TracBrowser for help on using the repository browser.