[37] | 1 | #!/usr/bin/perl |
---|
| 2 | # |
---|
| 3 | # pvripsplit: Splits a .conf file into subvols for later work by pvrip. |
---|
| 4 | # |
---|
| 5 | # |
---|
| 6 | |
---|
| 7 | |
---|
| 8 | sub 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 |
---|
| 57 | undef($EPSILON); |
---|
| 58 | $SVROOT = ""; |
---|
| 59 | $MINWARNSVSIZE = 100; |
---|
| 60 | $MAXWARNSVSIZE = 2000; |
---|
| 61 | undef($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. |
---|
| 67 | undef($LOADLIMIT); |
---|
| 68 | undef($LINESTART); |
---|
| 69 | $CHUNKLINES = 5; |
---|
| 70 | $PVRIPSPLIT = "pvripsplit"; # Program to call recursively |
---|
| 71 | @ORIGARGS = @ARGV; |
---|
| 72 | # Remove -loadlimit arg from origargs... |
---|
| 73 | for ($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 |
---|
| 81 | sub run { print @_; return(`@_`); } |
---|
| 82 | sub replace { $tt = $_[0]; $tt =~ s|$_[1]|$_[2]|g; return $tt; } |
---|
| 83 | sub ls { return(split(' ', `ls @_`)); } |
---|
| 84 | $starttime = time; |
---|
| 85 | |
---|
| 86 | # First handle all the -args, removing |
---|
| 87 | # them from the args list.... |
---|
| 88 | for ($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... |
---|
| 182 | if ($#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`; |
---|
| 196 | chop($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... |
---|
| 201 | if (!defined($EPSILON)) { |
---|
| 202 | $EPSILON = $SVSIZE * 0.10; |
---|
| 203 | } |
---|
| 204 | |
---|
| 205 | # Sanity checks on subvolsize... |
---|
| 206 | if ($SVSIZE <= 0) { |
---|
| 207 | print STDERR "\nErr: subvolsize must be greater than zero.\n"; |
---|
| 208 | &printUsage(); |
---|
| 209 | } |
---|
| 210 | if ($SVSIZE < $MINWARNSVSIZE) { |
---|
| 211 | print STDERR "Warning, subvolsize is less than $MINWARNSVSIZE. There might\n"; |
---|
| 212 | print STDERR " be LOTS of subvolumes....\n"; |
---|
| 213 | } |
---|
| 214 | if ($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 | |
---|
| 219 | print 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) |
---|
| 223 | if (defined($LINESTART)) { |
---|
| 224 | $nscans = $CHUNKLINES; |
---|
| 225 | } else { |
---|
| 226 | $nscans = `wc -l $INCONFNAME`; |
---|
| 227 | ($nscans, @rest) = split(' ', $nscans); |
---|
| 228 | } |
---|
| 229 | |
---|
| 230 | # Get bbox, if specified |
---|
| 231 | if (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... |
---|
| 241 | open(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 | |
---|
| 247 | if ($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 | |
---|
| 281 | if (-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 |
---|
| 291 | if (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; |
---|
| 336 | for ($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 | |
---|
| 530 | close 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); |
---|
| 540 | print "Total running time for pvripsplit: $hours:$minutes:$seconds"."s.\n"; |
---|
| 541 | exit(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 | |
---|
| 554 | sub 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 | |
---|
| 602 | sub 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 | |
---|
| 610 | sub floor { |
---|
| 611 | local($val) = $_[0]; |
---|
| 612 | local($newval) = int($val); |
---|
| 613 | $newval-- if ($newval > $val); |
---|
| 614 | return $newval; |
---|
| 615 | } |
---|