source: proiecte/pmake3d/make3d_original/Make3dSingleImageStanford_version0.1/third_party/vrippack-0.31/src/pvrip/pvripsplit @ 37

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

Added original make3d

  • Property svn:executable set to *
File size: 19.4 KB
Line 
1#!/usr/bin/perl
2#
3# pvripsplit:  Splits a .conf file into subvols for later work by pvrip.
4#
5#
6
7
8sub printUsage {
9    print STDERR "\n";
10    print STDERR "Usage: pvripsplit [options] <subvolsize> <in.conf>\n";
11    print STDERR "Where:\n";
12    print STDERR "      subvolsize     Is the size (in each dimension) of the subvol cube (mm).\n";
13    print STDERR "      in.conf        Is the conf file to splat across the subvols.\n";
14    print STDERR "Options:\n";
15    print STDERR "     -new            Creates new subvols, from scratch (default).\n";
16    print STDERR "     -update         Appends to a previously existing hierarchy.\n";
17    print STDERR "     -dice           Clips each input mesh to each bounding box, and\n"; 
18    print STDERR "                      writes each subpiece out separately (default)\n";
19    print STDERR "                      (uses lots of disk, maybe faster...)\n";
20    print STDERR "     -odice          Halfway between dice and nodice.  It will actually\n";
21    print STDERR "                      run plydice to see which subvols actually contain\n";
22    print STDERR "                      tris, but not generate any new ply files.\n";
23    print STDERR "     -nodice         Do not clip each input mesh.  This will use less\n";
24    print STDERR "                      disk space, but more RAM when pvrip runs, since\n";
25    print STDERR "                      each subvol will load every mesh whose bbox intersects.\n";
26    print STDERR "     -eps epsilon    Is the amount beyond the bbox of each subvol to\n";
27    print STDERR "                      include mesh vertices, roughly:\n";
28    print STDERR "                       (10 * maximum triangle edge length + \n";
29    print STDERR "                        vrip expansion epsilon)\n";
30    print STDERR "     -bound bbox.ply  Uses bbox.ply as the bound limits for generating subvols.\n";
31    print STDERR "                        Behavior outside this bbox is undefined... :-)\n";
32    print STDERR "     -root rootdir    Uses rootdir/XXmm/ as the root for the subvol hierarchy\n";
33    print STDERR "                        (default is ./XXXmm/)\n";
34    print STDERR "parallel options:\n";
35    print STDERR "     -loadlimit <file>   Uses the loadlimit file to run jobs across multiple\n";
36    print STDERR "                           cpus/machines.\n";
37    print STDERR "     -chunklines <size>  Group <size> lines together in a single chunk.  Default\n";
38    print STDERR "                           is 5 .conf lines per chunk. \n";
39    print STDERR "     -linestart  <line>  Only processes lines within a specified range, from\n";
40    print STDERR "                           linestart to linestart+chunklines-1. This is\n";
41    print STDERR "                           intended for recursive calls, not for the user.\n";
42    print STDERR "     -which <pvripsplit> Specify which pvripsplit to call recursively.  Defaults\n";
43    print STDERR "                           to the one in your path, after login.\n";
44    print STDERR "                           e.g. -which /u/lucasp/bin/pvripsplit\n";
45    print STDERR "\n";
46    print STDERR "Examples:\n";
47    print STDERR "one cpu:  pvripsplit -nodice 200 statue.conf\n";
48    print STDERR "parallel: pvripsplit -chunklines 2 -loadlimit loadlimit -dice 200 statue.conf\n";
49    print STDERR "\n";
50
51    exit(-1);
52}
53
54# defaults and stuff.
55$MODE = "new";
56$DODICE = 1;  # 1, .5, or 0
57undef($EPSILON);
58$SVROOT = "";
59$MINWARNSVSIZE = 100;
60$MAXWARNSVSIZE = 2000;
61undef($BOUNDNAME);
62
63# Parallelism assertions:
64# If loadlimit is not specified, then we are doing serial mode, not parallel.
65# If line number is specified, then we have been called from loadbalance,
66# and are doing only that single line.  First line is LineNo 0.
67undef($LOADLIMIT);
68undef($LINESTART);
69$CHUNKLINES = 5;
70$PVRIPSPLIT = "pvripsplit";   # Program to call recursively
71@ORIGARGS = @ARGV;
72# Remove -loadlimit arg from origargs...
73for ($i=0; $i <= $#ORIGARGS; $i++) {
74    if ($ORIGARGS[$i] eq "-loadlimit" ||
75        $ORIGARGS[$i] eq "-which") {
76        splice(@ORIGARGS, $i, 2); $i--;
77    }
78}
79
80# Helper functions for more readability
81sub run { print @_; return(`@_`); }
82sub replace { $tt = $_[0]; $tt =~ s|$_[1]|$_[2]|g; return $tt; }
83sub ls { return(split(' ', `ls @_`)); }
84$starttime = time;
85
86# First handle all the -args, removing
87# them from the args list....
88for ($i=0; $i <= $#ARGV; $i++) {
89    $arg = $ARGV[$i];
90    if (substr($arg, 0, 1) eq "-") {
91        if ($arg eq "-h") {
92            &printUsage;
93        } elsif ($arg eq "-new") {
94            $MODE = "new";
95            splice(@ARGV, $i, 1); $i--;
96        } elsif ($arg eq "-update") {
97            $MODE = "update";
98            splice(@ARGV, $i, 1); $i--;
99        } elsif ($arg eq "-dice") {
100            $DODICE = 1;
101            splice(@ARGV, $i, 1); $i--;
102        } elsif ($arg eq "-odice") {
103            $DODICE = .5;
104            splice(@ARGV, $i, 1); $i--;
105        } elsif ($arg eq "-nodice") {
106            $DODICE = 0;
107            splice(@ARGV, $i, 1); $i--;
108        } elsif ($arg eq "-eps") {
109            if ($i == $#ARGV) {
110                print STDERR "\nErr:  -eps needs another argument.\n";
111                &printUsage();
112            } else {
113                $EPSILON = $ARGV[$i+1];
114                if ($EPSILON <= 0) {
115                    print STDERR "\nErr:  epsilon must be greater than 0.\n";
116                    &printUsage();
117                }
118            }
119            splice(@ARGV, $i, 2); $i--;
120        } elsif ($arg eq "-root") {
121            if ($i == $#ARGV) {
122                print STDERR "\nErr:  -root needs another argument.\n";
123                &printUsage();
124            } else {
125                $SVROOT = $ARGV[$i+1];
126                $SVROOT .= "/" if (substr($SVROOT, -1, 1) ne "/");
127            }
128            splice(@ARGV, $i, 2); $i--;
129        } elsif ($arg eq "-bound") {
130            if ($i == $#ARGV) {
131                print STDERR "\nErr:  -bound needs another argument.\n";
132                &printUsage();
133                exit -1;
134            }
135            $BOUNDNAME = $ARGV[$i+1];
136            splice(@ARGV, $i, 2); $i--;
137        } elsif ($arg eq "-loadlimit") {
138            if ($i == $#ARGV) {
139                print STDERR "\nErr:  -loadlimit needs another argument.\n";
140                &printUsage();
141                exit -1;
142            }
143            $LOADLIMIT = $ARGV[$i+1];
144            splice(@ARGV, $i, 2); $i--;
145        } elsif ($arg eq "-chunklines") {
146            if ($i == $#ARGV) {
147                print STDERR "\nErr:  -chunklines needs another argument.\n";
148                &printUsage();
149                exit -1;
150            }
151            $CHUNKLINES = $ARGV[$i+1];
152            splice(@ARGV, $i, 2); $i--;
153        } elsif ($arg eq "-which") {
154            if ($i == $#ARGV) {
155                print STDERR "\nErr:  -which needs another argument.\n";
156                &printUsage();
157                exit -1;
158            }
159            $PVRIPSPLIT = $ARGV[$i+1];
160            splice(@ARGV, $i, 2); $i--;
161        } elsif ($arg eq "-linestart") {
162            if ($i == $#ARGV) {
163                print STDERR "\nErr:  -linestart needs another argument.\n";
164                &printUsage();
165                exit -1;
166            }
167            $LINESTART = $ARGV[$i+1];
168            splice(@ARGV, $i, 2); $i--;
169            # Set mode to update mode, because the hierarchy should already
170            # exist (since this is a child process of the original call to
171            # pvripsplit)
172            $MODE = "update";
173        } else {
174            print STDERR "\nErr, unhandled arg: $arg ...\n";
175            &printUsage();
176        }
177                       
178    }
179}
180
181# Now the args should just be the required args...
182if ($#ARGV != 1) {
183    print STDERR "\nErr: Wrong number of args\n";
184    print STDERR   "     (After stripping flags: @ARGV)\n";
185    &printUsage();
186}
187
188$SVSIZE =     $ARGV[0];
189$INCONFNAME = $ARGV[1];
190
191# Set inconfdir, which is the directory that contains the
192# conf file (then files mentioned in the conf file will be
193# found in $INCONFDIR/<whatever is mentioned>)
194$INCONFDIR = $INCONFNAME;
195$CWD = `pwd`;
196chop($CWD);
197$INCONFDIR = "$CWD/$INCONFDIR" if (substr($INCONFDIR, 0, 1) ne "/");
198$INCONFDIR =~ s|/[^/]+$||g;
199
200# Set epsilon to 10% of volume (173% data duplication), if not defined...
201if (!defined($EPSILON)) { 
202    $EPSILON = $SVSIZE * 0.10;
203}
204
205# Sanity checks on subvolsize...
206if ($SVSIZE <= 0) {
207    print STDERR "\nErr: subvolsize must be greater than zero.\n";
208    &printUsage();
209}
210if ($SVSIZE < $MINWARNSVSIZE) {
211    print STDERR "Warning, subvolsize is less than $MINWARNSVSIZE. There might\n";
212    print STDERR "         be LOTS of subvolumes....\n";
213}
214if ($SVSIZE > $MAXWARNSVSIZE) {
215    print STDERR "Warning, subvolsize is greater than $MAXWARNSVSIZE.  These subvols\n";
216    print STDERR "         might be too large to vrip...\n";
217}
218
219print STDOUT "Breaking conf file $INCONFNAME into subvols ".
220    "of size $SVSIZE, eps $EPSILON...\n";
221
222# Count number of input scans (so we can print progress)
223if (defined($LINESTART)) {
224    $nscans = $CHUNKLINES;
225} else {
226    $nscans = `wc -l $INCONFNAME`;
227    ($nscans, @rest) = split(' ', $nscans);
228}
229
230# Get bbox, if specified
231if (defined($BOUNDNAME)) {
232    $DOBOUND = 1;
233    $cmd = "plybbox $BOUNDNAME\n";
234    ($bminx, $bminy, $bminz, $bmaxx, $bmaxy, $bmaxz, @rest) =
235        split(' ', `$cmd`);
236} else {
237    $DOBOUND = 0;
238}
239
240# Open input conf file...
241open(INCONF, $INCONFNAME) || die 
242    "\nErr: Unable to open input .conf file $INCONFNAME, aborting.\n";
243
244# verify/make the directory...
245$SVROOT = "$SVROOT"."$SVSIZE"."mm";
246
247if ($MODE eq "new") {
248    if (-e $SVROOT) {
249        if (-d $SVROOT) {
250            # die "Err: Directory $SVROOT already exists. Aborting...\n";
251            print STDERR "============================================================\n";
252            print STDERR "Warn: Directory $SVROOT already exists. BAD BAD BAD! Appending..\n";
253            print STDERR "============================================================\n";
254        } else {
255            die "Err: A file by the name $SVROOT already exists. Aborting...\n";
256        }
257    } else {
258        $cmd = "mkdir -p $SVROOT\n";
259        system $cmd;
260        (!$?) || die "Err, could not mkdir $SVROOT. Aborting...\n";
261    }
262} else {
263    # Update mode
264    if (-e $SVROOT) {
265        if (-d $SVROOT) {
266            # Ok
267        } else {
268            die "Err: $SVROOT is a file, not a directory. Aborting...\n";
269        }
270    } else {
271        die "Err: Cannot find directory $SVROOT....\n";
272    }
273}
274
275# Read all.conf, the list of files that have been splatted into the
276# subvolume so far.  This helps resume a killed pvripsplit.
277# Note that if we're running in serial mode, LINESTART is undefined,
278# and therefore the file is called all.conf.
279$allconf = "$SVROOT/all$LINESTART.conf";
280
281if (-e $allconf) {
282    open(ALLCONF, $allconf) || die "Error: couldn't open $allconf.\n";
283    while (<ALLCONF>) {
284        $seen{$_} = 1;
285    }
286    close ALLCONF;
287}
288
289# Parallel Parent Process Procedure (PPPP):
290# At this point, if we're a parent process, then just call loadbalance
291if (defined($LOADLIMIT)) {
292    # first generate the command file
293    $COMMANDSFILE = "$SVROOT/pvripsplit.commands";
294    $automountdir = "/n/".`hostname`; chop $automountdir;
295    $PWD = `pwd`; chop $PWD;
296    if (substr($PWD, 0, 3) ne "/n/") {
297        $PWD = $automountdir.$PWD;
298    }
299    open(CMDS, ">$COMMANDSFILE") || 
300        die "Error, couldn't open $COMMANDSFILE for writing.\n";
301    for ($iscan = 0; $confline = <INCONF>; $iscan++) {
302        if (($iscan % $CHUNKLINES) == 0) {
303            # Generate the command line -- calling myself recursively
304            print CMDS "cd $PWD; $PVRIPSPLIT @ORIGARGS -linestart $iscan\n";
305        }
306    }
307    close CMDS;
308
309    # execute the commands
310    sleep 5; # Allow for NFS propagation delay
311    $LOGDIR = "$SVROOT/pvripsplit.logs";
312    # $cmd = "time /u/leslie/ply/src/pvrip/loadbalance $LOADLIMIT $COMMANDSFILE -logdir $LOGDIR\n";
313    $cmd = "time loadbalance $LOADLIMIT $COMMANDSFILE -logdir $LOGDIR\n";
314    system $cmd;
315
316    # Now concatenate stuff together
317    print "Merging all*.confs together....\n";
318    $cmd = "find $SVROOT -name 'all?*.conf'\n";
319    # print $cmd;
320    @alls = split(' ', `$cmd`);
321    foreach $all (@alls) {
322        ($gall = $all) =~ s/all.+\.conf/all.conf/;
323        $cmd = "cat $all >> $gall; /bin/rm $all\n";
324        system $cmd;
325    }
326    print "Done!\n";
327    exit(0);
328}
329       
330
331# Set stdout to autoflush
332$| = 1;
333
334# Process each file mentioned in the conf file...
335$iscan = 0;
336for ($iscan = 0; $confline = <INCONF>; $iscan++) {
337    # iscan, in human-readable (starts with 1) form...
338    $iscanhuman = $iscan + 1;
339
340    # Skip if we're in single-line mode, and wrong line.
341    next if (defined($LINESTART) && 
342             ($LINESTART > $iscan ||
343              $iscan >= $LINESTART + $CHUNKLINES));
344
345    @words = split(' ', $confline);
346    $ply = "$INCONFDIR/$words[1]";
347
348    # A few checks for quick skipping...
349    if ($words[0] ne "bmesh") {
350        print STDERR "Warn: skipping non-bmesh line: $confline...\n";
351        next;
352    }
353    if ($seen{$confline} == 1) {
354        print "Skipping $ply ($iscanhuman of $nscans).\n";
355        next;
356    }
357
358    $splatcount = 0;
359    print "Processing $ply ($iscanhuman of $nscans)....";
360
361    $tx = $words[2];
362    $ty = $words[3];
363    $tz = $words[4];
364    $q0 = $words[5];
365    $q1 = $words[6];
366    $q2 = $words[7];
367    $q3 = -$words[8];
368    $q3orig = $words[8];
369       
370    # bbox filename
371    $bboxfile = $ply;
372    $bboxfile =~ s/.ply$/.bbox/;
373    $rawply = $ply;
374    $rawply =~ s|^.*/||g;
375
376    if ($DODICE == 0) {
377        # nodice mode
378
379        # First figure out the bbox (either by cat'ing the bbox file,
380        # or by running plydice to generate a new one)
381        if (-e $bboxfile && 
382            (-M $bboxfile < -M $INCONFNAME)) {
383            $cmd = "cat $bboxfile\n";
384        } else {
385            $cmd = "plydice -t $tx $ty $tz -q $q0 $q1 $q2 $q3 -writebbox $bboxfile -printbbox $ply\n";
386        }
387        ($minx, $miny, $minz, $maxx, $maxy, $maxz, @rest) = split(' ', `$cmd`);
388        (!$?) || die "Err, getting bbox $bboxfile failed. aborting...\n";
389
390        # Clip against the user-specified bounds
391        if ($DOBOUND) {
392            $minx = $bminx if ($minx < $bminx);
393            $miny = $bminy if ($miny < $bminy);
394            $minz = $bminz if ($minz < $bminz);
395            $maxx = $bmaxx if ($maxx > $bmaxx);
396            $maxy = $bmaxy if ($maxy > $bmaxy);
397            $maxz = $bmaxz if ($maxz > $bmaxz);
398        }
399
400        # Figure out which subvols must be touched....
401        $minxi = &floor(($minx - $EPSILON) / $SVSIZE);
402        $minyi = &floor(($miny - $EPSILON) / $SVSIZE);
403        $minzi = &floor(($minz - $EPSILON) / $SVSIZE);
404        $maxxi = &floor(($maxx + $EPSILON) / $SVSIZE);
405        $maxyi = &floor(($maxy + $EPSILON) / $SVSIZE);
406        $maxzi = &floor(($maxz + $EPSILON) / $SVSIZE);
407
408        # For each subvol, carve away the chunk
409        if ($maxx < $minx || $maxy < $miny || $maxz < $minz) {
410            goto done;
411        }
412        for ($x = $minxi; $x <= $maxxi; $x++) {
413            for ($y = $minyi; $y <= $maxyi; $y++) {
414                for ($z = $minzi; $z <= $maxzi; $z++) {
415                    # print "$x $y $z...\n";
416                    $svdir = "$SVROOT/sv_$x"."_$y"."_$z";
417                    $svinply = "$svdir/in/$rawply";
418                    # Create the directory and necessary files....
419                    &CreateSubvolDir($svdir, $x, $y, $z);
420
421                    # Symlink in the original file (deleting if it exists)
422                    if (-e $svinply) {
423                        $cmd = "/bin/rm $svinply\n";
424                        # print $cmd;
425                        system $cmd;
426                        (!$?) || die "Error: rm $svinply failed.\n";
427                    }
428                    $cmd = "ln -s $INCONFDIR/$rawply $svinply\n";
429                    # print $cmd;
430                    system $cmd;
431                    (!$?) || die "Error: ln -s failed.\n";
432                   
433                    # Add this file to the end of the .conf file for the subvolume
434                    $svconfline = "bmesh in/$rawply $tx $ty $tz $q0 $q1 $q2 $q3orig\n";
435                    &AddToSubvolConf($svdir, $svconfline);
436                    $splatcount++;
437                }
438            }
439        }
440    } else {
441        # dice or odice mode....
442
443        # If bbox exists, and there was a user-supplied bound, then first
444        # do basic bbox intersection...
445        if ($DOBOUND && -e $bboxfile && 
446            (-M $bboxfile < -M $INCONFNAME)) {
447            $cmd = "cat $bboxfile\n";
448            ($minx, $miny, $minz, $maxx, $maxy, $maxz, @rest) = split(' ', `$cmd`);
449            (!$?) || die "Err, getting bbox $bboxfile failed. aborting...\n";
450            if ($minx > $bmaxx + $EPSILON ||
451                $miny > $bmaxy + $EPSILON ||
452                $minz > $bmaxz + $EPSILON ||
453                $maxx < $bminx - $EPSILON ||
454                $maxy < $bminy - $EPSILON ||
455                $maxz < $bminz - $EPSILON) {
456                goto done;
457            }
458        }
459
460        # There's not really an easy way to see if the dicing is up to date,
461        # so just always do it.....
462        $dicestr = "-dice";
463        $dicestr = "-odice" if ($DODICE != 1);
464        $basename = "tmp_$rawply";
465        $basename =~ s/.ply$//;
466        # Write bbox only if it's out of date...
467        $bbstr = "";
468        $bbstr = "-writebbox $bboxfile" if (!-e $bboxfile ||
469                                            -M $bboxfile >= -M $INCONFNAME);
470        # Crop to the user-specified bound?
471        if ($DOBOUND) {
472            $cropstr = " -crop $bminx $bminy $bminz $bmaxx $bmaxy $bmaxz ";
473        } else {
474            $cropstr = "";
475        }
476
477        # Do it
478        $cmd = "plydice -t $tx $ty $tz -q $q0 $q1 $q2 $q3 $bbstr ".
479            "$cropstr $dicestr $SVSIZE $EPSILON $basename $ply\n";
480        # print $cmd;
481        @subvols = `$cmd`;
482        (!$?) || die "Err, getting bbox $bboxfile failed. aborting...\n";
483
484        # Copy each subvol to the right place
485        foreach $sv (@subvols) {
486            chop($sv);
487            $nums = $sv;
488            $nums =~ s/.ply$//;
489            $nums =~ s/^$basename//;
490            ($dummy, $x, $y, $z) = split('_', $nums);
491            $svdir = "$SVROOT/sv_$x"."_$y"."_$z";
492            $svinply = "$svdir/in/$rawply";
493            # Create the directory and necessary files....
494            &CreateSubvolDir($svdir, $x, $y, $z);
495            if (-e $svinply) {
496                $cmd = "/bin/rm $svinply\n";
497                # print $cmd;
498                system $cmd;
499                (!$?) || die "Error: rm $svinply failed.\n";
500            }
501
502            # copy / symlink to put the file in place...
503            if ($DODICE == 1) {
504                $cmd = "/bin/mv $sv $svinply\n";
505            } else {
506                $cmd = "ln -s $INCONFDIR/$rawply $svinply\n";   
507            }
508            system $cmd;
509            (!$?) || die "Error: $cmd failed.\n";
510
511            # Add this file to the end of the .conf file for the subvolume
512            $svconfline = "bmesh in/$rawply $tx $ty $tz $q0 $q1 $q2 $q3orig\n";
513            &AddToSubvolConf($svdir, $svconfline);
514            $splatcount++;
515
516        }
517    }
518   
519  done:
520    # Done processing that .ply....
521    print "Done! ($splatcount subvols)\n";
522
523    # Remember this one's been processed
524    $seen{$confline} = 1;
525    open(ALLCONF, ">>$allconf");
526    print ALLCONF $confline;
527    close ALLCONF;
528}
529
530close INCONF;
531
532# Compute and print running time.
533$endtime = time;
534$totaltime = $endtime - $starttime;
535$hours = int($totaltime / 3600);
536$minutes = (int (($totaltime - $hours * 3600) / 60));
537$minutes = substr("000000$minutes",-2);
538$seconds = (int (($totaltime - ($hours * 3600 + $minutes * 60)) ));
539$seconds = substr("000000$seconds",-2);
540print "Total running time for pvripsplit: $hours:$minutes:$seconds"."s.\n";
541exit(0);
542
543######################################################################
544# End of Script.
545######################################################################
546
547
548############################################################
549# CreateSubvolDir:
550#   Creates the directory, as well as the basic files
551#   for it -- the in/ directory, all.conf, all.bbox.ply
552############################################################
553
554sub CreateSubvolDir {
555    local($svd, $x, $y, $z, @rest) = @_;
556    local($bboxminx) = $SVSIZE * $x;
557    local($bboxminy) = $SVSIZE * $y;
558    local($bboxminz) = $SVSIZE * $z;
559    local($bboxmaxx) = $SVSIZE * ($x+1);
560    local($bboxmaxy) = $SVSIZE * ($y+1);
561    local($bboxmaxz) = $SVSIZE * ($z+1);
562
563    # print "Creating subvoldir $svd....\n";
564    if (!-e $svd) {
565        local($cmd) = "mkdir -p $svd";
566        system $cmd;
567        #(!$?) || die "Error, $cmd failed.\n";
568    } 
569    local($svdin) = "$svd/in";
570    if (!-e $svdin) {
571        $cmd = "mkdir -p $svdin";
572        system $cmd;
573        #(!$?) || die "Error, $cmd failed.\n";
574    } 
575    local($svconf) = "$svd/all$LINESTART.conf";
576    if (!-e $svconf) {
577        $cmd = "touch $svconf";
578        system $cmd;
579        (!$?) || die "Error, $cmd failed.\n";
580    }
581    local($svbbox) = "$svd/all.bbox.ply";
582    if (!-e $svbbox) {
583        open(BBOX, ">$svbbox") || die "Couldn't open $svbbox.\n";
584        print BBOX "ply\n";
585        print BBOX "format ascii 1.0\n";
586        print BBOX "element vertex 2\n";
587        print BBOX "property float x\n";
588        print BBOX "property float y\n";
589        print BBOX "property float z\n";
590        print BBOX "end_header\n";
591        print BBOX "$bboxminx $bboxminy $bboxminz\n";
592        print BBOX "$bboxmaxx $bboxmaxy $bboxmaxz\n";
593        close(BBOX);
594    }
595}
596
597
598############################################################
599# Tiny helper funcs.
600############################################################
601
602sub AddToSubvolConf {
603    local($svd, $line) = @_;
604    $confname = "$svd/all$LINESTART.conf";
605    open(SVCONF, ">>$confname") || die "Error: Couldn't open $confname.\n";
606    print SVCONF $line;
607    close SVCONF;
608} 
609
610sub floor {
611    local($val) = $_[0];
612    local($newval) = int($val);
613    $newval-- if ($newval > $val);
614    return $newval;
615}
Note: See TracBrowser for help on using the repository browser.